试图写了一个双人贪吃蛇,结果蛇竖着跑正常,横着跑就只有头了,求解~
第一次发帖,如果有什么不对的地方,多多指教~效果如图
以下代码
程序代码:#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <windows.h>
#include <string.h>
#define W 70
#define H 22
#define N 2
#define MAX_LEN 400
typedef struct PLAYER
{
char key;//保存玩家输入
int head;//记录长度
int a[2];//记录蛇尾位置
int direct;
int snake [MAX_LEN][3];//每个点有三个属性 snake[i][0]=1用于表示头,0表示身体,snake【i】【1】表示横坐标。snake【i】【2】表示纵坐标。
}player;
/******光标移到指定位置**************************************************************/
void gotoxy(HANDLE hOut, int x, int y)
{
COORD pos;
pos.X = x; //横坐标
pos.Y = y; //纵坐标
SetConsoleCursorPosition(hOut, pos);
}
/******制作游戏窗口******************************************************************/
void make_frame()
{
int i;
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //定义显示器句柄变量
gotoxy(hOut,0,0); //打印框角
printf("*");
gotoxy(hOut,W,0);
printf("*");
gotoxy(hOut,0,H-1);
printf("*");
gotoxy(hOut,W,H-1);
printf("*");
for(i=0;i<W;i++)
{
gotoxy(hOut,i,0);
printf("*"); //打印上横框
}
for(i=1;i<W;i++)
{
gotoxy(hOut,i,H-1);
printf("*"); //打印下横框
}
for(i=0;i<H-1;i++)
{
gotoxy(hOut,0,i);
printf("*"); //打印左竖框
}
for(i=1;i<H-1;i++)
{
gotoxy(hOut,W,i);
printf("*"); //打印右竖框
}
}
//初始化
void init(char map[H][W],player stu[N])
{
int i,j;
//初始化蛇
//玩家一
stu[0].snake[0][0] = 0,stu[0].snake[0][1] = 9,stu[0].snake[0][2] = 7;
stu[0].snake[1][0] = 0,stu[0].snake[1][1] = 9,stu[0].snake[1][2] = 8;
stu[0].snake[2][0] = 1,stu[0].snake[2][1] = 9,stu[0].snake[2][2] = 9;
stu[0].direct=4;
//玩家二
stu[1].snake[0][0] = 0,stu[1].snake[0][1] = 13,stu[1].snake[0][2] = 7;
stu[1].snake[1][0] = 0,stu[1].snake[1][1] = 13,stu[1].snake[1][2] = 8;
stu[1].snake[2][0] = 1,stu[1].snake[2][1] = 13,stu[1].snake[2][2] = 9;
stu[1].direct=4;
}
//蛇的移动
void move(player stu[N],int number,int food[2])//number 表示玩家几
{
int x,y;//x,y作为临时交换的值,head作为蛇头
int i,j;
for(i=0;i<MAX_LEN;i++)//找到蛇头
{
if(stu[number].snake[i][0]==1)
{
stu[number].head = i;
break;
}
}
//将找到的蛇头坐标保存下来
x = stu[number].snake[stu[number].head][1];
y = stu[number].snake[stu[number].head][2];
//头移动
switch(stu[number].direct)
{
case 1://向上
stu[number].snake[stu[number].head][1]--;
break;
case 2://向下
stu[number].snake[stu[number].head][1]++;
break;
case 3://向左
stu[number].snake[stu[number].head][2]--;
break;
case 4:
stu[number].snake[stu[number].head][2]++;
break;
}
//判断是否吃到食物
if(ifEat(stu,number,food))
{
//将原来食物的位置变为蛇头
stu[number].snake[stu[number].head+1][0] = 1;
stu[number].snake[stu[number].head+1][1] = food[0];
stu[number].snake[stu[number].head+1][2] = food[1];
//将原来的蛇头变为身体
stu[number].snake[stu[number].head][0] = 0;
//将原来的食物置空
food[0] = 0;
food[1] = 0;
}
//身体移动,从头开始把前一个块的位置赋给后一个块,并保存后一个块的位置
stu[number].a[0]=stu[number].snake[0][1];
stu[number].a[1]=stu[number].snake[0][2];
for(j=stu[number].head-1;j>=0;j--)
{
int temp;
temp = x;
x = stu[number].snake[j][1];
stu[number].snake[j][1] = temp;
temp = y;
y = stu[number].snake[j][2];
stu[number].snake[j][2] = temp;
}
}
//判断是否吃到食物
int ifEat(player stu[N],int number,int food[2])
{
//判断头的位置和食物位置是否重合
if(stu[number].snake[stu[number].head][1]==food[0]&&stu[number].snake[stu[number].head][2]==food[1])
{
return 1;
}
else
{
return 0;
}
}
void makeFood(int food[2],player stu[N])
{
int x,y;
srand(time(0));
//生成一个随机坐标
x = rand() % (H-3) + 2;
y = rand() % (W-3) + 2;
while(ifReprat(stu,x,y))//如果重复再次生成,直到不重复
{
x = rand() % (H-3) + 2;
y = rand() % (W-3) + 2;
}
//!!!!!!!!!!!!!!!!!!!!!!!
food[0] = y;
food[1] = x;
}
int ifReprat(player stu[N],int x,int y)
{
int i,j;
for(i = 0;i<N;i++)
{
for(j = 0;j<MAX_LEN;j++)
{
if(stu[i].snake[j][0]==1)//到蛇头结束判断
{
break;
}
if((stu[i].snake[j][1] == x)&&(stu[i].snake[j][2] == y))//有重复
{
return 1;
}
}
}
return 0;
}
//绘制现在画面
void makeMap(HANDLE hOut,char map[H][W],player stu[N],int food[2])
{
int i,j;
/*
//重绘地图
for(i=0;i<H;i++)
{
for(j=0;j<W;j++)
{
if(i==0||j==0||i==H-1||j==W-1)
{
map[i][j] = '*';
}
else
{
map[i][j] = ' ';
}
}
}
*/
//重绘蛇
for(i=0;i<N;i++)
{
if(i==0)//不同的蛇,身体不同便于区分
{
gotoxy(hOut,stu[i].a[0],stu[i].a[1]);
printf(" ");
for(j=0;j<stu[i].head;j++)
{
gotoxy(hOut,stu[i].snake[j][1],stu[i].snake[j][2]);
if(j==0)
{
printf("○");
}
else
{
// if(stu[i].snake[j][0] == 1) break;//遇到头停止绘制
printf("⊙");
}
}
gotoxy(hOut,stu[i].snake[j][1],stu[i].snake[j][2]);
printf("¤");
}
if(i==1)
{
gotoxy(hOut,stu[i].a[0],stu[i].a[1]);
printf(" ");
gotoxy(hOut,stu[i].snake[0][1],stu[i].snake[0][2]);
printf("○");
for(j=1;j<MAX_LEN;j++)
{
if(stu[i].snake[j][0] == 1) break;//遇到头停止绘制
gotoxy(hOut,stu[i].snake[j][1],stu[i].snake[j][2]);
printf("⊙ ");
gotoxy(hOut,W,H);
}
gotoxy(hOut,stu[i].snake[j][1],stu[i].snake[j][2]);
printf("¤");
}
}
}
//判断是否撞(墙、自己、其他玩家)(判定方式待优化)
int ifBump(player stu[2],int number,int other)
{
int i,j;
if((stu[number].snake[stu[number].head][2]==0)||(stu[number].snake[stu[number].head][2]==H-1)||(stu[number].snake[stu[number].head][1]==0)||(stu[number].snake[stu[number].head][1]==W-1))
{//判断是否与墙相撞
printf("sifa1");
return 1;
}
for(j=0;j<stu[number].head-1;j++)
{//判断是不是与自己相撞
if(stu[number].snake[j][1]==stu[number].snake[stu[number].head][1]&&stu[number].snake[number][2]==stu[number].snake[stu[number].head][2])
{
printf("sifa2");
return 1;
}
}
for(i=0;i<stu[other].head-1;i++)
{//判断是不是与别人的身体相撞
if(stu[other].snake[i][1]==stu[number].snake[stu[number].head][1]&&stu[other].snake[i][2]==stu[number].snake[stu[number].head][2])
{
printf("sifa3");
return 1;
}
}
if(stu[other].snake[stu[other].head][1]==stu[number].snake[stu[number].head][1]&&stu[other].snake[stu[other].head][2]==stu[number].snake[stu[number].head][2])
{//判断是否与别人头相撞
if(stu[number].head<=stu[other].head)
{
printf("sifa4");
return 1;
}
}
return 0;
}
void getKey(player stu[N])
{
char choice;
if (_kbhit())
{
choice = _getch();
}
switch(choice)
{
case 'H':
//case 'w'://用户一按上键
if(stu[0].direct!=4)
{
stu[0].direct = 3;
}
break;
case 'P':
//case 's'://用户一按下键
if(stu[0].direct!=3)
{
stu[0].direct = 4;
}
break;
case 'K':
//case 'a'://用户一按左键
if(stu[0].direct!=2)
{
stu[0].direct = 1;
}
break;
case 'M':
// case 'd'://用户一按右键
if(stu[0].direct!=1)
{
stu[0].direct = 2;
}
break;
case '5':
//case 'i'://用户二按上键
if(stu[1].direct!=3)
{
stu[1].direct = 4;
}
break;
case '2':
//case 'k'://用户二按下键
if(stu[1].direct!=4)
{
stu[1].direct = 3;
}
break;
case '4':
// case 'j'://用户二按左键
if(stu[1].direct!=2)
{
stu[1].direct = 1;
}
break;
case '6':
// case 'l'://用户二按右键
if(stu[1].direct!=1)
{
stu[1].direct = 2;
}
break;
}
}
//存档
void Leaderboard(player stu[N],char rank[7])
{
int i,j,temp;
char ch;
FILE*fp;
if((fp=fopen("排行榜.txt","r"))==NULL)
{
printf("读取失败!\n");
exit(0);
}
ch=fgetc(fp);
i=0;
while(ch!=EOF)
{
rank[i]=ch;
ch=fgetc(fp);
i++;
}
fclose(fp);
rank[6]=stu[0].head;
rank[5]=stu[1].head;
for(i=0;i<6;i++)
{
for(j=i+1;j<7;j++)
{
if(rank[i]<rank[j])
{
temp=rank[i];
rank[i]=rank[j];
rank[j]=temp;
}
}
}
if((fp=fopen("排行榜.txt","w"))==NULL)
{
printf("缓存失败!\n");
exit(0);
}
for(i=0;i<7;i++)
{
fputc(rank[i],fp);
}
fclose(fp);
}
//判断输入是否合法
char ifLegal(char a,int low,int high)
{
a=_getch();
while(a>high||a<low)
{
a=_getch();
}
printf("%c",a);
return a;
}
int main()
{
int w;
char win;
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
char map[H][W];
int food[2];
char rank[7];
player stu[N];
int sign = 0;
food[0] = 2;
food[1] = 9;
// while(1)
// {
init(map,stu);
make_frame();
makeMap(hOut,map,stu,food);
// showview(map);
//绘制食物
gotoxy(hOut,food[0],food[1]);
printf("⊙");
while(1)
{
getKey(stu);
// system("cls");
Sleep(1000);
move(stu,0,food);
move(stu,1,food);
if (!food[0]&&!food[1])
{//食物已经被吃掉--重新生成食物
makeFood(food,stu);//生成食物坐标
gotoxy(hOut,food[0],food[1]);
printf("⊙");
}
// showview(map);
if (ifBump(stu,0,1))
{
printf("游戏结束,玩家二胜\n");
sign = 2;
break;
}
if (ifBump(stu,1,0))
{
printf("游戏结束,玩家一胜\n");
sign = 1;
break;
}
makeMap(hOut,map,stu,food);
getKey(stu);
}
// Leaderboard(stu,rank);
if(sign==1)
{
win='1';
}
else if(sign==2)
{
win='2';
}
// system("cls");
// again(map,food,rank,stu,win);
// }
gotoxy(hOut,0,H+2);//
return 0;
}

