当前位置:网站首页>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~
边栏推荐
猜你喜欢
随机推荐
HOG feature study notes
Oracle encapsulates restful interfaces into views
意识形态的机制
超越YOLO5-Face | YOLO-FaceV2正式开源Trick+学术点拉满
C语言基础知识 -- 指针
Jincang database KingbaseES V8 GIS data migration solution (3. Data migration based on ArcGIS platform to KES)
开篇-开启全新的.NET现代应用开发体验
优化Feed流遭遇拦路虎,是谁帮百度打破了“内存墙”?
EBS uses virtual columns and hint hints to optimize sql case
Greenplum Database Fault Analysis - Why Does gpstart -a Return Failure After Version Upgrade?
【OpenCV 图像处理2】:OpenCV 基础知识
如何基于OpenVINO POT工具简单实现对模型的量化压缩
第09章 性能分析工具的使用【2.索引及调优篇】【MySQL高级】
Utilities 蚁剑高级模块开发
Hypervisor related knowledge points
【Word】Word公式导出PDF后出现井号括号#()错误
【genius_platform软件平台开发】第七十六讲:vs预处理器定义的牛逼写法!!!!(其他组牛逼conding人员告知这么配置来取消宏定义)
居民用水问题
Using OpenVINO to implement the flying paddle version of the PGNet inference program