Saturday, November 24, 2018

[Game]Snake

实现贪食蛇的功能,具体如下:

  • 每次用户能做的操作是输入对应移动的方向
  • 每次只能有一个食物,被吃了之后继续随机生成
  • snake吃了食物之后长度加一
  • 碰到墙壁,或者自身之后游戏结束
功能很简单,实现起来也很straightforward,注意每次snake移动的时候,如果没有碰到食物,墙壁或者自身,只需要新加一个头的位置,去掉尾巴的位置,所以我们用list维护。

游戏效果如下:



代码如下:
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();
}
view raw Snake.cpp hosted with ❤ by GitHub

No comments:

Post a Comment