This repository was archived by the owner on Apr 8, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplayer.cpp
More file actions
240 lines (204 loc) · 5.91 KB
/
Copy pathplayer.cpp
File metadata and controls
240 lines (204 loc) · 5.91 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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/*****************************************************************************
* Project Nydus
****************************************************************************/
#include "player.h"
/*************************************************************************//**
* @file
*
* @Main file for player Nydus
****************************************************************************/
/*************************************************************************//**
* @author William Doering
*
* @par Description:
* This function will make a decision for what directon to move.
*
* @param[in] pf - Playfield class being used by the game
*
* @returns move - move chosen for player
****************************************************************************/
ValidMove Player::makeMove(const Playfield *pf)
{
const int *grid = pf->getGrid();
//Check for obstacles and run corresponding function.
static bool hasObstacles = obstacleCheck(grid);
if(!hasObstacles)
return noObstacles(grid);
return normPass(pf);
}
/*************************************************************************//**
* @author William Doering
*
* @par Description:
* This function will check for obstacles in the playfield.
*
* @param[in] grid - map of the playfield
*
* @returns true - has obstacles
* @returns false - doesn't have obstacles
****************************************************************************/
bool Player::obstacleCheck(const int *grid)
{
for(int i=0; i < SIZE; i++)
{
switch(grid[i])
{
case CLEAR_VALUE:
case HEAD_VALUE:
case FOOD_VALUE:
break;
case TAIL_VALUE:
return true;
}
}
return false;
}
/*************************************************************************//**
* @author William Doering
*
* @par Description:
* This function controls snake movement if there are obstacles. It uses a
* general sweep motion across the board to prevent colisions.
*
* @param[in] pf - Playfield class for the snake
*
* @returns move - best move for the snake
****************************************************************************/
ValidMove Player::normPass(const Playfield *pf)
{
const int *grid = pf->getGrid();
static ValidMove move;
ValidMove nextMove;
int food;
Graph map(grid, PLAYFIELD_WIDTH, PLAYFIELD_HEIGHT);
Heatmap path(map, pf);
food = path.findItem(grid, FOOD_VALUE);
nextMove = path.moveTowards(grid, food);
if(nextMove != NONE)
move = nextMove;
return move;
}
/*************************************************************************//**
* @author William Doering
*
* @par Description:
* This function controls snake movement if there are no obstacles. There are
* two separate algorithms, one for an odd height and one for an even one.
*
* @param[in] grid - map of the playfield
*
* @returns ValidMove - Move selected for snake
****************************************************************************/
ValidMove Player::noObstacles(const int *grid)
{
int pos;
ValidMove move;
//Find Head
for(int i=0; i<SIZE; i++)
if(grid[i] == HEAD_VALUE)
pos = i;
//Get next move based on even or odd
if(PLAYFIELD_HEIGHT%2)
move = oddHeight(grid, pos);
else
move = evenHeight(grid, pos);
//Check move
for(int i=0; i<SIZE; i++)
if(grid[i] == CLEAR_VALUE)
return move;
return NONE;
}
/*************************************************************************//**
* @author William Doering
*
* @par Description:
* This function selects a move for a playfield without obstacles that has an
* even height
*
* @param[in] grid - map of the playfield
* @param[in] pos - position of snake head
*
* @returns ValidMove - Move selected for snake
****************************************************************************/
ValidMove Player::evenHeight(const int *grid, int pos)
{
//If at origin
if(pos == 0)
return RIGHT;
//If along left side, but not origin
if(pos%PLAYFIELD_WIDTH == 0)
return DOWN;
//If on top row and not above cases
if((pos/PLAYFIELD_WIDTH) == (PLAYFIELD_HEIGHT-1))
return LEFT;
//Even or odd row check
if((pos/PLAYFIELD_WIDTH)%2 == 0)
{
if((pos%PLAYFIELD_WIDTH) == (PLAYFIELD_WIDTH-1))
return UP;
else
return RIGHT;
}
else
{
if((pos%PLAYFIELD_WIDTH) == 1)
return UP;
else
return LEFT;
}
//Return if no cases are found (an error)
return NONE;
}
/*************************************************************************//**
* @author William Doering
*
* @par Description:
* This function selects a move for a playfield without obstacles that has an
* odd height
*
* @param[in] grid - map of the playfield
* @param[in] pos - position of snake head
*
* @returns ValidMove - Move selected for snake
****************************************************************************/
ValidMove Player::oddHeight(const int *grid, int pos)
{
static bool skip = false;
int height = PLAYFIELD_HEIGHT - 1;
//If at origin
if(pos == 0)
{
skip = !skip;
return RIGHT;
}
//If along left side, but not origin
if(pos%PLAYFIELD_WIDTH == 0)
return DOWN;
//If on top row and not above cases
if((pos/PLAYFIELD_WIDTH) == (height))
return LEFT;
//If on second to top row and not above cases
if((pos/PLAYFIELD_WIDTH) == (height-1))
{
if(skip && ((pos%PLAYFIELD_WIDTH) == (PLAYFIELD_WIDTH-1)))
return UP;
return LEFT;
}
//Even or odd row check
if((pos/PLAYFIELD_WIDTH)%2 == 0)
{
if((pos%PLAYFIELD_WIDTH) == (PLAYFIELD_WIDTH-1))
return UP;
else
return RIGHT;
}
else
{
if((pos%PLAYFIELD_WIDTH) == 1)
return UP;
else
return LEFT;
}
//Return if no cases are found (an error)
return NONE;
}