三子棋我们再熟悉不过了,但是如何用C语言制作三子棋游戏呢?
首先我们用*号代表玩家下棋;我们用#号代表电脑下棋;接着我们可以通过输入坐标来控制棋子的输入,而电脑通过随机数的来下棋。
用模块化编程,将一个游戏分成3个文件来制作,分别为主文件test.c来执行主函数main、其次是注册函数的头文件game.h、最后是实现游戏功能的函数文件game.c。
主文件test.c 先打印出游戏开始界面,让用户输入1或0(1是真0是假)来控制游戏的开始与结束。用户通过scanf函数来输入,巧妙使用do...while函数来实现逻辑,先执行一次游戏菜单的打印,在游戏结束之后再调用游戏菜单。
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
// 打印菜单
void menu()
{
printf("****************************\n");
printf("********** 1.play **********\n");
printf("********** 0.exit **********\n");
printf("****************************\n");
}
// 主函数
int main()
{
int a = 0;
int input = 0;
srand((unsigned int)time(NULL));
//用户输入数字来开启游戏
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 0:
printf("退出游戏!\n");
break;
case 1:
// 调用游戏的主体函数game()
game();
break;
default:
printf("输入错误!\n");
break;
}
} while (input);
return 0;
}
游戏的主函数game(),主要调用game.c中的函数,再通过game.c函数中返回的值来对游戏进程进行判断。因为每次下完棋都要打印棋盘,所以每次执行完PlayerMove函数和ComputerMove函数都需要调用一次Displayboard函数来打印棋盘,再通过while循环不断运行游戏知道isWin函数通过返回值判断游戏是否结束,后break跳出循环结束游戏进程。
// 开始编写游戏
void game()
{
//创建一个二维数组
char board[ROW][COL] = { 0 };
char win = 0;
//调用game.c中的函数
Initboard(board, ROW,COL);
DisPlayBoard(board, ROW, COL);
while (1)
{
PlayerMove(board, ROW, COL);
win = isWin(board, ROW, COL);
// 通过game.c中返回的值来判断游戏的进程 用break来中止循环 结束游戏
if (win != 'C')
{
break;
}
DisPlayBoard(board, ROW, COL);
ComputerMove(board, ROW, COL);
win = isWin(board, ROW, COL);
if (win != 'C')
{
break;
}
DisPlayBoard(board, ROW, COL);
}
// 通过game.c中返回的值来判断游戏的进程
if (win == '*')
{
printf("玩家胜利!\n");
}
else if(win == '#')
{
printf("电脑胜利!\n");
}
else
{
printf("死棋了!\n");
}
DisPlayBoard(board, ROW, COL);
}
创建game.h头文件,来创建和初始化函数,以及引入所需要的头文件和创建宏来定义棋盘的大小。其他文件都需要引入game.h头文件,便于设置游戏参数。
#define _CRT_SECURE_NO_WARNINGS 1
#include <string.h>
#include <stdio.h>
#define ROW 3
#define COL 3
// 初始化棋盘
void Initboard(char board[ROW][COL], int row, int col);
// 打印棋盘
void DisPlayBoard(char board[ROW][COL], int row, int col);
// 玩家移动
void PlayerMove(char board[ROW][COL], int row, int col);
// 电脑移动
void ComputerMove(char board[ROW][COL], int row, int col);
// 判断胜利条件
char isWin(char board[ROW][COL], int row, int col);
在game.c文件中,我们主要实现游戏的各个功能以及对数组的初始化。
1. Initboard函数初始化棋盘
用双重for循环遍历board数组,并给board数组输入一个空格来初始化他。
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] = ' ';
}
}
}
2. DisPlayBoard函数打印游戏棋盘
用if判断是否到最后一行,如果满足条件(j<col-1)就未到最后一行,则打印竖杠。
下面一个if用于打印分割线,也是同理
void DisPlayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (int i = 0; i < row; i++)
{
int j = 0;
// 先打印行
for (int j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
{
printf("|");
}
else
{
printf("\n");
}
}
// 每打印一行就打印一行分隔线
if (i < row - 1)
{
int j = 0;
for (int j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
else
{
printf("\n");
}
}
}
}
}
3. PlayerMove函数控制玩家的移动
通过scanf函数来获取用户输入的坐标,再通过if对坐标的大小进行判断,超出棋盘大小则提示用户错误。再判断用户输入的坐标是否存在棋子, 没有就用*代表用户输入棋子并且用break退出while循环,有棋子的话通过while循环再次让用户输入。
// 玩家移动
void PlayerMove(char board[ROW][COL], int row, int col)
{
while (1)
{
int x = 0;
int y = 0;
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");
}
}
}
4. ComputerMove函数来实现电脑下棋
retX和retY变量代表两个随机数坐标,取模棋盘的大小用于控制随机数的范围,再次判断落子位置有没有棋子,如果有则再次循环没有则break跳出循环。
// 电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
while (1)
{
int retX = rand() % row;
int retY = rand() % col;
if (board[retX][retY] == ' ')
{
board[retX][retY] = '#';
break;
}
}
printf("电脑已下棋:>\n");
}
在test.c文件的main函数中,使用srand()初始化rand函数。time()函数给srand定义随机范围,unsigned int强制类型转换成srand函数所需要的数据类型。
srand((unsigned int)time(NULL));
4. isWin函数判断游戏进程
判断胜利条件根据条件返回给主游戏函数相应的值
玩家赢 - ‘*’
电脑赢 - ‘#’
死棋 - ‘Q’
游戏继续 - ‘C’
循环遍历判断行、列和对角线是否相同并且不为空,则返回其中的一个棋子,来判断是谁赢了
//判断胜利条件
// 玩家赢 - ‘*’
// 电脑赢 - ‘#’
// 死棋 - ‘Q’
// 继续 - ‘C’
char isWin(char board[ROW][COL], int row, int col)
{
// 判断行
int i = 0;
for (i = 0;i<row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] ==
board[i][2] && board[i][0] != ' ')
{
return board[i][0];
}
}
//判断列
int j = 0;
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] ==
board[2][j] && board[0][j] != ' ')
{
return board[0][j];
}
}
// 判断对角线
if (board[0][0] == board[1][1] && board[1][1] ==
board[2][2] && board[1][1] != ' ')
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] ==
board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
// 判断是否死棋
// 因为需要循环遍历数组的每一位
// 所以需要创建一个函数来返回这段遍历代码的最终结果
if (isFull(board, row, col))
{
return 'Q';
}
return 'C';
}
判断游戏有没有死棋(平局),则需要创建一个isFull函数,isFull函数中需要遍历board数组中的每一位判断他是否存在棋子,在循环结束后如果没有返回值即已经死棋,在根据isFull的返回值来判断游戏的进程再返回game函数所需要的值。
// 判断是否死棋
int isFull(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;
}
到这里整个三子棋游戏就完成实现了,谢谢观看!
标签:游戏,int,三子,C语言,board,printf,COL,ROW From: https://blog.csdn.net/m0_64574726/article/details/139775577