C语言井字棋的实现方法之一
井字棋作为最简单的一种下棋类型,实现难度并不高,同时和我之前写的五子棋的实现本质是一样的。
通过判断四个方向上连续三个棋子是不是一致的,从而判断是否三子成线,赢得了游戏。
今天这个井字棋的实现过程有点呆,因为井字棋棋盘一共就9个空格,所以把每个空格都做一个三子连线的可能并把它们逐一表述出来就能达到判断是否获胜的目的(对于井字棋还可以这么做,因为一共棋盘就9个空格,但对于五子棋来说有太多可能性因此对于五子棋可以参考我的另外一篇博文,不建议用这种实现方法)这样的表述过程不涉及到数组越界,同样的,这里采用的仍然是人机对战。
话不多说,上代码。
宏定义以及设置一个全局的二维数组:
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
#define hang 4 //设定行是4
#define lie 4 //设定列是4
char chess_map[hang][lie];
这里没什么强调的,下面是棋盘的初始化和打印棋盘:
void init(void)
{
int i,j;
for(i=0;i<hang;i++)
{
for(j=0;j<lie;j++)
{
chess_map[i][j]='*'; //这里可以用空格,我是习惯用*了
}
}
}
void drawmap(void)
{
int i,j;
printf("0 "); //打印序号
for(i=1;i<lie;i++)
{
printf("%d ",i);
}
printf("\n");
for(i=1;i<hang;i++)
{
printf("%d ",i); //打印序号
for(j=1;j<lie;j++)
{
printf("%c ",chess_map[i][j]);
}
printf("\n");
}
}
这里需要注意的就是序号要与每个棋盘的位置对齐。
接下来就是游戏函数:
void Game(void)
{
int x,y;
int x0,y0;
int n=0;
init();
while(1)
{
system("cls");
drawmap();
printf("请输入你的坐标:\n");
scanf("%d %d",&x,&y);
if((chess_map[x][y]=='*')&&(x>0&&x<4)&&(y>0&&y<4))
{
n++;
chess_map[x][y]='x';
}
else
{
printf("你输入的坐标不合法或者已存在,请尝试重新输入\n");
system("pause");
continue;
}
if(n==9) //判断平局
{
printf("平局!\n");
break;
}
while(1)
{
srand(time(NULL)); //采用srand函数给rand函数提供种子,让rand函数每次都能生成一个随机数,从而生成棋子的坐标
x0=rand()%3+1;
y0=rand()%3+1;
if(chess_map[x0][y0]!='x'&&chess_map[x0][y0]!='0')
{
chess_map[x0][y0]='0';
n++;
break;
}
else //如果是我方棋子或者已经下过的地方就重新生成随机数,即重新生成棋子
{
continue;
}
}
if(chess_map[1][1]=='x'&&chess_map[1][2]=='x'&&chess_map[1][3]=='x') //判断开始,把棋盘上9个位置每个位置都表述出可能出现的三子成线的情况
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[1][1]=='x'&&chess_map[2][1]=='x'&&chess_map[3][1]=='x')
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[1][1]=='x'&&chess_map[2][2]=='x'&&chess_map[3][3]=='x')
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[2][1]=='x'&&chess_map[2][2]=='x'&&chess_map[2][3]=='x')
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[3][1]=='x'&&chess_map[3][2]=='x'&&chess_map[3][3]=='x')
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[3][1]=='x'&&chess_map[2][2]=='x'&&chess_map[1][3]=='x')
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[1][2]=='x'&&chess_map[2][2]=='x'&&chess_map[3][2]=='x')
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[1][3]=='x'&&chess_map[2][3]=='x'&&chess_map[3][3]=='x')
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[1][1]=='0'&&chess_map[1][2]=='0'&&chess_map[1][3]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
if(chess_map[1][1]=='0'&&chess_map[2][1]=='0'&&chess_map[3][1]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
if(chess_map[1][1]=='0'&&chess_map[2][2]=='0'&&chess_map[3][3]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
if(chess_map[2][1]=='0'&&chess_map[2][2]=='0'&&chess_map[2][3]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
if(chess_map[3][1]=='0'&&chess_map[3][2]=='0'&&chess_map[3][3]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
if(chess_map[3][1]=='0'&&chess_map[2][2]=='0'&&chess_map[1][3]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
if(chess_map[1][2]=='0'&&chess_map[2][2]=='0'&&chess_map[3][2]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
if(chess_map[1][3]=='0'&&chess_map[2][3]=='0'&&chess_map[3][3]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
}
}
这里我没没有单独写一个judge函数,而是直接把judge函数装进了游戏主函数中,这里需要注意的就是不要重复判断三子成线。这里的n用于进行判断平局,我们每下一步n就加一,同样的,电脑每下一步也会加一,这样到了判断平局的目的。
菜单函数:
void menu(void)
{
printf("==========================\n");
printf("=========Tictactoe========\n");
printf("==========================\n");
printf("==========井字棋==========\n");
printf("==========================\n");
printf("========1.开始游戏========\n");
printf("==========================\n");
printf("========2.退出游戏========\n");
printf("==========================\n");
}
下面是main函数:
int main(void)
{
int start,end;
char select;
system("color 2");
menu();
printf("请输入你的选择:\n");
y:
scanf(" %c",&select);
switch(select)
{
case '1':
{
start=clock(); //开始计时
Game();
break;
}
case '2':
{
printf("正在退出......\n");
Sleep(1000);
return 0;
}
default:printf("输入错误,请重新输入:\n");
goto y;
break;
}
end=clock(); //结束计时
printf("本局用时为%d秒\n",(end-start)/1000);
system("pause");
return 0;
}
附源代码chess.c:
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
#define hang 4
#define lie 4
char chess_map[hang][lie];
void init(void);
void drawmap(void);
void Game(void);
void menu(void);
void init(void)
{
int i,j;
for(i=0;i<hang;i++)
{
for(j=0;j<lie;j++)
{
chess_map[i][j]='*';
}
}
}
void drawmap(void)
{
int i,j;
printf("0 ");
for(i=1;i<lie;i++)
{
printf("%d ",i);
}
printf("\n");
for(i=1;i<hang;i++)
{
printf("%d ",i);
for(j=1;j<lie;j++)
{
printf("%c ",chess_map[i][j]);
}
printf("\n");
}
}
void Game(void)
{
int x,y;
int x0,y0;
int n=0;
init();
while(1)
{
system("cls");
drawmap();
printf("请输入你的坐标:\n");
scanf("%d %d",&x,&y);
if((chess_map[x][y]=='*')&&(x>0&&x<4)&&(y>0&&y<4))
{
n++;
chess_map[x][y]='x';
}
else
{
printf("你输入的坐标不合法或者已存在,请尝试重新输入\n");
system("pause");
continue;
}
if(n==9)
{
printf("平局!\n");
break;
}
while(1)
{
srand(time(NULL));
x0=rand()%3+1;
y0=rand()%3+1;
if(chess_map[x0][y0]!='x'&&chess_map[x0][y0]!='0')
{
chess_map[x0][y0]='0';
n++;
break;
}
else
{
continue;
}
}
if(chess_map[1][1]=='x'&&chess_map[1][2]=='x'&&chess_map[1][3]=='x')
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[1][1]=='x'&&chess_map[2][1]=='x'&&chess_map[3][1]=='x')
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[1][1]=='x'&&chess_map[2][2]=='x'&&chess_map[3][3]=='x')
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[2][1]=='x'&&chess_map[2][2]=='x'&&chess_map[2][3]=='x')
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[3][1]=='x'&&chess_map[3][2]=='x'&&chess_map[3][3]=='x')
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[3][1]=='x'&&chess_map[2][2]=='x'&&chess_map[1][3]=='x')
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[1][2]=='x'&&chess_map[2][2]=='x'&&chess_map[3][2]=='x')
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[1][3]=='x'&&chess_map[2][3]=='x'&&chess_map[3][3]=='x')
{
system("cls");
drawmap();
printf("玩家获胜!\n");
break;
}
if(chess_map[1][1]=='0'&&chess_map[1][2]=='0'&&chess_map[1][3]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
if(chess_map[1][1]=='0'&&chess_map[2][1]=='0'&&chess_map[3][1]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
if(chess_map[1][1]=='0'&&chess_map[2][2]=='0'&&chess_map[3][3]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
if(chess_map[2][1]=='0'&&chess_map[2][2]=='0'&&chess_map[2][3]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
if(chess_map[3][1]=='0'&&chess_map[3][2]=='0'&&chess_map[3][3]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
if(chess_map[3][1]=='0'&&chess_map[2][2]=='0'&&chess_map[1][3]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
if(chess_map[1][2]=='0'&&chess_map[2][2]=='0'&&chess_map[3][2]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
if(chess_map[1][3]=='0'&&chess_map[2][3]=='0'&&chess_map[3][3]=='0')
{
system("cls");
drawmap();
printf("电脑获胜!\n");
break;
}
}
}
void menu(void)
{
printf("==========================\n");
printf("=========Tictactoe========\n");
printf("==========================\n");
printf("==========井字棋==========\n");
printf("==========================\n");
printf("========1.开始游戏========\n");
printf("==========================\n");
printf("========2.退出游戏========\n");
printf("==========================\n");
}
int main(void)
{
int start,end;
char select;
system("color 2");
menu();
printf("请输入你的选择:\n");
y:
scanf(" %c",&select);
switch(select)
{
case '1':
{
start=clock();
Game();
break;
}
case '2':
{
printf("正在退出......\n");
Sleep(1000);
return 0;
}
default:printf("输入错误,请重新输入:\n");
goto y;
break;
}
end=clock();
printf("本局用时为%d秒\n",(end-start)/1000);
system("pause");
return 0;
}
到这里就算结束啦,有问题还请指正,谢谢啦o( ̄▽ ̄)ブ
(PS:这里说一下,由于是用rand函数生成的坐标,电脑下棋就像一头猪一样/(ㄒoㄒ)/~~几乎可以确定的是我们是100%赢,只要不是故意让步。)