1.贪吃蛇如何实现。
贪吃蛇长度如同队列----先进先出:每次行走都入队,如果不是食物则出队。
“□”;//背景
“■”;//蛇身
“▲”;//果实
如:贪吃蛇长度为1时,前方第二个才是果实:■□▲
队列此时长度为1。往前走一步,先入队,"□"不是果实,队列出队,并将出队者设置为背景。此时队列长度还是1。 此时变为 :□■▲
在往前走一步时,"▲"是果实,队列入队。此时队列长度为2。变为:□■■。
2.代码结构
init();//初始数据
while (1)
{
show();//显示画面
move();//移动操作
data();//数据判断
}
3.全部代码
代码编写边测所以不太规范,并且都是用全局变量,函数不传参,没有声明,没有蛇头,可以自行修改。
刷新控制台windows用 system会闪屏,应该用自带光标设置,即每次都让光标从0,0位置开始显示。
linux用printf中的\033[y;xH设置光标位置。
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#define H 11
#define W 10
#define N H*W
const char* c0 = "□";//背景
const char* c1 = "■";//蛇身
const char* c2 = "▲";//果实
//布局大小
char arr[H][W];
//方向
char dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
//当前方向标志位 默认0-上 1-下 2-左 3-右
char flag_dir = 0;
//当前蛇头坐标
char flag_x,flag_y;
//队列存储蛇身所有点坐标
char she[N][2];
//队列首尾指针
char head,end;
//得分
char fen;
void gotoxy(int x, int y) //光标移动到(x,y)位置
{
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), (COORD){x,y});
}
void suiji() //随机刷出果实
{
int c = rand()%3 +1;
for(int i=0; i<c; i++)
{
int a = rand() % (H-2) + 1;
int b = rand() % (W-2) + 1;
if( arr[a][b] == 0 )
arr[a][b] = 2;
}
}
void push() //入队
{
arr[flag_x][flag_y] = 1;
she[end][0] = flag_x;
she[end++][1] = flag_y;
head %= H*W;
end %= H*W;
}
void init()
{
flag_dir = head = end = fen = 0;
flag_x = H/2;
flag_y = W/2;
push(); //入队蛇的初始位置
suiji();
}
void show()
{
for (int i = 0; i < H; i++)
{
for (int j = 0; j < W; j++)
{
//上下边界
if (0 == i || H-1 == i)
{
printf("--");
continue;
}
//左右边界
if (0 == j || W-1 == j)
{
printf(0 == j ? "| " : " |");
continue;
}
//背景
if (0 == arr[i][j])
{
printf("%s", c0);
}
//蛇身
if (1 == arr[i][j])
{
printf("%s", c1);
}
//果实
if (2 == arr[i][j])
{
printf("%s", c2);
}
}
printf("\n");
}
printf("fen:%d\n",fen);
gotoxy(0,0);
Sleep(100);
}
void updata() //蛇一次的移动
{
//移动后新蛇头位置
flag_x += dir[flag_dir][0];
flag_y += dir[flag_dir][1];
// 新蛇头在边界或者自身 游戏结束
if(flag_x == 0 || flag_y == 0 || flag_x == H-1 || flag_y == W-1
|| arr[flag_x][flag_y] == 1 )
{
exit(0);
}
else if( arr[flag_x][flag_y] == 0 )
{
//出队
arr[ she[head][0] ][ she[head++][1] ] = 0;
//入队
push();
}
else if( arr[flag_x][flag_y] == 2 )
{
push();
fen++;
}
}
void move()
{
//等待按键触发
if(_kbhit())
{
char c = getch();
switch(c)
{
case 'W':
case 'w':
flag_dir = 0;
updata();
break;
case 's':
case 'S':
flag_dir = 1;
updata();
break;
case 'a':
case 'A':
flag_dir = 2;
updata();
break;
case 'd':
case 'D':
flag_dir = 3;
updata();
break;
}
}
}
void data()
{
static int aa = 0;
aa++;
//每5次让蛇自动走一次
if( aa%5 == 0)
updata();
//每25次自动刷新果实
if( aa%25 == 0 )
{
aa = 0;
suiji();
}
}
int main()
{
init();
while(1)
{
show();
move();
data();
}
}