目录
一、代码思路
首先需要创建三个文件:
test.c //用于测试游戏的逻辑性
game.c //游戏代码的实现
game.h //游戏代码的声明(函数声明、符号定义)
- 实现三子棋流程:
开始菜单--->实现棋盘--->玩家、电脑下棋--->判断输赢
- 主要运用了函数和数组。
二、代码实现
1.菜单
- 首先我们需要打印一个菜单(开始游戏、结束游戏)以及最简单化游戏思路。
由于菜单至少需要执行一次,所以这里选用do while 循环,因为要进行选择是否开始游戏,所以我们这里需要用scanf输入一个数,并且用到switch来进行游戏选择,(这里的while判断为假的时候我们需要退出循环,结束游戏,所以这里可以巧妙的选用0来实现)。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
menu()
{
printf("**************\n");
printf("*** 1.play ***\n");
printf("*** 0.exit ***\n");
printf("**************\n");
}
int main()
{
int input = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
printf("三子棋\n");
break;
case 0:
printf("退出游戏!\n");
break;
default:
printf("选择错误,请重新选择\n");
}
} while (input);
return 0;
}
- 注意:每写完一个版块都要测试一下,以免写完后出问题,不知道问题在哪。
测试:
2.实现棋盘
首先,我们需要知道三子棋是一个3*3的格子组合而成,可以用我们的二维数组来进行实现
- 创建数组,初始化棋盘。(这里的ROW、COL在game.h文件中统一定义为3,这样方便于以后写多子棋,不用一个个去更改参数,game.c和test.c只需要引用头文件game.h即可)
//game.c中
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] = ' ';
}
}
}
//test.c中
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include"game.h"
menu()
{
printf("**************\n");
printf("*** 1.play ***\n");
printf("*** 0.exit ***\n");
printf("**************\n");
}
game()
{
char board[ROW][COL] = { 0 };
//初始化棋盘的函数
InitBoard(board, ROW, COL);
}
int main()
{
int input = 0;
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.h中
#pragma once
#define ROW 3
#define COL 3
//初始化棋盘的函数
void InitBoard(char board[ROW][COL], int row, int col);
- 打印棋盘,棋盘周围都有线相隔,所以我们需要用一些分割线来让数组看起来像棋盘。
这里函数的定义(test.c)声明(game.h)与上面相同,只是名称换了。
//game.c
//打印棋盘
void DisplayBoard(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");
}
}
}
//添加到game.h
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);
//添加到test.c
DisplayBoard(board,ROW,COL);
打印结果 :这样就有一个棋盘的雏形。
3.玩家下棋
这里的玩家落子,我们用 * 来表示, 玩家输入坐标后,我们首先需要判断坐标是否合法,合法后再判断玩家下的位置是否被占用。(这里函数的定义(test.c)声明(game.h)与上面相同,只是名称换了)。
- 这里用board[x-1][y-1]是因为,玩家在落子的时候应该只会从1开始,而数组的坐标是从0开始的,所以这里需要-1.
- 落子完成后,我们需要打印棋盘,给玩家可读性。
//game.c中
//玩家下棋
void Player(char board[ROW][COL], int row, int col)
{
int x = 0;//横坐标
int y = 0;//纵坐标
while (1)
{
printf("玩家下棋\n");
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");
}
}
}
//添加到test.c
//玩家下棋
Player(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
打印结果:成功落子
4.电脑下棋
要让电脑随机下棋,这里我们需要用的rand( )函数、srand( )函数和time(NULL)来生成随机数.
注意头文件的添加,要添加两个头文件在game.h中:#include<stdio.h>、#include<time.h>。
(这里函数的定义(test.c)声明(game.h)与上面相同,只是名称换了)
rand()函数和srand()函数是C语言中用于生成随机数的两个重要函数。
rand()函数:用于生成伪随机数。它存在于头文件
<stdlib.h>
中,返回一个介于0和RAND_MAX
(通常是32767)之间的伪随机整数。这个函数使用线性同余法来计算随机数,这意味着在一定范围内生成一串数字,有一个最大周期M。默认情况下,rand()函数的种子是1,所以每次运行程序时生成的随机数序列都是相同的。为了增加随机性,通常会配合srand()函数使用。srand()函数:用于设置随机数种子。它的作用是产生一个随机种子,将这个种子传递给rand()函数,从而达到生成不同的随机数序列的目的。srand()函数可以接受不同的参数来产生不同的种子,例如使用
time(NULL)
或getpid(NULL)
的返回值作为参数,以确保每次产生不同的种子。使用time(NULL)
可以确保每次程序运行时产生不同的时间,而getpid(NULL)
则用来取得目前进程的进程识别码,用于建立临时文件以避免文件同名问题。通过结合使用rand()和srand()函数,可以在C语言中生成所需的随机数,这对于模拟、游戏、加密等多种应用场景都非常有用。例如,可以通过调用srand(time(NULL))来初始化随机数生成器,然后使用rand()来生成一系列的随机数,从而实现各种随机过程
//电脑下棋
void Computer(char board[ROW][COL], int row, int col)
{
printf("电脑下棋\n");
int x = 0;
int y = 0;
while (1)
{
x = rand() % row;//0-2
y = rand() % col;//0-2
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
不要忘了在主函数中添加srand来设置随机数起点:
打印结果:
5.判断输赢
- 到这里就快成功了,首先需要把玩家下棋和电脑下棋使用循环,让他们打回合,不然一把就结束了。
- 然后进行输赢判断首先我们约定:玩家赢 函数返回‘*’,电脑赢 函数返回‘#’,平局 函数返回‘q’,继续 函数返回‘c’。(玩家和电脑之所以这样设定是因为,如果哪一方赢了,直接返回其中的一个棋子即可判断)
- 三子棋里赢的条件无非是横着三个,竖着三个,对角线三个。
- 我们还需要考虑棋盘是否放满了,如果放满了也没有人赢,那么就是平局。
- 我们应该把这个函数放在玩家落子和电脑落子之后(两个后面都放),这样我们才能及时判断。
//判断输赢
char Is_win(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][1] != ' ')
{
return board[i][1];
}
}
//列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
{
return board[1][i];
}
}
//对角
if (board[1][1] == board[0][0] && board[1][1] == board[2][2] && board[1][1] != ' ')
{
return board[1][1];
}
else if (board[1][1] == board[0][2] && board[2][0] == board[1][1] && board[1][1] != ' ')
{
return board[1][1];
}
//平局
if (Is_full(board, row, col))
{
return 'q';
}
return 'c';
}
//判断是否满盘
//满了返回1,没满返回0
int Is_full(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++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
基本流程到这里就结束了。
三、代码
1.game.h代码
#pragma once
#define ROW 3
#define COL 3
#include<stdlib.h>
#include<time.h>
//初始化棋盘的函数
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);
//玩家下棋
void Player(char board[ROW][COL], int row, int col);
//电脑下棋
void Computer(char board[ROW][COL], int row, int col);
//判断输赢
char Is_win(char board[ROW][COL], int row, int col);
int Is_full(char board[ROW][COL], int row, int col);
3.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 DisplayBoard(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 Player(char board[ROW][COL], int row, int col)
{
int x = 0;//横坐标
int y = 0;//纵坐标
while (1)
{
printf("玩家下棋\n");
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");
}
}
}
//电脑下棋
void Computer(char board[ROW][COL], int row, int col)
{
printf("电脑下棋\n");
int x = 0;
int y = 0;
while (1)
{
x = rand() % row;//0-2
y = rand() % col;//0-2
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
//判断是否满盘
//满了返回1,没满返回0
int Is_full(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++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
//判断输赢
char Is_win(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][1] != ' ')
{
return board[i][1];
}
}
//列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
{
return board[1][i];
}
}
//对角
if (board[1][1] == board[0][0] && board[1][1] == board[2][2] && board[1][1] != ' ')
{
return board[1][1];
}
else if (board[1][1] == board[0][2] && board[2][0] == board[1][1] && board[1][1] != ' ')
{
return board[1][1];
}
//平局
if (Is_full(board, row, col))
{
return 'q';
}
return 'c';
}
3.test.c代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include"game.h"
menu()
{
printf("**************\n");
printf("*** 1.play ***\n");
printf("*** 0.exit ***\n");
printf("**************\n");
}
game()
{
char r = 0;//接收输赢的返回值
char board[ROW][COL] = { 0 };
//初始化棋盘的函数
InitBoard(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
while (1)
{
//玩家下棋
Player(board, ROW, COL);
//判断输赢
r = Is_win(board, ROW, COL);
if (r != 'c')
break;
//打印棋盘
DisplayBoard(board, ROW, COL);
//电脑下棋
Computer(board, ROW, COL);
//判断输赢
r = Is_win(board, ROW, COL);
if (r != 'c')
break;
//打印棋盘
DisplayBoard(board, ROW, COL);
}
if (r == '*')
{
printf("玩家赢\n");
}
else if (r == '#')
{
printf("电脑赢\n");
}
else if (r == 'q')
{
printf("平局\n");
}
//打印棋盘
DisplayBoard(board, ROW, COL);
}
int main()
{
srand((unsigned int)time(NULL));//设置随机数起点
int input = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏!\n");
break;
default:
printf("选择错误,请重新选择\n");
}
} while (input);
return 0;
}
最终代码运行效果:
当然这个代码可能存在bug,还有很多可优化性,可以自己尝试更改代码 ,如果哪里写错了,欢迎指正。
标签:col,int,三子,C语言,小游戏,board,printf,COL,ROW From: https://blog.csdn.net/2203_75522143/article/details/140664369