游戏目标
在15*15的区域内,贪吃蛇可以进行上下左右的移动,食物随机产生在区域内的某个部分,当吃到食物时,根据食物类型,蛇身长度加一或减一。当蛇头部碰到尾部或蛇身长度为零时,判定为死亡,游戏结束。本游戏提供三种难度,玩家可自由选择,难度越高,蛇移动越快。
数据结构设计
1) 地图:行高和列宽,边框
2) 蛇:蛇头,蛇身,初始坐标(行号和列号)
3) 食物:随机坐标(行号和列号)
代码
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>
#include<iostream>
#include<iomanip>//使用setw()
using namespace std;
//定义地图
typedef struct
{
int arr[100][100];
int maxrow;
int maxcol;
char dir;
}MAP;
void tip(){
cout<<setw(60)<<"*** 设置 ***"<<endl;
cout<<setw(60)<<"***移动速度1,2,3***"<<endl;
cout<<setw(60)<<"*** 退出按0 ***"<<endl;
}
//定义一个点
typedef struct
{
int row;
int col;
}POINT;
//定义蛇的结构
typedef struct
{
POINT arr[100];
int len;
}SNAKE;
//定义食物
typedef struct
{
int row;
int col;
}FOOD;
//函数的声明
void readmap(SNAKE,MAP,FOOD,FOOD);
int move(SNAKE*,MAP*,FOOD*,FOOD*);
int gameover = 1;
int score=0; //计分
int main()
{ system("color E0");
int i,j,num,speed,maxs=0;
MAP map;
SNAKE snake;
FOOD food;
FOOD xxing;
while(1){
score=0;//新的一局重新开始
gameover = 1;
tip();
cin>>num;
if(num==0)
break;
switch(num){
case 1:{
speed=200;
break;
}
case 2:{
speed=100;
break;
}
case 3:{
speed=50;
break;
}
}
srand((int)time(0));
food.row = rand()%15;
food.col = rand()%15;
xxing.row=rand()%15;
xxing.col=rand()%15;
map.maxrow = 15;
map.maxcol = 15;
snake.arr[0].row = 7;
snake.arr[0].col = 7;
snake.arr[1].row = 7;
snake.arr[1].col = 6;
snake.len = 3;
map.dir = 'd';
while(gameover)
{
system("cls");
readmap(snake,map,food,xxing);
move(&snake,&map,&food,&xxing);
_sleep(speed);
}
if(gameover==0){
cout<<" 游戏结束!"<<endl;
}
if(score>maxs)
maxs=score;
cout<<"历史最高分:"<<maxs<<endl;
}
}
void readmap(SNAKE snake,MAP map,FOOD food,FOOD xxing)
{
int i,j,k,flag =0;
cout << "■■■■■■■■■■■■■■■■■" << endl;
for(i=0;i<map.maxrow;i++)
{
cout << "■" ;
for(j=0;j<map.maxcol;j++)
{
flag = 0; //flag为0表示该行没有蛇
for(k=0;k<snake.len;k++)
{
if(i==snake.arr[k].row && j==snake.arr[k].col)
{
if(k==0)
cout << "●" ;
else
cout << "○" ;
flag = 1; //设置flag,否则蛇所在的行右边界会超出
break;
}
}
if(flag ==0)
if(food.row==i && food.col==j)
{
cout << "★" ;
continue;
}
else if(xxing.row==i && xxing.col==j)
{
cout <<"* " ;
continue;
}
else
printf(" ");
}
cout << "■" ;
putchar('\n');
}
cout << "■■■■■■■■■■■■■■■■■" << endl;
}
int move(SNAKE *snake,MAP *map,FOOD *food,FOOD *xxing)
{
char c;
int i;
for(i=snake->len-1;i>0;i--)
snake->arr[i]=snake->arr[i-1]; //蛇移动时,从蛇尾开始往前挪动,除蛇头外,其他部位顺次往前挪动
if(kbhit())
{
c = getch();
if(c==27) //如果按下"esc",getch()返回按键的ascii的值。如果数值改为113,则表示按下"q"键
exit(1);
if(map->dir!='d' && c=='a')
map->dir = c;
else if(map->dir!='a' && c=='d')
map->dir = c;
else if(map->dir!='w' && c=='s')
map->dir = c;
else if(map->dir!='s' && c=='w')
map->dir = c;
}
if(map->dir=='d')
{
snake->arr[0].col++;
if(snake->arr[0].col >= map->maxcol)
snake->arr[0].col-=15;
}
if(map->dir=='a')
{
snake->arr[0].col--;
if(snake->arr[0].col < 0)
snake->arr[0].col+=15;
}
if(map->dir=='s')
{
snake->arr[0].row++;
if(snake->arr[0].row >= map->maxrow)
snake->arr[0].row-=15;
}
if(map->dir=='w')
{
snake->arr[0].row--;
if(snake->arr[0].row < 0)
snake->arr[0].row+=15;
}
if(snake->len==0)
gameover=0;
for(int k=4;k<snake->len;k++) //从蛇身(除蛇头外剩余部分)第4节判断蛇头是否和蛇身相碰
{
if(snake->arr[0].row==snake->arr[k].row && snake->arr[0].col==snake->arr[k].col)
gameover = 0; //若蛇头和蛇身相碰,则游戏结束
if(snake->arr[0].row==17||snake->arr[0].col==17)
gameover=0;
}
//吃到强食物,蛇身增加
if(food->row == snake->arr[0].row && food->col == snake->arr[0].col) //蛇头碰到强食物
{
snake->arr[snake->len].row = food->row;
snake->arr[snake->len].col = food->col;
snake->len++;
food->row = rand()%15;
food->col = rand()%15;
score+=10;
}
//吃到弱食物,蛇身减小
if(xxing->row == snake->arr[0].row && xxing->col == snake->arr[0].col) //蛇头碰到弱食物
{
snake->arr[snake->len].row = xxing->row;
snake->arr[snake->len].col = xxing->col;
snake->len--;
xxing->row = rand()%15;
xxing->col = rand()%15;
score-=5;
}
cout << "score=" << score;
return gameover;
}