当前位置:网站首页>Quickly learn chess from zero to one
Quickly learn chess from zero to one
2022-08-05 02:18:00 【wind waves】
前言
Three-piece chess is also known as tic-tac-toe chess,It's a small game for all ages,I'm sure everyone has played it,Not much to say about the rules of the game.今天我们就来用 C language to simply implement it.
一、Game expected screen

二、游戏的实现
1、菜单
void menu()
{
printf("*****************************\n");
printf("******* 1.play ********\n");
printf("******* 0.exit ********\n");
printf("*****************************\n");
}
2、主函数
首先,我们思考一下,This game should be executed at least once,Make selections during execution,那么我们应该使用 do while 循环来实现.根据选择不同,to execute the corresponding program,那么应该使用 switch 语句.
下面我们来看代码:
int main()
{
int input = 0;
do
{
menu(); //Each time the menu is printed before selection
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game(); //开始游戏
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重新选择!\n");
break;
}
} while (input); //Determines whether to loop based on the entered value,0则退出循环
return 0; //This is why in the menu to quit the game is set to0的原因
}
3、game函数的实现
3.1、棋盘的打印
We can judge from the expected picture,我们应该创建一个 3*3 An array of chess to store our moves,And have to initialize the array to spaces.We can choose the position of the move based on the coordinates.那么问题来了,How should we print the chessboard?
首先,Let's take a closer look at the chessboard in the picture,We can find that every time we play chess, we play in the middle of the grid, which is the picture below:
That is, there are spaces next to each number,Used between peer numbers | 隔开,第二行是由 - 和 | 组成.
We treat the first row and the second row as a group,We can get three groups(Suppose the second row of the third group exists)
That is, like the picture below:

So we can write the following code:
#define M 3
#define N 3
void game()
{
char arr[M][N] = {
0 };
chu_shi(arr, M, N); //初始化数组
da_yin(arr, M, N); //打印棋盘
}
void chu_shi(char arr[M][N], int m, int n)
{
int i = 0;
int j = 0;
for(i=0;i<m;i++)
for (j = 0; j < n; j++)
{
arr[i][j] = ' '; //将数组初始化为空格
}
}
void da_yin(char arr[M][N], int m, int n)
{
int i = 0;
for (i; i < m; i++)
{
printf(" %c | %c | %c \n", arr[i][0], arr[i][1], arr[i][2]);
}
if (i < m - 1) //若没有 if Then the second line of the third group is printed,if 起限制作用
printf("---|---|---\n");
}
这样,We just printed out the entire chessboard.但有个小问题,That is, if I change the size of the chessboard,现在是 3 * 3 ,我改动 M N 的值为 5 5 呢,我们可以看出,line is right,But only three columns are printed,这明显不行,So we print the column according to the idea of printing the row,Similarly divide the columns into three groups,如图:

