Man-machine war? ——Take you to play backgammon (C language)

@TOC

1 Introduction

After learning about arrays, we can implement a simple game by ourselves—three chess!
insert image description here
In order to ensure the independence of the program: we created a source function game.c and test.c, a header file game.h
test.c - test game
game.c - the implementation of the game function
game.h - game function statement of

2. Rules of the game of backgammon

Game rules of backgammon: The computer and players take turns playing chess until one side wins or the board is full, the game ends.
Winning evaluation: If one of the players or the computer is the first to realize the three-piece connection (horizontal connection, vertical connection, diagonal connection), that side wins. If the board is full, it is a draw.

3. Thinking about the implementation of backgammon

First of all, after the game starts, let the player choose whether to start the game: Create a game menu (1. Play the game, 0. Exit the game) The
next step is the game implementation process: print the board —> the player takes a step —> the computer takes a step —> Win or lose.

After the game starts, we need to output the Jiugong grid on the screen, so we can initialize the chessboard first, and at the same time use a 3x3 array to store the data information of the chess pieces played by both sides

Playing chess:
player moves —> input chess piece subscript —> print the chess piece if the coordinates are blank ( you need to consider whether the coordinates are occupied, or the coordinates are illegal )
the computer moves —> set the random coordinates of the computer —> print the chess piece if it is a space

Judging winning or losing:
judging winning or losing —> one side on the board is the first to realize three-piece connection (horizontal, vertical, oblique) then that side wins —> the board is full and it is a draw

Tips:

  • In order to achieve the final display effect, each side takes a step to print the chessboard once

4. Code implementation process

4.1 Implementation of menu function and main function

First, after the game starts, let the player choose whether to start the game: Create the game menu menu() function

void menu()
{
    
    
	printf("******************************\n");
	printf("******      1.play       *****\n");
	printf("******      0.exit       *****\n");
	printf("******************************\n");
}
int main()
{
    
    
	int input = 0;
	//srand((unsigned int)time(NULL));
	do
	{
    
    
		menu();
		printf("请选择:>\n");
		scanf("%d", &input);

		switch (input)
		{
    
    
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		}

	} while (input);
	return 0;
}

Tips:

  • The purpose of using the do...while statement is to ensure that the statement is executed at least once .

5. Implementation and dismantling of the game() function

All the above are carried out in test.c, and then the game() function is called in the test.c file, and its function is realized in the game.c source file. The implementation of the game() function in the test.c file is as follows:

