-
Notifications
You must be signed in to change notification settings - Fork 0
/
game.cpp
90 lines (77 loc) · 2.26 KB
/
game.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "game.h"
Game::Game() {
level.emplace_back();
level.front().load_level(at);
player = std::make_shared<Player>();
spawn(player, {1, 1});
spawn(std::make_shared<Feline>(), {1, 3});
spawn(std::make_shared<Money>(), {3, 4});
}
Outcome Game::transfer(std::shared_ptr<Object> object,
std::shared_ptr<Object> old_owner,
std::shared_ptr<Object> new_owner) {
auto& here = old_owner->inventory;
auto is_here = std::find(here.begin(), here.end(), object);
if (is_here != here.end()) {
new_owner->inventory.splice(new_owner->inventory.end(), here, is_here);
object->location = new_owner->location;
return SUCCESS;
}
return FAIL;
}
Outcome Game::move(std::shared_ptr<Object> subject, coord destination) {
if (!at[destination]->is_clear())
return FAIL;
return transfer(subject, at[subject->location], at[destination]);
}
Outcome Game::pick_up(std::shared_ptr<Object> subject) {
// TODO: overload transfer with versions that can transfer the entire
// inventory, and later versions that can sort to transfer specific
// types of items
auto& this_place = subject->location;
for (auto item : at[this_place]->inventory)
if (item->is(CARRYABLE))
// just pick up the top item
return transfer(item, at[this_place], subject);
return FAIL;
}
Outcome Game::spawn(std::shared_ptr<Object> subject, coord location) {
subject->location = location;
items.push_back(subject);
at[location]->hold(subject);
return SUCCESS;
}
void Game::take_turn() {
// clear message line
::move(7,0);
clrtoeol();
for (auto& thing : items) {
auto e = thing->action(input);
message(thing->msg[e.action][process_event(thing, e)]);
}
}
Outcome Game::process_event(std::shared_ptr<Object> thing, event e) {
switch (e.action) {
case MOVE:
return move(thing, e.end);
case PICK_UP:
return pick_up(thing);
case WAIT:
default: return SUCCESS;
}
}
void Game::message(std::string str) {
::move(7,0);
addstr(str.c_str());
}
void Game::display() {
for (auto& place : at)
place.second->display();
}
void Game::loop() {
display();
while ((input = getch()) != KEY_F(1)) {
take_turn();
display();
}
}