三子棋,无非就是在一个3乘3的棋盘上,使相同3个的棋子连续排列。获胜的方式也很简单,就是谁先排列成功谁胜利。
2.正文 (1)思路我们把三子棋这一个项目分为三个文件,test.c game.c game.h
test.c里我们写三子棋的程序流程;game.c里我们写需要用到的函数;game.h里我们写各个函数的声明,宏,头文件等。
(2)对于一个棋盘,我们可以用一个二维数组来表示。无论是玩家还是电脑下棋时,过程都是向这个二维数组里面放置元素,当玩家或电脑下完棋后,为了方便玩家是否下棋成功,我们还要将下完棋后的棋盘打印出来,也就是将添加完元素的数组打印出来。这样,玩家和电脑下棋一直到最后出现结果。对于结果,有三种可能,玩家胜利、电脑胜利、平局。其中平局是当整个棋盘都下满了也没出现相同的棋子三子连续排列。
(3)代码实现当调试代码后,首先要打印出游戏的菜单,这样我们才能选择进入游戏还是退出游戏
printf("欢迎来到三子棋n");
printf("******1.进入游戏********n");
printf("******0.退出游戏********n");
第二步,当我们选择1就进入游戏,选择0就退出游戏,但此时万一我们输入错误了怎么半呢,所以我们设定了当输入不是1或0时,就打印输入错误,请重新输入。无论是玩完游戏还是直接选择0退出游戏,游戏将主动退出。因此我们这里就要用到了do.....while循环。
do
{
scanf("%d", &input);
//输入1后,先显示成功,然后进入游戏,显示游戏界面
if (input == 1)
{
printf("进入游戏成功n");
game();
break;
}
else if (input == 0)
{
printf("即将退出游戏n");
break;
}
else
{
printf("输入错误,请重新输入n");
continue;
}
} while (input);
输入我们使用一个整型变量input来接收的。
然后就到了进入游戏,游戏的实现我们用了一个函数game()。它里面包括了二维数组定义,棋盘初始化, 玩家电脑下棋,每次下完棋后的判断,是否平局等。
void game()
{
//三子棋界面本质是二维数组
char tmp = 0;
char board[ROW][COL] = {0};
//初始化
initboard(board, ROW, COL);
display(board, ROW, COL);
while (1)
{
//开始下棋,玩家*,电脑#,而且不论玩家还是电脑下一次,都要判断一次
gamplay(board, ROW, COL);
tmp = judgement(board, ROW, COL);
if (tmp != 'C')
{
break;
}
display(board, ROW, COL);
complay(board, ROW, COL);
tmp = judgement(board, ROW, COL);
if (tmp != 'C')
{
break;
}
display(board, ROW, COL);
}
if (tmp == '*')
{
printf("玩家赢n");
}
else if (tmp == '#')
{
printf("电脑赢n");
}
else
printf("平局n");
display(board, ROW, COL);
}
代码中的ROW,COL是宏定义,我将它们放在了game.h当中
#define ROW 3 #define COL 3
数组初始化和棋盘初始化是在一起的,显示棋盘就是打印数组。在最开始棋盘里面没有棋子 ,但是不代表说这个数组里面什么都没有,如果数组里面什么都没有,打印数组就会显示出0,但是显示出来的棋盘中是没有0的,所以我们联想到了空格,将数组里面全放空格,这样打印出来我们也看不到其他元素
void initboard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
打印棋盘时候,我们用 | 和---来打印
void display(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
{
printf("|");
}
}
printf("n");
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
printf("n");
}
}
}
玩家下棋
void gamplay(char board[ROW][COL], int row, int col)
{
printf("请输入坐标>-:");
//输入的范围是1~3,实际进入数组的范围是0~2
int i = 0;
int j = 0;
scanf("%d %d", &i, &j);
while (1)
{
//先判断输入是否合法,然后判断此时要输入的位置是不是空格,如果是则输入*,如果不是就打印输入错误
if (i >= 1 && i <= row && j >= 1 && j <= col)
{
if (board[i - 1][j - 1] == ' ')
{
board[i - 1][j - 1] = '*';
break;
}
else
{
printf("该位置无法下棋或位置不合法,请重新选择其他位置");
}
}
}
}
电脑下棋
void complay(char board[ROW][COL], int row, int col)
{
printf("电脑下棋>-:n");
int i = 0;
int j = 0;
while(1)
{
i = rand() % row;
j = rand() % col;
if (board[i][j] == ' ')
{
board[i][j] = '#';
break;
}
}
}
下完棋后的判断
//判断,如果数组出现某一行,某一列或某一对角线连续三个相同,则输出游戏结束,玩家或电脑胜利
//玩家赢返回*,电脑赢返回#,平局返回A,还没出现结果返回C
char judgement(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2])
{
if (board[i][1] == '*')
{
return '*';
}
else if (board[i][1] == '#')
{
return '#';
}
}
}
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j])
{
if (board[1][j] == '*')
{
return '*';
}
else if (board[1][j] == '#')
{
return '#';
}
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
{
if (board[1][1] == '*')
{
return '*';
}
else if (board[1][1] == '#')
{
return '#';
}
}
if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
{
if (board[1][1] == '*')
{
return '*';
}
else if (board[1][1] == '#')
{
return '#';
}
}
if (isfull(board, row, col))
{
return 'A';
}
return 'C';
}
上面代码最后的isfull()是来判断是否棋盘已经下满了
int isfull(char board[ROW][COL],int row,int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for(j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
(4)完整的代码 1 test.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
//游戏
void game()
{
//三子棋界面本质是二维数组
char tmp = 0;
char board[ROW][COL] = {0};
//初始化
initboard(board, ROW, COL);
display(board, ROW, COL);
while (1)
{
//开始下棋,玩家*,电脑#,而且不论玩家还是电脑下一次,都要判断一次
gamplay(board, ROW, COL);
tmp = judgement(board, ROW, COL);
if (tmp != 'C')
{
break;
}
display(board, ROW, COL);
complay(board, ROW, COL);
tmp = judgement(board, ROW, COL);
if (tmp != 'C')
{
break;
}
display(board, ROW, COL);
}
if (tmp == '*')
{
printf("玩家赢n");
}
else if (tmp == '#')
{
printf("电脑赢n");
}
else
printf("平局n");
display(board, ROW, COL);
}
int main()
{
srand((unsigned int)time(NULL));//设置随机数起点
printf("欢迎来到三子棋n");
printf("******1.进入游戏********n");
printf("******0.退出游戏********n");
int input = 0;
do
{
scanf("%d", &input);
//输入1后,先显示成功,然后进入游戏,显示游戏界面
if (input == 1)
{
printf("进入游戏成功n");
game();
break;
}
else if (input == 0)
{
printf("即将退出游戏n");
break;
}
else
{
printf("输入错误,请重新输入n");
continue;
}
} while (input);
return 0;
}
2 game.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void initboard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
//玩家下棋
void gamplay(char board[ROW][COL], int row, int col)
{
printf("请输入坐标>-:");
//输入的范围是1~3,实际进入数组的范围是0~2
int i = 0;
int j = 0;
scanf("%d %d", &i, &j);
while (1)
{
//先判断输入是否合法,然后判断此时要输入的位置是不是空格,如果是则输入*,如果不是就打印输入错误
if (i >= 1 && i <= row && j >= 1 && j <= col)
{
if (board[i - 1][j - 1] == ' ')
{
board[i - 1][j - 1] = '*';
break;
}
else
{
printf("该位置无法下棋或位置不合法,请重新选择其他位置");
}
}
}
}
//电脑下棋
void complay(char board[ROW][COL], int row, int col)
{
printf("电脑下棋>-:n");
int i = 0;
int j = 0;
while(1)
{
i = rand() % row;
j = rand() % col;
if (board[i][j] == ' ')
{
board[i][j] = '#';
break;
}
}
}
int isfull(char board[ROW][COL],int row,int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for(j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
//判断,如果数组出现某一行,某一列或某一对角线连续三个相同,则输出游戏结束,玩家或电脑胜利
//玩家赢返回*,电脑赢返回#,平局返回A,还没出现结果返回C
char judgement(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2])
{
if (board[i][1] == '*')
{
return '*';
}
else if (board[i][1] == '#')
{
return '#';
}
}
}
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j])
{
if (board[1][j] == '*')
{
return '*';
}
else if (board[1][j] == '#')
{
return '#';
}
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
{
if (board[1][1] == '*')
{
return '*';
}
else if (board[1][1] == '#')
{
return '#';
}
}
if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
{
if (board[1][1] == '*')
{
return '*';
}
else if (board[1][1] == '#')
{
return '#';
}
}
if (isfull(board, row, col))
{
return 'A';
}
return 'C';
}
//显示当前棋盘
void display(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
{
printf("|");
}
}
printf("n");
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
printf("n");
}
}
}
3 game.h
#pragma once #include以上就是我三子棋代码的实现,其实有些地方写的并不好,我可能还需要多思考更好的实现方式。#include #include #define ROW 3 #define COL 3 //游戏 void game(); //数组初始化 void initboard(char board[ROW][COL], int row, int col); //棋盘初始化 //void initdisplay(char board[ROW][COL], int row, int col); //玩家下棋 void gamplay(char board[ROW][COL], int row, int col); //电脑下棋 void complay(char board[ROW][COL], int row, int col); //判断 char judgement(char board[ROW][COL], int row, int col); //判断棋盘是否满了 int isfull(char board[ROW][COL], int row, int col); //显示当前棋盘 void display(char board[ROW][COL], int row, int col);



