diff --git a/Gobang.txt b/Gobang.txt new file mode 100644 index 0000000..f25a4d6 --- /dev/null +++ b/Gobang.txt @@ -0,0 +1,484 @@ +#include +#include +#include +#include + +#define N 100 + +char c, j; //用于通过按键移动 +int score1=0, score2=0; //分数 +int map[N][N]={0}; //定义棋盘的初始值为0 + +void gamestart(); //游戏开始界面 +void help(); //帮助界面,告知玩家如何操作 +void gotoxy(int ,int ); //控制光标的移动 +void creatmap(); //画棋盘 +void playchess(); //玩五子棋 +int judge1(int ,int ); //判断玩家一是否连成五子 +int judge2(int ,int ); //判断玩家二是否连成五子 +void renew(); //将棋盘恢复成初始值0 +void scoring(int ); //计分 +void game_over(); //一局游戏结束的画面 + +int main() +{ + system("COLOR F0"); //设置背景色和棋盘色 + gamestart(); + playchess(); + return 0; +} + +/*----------------------------------------------------------*/ + +void gamestart() //游戏开始的界面 +{ + gotoxy(45,15); + printf("欢迎来到五子棋游戏"); + gotoxy(45,18); + printf("请按任意键进入帮助界面"); + getch(); + system("cls"); //清屏 + help(); +} + +/*-----------------------------------------------------------*/ + +void help() +{ + gotoxy(45,10); + printf("请在英文状态下进行五子棋对弈"); + gotoxy(45,13); + printf("一号玩家为w、s、a、d控制上下左右,空格键落子"); + gotoxy(45,14); + printf("二号玩家为↑、↓、←、→控制上下左右,回车键落子"); + gotoxy(45,15); + printf("按Backspace键可悔棋,按ESC键退出游戏"); + gotoxy(45,18); + printf("请按任意键确定进入游戏界面"); + getch(); + system("cls"); +} + +/*-----------------------------------------------------------*/ + +void game_over() +{ + char z; + system("cls"); + gotoxy(45,10); + printf("游戏结束,是否开始新一局游戏?"); + gotoxy(45,11); + printf("继续游戏请按Y/y,结束游戏请按N/n"); + lable3: //设置一个标签三 + { + z=getch(); + if(z!='Y' && z!='y' && z!='N' && z!='n') + { + gotoxy(45,14); + printf("输入错误,请重新输入"); + goto lable3; //重新进行标签三里的语句 + } + if(z=='Y' || z=='y') + { + system("cls"); + renew(); + playchess(); + } + if(z=='Z' || z=='n') + { + exit(0); + } + } +} + +/*-----------------------------------------------------------*/ + +void gotoxy(int x, int y) //定位到第y行的第x列 +{ + int xx=0x0b; + HANDLE hOutput; + COORD loc; + loc.X = x; + loc.Y=y; + hOutput = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleCursorPosition(hOutput, loc); + return; +} + +/*------------------------------------------------------------*/ + +void gotoprint(int x,int y) +{ + gotoxy(x,y); + printf("┬"); +} +void gotoprint2(int x,int y) +{ + gotoxy(x,y); + printf("├ "); +} +void gotoprint3(int x,int y) +{ + gotoxy(x,y); + printf("┼"); +} +void gotoprint4(int x,int y) +{ + gotoxy(x,y); + printf("┤"); +} +void gotoprint5(int x,int y) +{ + gotoxy(x,y); + printf("┴"); +} +void gotoprint6(int x,int y) +{ + gotoxy(x,y); + printf("-"); +} +void gotoprint7(int x,int y) +{ + gotoxy(x,y); + printf("★"); +} + +/*-------------------------------------------------------------*/ + +void creatmap() +{ + int i, j; + gotoxy(0,1); + printf("┌"); + for(i=1;i<=39;i++) //横轴上的必须翻倍才与纵轴相等!!!! + { + if(i%2!=0) + { + gotoprint6(i,1); + gotoprint6(i,21); + } + else + { + gotoprint(i,1); + gotoprint5(i,21); + } + } + gotoxy(0,21); + printf("└"); + gotoxy(40,1); + printf("┐"); + for(i=2;i<=20;i++) + { + gotoprint2(0,i); + gotoprint4(40,i); + } + for(i=2;i<40;i+=2) + { + for(j=2;j<=20;j++) + gotoprint3(i,j); + } + gotoxy(40,21); + printf("┘"); + printf("\n"); +} + +/*-------------------------------------------------------------*/ + +void playchess() +{ + creatmap(); + gotoxy(45,5); + printf("请在棋盘内落子,边缘不可落子"); + int whoturn=0; //判断一号玩家还是二号玩家落子 + int a=2, b=2; //游戏刚开始时光标所在的位置 + int q, w, e, r; //悔棋时用 + while(1) + { + if(whoturn%2==0) + { + lable1: //设置标签一,用于一号玩家悔棋 + { + c=1; + gotoxy(18,0); + printf("黑子"); + gotoxy(45,10); + printf("现在轮到一号玩家,请落子"); //提示一号玩家落子 + while(c!=' ') + { + c=getch(); + switch (c) + { + case 'w': //向上,纵坐标减一 + { + gotoxy(a,b-1); + b-=1; + break; + } + case 's': //向下,纵坐标加一 + { + gotoxy(a,b+1); + b+=1; + break; + } + case 'a': //向左,横坐标减二 + { + gotoxy(a-2,b); + a-=2; + break; + } + case 'd': //向右,横坐标加二 + { + gotoxy(a+2,b); + a+=2; + break; + } + } + q=a,w=b; + if(c==' ') //按空格键落子 + { + gotoxy(a,b); + if(map[a][b]==1 || map[a][b]==2) //如果所要下的地方为已经下过的则重新选地方下子 + goto lable1; + map[a][b]=2; //将一号玩家落子的地方的值变为2,以判断一号玩家是否连成五子 + printf("●"); //一号玩家为黑子 + if(judge1(a,b)==1) //一号玩家连成五子 + { + scoring(1); + gotoxy(45,15); + printf("恭喜一号玩家胜利!!!\a"); + Sleep(2000); //延迟两秒再清屏开始新一局游戏 + game_over(); //进入游戏结束画面 + } + } + if(c==8) //Backspace键的ASCII码为8 + { + gotoprint3(e,r); + whoturn--; //二号玩家悔棋,回到上一次的二号玩家 + goto lable2; + } + if(c==27) //ESC键的ASCII码为27 + { + system("cls"); + exit(0); //实现按ESC键退出游戏的功能 + } + } + } + } + if(whoturn%2==1) + { + lable2: //设置标签二,用于二号玩家悔棋 + { + j=1; + gotoxy(18,0); + printf("白子"); + gotoxy(45,10); + printf("现在轮到二号玩家,请落子"); //提示二号玩家落子 + while(j!=13) + { + j=getch(); + if(j==0xE0) //方向键按一次会有两个值,所以得接收两次 + j=getch(); + switch (j) + { + case 72: //向上,纵坐标减一 + { + gotoxy(a,b-1); + b-=1; + break; + } + case 80: //向下,纵坐标加一 + { + gotoxy(a,b+1); + b+=1; + break; + } + case 75: //向左,横坐标减二 + { + gotoxy(a-2,b); + a-=2; + break; + } + case 77: //向右,横坐标加二 + { + gotoxy(a+2,b); + a+=2; + break; + } + } + e=a,r=b; + if(j==13) //Enter键的ASCII码为13,按Enter键时落子 + { + gotoxy(a,b); + if(map[a][b]==2 || map[a][b]==1) //如果所要下的地方为已经下过的则重新选地方下子 + goto lable2; + map[a][b]=1; //将二号玩家落子的地方的值变为1,以判断二号玩家是否连成五子 + printf("○"); //二号玩家为白子 + if(judge2(a,b)==1)//二号玩家连成五子 + { + scoring(2); + gotoxy(45,15); + printf("恭喜二号玩家胜利!!!\a"); + Sleep(2000); //延迟两秒后清屏 + game_over(); //进入游戏结束画面 + } + } + if(j==8) //一号玩家悔棋 + { + gotoprint3(q,w); + whoturn--; //回到上一次的一号玩家 + goto lable1; + } + if(j==27) //退出 + { + system("cls"); + exit(0); + } + } + } + } + whoturn++; + if(whoturn==360) //整个棋盘下满还未分出胜负为平局 + { + gotoxy(45,15); + printf("平局"); + Sleep(2000); //延迟两秒后清屏 + system("cls"); + renew(); //清除上一句的痕迹 + playchess(); //开始新的一局 + } + } +} + +/*----------------------------------------------------------*/ + +int judge1(int x,int y) //判断一号玩家是否胜利 +{ + int i, j; + for(i=x-8;i<=x+8;i++)//判断横 + { + if(map[i][y]==2 && map[i+2][y]==2 && map[i+4][y]==2 && map[i+6][y]==2 && map[i+8][y]==2) + { + gotoprint7(i,y),gotoprint7(i+2,y),gotoprint7(i+4,y),gotoprint7(i+6,y),gotoprint7(i+8,y); //若胜利便将连成了五个子变为五角星 + return 1; + } + else + continue; + } + for(j=y-4;j<=y+4;j++)//判断竖 + { + if(map[x][j]==2 && map[x][j+1]==2 && map[x][j+2]==2 && map[x][j+3]==2 && map[x][j+4]==2) + { + gotoprint7(x,j),gotoprint7(x,j+1),gotoprint7(x,j+2),gotoprint7(x,j+3),gotoprint7(x,j+4); + return 1; + } + else + continue; + } + for(i=x-8,j=y-4;i<=x+8;i+=2,j++)//判断右斜 + { + if(map[i][j]==2 && map[i+2][j+1]==2 && map[i+4][j+2]==2 && map[i+6][j+3]==2 && map[i+8][j+4]==2) + { + gotoprint7(i,j),gotoprint7(i+2,j+1),gotoprint7(i+4,j+2),gotoprint7(i+6,j+3),gotoprint7(i+8,j+4); + return 1; + } + else + continue; + } + for(i=x-8,j=y+4;i<=x+8;i+=2,j--)//判断左斜 + { + if(map[i][j]==2 && map[i+2][j-1]==2 && map[i+4][j-2]==2 && map[i+6][j-3]==2 && map[i+8][j-4]==2) + { + gotoprint7(i,j),gotoprint7(i+2,j-1),gotoprint7(i+4,j-2),gotoprint7(i+6,j-3),gotoprint7(i+8,j-4); + return 1; + } + else + continue; + } + return 0; +} + +/*----------------------------------------------------------*/ + +int judge2(int x,int y) //判断二号玩家是否胜利 +{ + int i, j; + for(i=x-8;i<=x+8;i++)//判断横 + { + if(map[i][y]==1 && map[i+2][y]==1 && map[i+4][y]==1 && map[i+6][y]==1 && map[i+8][y]==1) + { + gotoprint7(i,y),gotoprint7(i+2,y),gotoprint7(i+4,y),gotoprint7(i+6,y),gotoprint7(i+8,y); + return 1; + } + else + continue; + } + for(j=y-4;j<=y+4;j++)//判断竖 + { + if(map[x][j]==1 && map[x][j+1]==1 && map[x][j+2]==1 && map[x][j+3]==1 && map[x][j+4]==1) + { + gotoprint7(x,j),gotoprint7(x,j+1),gotoprint7(x,j+2),gotoprint7(x,j+3),gotoprint7(x,j+4); + return 1; + } + else + continue; + } + for(i=x-8,j=y-4;i<=x+8;i+=2,j++)//判断右斜 + { + if(map[i][j]==1 && map[i+2][j+1]==1 && map[i+4][j+2]==1 && map[i+6][j+3]==1 && map[i+8][j+4]==1) + { + gotoprint7(i,j),gotoprint7(i+2,j+1),gotoprint7(i+4,j+2),gotoprint7(i+6,j+3),gotoprint7(i+8,j+4); + return 1; + } + else + continue; + } + for(i=x-8,j=y+4;i<=x+8;i+=2,j--)//判断左斜 + { + if(map[i][j]==1 && map[i+2][j-1]==1 && map[i+4][j-2]==1 && map[i+6][j-3]==1 && map[i+8][j-4]==1) + { + gotoprint7(i,j),gotoprint7(i+2,j-1),gotoprint7(i+4,j-2),gotoprint7(i+6,j-3),gotoprint7(i+8,j-4); + return 1; + } + else + continue; + } + return 0; +} + +/*----------------------------------------------------------*/ + +void renew() +{ + int i, j; + for(i=0;i<=50;i++) + for(j=0;j<=50;j++) + { + map[i][j]=0; + } +} + +/*----------------------------------------------------------*/ + +void scoring(int x) +{ + FILE* fp; + char read[100]; + if((fp=fopen("score.txt","w+"))==NULL)//w+即可读写 + { + gotoxy(55,10); + printf("The file can not be opened\n"); + exit(1); + } + if(x==1) + score1+=1; + if(x==2) + score2+=1; + fputs("player1: ",fp); + fprintf(fp,"%d ",score1); + fputs("player2: ",fp); + fprintf(fp,"%d",score2); + rewind(fp); //将指针回到文件开头 + fgets(read,30,fp); //读取文件里的内容,即记分板 + gotoxy(45,18); + printf("%s",read); //输出文件内容 +}