目录
前言
三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利,而对方就算输了,但是三子棋在很多时候会出现和棋的局面。---百度百科
在三子棋小游戏的编写过程中,可以用到数组,循环等c语言基础知识,是练习c语言基础的推荐之一,下面就让我们一步一步实现它吧!
模块介绍
-
测试模块
1.测试文件
在整个编写开始前,建议可以先写好测试文件,写完一个功能函数测试一个函数,保证思路的顺利展开,否则,若一下全写完再测试,如果出现问题,就不清楚错从何处来,会影响到自己的思路。
主函数使用了一个do while循环以及嵌套一个switch语句,可以保证游戏可以在ta的选择下一直进行。
代码(test.c):
#define _CRT_SECURE_NO_WARNINGS
#include "game_szq.h"
int main()
{
int input = 0;
srand((unsigned int)time(NULL)); //rand函数的辅助
//在猜数字游戏中有详细介绍,这里不再赘述
do
{
menu(); //菜单
scanf("%d", &input);
switch (input)
{
case 1:
game(); //博弈
break;
case 0:
printf("退出成功\n");
break;
default:
printf("输入错误\n");
break;
}
} while (input);
return 0;
}
-
功能实现模块
1.头文件
在测试文件中可以看到,主函数主要包括菜单,博弈,而三子棋主要核心在于博弈,主要有初始化棋盘、打印棋盘、玩家下棋、电脑下棋以及判断输赢等功能模块。
代码(game.h):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3 //行数
#define COL 3 //列数
//菜单
void menu();
//游戏具体实现
void game();
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void PrintBoard(char board[ROW][COL], int row, int col);
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void PCMove(char board[ROW][COL], int row, int col);
//判断输赢
char is_win(char board[ROW][COL], int row, int col);
2.函数实现文件
1)菜单
菜单的制作依旧很简单,是读者展示自己个性的地方,可以根据自己对游戏的理解装点菜单界面,让ta可以对游戏的功能一目了然。
代码:
void menu()
{
printf("*********三子棋************\n");
printf("*********1.start***********\n");
printf("*********0.exit************\n");
printf("***************************\n");
}
测试:
2)初始化棋盘
棋盘在程序中就是一个二维数组,为在.exe文件表现成一个棋盘模样(如图),将二维数组的所有元素初始化为 空格 。
代码:
void InitBoard(char board[ROW][COL], int row, int col)
{
int i = 0, j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
3)打印棋盘
打印棋盘是三子棋小游戏中的难点之一,可以细细打敲,在.exe文件中,可以将棋盘分解为如左图的格式,其中半格代表空格,方格代表字符,竖线、横线则是棋盘网格线,而棋盘的一行占.exe文件中的两行,如右图的①②两行。
![]()
代码:
void PrintBoard(char board[ROW][COL], int row, int col)
{
int i = 0, j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]); //打印上图的①
if (j < col - 1) //防止出现右边框
printf("|"); //因为最右边不需要竖线,所以加上if语句进行特殊处理
}
printf("\n");
if (i < row - 1) //防止出现下边框,最下边不需要横线
{
for (j = 0; j < col; j++)
{
printf("---"); //打印上图的②
if (j < col - 1) //防止出现右边框
printf("|");
}
printf("\n");
}
}
printf("\n");
}
测试:
注意:笔者在前面的头文件中对棋盘的行列作了预处理设置,即#define ROW 3 #define COL 3,此时,若将3改成5,则棋盘变成了5X5,如左图,若改为10,则变成10X10,如右图,所以读者可以任意更改棋盘的格式成为n子棋(但游戏规则没有发生变化,依旧是三子棋的规则hahaha)。
4)玩家下棋
当轮到玩家下棋时,玩家根据三子棋的规则去放置己方棋子(*),使用if语句对所选择坐标做出限制,选择不当时作出提示,让玩家重新选择,此时,也需要一个循环去实现重复选择坐标的效果,当选择合法坐标时跳出循环。
代码:
void PlayerMove(char board[ROW][COL], int row, int col)
{
int i = 0, j = 0;
printf("玩家下棋\n");
while (1)
{
printf("请输入棋盘坐标:\n");
scanf("%d %d", &i, &j);
if (i >= 1 && i <= row && j >= 1 && j <= col&&board[i - 1][j - 1]==' ')
//限制棋盘坐标的选择,包括坐标合法以及此坐标为空(为空格符)
{
board[i - 1][j - 1] = '*';
break;
}
else
{
printf("输入错误,请重新输入\n");
}
}
}
测试:
5)电脑下棋
当电脑下棋时,电脑会根据剩下棋格随机放入棋子(#)(由于笔者能力有限,同时其作为c语言基础的练习,无法去实现智能下棋,有能力的可以尝试做一下),此时也就利用到了rand函数(别忘了在主函数中加上srand函数以及头文件哦,这个知识点在猜数字游戏中讲过)。同时,与玩家下棋一样,也要利用循环做出 坐标非法就重新选择坐标 的效果。
代码:
void PCMove(char board[ROW][COL], int row, int col)
{
int i = 0, j = 0;
printf("电脑下棋\n");
while (1)
{
i = rand() % row; //随机行坐标
j = rand() % col; //随机列坐标
if (board[i][j] == ' ') //限制坐标为空(为空格符)
{
board[i][j] = '#';
break;
}
}
}
测试:
6)判断输赢
判断输赢也是三子棋游戏的难点之一,因为需要考虑游戏结果的多种情况,包括①三行、三竖、两斜成线均为赢,②没人赢但棋格满了为平局,③没人赢且棋格没满则继续,具体看代码注释。
代码:
char is_win(char board[ROW][COL], int row, int col)
{
int i = 0, j = 0;
//判断行
for (i = 0; i < row; i++) //循环判断每一行
{
for (j = 1; j < col; j++) //判断玩家有无成行
{
if (board[i][j] != board[i][0] || board[i][0] != '*')
break;
} //从此循环出来有两种情况 ①break出来,即出现if语句中的情况
//②j==col,即未出现if语句的情况,即if语句的反命题,
//即在第某行中,每一个棋盘的棋子均与第一个棋子相同且棋子为*,即玩家成行
if (j==col) //此if语句就是判断是否为②的情况
return '*';
for (j = 1; j < col; j++) //判断电脑是否成行,情况与玩家一致
{
if (board[i][j] != board[i][0] || board[i][0] != '#')
break;
}
if (j==col)
return '#';
}
//判断列
for (j = 0; j < col; j++) //循环判断每一列,与判断每一行情况一致
{
for (i = 1; i < row; i++)
{
if (board[i][j] != board[0][j] || board[0][j] != '*')
break;
}
if (i == row)
return '*';
for (i = 1; i < row; i++)
{
if (board[i][j] != board[0][j] || board[0][j] != '#')
break;
}
if (i == row)
return '#';
}
//判断正对角线
for (i = 1; i < row; i++) //仔细理解判断行的情况,理解之后,判断正副对角线就不难理解了
{
if (board[0][0] == ' ' || board[i][i] != board[0][0])
break;
}
if (i==row)
return board[0][0];
//判断副对角线
for (i = 1; i < row; i++)
{
if (board[0][row - 1] == ' ' || board[i][row - i - 1] != board[0][row - 1])
break;
}
if (i == row)
return board[0][row - 1];
//当没人赢且有空格符时则继续
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 'c'; //继续
}
}
//当没人赢且没有空格符时则判为平局
return 'q'; //平局
}
测试:
7)博弈
在玩家与电脑下棋之前,需要将棋盘初始化,之后利用循环进行玩家与电脑的博弈,当某方下完棋之后立马判断是否有人胜利,有人胜利时就退出循环公布结果,否则就继续下棋。
代码:
void game()
{
char tmp = 0;
//设置棋盘
char board[ROW][COL] = {0};
//初始化棋盘
InitBoard(board, ROW, COL);
//打印
PrintBoard(board, ROW, COL);
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
PrintBoard(board, ROW, COL);
tmp = is_win(board, ROW, COL);
if (tmp != 'c')
break;
//电脑下棋
PCMove(board, ROW, COL);
PrintBoard(board, ROW, COL);
tmp = is_win(board, ROW, COL);
if (tmp != 'c')
break;
}
printf("游戏结束,结果:\n");
if (tmp == '*')
printf("玩家获胜\n");
else if (tmp=='#')
printf("电脑获胜\n");
else
printf("平局\n");
}
测试:
完整测试
后记
以上就是三子棋小游戏的实现,在设计过程中,有些部分可能做的不是很好,有错误或者需要改进的可以写在评论区,我会学习的,一起进步!有老铁想要源码可以三连加关注私信我或者写在评论区哦,谢谢。