三子棋是黑白棋的一种。三子棋是一种民间传统游戏,只要将自己的三个棋子走成一条线(横、竖、对角线),对方就算输了。但是,有很多时候会出现和棋的情况。让我们用C语言来实现简单版的三子棋吧!
目录
前言
通常项目开发需采取分文件形式编写,分别为:
- test.c 作为代码测试的入口
- game.c 此次三子棋编写涉及到的功能函数实现
- game.h 此头文件通常用来完成函数声明、头文件的引用、宏定义变量。
先把完整代码整上:
一、test.c
#include"game.h"
game()
{
char ret = 0;
char board[ROW][COL] = { 0 };
Initboard(board, ROW, COL);
Display(board, ROW, COL);
while (1)
{
Playermove(board, ROW, COL);
ret=Iswin(board, ROW, COL);
Display(board, ROW, COL);
if (ret != 'C')
{
break;
}
Computermove(board, ROW, COL);
ret = Iswin(board, ROW, COL);
Display(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '#')
{
printf("电脑赢了\n");
}
if (ret == '*')
{
printf("玩家赢了\n");
}
if (ret == 'Q')
{
printf("平局了\n");
}
}
menu()
{
printf("********************************\n");
printf("*******1. play game*************\n");
printf("*******0. exit **************\n");
printf("********************************\n");
printf("********************************\n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入有误,重新输入\n");
}
}while (input);
return 0;
}
二、game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void Initboard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
void Display(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
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 Playermove(char board[ROW][COL], int row, int col)
{
printf("玩家走\n");
int x = 0;
int y = 0;
while (1)
{
printf("请输入您的坐标");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row&&y >= 1 && y <= col)
{
if (board[x-1][y-1] = ' ')
{
board[x-1][y-1] = '*';
break;
}
else
{
printf("已被占用,重新输入。\n");
}
}
else
{
printf("坐标输入有误,请重新输入\n");
}
}
}
Computermove(char board[ROW][COL], int row, int col)
{
printf("电脑走\n");
while (1)
{
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
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;
}
char Iswin(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] && board[i][2] != ' ')
{
return board[i][0];
}
}
for (j= 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[2][j] != ' ')
{
return board[0][j];
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] != ' ')
{
return board[0][0];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] != ' ')
{
return board[2][0];
}
if (Isfull(board,ROW,COL) == 1)
{
return 'Q';
}
else
{
return 'C';
}
}
三、game.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3
#define COL 3
void Initboard(char board[ROW][COL], int row, int col);
void Display(char board[ROW][COL], int row, int col);
void Playermove(char board[ROW][COL], int row, int col);
Computermove(char board[ROW][COL], int row, int col);
char Iswin(char board[ROW][COL], int row, int col);
整体思路:
1.菜单界面选择开始或者退出游戏。
而且游戏程序本身应该允许用户反复进行玩耍,所以在主函数中,我们需要用一个循环来完成这个功能。
do-while循环在调用时会先运行循环体,而后在进行判断,所以这里我们选择使用do-while循环。
![](https://img-blog.csdnimg.cn/20210730234844924.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzU3OTg3ODMx,size_16,color_FFFFFF,t_70)
2.创建棋盘并初始化。
正式进入游戏game(),首先创建棋盘并且初始化棋盘。
在程序开始阶段,我们首先要创建一个3*3的二维字符数组,
由于长和宽我们要经常用到,为了后续修改方便,我们在game.h中采用宏定义方式:
接下来在game()函数中创建数组:
并将这个数组进行初始化,因为这个数组在后续需要输出展示在用户面前,所以我们将值初始化为空格“ ”。
初始化用函数进行完成:
3.打印棋盘。
4.玩家走棋('*'代表player)
1.玩家落子需要在棋盘范围内。
2.注意数组的坐标命名不同于我们平常对坐标的命名。x,y均需减一。
3.玩家要在棋盘上空的地方下棋。
5.判定胜负关系(输,赢,平局(‘Q’))
判定电脑玩家胜利:
1 判定所有的行
2 判定所有的列
3 判定两条对角线
接上图:
由于可能出现棋盘下满,却没人获胜的情况,
所以我们需要在其中判断一下平局的情况,
这里我们编写了一个is_full()函数,用来判断棋盘是否下满:
1 调用isFull函数。
2 如果数组中有元素为’ ‘,那么没满,返回0。如果全不为’ ',满了,返回1。
3 如果棋盘满了未分出胜负,和棋。
返回结果的含义:
1 ‘*’ 表示玩家获胜
2 ‘#’ 表示电脑获胜
3 ’C ’ 表示胜负未分
4 ‘Q’ 表示和棋
6.电脑走棋('*'代表computer)
1.rand()是用来生成随机数的,这里我们还需要在主函数main中加上一行代码。
将时间作为随机数种子,确保得到的行列坐标是真随机。
2. 生成随机数需要引用time.h这个头文件。
![](https://img-blog.csdnimg.cn/2021073100141080.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzU3OTg3ODMx,size_16,color_FFFFFF,t_70)
7.判定胜负关系(输,赢,平局(‘Q’))
同步骤五
8.循环3-8步骤