Elementary C language - chess game

        After learning the relevant knowledge of arrays, then with the knowledge we have learned now, we can write some simple logic games, and then the next thing is: the game of chess. I believe that some people have heard of this game, or that there are more people who know tic-tac-toe. Then we're going to implement this game (excited, writing a game for the first time).

        Want the code to drop directly into the final implementation (haha).


content

1. Create a project environment

2. test.c file

3. Create the game function

4. Play chess

        4.1 Players play chess

        4.2 Computer Chess

5. Start playing

6. Judging winners and losers

7. Final Implementation

Bonus: Player VS Player

Conclusion: 


1. Create a project environment

        In the original code we wrote, we usually create a new project first, and add a test.c source file to the new project.

But now we have to write code in modules to implement this game.

Two source files are created here, and one header file implements their respective functions.


 2. test.c file

The code in text.c at the beginning is as follows:

#include "game.h"//引用自己创建的头文件,可以把stdio.h这个头文件包括在那里面

//测试三子棋的逻辑

void menu()
{
	printf("*****************************\n");
	printf("*********  1.play  **********\n");
	printf("*********  0.exit  **********\n");
	printf("*****************************\n");
}
void test()
{
	int input = 0;
	do
	{
		menu();//打印菜单,1.代表玩游戏,0.代表退出
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1://玩游戏
            game();//游戏的逻辑在game函数中去实现
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		}
	} while (input);//想要能够重复玩,所以这里是循环
}
int main()
{
	test();
	return 0;
}

3. Create the game function

Since you want to play Sanbang, you must have a chessboard, and of course the first step is to print the chessboard

void game()
{
	//存放下棋的数据
	char board[ROW][COL] = { 0 };
	//初始化棋盘为全空格
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
}

 game.h header file code

#include <stdio.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);

 Implementation of the chessboard in the game.c file

#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++)
	{
		//打印数据
		int j = 0;
		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 final look of the chessboard, at first all the arrays of the chessboard are assigned spaces, and then it is the chessboard we carefully designed with ' | ' and ' - '. In this way, you can print the multi-character chess board even if it is not a chess piece in the future, but this time we will write a chess piece.

 Now that the board is ready, let's start playing chess.


4. Play chess

        4.1 Players play chess

       I will write the definitions of all functions in the game function, the function declarations in the game.h header file, and the implementation of all functions in the game.c file.

void game()
{
	//存放下棋的数据
	//char board[ROW][COL] = { 0 };
	//初始化棋盘为全空格
	//InitBoard(board, ROW, COL);
	//打印棋盘
	//DisplayBoard(board, ROW, COL);

	//玩家下棋
	player_move(board, ROW, COL);
	DisplayBoard(board, ROW, COL);//下完之后打印棋盘
}

       What if you don't know that the subscripts of the array start at 0? So enter a number between 1 and 3 and subtract 1 to convert it into an array subscript.

        It is also necessary to judge whether the coordinate has been occupied, or a coordinate beyond the chessboard range has been entered.

void player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家下棋\n");
	while (1)//这里写成循环,因为我们如果输入错误需要重新输入,输入正确就break跳出
	{
		printf("请输入坐标:>");
		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");
		}
	}
}

        


        4.2 Computer Chess

       With the current ability, I can only make the computer play chess randomly. Too complicated code can't be written yet. Although the player and the computer play chess here, I will also write a piece of code for the player VS player later.

void game()
{
	//存放下棋的数据
	//char board[ROW][COL] = { 0 };
	//初始化棋盘为全空格
	//InitBoard(board, ROW, COL);
	//打印棋盘
	//DisplayBoard(board, ROW, COL);
	//玩家下棋
	//player_move(board, ROW, COL);
	//DisplayBoard(board, ROW, COL);

	//电脑下棋
	Computer_move(board, ROW, COL);//随机下棋
	DisplayBoard(board, ROW, COL);
}
void Computer_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("电脑下棋:>\n");
	while (1)
	{
		x = rand() % row;//0~2
		y = rand() % col;//0~2  所以不需要判断是否合法
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

       If you want to generate a random number here, you need to use the rand function. You can search for the use of this function yourself. It needs a timestamp to generate a random number. The time changes every second. If you use a single rand function, The random number generated each time is the same, so the srand function is used, and we put the timestamp in, so that the number generated each time will be different.

 Header files are also required to use library functions

 


5. Start playing

       Now that the code for the chess game has been written, it's time to start playing. There should be one step for the player and one step for the computer, so there should be a loop here.

void game()
{
	//存放下棋的数据
	//char board[ROW][COL] = { 0 };
	//初始化棋盘为全空格
	//InitBoard(board, ROW, COL);
	//打印棋盘
	//DisplayBoard(board, ROW, COL);
	
    while (1)
	{
		//玩家下棋
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//电脑下棋
		Computer_move(board, ROW, COL);//随机下棋
		DisplayBoard(board, ROW, COL);
	}
}

  In this way, the code can basically realize the battle between the player and the computer, and finally it is left to judge whether to win or lose.


6. Judging winners and losers

The game is over in these cases:

Player wins, computer wins, draw.

void game()
{
	//存放下棋的数据
	//char board[ROW][COL] = { 0 };
	//初始化棋盘为全空格
	//InitBoard(board, ROW, COL);
	//打印棋盘
	//DisplayBoard(board, ROW, COL);

	char ret = 0;
	while (1)
	{
		//玩家下棋
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;
		//电脑下棋
		Computer_move(board, ROW, COL);//随机下棋
		DisplayBoard(board, ROW, COL);
		//判断输赢		
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
		printf("玩家赢了\n");
	else if (ret == '#')
		printf("电脑赢了\n");
	else
		printf("平局\n");
	DisplayBoard(board, ROW, COL);//最后再打印一遍棋盘
}
//玩家赢了 - 返回'*'
//电脑赢了 - 返回'#'
//平局    - 返回'Q'
//继续    - 返回'C'
static int is_full(char board[ROW][COL], int row, int col)//static修饰,这个函数只能在这个源文件中使用
{
	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 is_win(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][1] != ' ')
		{
			return board[i][1];
		}
	}
	//判断列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
		{
			return board[1][i];
		}
	}
	//判断对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	//判断平局
	if (is_full(board, row, col) == 1)
	{
		return 'Q';
	}
	//继续
	return 'C';
}

