五子棋
程序员文章站
2022-06-14 11:00:36
...
直接贴代码,复制粘贴,Linux下编译运行。。。
/****************************************
*********** 对战版五子棋 ***************
****************************************
************* BLUSELI ******************
****************************************
************ 2019-7-29 *****************
****************************************/
#include <stdio.h>
#include <stdlib.h>
#define ROW 15 //棋盘宽度
#define COL 15 //棋盘长度
#define BAK 0 //背景 打印*
#define PL1 1 //玩家1 打印#
#define PL2 2 //玩家2 打印@
#define POS1 3 //光标1 实现交替打印0
#define POS2 4 //光标2 实现交替打印O
#define POS_X 3 //光标默认位置X坐标
#define POS_Y 7 //光标默认位置y坐标
#define STEP 1 //移动步长
int temp[ROW][COL]; //棋盘
int pos_x, pos_y; //当前光标位置
int player; //角色
//打印棋盘,棋子,光标
void printbackplane();
//开始
void begin();
//移动光标
void move();
//下棋
void play();
//判别胜利
int victory();
//重新开始
void restart();
//自定义延迟函数
void delay();
int main()
{
begin();
play();
return 0;
}
void delay()
{
int i=65535;
while(i--);
}
void printbackplane()
{
system("clear");
printf("--------------------------------------------\n");
printf("----------- 五子棋对战版 BluseLi------------\n");
printf("--- wsad - 上下左右 - o - 落子 - q - 退出 --\n");
if(player==PL1)
printf("------------- 等待玩家PL2落子 --------------\n");
else
printf("------------- 等待玩家PL1落子 --------------\n");
printf("--------------------------------------------\n");
for(int i=0; i<ROW; i++)
{
for(int j=0; j<COL; j++)
{
switch(temp[i][j])
{
case BAK:
printf(" * ");
break;
case PL1:
printf(" # ");
break;
case PL2:
printf(" @ ");
break;
case POS1:
printf(" 0 ");
temp[i][j]=0;
break;
case POS2:
printf(" O ");
break;
default:
break;
}
}
printf("\n");
}
}
void begin()
{
pos_x=POS_X, pos_y=POS_Y;
player=PL2;
for(int i=0; i<ROW; i++)
{
for(int j=0; j<COL; j++)
{
temp[i][j]=BAK;
}
}
temp[pos_x][pos_y]=POS1;
}
void move()
{
//执行system中的内容,
//当按下方向键 w s a d
//后不需要按下回车
system("stty raw echo");
char c = getchar();
switch(c)
{
case 'w':
if(pos_x-STEP>-1)
pos_x-=STEP;
break;
case 's':
if(pos_x+STEP<COL)
pos_x+=STEP;
break;
case 'a':
if(pos_y-STEP>-1)
pos_y-=STEP;
break;
case 'd':
if(pos_y+STEP<COL)
pos_y+=STEP;
break;
case 'o':
if(player==PL1)
player=PL2;
else
player=PL1;
break;
case 'q':
//避免用户退出程序后,终端排版乱码
//当执行本程序后退出,中文任然会乱码,重新打开一个终端即可恢复
//这里给差评,哈哈,因为我也不知道这么处理
system("stty cooked echo");
exit(0);
break;
default:
break;
}
system("stty cooked echo");
}
void play()
{
static int state=PL2;
while(1)
{
printbackplane();
move();
if(player!=state)
{
if(player==PL1)
{
if(temp[pos_x][pos_y]!=PL2)
{
state=PL1;
temp[pos_x][pos_y]=PL1;
if(victory())
{
restart();
}
}
else
{
player=state;
}
}
if(player==PL2)
{
if(temp[pos_x][pos_y]!=PL1)
{
state=PL2;
temp[pos_x][pos_y]=PL2;
if(victory())
{
restart();
}
}
else
{
player=state;
}
}
}
else
{
if(temp[pos_x][pos_y]==BAK)
temp[pos_x][pos_y]=POS1;
}
delay();
}
}
int victory()
{
//这里代码看着比较多,其实很简单
//就是挨个扫描棋盘,发现有5个旗子连在一起就判定为游戏结束
int i = 0,j = 0;
int flag = 0;
for(i=2;i<ROW-2;i++)
{
for(j=2;j<COL-2;j++)
{
//判断左斜是否有五子相连
if(temp[i][j]!=0&&temp[i-2][j-2]==temp[i][j]&&temp[i-1][j-1]==temp[i][j]&&temp[i+1][j+1]==temp[i][j]&&temp[i+2][j+2]==temp[i][j])
{
flag=1;
break;
}
//判断右对角是否有五子相连
if(temp[i][j]!=0&&temp[i+2][j-2]==temp[i][j]&&temp[i+1][j-1]==temp[i][j]&&temp[i-1][j+1]==temp[i][j]&&temp[i-2][j+2]==temp[i][j])
{
flag=1;
break;
}
}
}
if(flag==0)
{
for(i=0;i<ROW;i++)
{
for(j=2;j<COL-2;j++)
{
//上面两种情况都不成立,则判断是否有横向五子相连
if(temp[i][j]!=0&&temp[i][j-2]==temp[i][j]&&temp[i][j-1]==temp[i][j]&&temp[i][j+1]==temp[i][j]&&temp[i][j+2]==temp[i][j])
{
flag=1;
break;
}
}
}
}
if(flag==0)
{
//判断纵向五子相连
for(i=2;i<ROW-2;i++)
{
for(j=0;j<COL;j++)
{
if(temp[i][j]!=0&&temp[i+2][j]==temp[i][j]&&temp[i+1][j]==temp[i][j]&&temp[i-1][j]==temp[i][j]&&temp[i-2][j]==temp[i][j])
{
flag=1;
break;
}
}
}
}
return flag;
}
void restart()
{
system("clear");
printf("--------------------------------------------\n");
printf("--------------------------------------------\n");
printf("----------- 五子棋对战版 BluseLi------------\n");
printf("--------------------------------------------\n");
printf("--------------------------------------------\n");
if(player==PL1)
printf("-------------- 玩家PL1胜利 ---------------\n");
else
printf("-------------- 玩家PL2胜利 ---------------\n");
printf("--------------------------------------------\n");
printf("--------------------------------------------\n");
printf("-------------- 是否重新开始 ----------------\n");
printf("--------------------------------------------\n");
printf("-------------- Y 是 -- N 否 ----------------\n");
printf("--------------------------------------------\n");
printf("--------------------------------------------\n");
char c=getchar();
if(c=='Y')
{
begin();
}
else
{
exit(0);
}
}
已经落子的地方,光标移动过去不改变,以及对输入方向键后不需要按回车进行处理后会出现编码问题,还有光标闪烁,这三个地方等空了再改改。
上一篇: Mutations