#Beginner must see#Teach you how to write three chess tutorials#B Station Pengge

foreword

Those who know how to write may not really understand. This article combines the writing techniques of Brother Peng at station B, advances the knowledge points step by step, and teaches you to write code step by step. It is very suitable for beginners to learn, and it is recommended to watch it repeatedly.

At the same time, the author, I am also a beginner of C language station B, welcome to learn and communicate together, criticize and correct.


Let's write an outline first, tell your computer what to do?


Tell your computer what it is going to do, that is, assign it a task, and then instruct it to complete that task.

Let's talk about a specific process first:

first part:

ccd8c58428eb40579bc365f2fe199717.png

the second part: 

 3970f8f344c140baa9f1f925456050a7.png

 The flow chart of the entire program is attached above, which is the task you want the computer to complete. Once you know what you're going to do, it's easy to talk to the computer about the specifics.

Let's talk about the specifics again, how does the program work?


first part:

Create the main() function, print your menu, and make your menu work.

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"game.h"
void menu()
{
	printf("**************************************************\n");
	printf("****************     三子棋      *****************\n");
	printf("************* 1.游戏开始 2.游戏结束 **************\n");
	printf("**************************************************\n");
}
void   game()
{
  //第二部分实现
}
int main()
{
	//打印菜单
	menu();  
	int input;
	do {
		printf("请输入1/0是否开始游戏->\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("您的三子棋游戏开始\n");
            game();
			break;
		case 0:
			printf("谢谢!游戏已经退出\n ");
			break;
		default:
			printf("对不起,请输入正确的值\n");
			break;
		}
	} while (input);
    return 0;
}

focus! ! ! Let me tell you the pits and solutions I have stepped on:

1. Your printf and scanf may be placed outside the do{}while loop due to your personal habits, which will cause the break to be unusable later.

2. You may consider using if () else if to write, but you must not forget else when writing if () else of.

3. Some people may not use the menu key of 1 or 0, but use the string key like yes/no, so that the branch of switch case cannot be used. Only then use if, else if branch, and use It cannot be judged by "==", but by trcmp(arr,"yes")==0.

4. I use the VS2022 compiler, I used #define _CRT_SECURE_NO_WARNINGS, and#include<stdio.h>,也会报一个scanf返回值被忽略的警告。(有大神知道是什么回事吗?)

加#include <cstdlib>头文件就好了

注:这里引用了一个自定义#include"game.h"的头文件,后面会用到,用来声明函数。

Check out the results:

036e9d1cea484d5a8794f8f3bced482d.png


 Part II: (emphasis)

4952d823970f42d7990df90c843132c6.png

Then all the second part functions that need to be created are in the void game() function.

Now that we have the menu, we can start playing chess, but we don't have a board yet, so let's get one.

Initialize the chessboard and print the chessboard

void game()
{
	//创建一个二维数组
	char shangziqi[ROW][COL] = { 0 };
	//初始化棋盘
	InitBoard(shangziqi, ROW, COL);
	//打印棋盘
	DipiayBoard(shangziqi, ROW, COL);
}
//头文件中声明函数
#define ROW 3
#define COL 3
//初始化棋盘
void InitBoard(char shangziqi[ROW][COL], int row, int col);
//打印棋盘
void DipiayBoard(char shangziqi[ROW][COL], int row, int col);

Create another function file in the program to increase readability

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
#include<stdio.h>
//初始化棋盘
void InitBoard(char shangziqi[ROW][COL], int row, int col)
{
    int i = 0;
    for (i = 0; i < row; i++)
    {
        int j = 0;
        for (j = 0; j < col; j++) {
            shangziqi[i][j] = ' ';
        }
    }
}
//打印棋盘
void DipiayBoard(char shangziqi[ROW][COL], int row, int col)
{
    int i, j;
    for (i = 0; i < row; i++) 
    {
        for (j = 0; j < col; j++) 
        {
            printf(" %c ", shangziqi[i][j]);
            if (j < col - 1)
            {
                printf("|");
            }
        }
        printf("\n");
        if (i < row - 1)
        {
            for (j = 0; j < row; j++) 
            {
                printf("---");
                if (j < col - 1)
                {
                    printf("|");
                }
            } 
            printf("\n");
        }
    }
}