void game()
{
    
    
	//创建3x3二位数组,存储棋盘数据
	char board[ROW][COL] = {
    
     0 };
	//初始化棋盘为空格
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	char ret = 1;
	while (1)
	{
    
    
		//玩家下棋
		PlayerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;
		//电脑下棋
		ComputerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
		printf("玩家赢\n");
	else if (ret == '#')
		printf("电脑赢\n");
	else
		printf("平局\n");
}

Next, let's take a look at the specific implementation process of each part.

5.1 Create a 3x3 two-dimensional array

void game()
{
    
    
	char board[3][3];
}
  • In order to avoid the dimension of the chessboard being limited by the number of dimensions and reduce the engineering effort when modifying the dimension, we define two constant variables ROW (row) and COL (column) defined in the header file game.h to represent the rows and columns of the chessboard.
#define ROW 3
#deine COL 3

So creating a 3x3 2D array ends up as follows:

void game()
{
    
    
	char board[3][3];
}

5.2 Board initialization

Before each game starts, we want to get a clean board. So we can initialize the chessboard as a space, and initialize each element of the array as a space.

//初始化棋盘为空格
void InitBoard(char board[ROW][COL], int row, int col)
{
    
    
	int i = 0;
	for (i = 0; i < row; i++)
	{
    
    
		int j = 0;
		for (j = 0; j < col; j++)
		{
    
    
			board[i][j] = ' ';
		}
	}
}

5.3 Print the chessboard

insert image description here

It is obviously not enough to just initialize the chessboard with spaces!
If we want to print the nine-square grid like the above picture, we need to add dividing lines appropriately

//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col)
{
    
    
	int i = 0;
	for (i = 0; i < row; i++)
	{
    
    
		//1.打印数据
		int j = 0;
		for (j = 0; j < col; j++)
		{
    
    
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");

		//2.打印分割线
		if (i < row-1)
		{
    
    
			int j = 0;
			for (j = 0; j < col; j++)
			{
    
    
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}

	}
}

5.4 Players play chess

Some players are always unusual when playing chess (the coordinates of the game are beyond the board), so after the player enters the coordinates, the program should judge whether the game is legal and falls on the board. At the same time, the program should judge whether the place where the player plays chess is a space. If not, then you cannot place a son at this place.

//玩家下棋 -下*
void PlayerMove(char board[ROW][COL], int row, int col)
{
    
    
	int x = 0;
	int y = 0while (1)
	{
    
    	//输入坐标
		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("坐标被占用,不能落子,重新输入坐标\n");
			}
		}
		else//坐标非法
		{
    
    
			printf("坐标非法,重新输入\n");
		}
	}
}

Tips:

  • The array index starts from 0, but not every player is a program. So we should subtract 1 from the input horizontal/vertical coordinates to get its position in the coordinates. For example: the player enters 2 3, that is, the second row and the third column, but the array is board[1][3].

5.5 Computer chess

Computer chess is random chess, there is no intelligent means. So we first need to randomly generate two random numbers to represent the horizontal/vertical coordinates of the child. The C library function provides the rand() function for generating random numbers. However, the generated random numbers may exceed the range represented by the chessboard and need further processing.

So we can handle it like this:

int x=rand()%ROW; //随机生成0~COL的横坐标
int y=ranf()%COL; //随机生成0~COL的纵坐标
//电脑下棋 -下#
void ComputerMove(char board[ROW][COL], int row, int col)
{
    
    
	int x = 0;
	int y = 0;
	printf("电脑下棋\n");
	while (1)
	{
    
    
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
    
    
			board[x][y] = '#';
			break;
		}
	}
}

5.6 Judging Win or Lose

In the end, it's the winners and losers!

Here we design to determine the final result by judging the return value of the function IsWin().
// computer wins - returns '*'
// player wins - returns '#'
draw - returns "Q"
continues - returns "C

The code logic is as follows:

