C language to achieve three chess game

Keywords: C

preface

This is my first blog as a C language beginner and a freshman. After a short period of study before that, I successfully wrote a simple Sanzi game. If there is anything to be corrected, I hope you can criticize and correct.

thinking

I plan to implement the code of the whole game in two source files. The first source file test.c is used to implement the general process of the whole game, and the second source file game.c is used to implement the logic of the specific steps of the game. Therefore, a header file game.h is needed to simplify the declaration of the functions in game.c in test.c.

When opening the game, you need to print a menu for players to choose whether to start or end the game. When players finish a game, you also need to ask them whether they need to start again. Therefore, it can be realized through circulation.

During the game, the process is to print an empty chessboard -- > player playing chess -- > Print chessboard -- > computer playing chess -- > Print chessboard -- > player playing chess -- > Print chessboard -- > computer playing chess -- > Print chessboard... The game ends when one party forms three chessboards or the chessboard is completely occupied.

Game implementation

    Header file game.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//Defines the size of the chessboard, which can be modified
#define ROW 5
#define COL 5

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);

The header file game.h is used to declare functions, contain system header files, and define constants.

Declaring functions: simplify the process of declaring functions in game.c in tect.c

Include system header files: only game.h needs to be included in the two source files

Define constant: just change the constant in game.h to change the size of the chessboard

    Source file test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

void menu()
{
	printf("******************************\n");
	printf("**********1.Start the game**********\n");
	printf("**********0.End the game**********\n");
	printf("******************************\n");
}

void game()
{
	char board[ROW][COL];
	char ret;
	InitBoard(board, ROW, COL);//Initialize 2D array
	DisplayBoard(board, ROW, COL);//Print chessboard
	while (1)
	{
		PlayerMove(board, ROW, COL);//Players play chess
		DisplayBoard(board, ROW, COL);
		ret = IsWin(board, ROW, COL);//Determine whether to end
		if (ret != 'C')
			break;
		ComputerMove(board, ROW, COL);//Computer chess
		DisplayBoard(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
		printf("Player wins\n");
	else if (ret == '#')
		printf("Computer wins\n");
	else
		printf("it ends in a draw\n");
}

int main()
{
	int input = 0;
	srand((unsigned)time(NULL));
	do//Initial menu
	{
		menu();//Print menu
		printf("Please enter:>");
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				game();
				break;
			case 0:
				printf("End the game");
				break;
			default:
				printf("Input error, please re-enter");
				break;
		}
	}while (input);
	return 0;
}

        1.main function

int main()
{
	int input = 0;
	srand((unsigned)time(NULL));
	do//Initial menu
	{
		menu();//Print menu
		printf("Please enter:>");
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				game();
				break;
			case 0:
				printf("End the game");
				break;
			default:
				printf("Input error, please re-enter");
				break;
		}
	}while (input);
	return 0;
}

In the main function, we need to implement the general process of the game.

Because you need to allow multiple games and play at least once (start or end the game), use the do while loop.

Here, the variable input is used to accept the selection results of the player's menu page. You can directly use input as the judgment condition of the do while loop (0 is false, non-0 is true).

The switch statement is used to be more intuitive. You can also use the if statement.

        2.menu function

void menu()
{
	printf("******************************\n");
	printf("**********1.Start the game**********\n");
	printf("**********0.End the game**********\n");
	printf("******************************\n");
}

This function is responsible for printing the menu. The purpose is to make the idea in the main function more intuitive.

  menu function effect

          3.game function

void game()
{
	char board[ROW][COL];
	char ret;
	InitBoard(board, ROW, COL);//Initialize 2D array
	DisplayBoard(board, ROW, COL);//Print chessboard
	while (1)
	{
		PlayerMove(board, ROW, COL);//Players play chess
		DisplayBoard(board, ROW, COL);
		ret = IsWin(board, ROW, COL);//Determine whether to end
		if (ret != 'C')
			break;
		ComputerMove(board, ROW, COL);//Computer chess
		DisplayBoard(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
		printf("Player wins\n");
	else if (ret == '#')
		printf("Computer wins\n");
	else
		printf("it ends in a draw\n");
}

This function is also to make the idea in the main function more intuitive and display the whole Sanzi game logic separately.

Because the chessboard is two-dimensional, you need to create a two-dimensional array and initialize it completely. After initialization, the chessboard needs to be printed and displayed to the player. After that, the player and the computer need to play chess repeatedly through the cycle time and judge whether the game is over.

    Source file game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

void InitBoard(char board[ROW][COL], int row, int col)
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j != col - 1)
				printf("|");
		}
		printf("\n");
		if (i != row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j != col - 1)
					printf("|");
			}
		}
		printf("\n");
	}
}

void PlayerMove(char board[ROW][COL], int row, int col)
{
	while (1)
	{
		int x,y;
		printf("Players go, please enter the coordinates:>");
		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("The input coordinates are occupied, please re-enter\n");
		}
		else
			printf("The coordinates entered are illegal. Please re-enter\n");
	}
}

void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("Computer walk\n");
	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

