-
Notifications
You must be signed in to change notification settings - Fork 0
/
Snake.cpp
114 lines (110 loc) · 2.52 KB
/
Snake.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
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
#ifndef SNAKE_H
#define SNAKE_H
#include <ctime>
#include <utility>
#include <vector>
using namespace std;
typedef pair<int, int> PII;
class SnakeNode {
public:
PII pos;
char dir;
SnakeNode(PII pos, char dir) : pos(pos), dir(dir){};
};
class Snake {
private:
PII head;
PII tail;
char dir = 'r';
char tdir = 'r';
vector<SnakeNode*> body;
clock_t lastChangeDir = clock();
public:
/**
* @brief Construct a new Snake
*
* @param head the coordinate of the head
* @param len the length of the snake
*/
Snake(PII head, int len) {
this->head = head;
for (int i = head.second; i >= head.second - len + 1; i--) {
cout << head.first << ',' << i << endl;
body.push_back(new SnakeNode(make_pair(head.first, i), 'r'));
}
}
/**
* @brief function used by another thread to change the direction of the snake
*
* @param dir can be u, d, l, r
* @param sleepTime prevent from changing the direction too frequently
*/
void changeDir(char dir, int sleepTime) {
auto t = clock();
if (t - lastChangeDir < sleepTime / 1000) {
return;
}
lastChangeDir = clock();
if (dir == this->dir) {
return;
}
if (this->dir + dir == 'u' + 'd') {
return;
}
if (this->dir + dir == 'l' + 'r') {
return;
}
this->dir = dir;
}
/**
* @brief move the snake according to the current status
*
*/
void move() {
tdir = body.back()->dir;
tail = body.back()->pos;
// each body node should follow the one ahead, and the head should follow the instruction given by the player
for (int i = body.size() - 1; i >= 1; i--) {
body[i]->dir = body[i - 1]->dir;
}
body.front()->dir = this->dir;
for (int i = 0; i < body.size(); i++) {
switch (body[i]->dir) {
case 'u':
body[i]->pos.first--;
break;
case 'r':
body[i]->pos.second++;
break;
case 'd':
body[i]->pos.first++;
break;
case 'l':
body[i]->pos.second--;
break;
}
}
}
/**
* @brief when the snake eats food, it should grow longer
*
*/
void grow() {
auto node = new SnakeNode(tail, body.back()->dir);
body.push_back(node);
}
/**
* @brief Get every coordinate of the body of the snake
*
* @return vector<PII>
*/
vector<PII> getLoc() {
vector<PII> loc;
for (int i = 0; i < body.size(); i++) {
loc.push_back(body[i]->pos);
}
return loc;
}
PII getHeadLoc() { return body.front()->pos; }
};
#endif