void game()
{
    
    
	//创建棋盘数据
	char board[ROW][COL] = {
    
     0 };
	//初始化棋盘为空格
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	char ret = 1;
	while (1)
	{
    
    
		//玩家下棋
		PlayerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;
		//电脑下棋
		ComputerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
		printf("玩家赢\n");
	else if (ret == '#')
		printf("电脑赢\n");
	else
		printf("平局\n");
}

The encapsulation code for judging the winning and losing functions is as follows:

char IsWin(char board[ROW][COL], int row, int col)
{
    
    
	//赢
	//行
	int i = 0;
	for (i = 0; i < row; i++)
	{
    
    
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
		{
    
    
			return board[i][0];
		}
	}
	//列
	for (i = 0; i < col; i++)
	{
    
    
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
    
    
			return board[0][i];
		}
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
		return board[0][0];
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
		return board[0][2];
	//平局
	if (IsFull(board, row, col) == 1)  //调用IsFull函数
		return 'Q';
	//继续
	return 'C';
}

The encapsulation code of the IsFull() judging draw function is as follows:

int IsFull(char board[ROW][COL], int row, int col)
{
    
    
	int i = 0;
	for (i = 0; i < row; i++)
	{
    
    
		int j = 0;
		for (j = 0; j < col; j++)
		{
    
    
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}
  • Here we design the return value of the judging function as '*', '#', 'Q', and 'C'. In fact, there is still a purpose. If the ret of the game function receives the return value of the judging function, if it is not 'C ' 'Yes, it proves that there is a win or loss, but I don't know whether the player wins or the computer wins. Here the player is '*' all of a sudden, and the computer is '#' all of a sudden, so in the end we only need to judge what the return value is to judge who wins up.

6. All the codes are as follows:

So far,
all the codes are as follows:
- game.h

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

#define ROW 3
#define COL 3

//初始化棋盘
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);

//判断输赢
//玩家赢—‘*’
//电脑赢—‘#’
//平局—‘Q’
//继续—‘C’
char IsWin(char board[ROW][COL], int row, int col);
  • test.c
#include "game.h"

void menu()
{
    
    
	printf("******************************\n");
	printf("******      1.play       *****\n");
	printf("******      0.exit       *****\n");
	printf("******************************\n");
}

void game()
{
    
    
	//创建棋盘数据
	char board[ROW][COL] = {
    
     0 };
	//初始化棋盘为空格
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	char ret = 1;
	while (1)
	{
    
    
		//玩家下棋
		PlayerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;
		//电脑下棋
		ComputerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
		printf("玩家赢\n");
	else if (ret == '#')
		printf("电脑赢\n");
	else
		printf("平局\n");
}

int main()
{
    
    
	int input = 0;
	srand((unsigned int)time(NULL));
	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;
}
  • game.c`
#include "game.h"

//初始化棋盘为空格
void InitBoard(char board[ROW][COL], int row, int col)
{
    
    
	int i = 0;
	for (i = 0; i < row; i++)
	{
    
    
		int j = 0;
		for (j = 0; j < col; j++)
		{
    
    
			board[i][j] = ' ';
		}
	}
}

//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col)
{
    
    
	int i = 0;
	for (i = 0; i < row; i++)
	{
    
    
		//1.打印数据
		int j = 0;
		for (j = 0; j < col; j++)
		{
    
    
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");

		//2.打印分割线
		if (i < row-1)
		{
    
    
			int j = 0;
			for (j = 0; j < col; j++)
			{
    
    
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}

	}
}

//玩家下棋 -下*
void PlayerMove(char board[ROW][COL], int row, int col)
{
    
    
	int x = 0;
	int y = 0;
	printf("玩家下棋>:\n");
	printf("请输入下棋的下标,中间使用空格\n");
	while (1)
	{
    
    
		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("坐标被占用,不能落子,重新输入坐标\n");
			}
		}
		else//坐标非法
		{
    
    
			printf("坐标非法,重新输入\n");
		}
	}
}

//电脑下棋 -下#
void ComputerMove(char board[ROW][COL], int row, int col)
{
    
    
	int x = 0;
	int y = 0;
	printf("电脑下棋\n");
	while (1)
	{
    
    
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
    
    
			board[x][y] = '#';
			break;
		}
	}
}

int IsFull(char board[ROW][COL], int row, int col)
{
    
    
	int i = 0;
	for (i = 0; i < row; i++)
	{
    
    
		int j = 0;
		for (j = 0; j < col; j++)
		{
    
    
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}

char IsWin(char board[ROW][COL], int row, int col)
{
    
    
	//赢
	//行
	int i = 0;
	for (i = 0; i < row; i++)
	{
    
    
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
		{
    
    
			return board[i][0];
		}
	}
	//列
	for (i = 0; i < col; i++)
	{
    
    
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
    
    
			return board[0][i];
		}
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
		return board[0][0];
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
		return board[0][2];
	//平局
	if (IsFull(board, row, col) == 1)
		return 'Q';
	//继续
	return 'C';
}

7. End

This concludes this article! But the game of backgammon can continue to be improved: for example, making the computer more intelligent, able to block chess, and so on. Readers who are interested can find relevant codes by themselves.
It is not easy to create, if it is helpful to you, remember to like and pay attention! thank you for your support! !

Guess you like

Origin blog.csdn.net/Zhenyu_Coder/article/details/130651523