char IsWin(char board[ROW][COL], int row, int col)
{
	int x, y;
	for (x = 0; x < row - 2; x++)
	{
		for (y = 0; y < col; y++)//Judge a column
		{
			if (board[x][y] == board[x + 1][y] && board[x + 1][y] == board[x + 2][y] && board[x][y] != ' ')
				return board[x][y];
		}
		for (y = 0;y < col - 2; y++)//Judge right skew
		{
			if (board[x][y] == board[x + 1][y + 1] && board[x + 1][y + 1] == board[x + 2][y + 2] && board[x][y] != ' ')
				return board[x][y];
		}
		for (y = 3; y < col; y++)//Judge left skew
		{
			if (board[x][y] == board[x + 1][y - 1] && board[x + 1][y - 1] == board[x + 2][y - 2] && board[x][y] != ' ')
				return board[x][y];
		}
	}
	for (x = 0; x < row; x++)
	{
		for (y = 0; y < col - 2; y++)//Judge a column
		{
			if (board[x][y] == board[x][y + 1] && board[x][y + 1] == board[x][y + 2] && board[x][y] != ' ')
				return board[x][y];
		}
	}
	for (x = 0; x < row; x++)
	{
		for (y = 0; y < col; y++)//Judge full lattice
		{
			if (board[x][y] == ' ')
				return 'C';
		}
	}
	return 'P';
}

        1.InitBoard function

void InitBoard(char board[ROW][COL], int row, int col)
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

  The InitBoard function initializes all two-dimensional arrays to '' through two for loops.

        2.DisplayBoard function

void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j != col - 1)
				printf("|");
		}
		printf("\n");
		if (i != row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j != col - 1)
					printf("|");
			}
		}
		printf("\n");
	}

  The DisplayBoard function also prints the two-dimensional array and the dividing line of the chessboard through a double for loop.

DisplayBoard function effect

        3.PlayerMove function

void PlayerMove(char board[ROW][COL], int row, int col)
{
	while (1)
	{
		int x,y;
		printf("Players go, please enter the coordinates:>");
		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("The input coordinates are occupied, please re-enter\n");
		}
		else
			printf("The coordinates entered are illegal. Please re-enter\n");
	}
}

When a player plays chess, the player needs to successfully complete the chess step before he can execute the next step. Therefore, a while (1) dead loop is required to enable him to play chess again when the player's input coordinates are illegal or occupied.

In the PlayerMove function, it should be noted that the rows and columns of the two-dimensional array start from 0, so you need to subtract 1 from each of the coordinates entered by the player.

  PlayerMove function effect

        4.ComputerMove function

void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("Computer walk\n");
	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

In order to prevent the illegal position of random chess playing on the computer, rand()% row and   Rand()% col defines that random numbers can only take 0 to (row-1) or (col-1).

At the same time, in order to prevent the computer from playing chess again after the random chess position has been occupied, it also needs a while (1) loop and if statement to judge and break.

  ComputerMove function effect

          5.IsWin function

char IsWin(char board[ROW][COL], int row, int col)
{
	int x, y;
	for (x = 0; x < row - 2; x++)
	{
		for (y = 0; y < col; y++)//Judge a column
		{
			if (board[x][y] == board[x + 1][y] && board[x + 1][y] == board[x + 2][y] && board[x][y] != ' ')
				return board[x][y];
		}
		for (y = 0;y < col - 2; y++)//Judge right skew
		{
			if (board[x][y] == board[x + 1][y + 1] && board[x + 1][y + 1] == board[x + 2][y + 2] && board[x][y] != ' ')
				return board[x][y];
		}
		for (y = 3; y < col; y++)//Judge left skew
		{
			if (board[x][y] == board[x + 1][y - 1] && board[x + 1][y - 1] == board[x + 2][y - 2] && board[x][y] != ' ')
				return board[x][y];
		}
	}
	for (x = 0; x < row; x++)
	{
		for (y = 0; y < col - 2; y++)//Judge a column
		{
			if (board[x][y] == board[x][y + 1] && board[x][y + 1] == board[x][y + 2] && board[x][y] != ' ')
				return board[x][y];
		}
	}
	for (x = 0; x < row; x++)
	{
		for (y = 0; y < col; y++)//Judge full lattice
		{
			if (board[x][y] == ' ')
				return 'C';
		}
	}
	return 'P';
}

Because each quantity of a two-dimensional array is involved, a double for loop is required for each judgment.

It should be noted that whether you judge a row, a column, left skew or right skew, you need to limit the range of x and y to prevent exceeding the range of two-dimensional array.

In addition, it is also necessary to ensure that the judgment on whether the full grid is a draw is placed at the end. Even if the judgment on the full grid is consistent with the judgment on the for function of the outer layer of a column, it cannot be put together. Otherwise, 'C' will be returned before the judgment is completed in the first four cases, resulting in the continuation of the game even if the player or computer wins.

Finally, the return value is used to judge whether the computer wins, the player wins, draws or continues.

epilogue

At present, there is still room for optimization of this function, especially the design of computer chess algorithm, but at present, I don't have enough ability to design, and I may fill the pit in the future.

It was wonderful to write a blog for the first time. I had thought about the general idea, but I was still a little confused after I started. After repeated polishing, I also have a deeper understanding of the code I wrote. Maybe the code I forgot a few days later is printed in my mind, which makes me more convinced that blogging is not a waste of time, but the consolidation of knowledge. At the same time, I can gain everyone's correction. Why not?

After that, I will also use my spare time to write my own code and learning experience into a blog to share. It is expected that the next article will be the mine sweeping game just written in recent days.

Posted by catnip_uk on Sun, 19 Sep 2021 08:00:29 -0700