先简单介绍一下三子棋的规则,方便我们接下来的编程和理解。规则如下:
在九宫格棋盘上,只要将自己的三个棋子走成一条线(横、竖、对角线),对方就算输了。
规则很简单,但是我们应该从哪里入手完成这个三子棋程序呢?
首先,我们的游戏程序应该先有个菜单页面,这个菜单页面用来让用户操作选择玩游戏,或是退出。
界面可以很简单,只需要几条 printf 语句即可:
这就是一个简单的操作界面,效果如下:
既然菜单中有选项,我们就必须要设计一个变量用来接收用户的选择。
而且游戏程序本身应该允许用户反复进行玩耍,所以在主函数中,我们需要用一个循环来完成这个功能。
do-while循环在调用时会先运行循环体,而后在进行判断,所以这里我们选择使用do-while循环;
由于用户选择选项1时我们需要为用户启动游戏程序,所以这里我们使用一个switch语句来接受用户的选择。
选择0时退出程序,所以我们只需要跳出循环,即可退出。
而输入0、1之外的值时,我们应该向用户报输入错误,所以在default中输出一条报错信息。
接下来,就是三子棋游戏本身了:
在game.h头文件中放入函数名,在game.c源文件中放入实现函数。
由于长和宽我们要经常用到,为了后续修改方便,我们采用宏定义方式:
接下来在game()函数中创建数组:
并将这个数组进行初始化,因为这个数组在后续需要输出展示在用户面前,所以我们将值初始化为空格“ ”。
初始化用函数进行完成:
接下来,我们应该输出这个数组棋盘,来检查一下是否初始化完成,
但我们没有展示棋盘的函数,所以我们需要完成这个显示棋盘函数:
这里需要利用循环来输出我们棋盘的格式,格式不统一,可以根据自己的喜好进行修改。
下面展示一下我这个代码所输出的棋盘:
上面已经看出我的棋盘初始化已经完成,所以接下来我们需要考虑如何让电脑或用户进行下棋操作了。
电脑走需要让电脑产生随机坐标,然后在数组的这个坐标位置放入一个“X”作为电脑的棋子。
所以代码如下:
电脑下完棋后,需要轮到我们的用户进行下棋操作,这个函数和电脑下棋大同小异,
但是要注意人的习惯不会输入(0,0)这个坐标,而是输入(1,1)。
所以这里我们要给传过去的参数-1。
解决这个问题后的代码如下:
在双方走完后,我们需要判断是否胜利,也就是判断之前我们提到的规则,
这时我们需要编写一个checkwin()函数来检测并返回一个值表示谁获胜。
代码如下:
由于可能出现棋盘下满,却没人获胜的情况,
所以我们需要在其中判断一下平局的情况:
完整代码如下:
头文件game.h:
#define _CRT_SECURE_NO_WARNINGS 1
#ifndef __GAME_H__
#define __GAME_H__
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#define ROW 3
#define COL 3
void game ();
void InitBoard(char arr[ROW][COL],int row,int col);
void DisplayBoard(char arr[ROW][COL],int row,int col);
void PlayerChess (char arr[ROW][COL],int row,int col);
void ComputerChess (char arr[ROW][COL],int row,int col);
char CheckWin (char arr[ROW][COL],int row,int col);
int CheckFull(char arr[ROW][COL],int row,int col);
#endif//__GAME_H__
源文件game.c:
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void InitBoard (char arr[ROW][COL],int row,int col)
{
memset(arr,' ',row*col*sizeof(arr[0][0]));
}
void DisplayBoard(char arr[ROW][COL],int row,int col)
{
int i = 0;
printf (" -----------\n");
for (i = 0;i < ROW;i++)
{
printf ("| %c | %c | %c |\n",arr[i][0],arr[i][1],arr[i][2]);
if (i < 2)
{
printf (" ---|---|---");
}
else
printf (" -----------");
printf ("\n");
}
}
void PlayerChess (char arr[ROW][COL],int row,int col)
{
int x = 0;
int y = 0;
while (1)
{
printf ("玩家走:\n");
scanf_s ("%d %d",&x,&y);
x--;
y--;
if (arr[x][y] == ' ')
{
arr[x][y] = 'X';
break;
}
else
{
printf ("输入非法,请重输\n");
continue;
}
}
}
void ComputerChess (char arr[ROW][COL],int row,int col)
{
while (1)
{
int x = 0;
int y = 0;
srand((unsigned)time(NULL));
x = rand() % 3;
y = rand() % 3;
if (arr[x][y] == ' ')
{
arr[x][y] = '0';
break;
}
}
}
static int CheckFull(char arr[ROW][COL],int row,int col)
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (arr[i][j] == ' ')
return 0;
}
}
return 1;
}
char CheckWin (char arr[ROW][COL],int row,int col)
{
int i = 0;
int ret = 0;
for (i = 0;i < row;i++)
{
if ((arr[i][0] == arr[i][1]) && (arr[i][1] == arr[i][2])&& (arr[i][0] != ' '))
{
return arr[i][0];
}
}
for (i = 0;i < COL;i++)
{
if ((arr[0][i] == arr[1][i]) && (arr[1][i] == arr[2][i]) && (arr[0][i]))
{
return (arr[0][i]);
}
}
if ((arr[0][0] == arr[1][1]) && (arr[1][1] == arr[2][2]) && (arr[0][0] != ' '))
{
return (arr[0][0]);
}
if ((arr[0][2] == arr[1][1]) && (arr[1][1] == arr[2][0] && (arr[0][2] != ' ')))
{
return (arr[0][2]);
}
ret = CheckFull(arr,row,col);
if (ret = 1)
{
return 'q';
}
return ' ';
}
源文件test.c:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "game.h"
void menu()
{
printf ("***********************\n");
printf ("*****1.play 0.exit*****\n");
printf ("***********************\n");
}
int main()
{
int input = 0;
do
{
menu();
scanf("%d",&input);
switch (input)
{
case 1:
game();
break;
case 0:
break;
default:
printf ("输入错误\n");
break;
}
}while (input);
getchar();
return 0;
}
void game()
{
int ret = 0;
char arr[ROW][COL] ={0};
InitBoard(arr,ROW,COL);
DisplayBoard(arr,ROW,COL);
srand((unsigned int)time(NULL));
while (1)
{
PlayerChess(arr,ROW,COL);
if((ret = CheckWin(arr,ROW,COL)) != ' ')
break;
DisplayBoard(arr,ROW,COL);
ComputerChess(arr,ROW,COL);
if((ret = CheckWin(arr,ROW,COL)) != ' ')
break;
DisplayBoard(arr,ROW,COL);
}
if(ret = 'X')
{
printf ("玩家胜\n");
}
else if(ret = '0')
{
printf ("电脑胜\n");
}
else if(ret = 'q')
{
printf ("平局\n");
}
DisplayBoard(arr,ROW,COL);
}
优化电脑:
只需在void ComputerChess (char arr[ROW][COL],int row,int col)中加入:
while (1)
{
if (arr[1][1] == ' ')
{
arr[1][1] = '0';
}
int i = 0;
int j = 0;
int x = 0;
int y = 0;
for (i = 0;i < row;i++)
{
if ((arr[0][j] ==arr[1][j]) && (arr[2][j] == ' '))
{
arr[2][j] = '0';
}
else if ((arr[0][j] ==arr[2][j]) && (arr[1][j] == ' '))
{
arr[1][j] = '0';
}
else if ((arr[1][j] == arr[2][j]) && (arr[0][j] == ' '))
{
arr[0][j] = '0';
}
}
for (j = 0;j < col;j++)
{
if ((arr[i][0] == arr[i][1]) && (arr[i][2] == ' '))
{
arr[i][2] = '0';
}
else if ((arr[i][0] == arr[i][2]) && (arr[i][1] == ' '))
{
arr[i][1] = '0';
}
else if((arr[i][1] == arr[i][2]) && (arr[i][0] == ' '))
{
arr[i][0] = '0';
}
}
if ((arr[0][0] == arr[1][1]) && (arr[2][2] == ' '))
{
arr[2][2] = '0';
}
else if ((arr[0][0] == arr[2][2]) && (arr[1][1] == ' '))
{
arr[1][1] = '0';
}
else if ((arr[1][1] == arr[2][2]) && (arr[0][0] == ' '))
{
arr[0][0] = '0';
}
if ((arr[0][2] == arr[1][1]) && (arr[2][0] == ' '))
{
arr[2][0] = '0';
}
else if ((arr[0][2] == arr[2][0]) && (arr[1][1] == ' '))
{
arr[1][1] = '0';
}
else if ((arr[1][1] == arr[2][0]) && (arr[0][2] == ' '))
{
arr[0][2] = '0';
}
x = rand() % row;
y = rand() % col;
if (arr[x][y] == ' ')
{
arr[x][y] = '0';
}
}