|
|
#include<stdio.h>
|
|
|
#include<stdlib.h>
|
|
|
#include<windows.h>
|
|
|
#include<conio.h>
|
|
|
|
|
|
#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); //输出文件内容
|
|
|
}
|
|
|
|