This creates the chessboard and is ready to print.

It is recommended to use the memory analysis method for the printing method here, because the description of the printing method is too long, so it is inconvenient to describe here, please Q me if you are interested.

Let's see the effect:

6f72c50283d549eb8983b51200c06fb2.png


 player down 

First create the function name in the game function

//玩家下
	PlayGo(shangziqi, ROW, COL);
//然后打印
	DipiayBoard(shangziqi, ROW, COL);

Then declare in your custom header file

//玩家下
void PlayGo(char shangziqi[ROW][COL], int row, int col);

Finally, write the specific implementation method of the PayGo() function

}//玩家下
void PlayGo(char shangziqi[ROW][COL], int row, int col)
{
    int arr1, arr2;
    printf("到你走了\n");
    printf("操作介绍:输入1.1至3.3之内的坐标\n");
    while (1) {
        printf("请输入坐标—>\n");
        scanf("%d%d", &arr1, &arr2);
        if (arr1 >= 1 && arr1 <= row && arr2 <= col && arr2 >= 1)
        {
            if (shangziqi[arr1 - 1][arr2 - 1] == ' ') {
                shangziqi[arr1 - 1][arr2 - 1] = '*';
                break;
            }
            else {
                printf("该位置已被占用\n");
            }
        }
        else
        {
            printf("您的输入范围有误,请重新输入->\n");
        }
    }
}

Detailed interpretation:

1. Why the while() loop condition is 1?

Remember that the last part of our game is to judge whether to win or lose. Before we judge whether to win or lose, we have to keep playing, so when to skip the loop is realized when we finally judge whether to win or lose. It is indeed an infinite loop when I write this, but I haven't finished writing it yet, and I can pick out the infinite loop when I finish writing.

2. What do the two ifs here mean?

The first if is to judge whether the coordinates entered by the player are between 1 and 3, and the second if is to judge whether the chessboard grid is placed.

Note: When inputting coordinates, no addition is allowed between two numbers.

Take a look at the effect:

2985640b03f947d1953573fde138da0b.png


under computer

The game between humans and AI has begun

First create the function name in the game function

//ai下
	PlayGoai(shangziqi, ROW, COL);
	//下完打印棋盘
	DipiayBoard(shangziqi, ROW, COL);

Then declare in your custom header file

//ai下
void PlayGoai(char shangziqi[ROW][COL], int row, int col);

Finally, write the specific implementation method of the PlayGoai() function

#include<time.h>
#include <cstdlib>
//ai下
void PlayGoai(char shangziqi[ROW][COL], int row, int col)
{
    while (1) {
        srand((unsigned int)time(NULL));
        int arr3 = rand() % row;
        int arr4 = rand() % col;
        if (shangziqi[arr3][arr4] == ' ')
        {
            shangziqi[arr3][arr4] = '#';
            break;
        }
    }
}

detail analysis:

rand is a library function that generates random 1-1024 numbers. Here, % row or % col is used to control its random value between 1-3. At the same time, in order to ensure that the random value is not Similarly, it will be used together with the srand function, as described above, because the library function needs to refer to the header file, here are #include<time.h> and #include <cstdlib>.

Take a look at the results:
519ae750cdeb439f85b4eba906f5291c.png


Judging whether to win or lose (warning: this function is not finished yet, there is a final step to be discussed below)

Here is a judgment function suitable for beginners to learn

First create the function name in the game function

void game()
{
	//创建一个二维数组
	char shangziqi[ROW][COL] = { 0 };
	//初始化棋盘
	InitBoard(shangziqi, ROW, COL);
	//打印棋盘
	DipiayBoard(shangziqi, ROW, COL);
	//玩家下
	PlayGo(shangziqi, ROW, COL);
    //下完打印棋盘
	DipiayBoard(shangziqi, ROW, COL);
//第一部分
char ret = IsWin(shangziqi, ROW, COL);

	//ai下
	PlayGoai(shangziqi, ROW, COL);
	//下完打印棋盘
	DipiayBoard(shangziqi, ROW, COL);
//第二部分
	ret = IsWin(shangziqi, ROW, COL);

//第三部分
	if (ret == '*')
	{
		printf("玩家赢\n");
		//break;
	}
	else if (ret == '#')
	{
		printf("电脑赢\n");
		//break;
	}
	else if (ret == 'q')
	{
		printf("平局\n");
		//break;
	}
}

