-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCellOccupier.cpp
More file actions
146 lines (127 loc) · 3.82 KB
/
Copy pathCellOccupier.cpp
File metadata and controls
146 lines (127 loc) · 3.82 KB
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include "CellOccupier.hpp"
#include "Board.hpp"
#include "Rules.hpp"
void CellOccupier::move_snake(Coord front, shared_ptr<Board> board, Snake* snake) const{
Coord old_front = board->find(snake);
board->move(snake, front);
if (snake->get_size() > 1){
SnakeTail* tail = snake->find_tail();
board->move(tail, old_front);
snake->move_tail();
}
}
bool FoodOccupier::handle_move(Coord coord, Vector::Direction, CoordinateSpace, shared_ptr<Board> board, Snake* snake, Rules* rules) const{
board->remove(this);
snake->grow(board, coord);
rules->place_food();
return true;
}
bool WallOccupier::handle_move(Coord, Vector::Direction, CoordinateSpace, shared_ptr<Board>, Snake* snake, Rules*) const{
snake->set_alive(false);
return false;
}
bool TeleportOccupier::handle_move(Coord coord, Vector::Direction direction, CoordinateSpace space, shared_ptr<Board> board, Snake* snake, Rules* rules) const{
Coord new_coord = space.move(coord, direction);
const CellOccupier* occupier = board->lookup(new_coord);
return occupier->handle_move(new_coord, direction, space, board, snake, rules);
}
bool Snake::handle_move(Coord, Vector::Direction, CoordinateSpace, shared_ptr<Board>, Snake* snake, Rules*) const{
snake->set_alive(false);
return false;
}
bool SnakeTail::handle_move(Coord, Vector::Direction, CoordinateSpace, shared_ptr<Board>, Snake* snake, Rules*) const{
snake->set_alive(false);
return false;
}
Snake::Snake(int size, Vector::Direction d) : CellOccupier(){
m_size = size;
m_alive = true;
m_direction = d;
m_next = NULL;
m_speed = FAST;
}
Snake::~Snake(){
if( m_next != NULL ){
SnakeTail* front = m_next;
SnakeTail* next_tail = m_next->get_next();
front->m_next = NULL; // Break the loop.
while( next_tail != NULL ){
SnakeTail* current = next_tail;
next_tail = current->get_next();
delete current;
}
}
}
Vector::Direction Snake::get_direction() const{
return m_direction;
}
void Snake::set_direction(Vector::Direction d){
m_direction = d;
}
void Snake::build_tail(shared_ptr<Board> board, CoordinateSpace space){
if( m_size > 1 ){
Coord front;
for (int i = 0; i < m_size - 1; ++i){
front = board->find(this);
grow(board, space.move(front, m_direction));
}
}
}
SnakeTail* Snake::find_tail() const{
if( m_next != NULL ){
return find_prev(m_next);
}
return NULL;
}
int Snake::get_size() const{
return m_size;
}
void Snake::move_tail(){
SnakeTail* tail = find_tail();
m_next = tail;
}
SnakeTail* Snake::find_prev(SnakeTail* tail) const{
SnakeTail* next = m_next;
while(next->m_next != tail ){
next = next->m_next;
}
return next;
}
void Snake::grow(shared_ptr<Board> board, Coord new_front){
Coord old_front = board->find(this);
if (m_next != NULL){
SnakeTail* new_tail = new SnakeTail();
SnakeTail* end_of_tail = find_prev(m_next);
end_of_tail->m_next = new_tail;
new_tail->m_next = m_next;
m_next = new_tail;
board->move(this, new_front);
board->insert(new_tail, old_front);
} else {
m_next = new SnakeTail();
m_next->m_next = m_next;
board->move(this, new_front);
board->insert(m_next, old_front);
}
}
int Snake::get_speed() const{
return m_speed;
}
void Snake::set_alive(bool alive){
m_alive = alive;
}
bool Snake::is_alive() const{
return m_alive;
}
SnakeIterator Snake::begin() const{
return SnakeIterator(this, NULL);
}
SnakeIterator Snake::end() const{
return SnakeIterator(this->next(), find_tail());
}
const IterableSnake * Snake::next() const{
return m_next;
}
const CellOccupier * Snake::get_cell_occupier() const{
return this;
}