- 每次用户能做的操作是输入对应移动的方向
- 每次只能有一个食物,被吃了之后继续随机生成
- snake吃了食物之后长度加一
- 碰到墙壁,或者自身之后游戏结束
功能很简单,实现起来也很straightforward,注意每次snake移动的时候,如果没有碰到食物,墙壁或者自身,只需要新加一个头的位置,去掉尾巴的位置,所以我们用list维护。
游戏效果如下:
代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Snake | |
{ | |
public: | |
Snake(int r, int c) | |
{ | |
rows = r; | |
cols = c; | |
snake.push_back(0); | |
used.insert(0); | |
food = getFood(); | |
} | |
void Start() | |
{ | |
cout << "Game Start, you are at (0, 0), board: " << endl; | |
print(); | |
while(true) | |
{ | |
cout << "Please enter your moving direction: "; | |
char c; | |
cin >> c; | |
while(!inputValid(c)) | |
{ | |
cout << endl; | |
cout << "Please make sure your input isvalid(U/R//D/L): "; | |
cin >> c; | |
} | |
int res = move(c); | |
if(res == -1) | |
{ | |
cout << "Game end!" << endl; | |
getchar(); | |
return; | |
} | |
print(); | |
cout << "Current socre: " << score() << endl; | |
} | |
} | |
private: | |
int rows, cols, food; | |
list<int> snake; | |
unordered_set<int> used; | |
vector<pair<int, int>> dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; | |
int move(char c) | |
{ | |
c = toupper(c); | |
int head = snake.front(), x = head / cols, y = head % cols; | |
switch(c) | |
{ | |
case 'U': | |
x += dirs[0].first; y += dirs[0].second; | |
break; | |
case 'R': | |
x += dirs[1].first; y += dirs[1].second; | |
break; | |
case 'D': | |
x += dirs[2].first; y += dirs[2].second; | |
break; | |
case 'L': | |
x += dirs[3].first; y += dirs[3].second; | |
break; | |
default: | |
return -1; | |
} | |
if(x >= 0 && x < rows && y >= 0 && y < cols) | |
{ | |
int tail = snake.back(); | |
if(x * cols + y != food) | |
{ | |
used.erase(tail); | |
snake.pop_back(); | |
} | |
else | |
food = getFood(); | |
if(used.find(x * cols + y) != used.end())return -1; | |
snake.push_front(x * cols + y); | |
used.insert(x * cols + y); | |
return score(); | |
} | |
else return -1; | |
} | |
void print() | |
{ | |
for(int i = 0; i < rows; ++i) | |
{ | |
for(int j = 0; j < cols; ++j) | |
{ | |
int key = i * cols + j; | |
if(food == key) | |
cout << "#"; | |
else if(used.find(key) != used.end()) | |
cout << "*"; | |
else | |
cout << "X"; | |
} | |
cout << endl; | |
} | |
} | |
int score() | |
{ | |
return static_cast<int>(snake.size()); | |
} | |
int getFood() | |
{ | |
int x = rand() % (rows * cols); | |
while(used.find(x) != used.end()) | |
x = rand() % (rows * cols); | |
return x; | |
} | |
bool inputValid(char c) | |
{ | |
c = toupper(c); | |
switch(c) | |
{ | |
case 'U': | |
case 'R': | |
case 'D': | |
case 'L': | |
return true; | |
default: | |
return false; | |
} | |
} | |
}; | |
int main() | |
{ | |
Snake snake(10, 10); | |
snake.Start(); | |
} |
No comments:
Post a Comment