Detailed analysis:

There are three parts here, let's talk about them one by one. First, the first part creates a char type variable named ret, which is used to return a value, which will be used in the if judgment of the third part. Then, the second part also uses this char-type ret variable, which has the same function as the first part, and both return a value. The computer wins when #, the player wins when ret is *, and the draw when ret is q.

Declare in custom header file

//判断输赢
char IsWin(char shangziqi[ROW][COL], int row, int col);

Finally, write the specific implementation method of the IsWin() function

Don't look at it a lot, the principle is very simple, there is no one that we haven't seen, hold on! ! !

int IsFin(char shangziqi[ROW][COL], int row, int col)
{
    int i, j;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            if (shangziqi[i][j] == ' ')
            {
                return 0;
            }
        }
    }
    return 1;
}
char IsWin(char shangziqi[ROW][COL], int row, int col)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < row; i++)
    {
        if (shangziqi[i][0] == shangziqi[i][1] && shangziqi[i][2] == shangziqi[i][1] && shangziqi[i][0] != ' ')
        {
            return shangziqi[i][1];
        }
    }
    for (j = 0; j < col; j++)
    {
        if (shangziqi[0][j] == shangziqi[1][j] && shangziqi[1][j] == shangziqi[2][j] && shangziqi[0][j] != ' ')
        {
            return shangziqi[1][j];
        }
    }
    if (shangziqi[0][0] == shangziqi[1][1] && shangziqi[1][1] == shangziqi[2][2] && shangziqi[1][1] != ' ')
    {
        return  shangziqi[1][1];
    }
    if (shangziqi[2][0] == shangziqi[1][1] && shangziqi[0][2] == shangziqi[1][1] && shangziqi[1][1] != ' ')
    {
        return  shangziqi[1][1];
    }
    if (1 == IsFin(shangziqi, ROW, COL))
    {
        return 'q';
    }
    return 'c';
}

Detailed analysis:

Let's see how he returns a value!

 The if judgment condition here actually includes all its results, whether it is a bundled three-connection, or a horizontal three-connection, or a two-oblique connection. In these eight cases, it is judged whether the connection is * or #. You can judge which one wins or loses; another result is a tie, and at this time, use the else judgment other than the above result.

The function of the above InFin function is to judge when the function has been downloaded, that is, when the same three consecutive situations occur for the first time.

When writing here, the things you let the computer do are basically finished, but there is still a step...

last step

Your computer knows how to play chess, but you should know that you play chess in a cycle, and now the computer will only go once, you have to let it cycle until the end of the game, all we need A while loop.

void game()
{
	//创建一个二维数组
	char shangziqi[ROW][COL] = { 0 };
	//初始化棋盘
	InitBoard(shangziqi, ROW, COL);
	//打印棋盘
		DipiayBoard(shangziqi, ROW, COL);
//循环开始
		while (1) {
	//玩家下
		PlayGo(shangziqi, ROW, COL);
		DipiayBoard(shangziqi, ROW, COL);
		char ret = IsWin(shangziqi, ROW, COL);
		//ai下
		PlayGoai(shangziqi, ROW, COL);
		//下完打印棋盘
		DipiayBoard(shangziqi, ROW, COL);
		ret = IsWin(shangziqi, ROW, COL);
		if (ret == '*')
		{
			printf("玩家赢\n");
			break;
		}
		else if (ret == '#')
		{
			printf("电脑赢\n");
			break;
		}
		else if (ret == 'q')
		{
			printf("平局\n");
			break;
		}
	}//循环结束
}

The whole program has been completed so far, let me explain: while (1) is a lazy way of writing, the break here is the key to jump out of the loop.

Check out the results:

 awesome! ! !


I beg my family members to give me three links, I will continue to publish some articles suitable for beginners, so that everyone can avoid detours and avoid the pits I stepped on, please!

Guess you like

Origin blog.csdn.net/2301_77479336/article/details/129994263