We can optimize the printing checkerboard code as follows:
void da_yin(char arr[M][N], int m, int n)
{
int i = 0;
for (i; i < m; i++)
{
int j = 0;
for (j = 0; j < n; j++)
{
printf(" %c ", arr[i][j]);
if (j < n - 1) //限制 | 的打印
printf("|");
}
printf("\n");
if (i < m - 1)
{
for (j = 0; j < n; j++)
{
printf("---");
if (j < n - 1) //限制 | 的打印
printf("|");
}
}
printf("\n");
}
}
3.2、玩家下棋
Then we should start the real game,That is, enter the drop position.
我们思考一下,Our coordinates should be reasonable,Cannot exceed the array specification,And our children should be preserved,The point cannot be selected next time.
我们可以写出如下代码:
void wan_jia(char arr[M][N], int m, int n)
{
int x = 0;
int y = 0; //Because the player may not know it is from0行0列开始的
printf("玩家下棋:>\n"); //So we set it to start from the first1行1列到第3行3列
while (1)
{
printf("请输入要下棋的坐标:>\n");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= m && y >= 1 && y <= n)
{
if (arr[x - 1][y - 1] == ' ')
{
arr[x - 1][y - 1] = '*';
break;
}
else
{
printf("该坐标被占用,请重新输入\n");
}
}
else
{
printf("坐标非法请重新输入");
}
}
}
3.3、电脑下棋
Now we take the next step,Next it's the computer's turn,同样的逻辑,But computer chess is random,So we want to generate random numbers,The random number generation code is as follows:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
srand((unsigned int)time(NULL)); //Set up a random number generator
int m = rand()%3; //因为 rand 生成随机数范围0~32767
printf("%d",m); //所以 %3 Make the random number generation range 0~2
}
Therefore, we can write the computer chess code:
srand((unsigned int)time(NULL)); //我们需要放在 main 函数中
void dian_nao(char arr[M][N], int m, int n)
{
printf("电脑下棋:>\n");
while (1)
{
int x = rand() % m;
int y = rand() % n;
if (arr[x][y] == ' ')
{
arr[x][y] = '#';
break;
}
}
}
In this way, we can complete the game between the player and the computer,但是美中不足的是,We cannot judge winners or losers.因此,Next we decide to win or lose.
3.4、判断输赢
We know that there are several states during the game:玩家赢、电脑赢、平局、游戏继续,We use these four states separately ’ * ’ 、’ # ‘、’ Q ‘、’ C '来作为返回值.
We know that three pieces of chess are nothing more than horizontal or vertical or oblique three pieces into a line,So we can write the following code:
char is_win(char arr[M][N], int m, int n)
{
//We want to return characters so use char
int i = 0;
for (i = 0; i < m; i++) //判断行
{
if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != ' ')
{
return arr[i][0];
}
}
for (i = 0; i < n; i++) //判断列
{
if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != ' ')
{
return arr[0][i];
}
}
//The two slashes are judged below
if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[0][0] != ' ')
{
return arr[0][0];
}
if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[1][1] != ' ')
{
return arr[1][1];
}
}
We can already judge winners and losers,But we also seem to have missed a draw.
We then create a function to traverse arr 数组,to check if there are any spaces,If there is, the board is not full,返回0,反之返回1.
由此,我们可以写出如下代码:
//如果棋盘满了,返回1
//不满返回0
int is_full(char arr[M][N], int m, int n)
{
int i = 0;
for (i = 0; i < m; i++)
{
int j = 0;
for (j = 0; j < n; j++)
{
if (' ' == arr[i][j])
return 0;
}
}
return 1;
}
We then insert it into the judgment code,可以得到:
char is_win(char arr[M][N], int m, int n)
{
int i = 0;
for (i = 0; i < m; i++)
{
if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != ' ')
{
return arr[i][0];
}
}
for (i = 0; i < n; i++)
{
if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != ' ')
{
return arr[0][i];
}
}
if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[0][0] != ' ')
{
return arr[0][0];
}
if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[1][1] != ' ')
{
return arr[1][1];
}
//判断平局
if (is_full(arr, m, n) == 1)
{
return 'Q';
}
//继续
return 'C';
}
3.5、game函数的真正实现
我们将 game 函数的实现过程,The function to be called understands it again,Let's look at the specifics below game 函数如何实现:
void game()
{
char ret = 0;
char arr[M][N] = {
0 };
chu_shi(arr, M, N); //首先,我们初始化数组
da_yin(arr, M, N); //打印一下棋盘
while (1) //进行游戏
{
wan_jia(arr, M, N); //玩家先下
ret = is_win(arr, M, N); //Judge each step
if (ret != 'C') //Determine if there is a win or a draw·
break; //'C'代表继续,不等于 'C' The result appears
//break 跳出循环
da_yin(arr, M, N); //Print the board after each move
dian_nao(arr, M, N); //电脑下
ret = is_win(arr, M, N);
if (ret != 'C')
break;
da_yin(arr, M, N);
}
if (ret == '*')
printf("玩家赢\n");
else if (ret == '#')
printf("电脑赢\n");
else
printf("平局\n");
da_yin(arr, M, N); //At the end of the game print the board
}
注意,We judge winning or losing before printing the board,If there is a result,We don't know the state of the board,So the game should print the board at the end.
4、Game specific code
a game like this,We should have three parts:game.h、test.c、game.c.
game.h : Include header files and pairs test.c 中函数的声明.
test.c :Encapsulate the function,使得 game.c 尽量简洁
game.c : 游戏主体,包含 main 函数.
4.1、game.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define M 3
#define N 3
//初始化数组
void chu_shi(char arr[M][N], int m, int n);
//打印棋盘
void da_yin(char arr[M][N], int m, int n);
//玩家下棋
void wan_jia(char arr[M][N], int m, int n);
//电脑下棋
void dian_nao(char arr[M][N], int m, int n);
//判断游戏状态
char is_win(char arr[M][N], int m, int n);
4.2、test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//初始化数组
void chu_shi(char arr[M][N], int m, int n)
{
int i = 0;
int j = 0;
for(i=0;i<m;i++)
for (j = 0; j < n; j++)
{
arr[i][j] = ' ';
}
}
//打印棋盘
void da_yin(char arr[M][N], int m, int n)
{
int i = 0;
for (i; i < m; i++)
{
int j = 0;
for (j = 0; j < n; j++)
{
printf(" %c ", arr[i][j]);
if (j < n - 1)
printf("|");
}
printf("\n");
if (i < m - 1)
{
for (j = 0; j < n; j++)
{
printf("---");
if (j < n - 1)
printf("|");
}
}
printf("\n");
}
}
//玩家下棋
void wan_jia(char arr[M][N], int m, int n)
{
int x = 0;
int y = 0;
printf("玩家下棋:>\n");
while (1)
{
printf("请输入要下棋的坐标:>\n");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= m && y >= 1 && y <= n)
{
if (arr[x - 1][y - 1] == ' ')
{
arr[x - 1][y - 1] = '*';
break;
}
else
{
printf("该坐标被占用,请重新输入\n");
}
}
else
{
printf("坐标非法请重新输入");
}
}
}
//电脑下棋
void dian_nao(char arr[M][N], int m, int n)
{
printf("电脑下棋:>\n");
while (1)
{
int x = rand() % m;
int y = rand() % n;
if (arr[x][y] == ' ')
{
arr[x][y] = '#';
break;
}
}
}
//如果棋盘满了,返回1
//不满返回0
int is_full(char arr[M][N], int m, int n)
{
int i = 0;
for (i = 0; i < m; i++)
{
int j = 0;
for (j = 0; j < n; j++)
{
if (' ' == arr[i][j])
return 0;
}
}
return 1;
}
//判断输赢
char is_win(char arr[M][N], int m, int n)
{
int i = 0;
for (i = 0; i < m; i++)
{
if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != ' ')
{
return arr[i][0];
}
}
for (i = 0; i < n; i++)
{
if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != ' ')
{
return arr[0][i];
}
}
if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[0][0] != ' ')
{
return arr[0][0];
}
if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[1][1] != ' ')
{
return arr[1][1];
}
//判断平局
if (is_full(arr, m, n) == 1)
{
return 'Q';
}
//继续
return 'C';
}
4.3、game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h" //包含 game.h
void menu()
{
printf("*****************************\n");
printf("******* 1.play ********\n");
printf("******* 0.exit ********\n");
printf("*****************************\n ");
}
void game()
{
char ret = 0;
char arr[M][N] = {
0 };
chu_shi(arr, M, N);
da_yin(arr, M, N);
while (1)
{
wan_jia(arr, M, N);
ret = is_win(arr, M, N);
if (ret != 'C')
break;
da_yin(arr, M, N);
dian_nao(arr, M, N);
ret = is_win(arr, M, N);
if (ret != 'C')
break;
da_yin(arr, M, N);
}
if (ret == '*')
printf("玩家赢\n");
else if (ret == '#')
printf("电脑赢\n");
else
printf("平局\n");
da_yin(arr, M, N);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL)); //Set up a random number generator
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重新选择!\n");
break;
}
} while (input);
return 0;
}
This completes our backgammon game,At first glance it seems dizzy,But if we break it down into small steps,We can easily understand and write it out.
学习就是这样,When encountering difficult problems, it is often easier to split the steps.
下期预告
The next issue will definitely bring you a thrilling and exciting mine sweeping.
Then we'll see you next time~
边栏推荐
- Simple implementation of YOLOv7 pre-training model deployment based on OpenVINO toolkit
- 英特尔 XDC 2022 精彩回顾:共建开放生态,释放“基建”潜能
- .Net C# 控制台 使用 Win32 API 创建一个窗口
- 在这个超连接的世界里,你的数据安全吗
- 优化Feed流遭遇拦路虎,是谁帮百度打破了“内存墙”?
- 常见的硬件延迟
- J9数字货币论:web3的创作者经济是什么?
- 刷爆朋友圈,Alibaba出品亿级并发设计速成笔记太香了
- [Unity Entry Plan] Handling of Occlusion Problems in 2D Games & Pseudo Perspective
- iNFTnews | 对体育行业和球迷来说,NFT可以带来什么?
猜你喜欢

