数据结构:双向链表
1.程序未使用graphis.h中的 函数,所以采用先清屏,再打印的方式显示图形,大约每秒刷新一次;
2.除蛇头元素外,其它元素的状态(行进方向)均重复前一元素;
3.蛇的图形元素为笑脸,可在源码中更改symbol参数选用不同元素。
游戏截图1
游戏截图2
/*********************************
*time: 2016.09.17 22:50
*version:1.0
*********************************/
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<conio.h>
#defineUP 0
#defineDOWN 1
#defineLEFT 2
#defineRIGHT 3
#defineHIGH 35
#defineWIDTH 80//必须为偶数
inttemp[HIGH][WIDTH];//像素数组,用于打印图形(蛇、食物、空格)
intSTATE = LEFT;//初始状态为向左走
intFOODPOS =700;//WIDTH*HIGH/2+WIDTH/2-WIDTH*HIGH/4;//食物的初始位置
#defineINIT_LEN 1//初始蛇的长度
intinit_pos[INIT_LEN] = {HIGH/2*WIDTH+WIDTH/2};//蛇的初始位置
intSCORE =0;//得分
//蛇的结构体
structItem{
intpos;//位置
intstate;//状态:上下左右
structItem*per, *next;
};
structItem*head, *tail, *iTemp;
charsymbol =2;//元素符号
//获取元素的位置
intgetPos(intpos,intstate){
if(state == UP)
pos -= WIDTH;
elseif(state == DOWN)
pos += WIDTH;
elseif(state == LEFT)
pos -=2;
elseif(state == RIGHT)
pos +=2;
else
{
printf("\n状态state出错!");
exit(-1);
}
returnpos;
}
//更新蛇的位置与状态
voidchange(){
while(1){
print();
iTemp = tail;
while(iTemp != head){
iTemp->state = iTemp->per->state;//当前元素的状态等于其前驱的状态
iTemp->pos = getPos(iTemp->pos,iTemp->state);//更新位置信息
iTemp = iTemp->per;
}
head->state = STATE;
head->pos = getPos(head->pos, head->state);
}
}
//打印图形
voidprint(){
inth, w;
for(h =1; h < HIGH-1; h++)//初始化像素数组
for(w =1; w < WIDTH-1; w++)
temp[h][w] =0;
for(w =0; w < WIDTH; w +=2){//置第0行和最后一行为2
temp[0][w] =2;
temp[HIGH-1][w] =2;
}
for(h =0; h < HIGH; h++){//置第0列和最后一列为2
temp[h][0] =2;
temp[h][WIDTH-1] =2;
}
iTemp = head->next;
while(iTemp){
h = iTemp->pos / WIDTH;
w = iTemp->pos % WIDTH;
temp[h][w] =1;
iTemp = iTemp->next;
}
h = head->pos / WIDTH;
w = head->pos % WIDTH;
inti;
if(temp[h][w] ==2|| temp[h][w] ==1){//撞到墙或自己,游戏结束head->pos < 0 || head->pos > HIGH*WIDTH
for(i =0; i < (WIDTH-12)/2; i++)
printf(" ");
printf("游戏结束:%d分", SCORE);
getchar();
exit(0);
}
else
temp[h][w] =1;
temp[FOODPOS/WIDTH][FOODPOS%WIDTH] =1;
if(head->pos == FOODPOS){
//吃食物
structItem*new= (structItem*)malloc(sizeof(structItem));
new->next = head;
head->per =new;
//head = new;
new->per =NULL;
new->pos = getPos(head->pos, head->state);
new->state = head->state;
head =new;
SCORE +=10;
//产生新食物
while(temp[FOODPOS/WIDTH][FOODPOS%WIDTH] ==1|| temp[FOODPOS/WIDTH][FOODPOS%WIDTH] ==2|| FOODPOS %2==1){
FOODPOS = rand() % (HIGH * WIDTH);
}
temp[FOODPOS/WIDTH][FOODPOS%WIDTH] =1;
}
//清屏并打印图形
system("cls");
for(h =0; h < HIGH; h++)
for(w =0; w < WIDTH; w++){
if(temp[h][w] ==0)
printf(" ");
elseif(temp[h][w] ==1)
printf("%c", symbol);
elseif(temp[h][w] ==2)
printf("*");
else{
printf("\t\t\t\t\t error!");
exit(-2);
}
}
}
//初始化结构体
voidinit(){
inti;
head = (struct Item*)malloc(sizeof(struct Item));
head->per =NULL;
iTemp = head;
iTemp->pos = init_pos[0];
iTemp->state = LEFT;
for(i =1; i < INIT_LEN; i++){
iTemp->next = (struct Item*)malloc(sizeof(struct Item));
iTemp->next->per = iTemp;
iTemp = iTemp->next;
iTemp->pos = init_pos[i];
iTemp->state = LEFT;
}
iTemp->next =NULL;
tail = iTemp;
}
DWORD WINAPIThread1(LPVOID pM){
while(1){
change();
}
return0;
}
DWORD WINAPIThread2(LPVOID pM){
charc;
while(1){
c = _getch();//控制蛇的行进方向
if(c =='a'&& STATE != RIGHT)
STATE = LEFT;
elseif(c =='d'&& STATE != LEFT)
STATE = RIGHT;
elseif(c =='w'&& STATE != DOWN)
STATE = UP;
elseif(c =='s'&& STATE != UP)
STATE = DOWN;
else
continue;
}
return0;
}
intmain(void){
system("mode con cols=80 lines=40");//设置窗口大小
system("color 8f");//设置窗口颜色
init();
HANDLE handle1 = CreateThread(NULL,0, Thread1,NULL,0,NULL);//线程1
HANDLE handle2 = CreateThread(NULL,0, Thread2,NULL,0,NULL);//线程2
WaitForSingleObject(handle1, INFINITE);
WaitForSingleObject(handle2, INFINITE);
return0;
}
如果你对编程感兴趣或者想往编程方向发展,可以关注微信公众号【筑梦编程】,大家一起交流讨论!小编也会每天定时更新既有趣又有用的编程知识!
网友评论