#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); //输出文件内容 }