常见的硬件延迟

第09章 性能分析工具的使用【2.索引及调优篇】【MySQL高级】

【MySQL系列】- LIKE查询 以%开头一定会让索引失效吗

迅睿cms网站搬迁换了服务器后网站不能正常显示

LeetCode使用最小花费爬楼梯----dp问题

1349. 参加考试的最大学生数 状态压缩

【Unity入门计划】2D游戏中遮挡问题的处理方法&伪透视

Understand the recommendation system in one article: Recall 06: Two-tower model - model structure, training method, the recall model is a late fusion feature, and the sorting model is an early fusion

leetcode 15

Tree search (bintree)
随机推荐
PHP技能评测
PHP Skills Assessment
【Unity入门计划】2D游戏中遮挡问题的处理方法&伪透视
Jincang database KingbaseES V8 GIS data migration solution (3. Data migration based on ArcGIS platform to KES)
网络安全与元宇宙:找出薄弱环节
SuperMap支持的国产环境汇总
《.NET物联网从零开始》系列
[parameters of PyQT5 binding functions]
领域驱动设计——MDD
Greenplum数据库故障分析——能对数据库base文件夹进行软连接嘛?
【Word】Word公式导出PDF后出现井号括号#()错误
oracle将restful接口封装到视图中
Optimizing the feed flow encountered obstacles, who helped Baidu break the "memory wall"?
“配置”是把双刃剑,带你了解各种配置方法
Simple implementation of YOLOv7 pre-training model deployment based on OpenVINO toolkit
MySQL3
散列表的查找(哈希表)
CPDA|运营人如何从负基础学会数据分析(SQL)
基于OpenVINO工具套件简单实现YOLOv7预训练模型的部署
记录谷歌gn编译时碰到的一个错误“I could not find a “.gn“ file ...”