试图写了一个双人贪吃蛇,结果蛇竖着跑正常,横着跑就只有头了,求解~
第一次发帖,如果有什么不对的地方,多多指教~效果如图
以下代码
程序代码:
#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; }