7. Final Implementation

At this point, the game has been written, let's take a look at the final effect. 

All code attached:

game.h file

#pragma once

#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 player_move(char board[ROW][COL], int row, int col);

//电脑下棋
void Computer_move(char board[ROW][COL], int row, int col);

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

game.c file

#define _CRT_SECURE_NO_WARNINGS 1
#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++)
	{
		//打印数据
		int j = 0;
		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 player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家下棋:>\n");
	while (1)
	{
		printf("请输入坐标:>");
		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 Computer_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("电脑下棋:>\n");
	while (1)
	{
		x = rand() % row;//0~2
		y = rand() % col;//0~2  所以不需要判断是否合法
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

static int is_full(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 is_win(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][1] != ' ')
		{
			return board[i][1];
		}
	}
	//判断列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
		{
			return board[1][i];
		}
	}
	//判断对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	//判断平局
	if (is_full(board, row, col) == 1)
	{
		return 'Q';
	}
	//继续
	return 'C';
}

test.c file

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

//测试三子棋的逻辑

void menu()
{
	printf("*****************************\n");
	printf("*********  1.play  **********\n");
	printf("*********  0.exit  **********\n");
	printf("*****************************\n");
}
void game()
{
	char ret = 0;
	//存放下棋的数据
	char board[ROW][COL] = { 0 };
	//初始化棋盘为全空格
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	while (1)
	{
		//玩家下棋
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;
		//电脑下棋
		Computer_move(board, ROW, COL);//随机下棋
		DisplayBoard(board, ROW, COL);
		//判断输赢		
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
		printf("玩家赢了\n");
	else if (ret == '#')
		printf("电脑赢了\n");
	else
		printf("平局\n");
	DisplayBoard(board, ROW, COL);//最后再打印一遍棋盘
}
//玩家赢了 - 返回'*'
//电脑赢了 - 返回'#'
//平局    - 返回'Q'
//继续    - 返回'C'

void test()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();//打印菜单,1.代表玩游戏,0.代表退出
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1://玩游戏
			game();
			break;
		case 0://退出游戏
			printf("退出游戏\n");
			break;
		default://选择错误,重新选择
			printf("选择错误,重新选择\n");
			break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

Bonus: Player VS Player

The game.h file is the same as above

game.c file

#define _CRT_SECURE_NO_WARNINGS 1
#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++)
	{
		//打印数据
		int j = 0;
		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 player1_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家1下棋:>\n");
	while (1)
	{
		printf("请输入坐标:>");
		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] = '*';//玩家1下棋用*代表
				break;
			}
			else
			{
				printf("该坐标被占用,请重新输入\n");
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}
}

void player2_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家2下棋:>\n");
	while (1)
	{
		printf("请输入坐标:>");
		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] = '#';//玩家2下棋用#代表
				break;
			}
			else
			{
				printf("该坐标被占用,请重新输入\n");
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}
}

static int is_full(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 is_win(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][1] != ' ')
		{
			return board[i][1];
		}
	}
	//判断列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
		{
			return board[1][i];
		}
	}
	//判断对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	//判断平局
	if (is_full(board, row, col) == 1)
	{
		return 'Q';
	}
	//继续
	return 'C';
}

test.c file

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

//测试三子棋的逻辑

void menu()
{
	printf("*****************************\n");
	printf("*********  1.play  **********\n");
	printf("*********  0.exit  **********\n");
	printf("*****************************\n");
}
void game()
{
	char ret = 0;
	//存放下棋的数据
	char board[ROW][COL] = { 0 };
	//初始化棋盘为全空格
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	while (1)
	{
		//玩家1下棋
		player1_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;
		//玩家2下棋
		player2_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢		
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
		printf("玩家1赢了\n");
	else if (ret == '#')
		printf("玩家2赢了\n");
	else
		printf("平局\n");
	DisplayBoard(board, ROW, COL);//最后再打印一遍棋盘
}
//玩家1赢了 - 返回'*'
//玩家2赢了 - 返回'#'
//平局    - 返回'Q'
//继续    - 返回'C'

void test()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();//打印菜单,1.代表玩游戏,0.代表退出
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1://玩游戏
			game();
			break;
		case 0://退出游戏
			printf("退出游戏\n");
			break;
		default://选择错误,重新选择
			printf("选择错误,重新选择\n");
			break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

Conclusion:

It was the first time to write a game, it felt very fun, and it was also a test, but I have to persevere, I can still write (haha)! ! !

Guess you like

Origin blog.csdn.net/m0_64607843/article/details/122637247