【C/C++】Os exercícios de três golpes são simples e fáceis de entender


prefácio

A prática do xadrez de três luas é usar e testar o conhecimento aprendido antes. O xadrez de três luas aqui precisa encapsular a função em uma função de função, porque o código do xadrez de três luas é muito longo para ser colocado na função principal. Se tudo for colocado na função principal O código na função principal é difícil de reutilizar e a legibilidade não é boa.
Desde que a função seja encapsulada em uma função de função, a legibilidade do código também será melhorada, porque, desde que você adicione um comentário antes da função, poderá encontrar facilmente a função de função necessária e reutilizá-la.


1. Ideia geral

需要完成的效果图
insira a descrição da imagem aqui

接下来介绍一下需要完成的功能

这里打错字了为了节省时间暂时先不改,
Exemplo: pandas é uma ferramenta baseada em NumPy criada para resolver tarefas de análise de dados.

Vamos pensar primeiro no processo geral de produção.
O primeiro passo é imprimir o início e o fim do jogo. É concebível que este passo seja imprimir diretamente com printf.

Na segunda etapa, você precisa concluir o efeito de selecionar o início e aqui pode usar a chave para concluir o efeito da seleção.

A terceira etapa é imprimir o tabuleiro de xadrez. Observe primeiro o tabuleiro de xadrez. Existem três caracteres no tabuleiro de xadrez: espaços, delimitadores e barras. Você só precisa usar loops de várias camadas para alcançá-lo. Você deve tentar você mesmo.
A quarta etapa requer interação humano-computador.Aqui, a função de interação humano-computador pode ser dividida em duas funções funcionais.
A quinta etapa é implementada com a função scanf da biblioteca de entrada comumente usada.

这里在补充一点,人机交互肯定是需要重复执行,所以这里直接用死循环


Dois, o arquivo de cabeçalho

头文件比较重要还是单独拿出来讲解

O que é um arquivo de cabeçalho? Pelo que entendi, existem vários arquivos de origem em um projeto. Por exemplo, um arquivo e um arquivo B existem independentemente. Se um arquivo deseja chamar a função do arquivo B, ele deve estar no arquivo de cabeçalho. Basta declarar no arquivo a função do arquivo B. Afinal, o arquivo de cabeçalho é fazer com que os dois arquivos de origem independentes estejam diretamente relacionados.

三子棋头文件完整代码

#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 playerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);


//判断输赢
//玩家 - 'x'
//电脑赢 - '#'
//平局 - 'Q'
//继续 - 'C'
char IsWin(char board[ROW][COL], int row, int col);


3. Processo de implementação

说了这么还是得动手实操,来跟我一起深入浅出的学习吧!

1. O primeiro passo

文件目录

O arquivo de cabeçalho game.h é usado para declarar a
implementação da função game.c game function
testa o corpo principal do jogo e chama game.c a partir dele

以上后面会细讲

insira a descrição da imagem aqui


这里是函数主体布局完整代码,我会分几步讲解

O código é o seguinte (exemplo):

int main()
{
    
    
	int input = 0;
	do					
	{
    
    
		menu();			//开始界面打印
		printf("请选择>");
		scanf("%d", &input);	//输入坐标
		switch (input)			//开始与结束选项
		{
    
    
			case 1:
				printf("三子棋游戏\n");
				game();		//三子棋内部的实现
				break;
			case 0:
				printf("退出游戏\n");
				
			default:
				printf("选择错误,请重新输入\n");
				break;
		}
	} while (input);

		return 0;
}

打印开始界面其实很简单用printf就能实现。


1.0, instruções suplementares faça-enquanto

Aqui está uma explicação suplementar para aqueles que não estão familiarizados com o loop do-while: para esta pessoa, sou eu . do-while executa primeiro no julgamento, e o resultado do julgamento é falso e termina diretamente, então é muito adequado executar do-while aqui.

do
{
    
    

}
while();

1.1、menu()

开始界面打印
O código é o seguinte (exemplo):

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

**打印开始界面其实很简单用printf就能实现。**


2. A função principal da função do jogo Sanbang

1.0 Explicação interna da função do jogo

game()函数是三子棋核心函数

		switch (input)
		{
    
    
			case 1:
				printf("三子棋游戏\n");
				game();		//game()函数是三子棋核心函数
				break;
			case 0:
				printf("退出游戏\n");
				
			default:
				printf("选择错误,请重新输入\n");
				break;
		}

完整game功能函数

void game()
{
    
    
	//存储数据 - 二维数组
	char board[ROW][COL];
	//初始化棋盘 - 初始化
	InitBoard(board, ROW, COL);
	//打印一下棋盘 - 本质是打印数组的内容
	DisplayBoard(board, ROW, COL);
	char ret = 0;
	while (1)
	{
    
    
		//电脑下棋
		ComputerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);

		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;

		//玩家下棋
		playerMove(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");
}

1.1, InitBoard (inicializar a placa)

InitBoard完整代码

//初始化棋盘
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] = ' ';
		}
	}
}

补充#define知识

#define instruções de pré-processamento também são chamadas de definições de macro, que podem definir constantes e funções também podem ser definidas em profundidade. #define é usado para definir constantes em três xadrez

	#define ROW 3
	#define COL 3
	//二维数组用来存储棋盘数据
	char board[ROW][COL];		//这种定义的好处是可以让三子棋变成五子棋
	//初始化棋盘 - 初始化
	InitBoard(board, ROW, COL);			//1.把数组传入,2.初始化棋盘时用循环时肯定需要一个限定值,那就得把行跟列传过去
void InitBoard(char board[ROW][COL], int row, int col)	//函数传参,char board[ROW][COL]这里传了个二维数组,后面的传的就是行跟列
{
    
    
	
	int i = 0;
	for (i = 0; i< row; i++)	//初始化行
	{
    
    																
		int j = 0;
		for (j = 0; j < col; j++)	//初始化列
		{
    
    
			board[i][j] = ' ';		//把初始化的空格传给二维数组
		}
	}
}

1.2, DisplayBoard (imprime o código completo do tabuleiro de xadrez)

DisplayBoard完整代码

//打印棋盘
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]);	//数据的打印,%c两边还有两空格让打印的数据更加美观
			if (j < col - 1)		//
			 	printf("|");
		}
		printf("\n");
		if (i < row - 1)
		{
    
    
			int j = 0;
			for (j = 0; j < col; j++)
			{
    
    
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}

1.2.1. Impressão de dados e delimitadores

Para deixar o código mais flexível, você pode percorrer primeiro as linhas e colunas, e imprimir os dados um a um. Aqui, você só precisa alterar os valores das linhas e colunas para transformar o tabuleiro em um tabuleiro de xadrez. A ordem de impressão aqui é imprimir os dados primeiro. on print | then on print—,

for (i = 0; i < row; i++)		//遍历行
	{
    
    
		int j = 0;
		for (j = 0; j < col; j++)		//遍历列
		{
    
    
			printf(" %c ", board[i][j]);	//数据的打印,%c两边还有两空格让打印的数据更加美观
			if (j < col - 1)		//col - 1为了美观行会少打印最后一列
			 	printf("|");
		}
		printf("\n");		//第一行数据跟分隔符打印完换行
		if (i < row - 1)		//少打印最后一行---
		{
    
    
			int j = 0;
			for (j = 0; j < col; j++)		//换行后在打印---
			{
    
    
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}

1.3, playerMove (jogador jogando xadrez)

playerMove完整代码


//玩家下棋
void playerMove(char board[ROW][COL], int row, int col)
{
    
    
	//定义x,y坐标
	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] == ' ')		//数组下标是从0开始计算,正常人思维是从1开始计算,所以要-1
			{
    
    
				//x-1是之前x>1判断坐标是否被占用
				//玩家下棋
				board[x - 1][y - 1] = '*';
				break;		//下完一次退出
			}
			else
			{
    
    
				printf("坐标被占用,请重新输入\n");
			}
		}
		else
		{
    
    
			printf("坐标非法,请重新输入\n");
		}
	}
	
}

1.4, ComputerMove (xadrez de computador)

ComputerMove完整代码

//电脑随机下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
    
    
	int x = 0;
	int y = 0;

	printf("电脑下棋:>\n");
	//给电脑随机下棋坐标
	while (1)
	{
    
    
		//电脑自动下棋核心部分
		x = rand() % row;		//限制电脑x的坐标,假如row值为3,行随机范围为0-3,y同理
		y = rand() % col;

		if (board[x][y] == ' ')		
		{
    
    
			board[x][y] = '#';
			break;
		}
	}
	
}

1.5. Julgar ganhar ou perder com base nos pontos mais difíceis

Ganhar ou perder
jogador - 'x'
computador ganha - '#'
empate - 'Q'
continuar - 'C'

IsWin完整代码

//判断输赢
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 < row; 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[1][1] != ' ')
		return board[1][1];
	if(board[0][2] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
		return board[1][1];
	//平局

	if (IsFull(board, row, col)==1)
	{
    
    
		return 'Q';
	}
	//继续
	return 'C';
}

1.5.1, linha

加张图有利于理解
insira a descrição da imagem aqui

Use um loop para percorrer cada linha de xadrez e não pode ser igual a um espaço

//行
	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];		//返回第一列遍历每行的值
		}
	}
	

1.5.2, colunas

加张图有利于理解
insira a descrição da imagem aqui

跟行同理

//列
	for (i = 0; i < row; i++)
	{
    
    
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
    
    
			return board[0][i];

		}
	}
	

1.5.3, Diagonais

加张图有利于理解
insira a descrição da imagem aqui

//对角线
	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][2] && board[1][1] != ' ')
		return board[1][1];

1.5.4. Empate

棋盘下完返回Q

if (IsFull(board, row, col)==1)
	{
    
    
		return 'Q';
	}

IsFull完整代码

Se o tabuleiro estiver vazio, retorne 0, se o tabuleiro estiver cheio, retorne 1

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

1.5.5, continuar

Nenhum dos casos acima retorna diretamente C

//继续
	return 'C';

Em terceiro lugar, a chamada aninhada da função end

A ordem dos jogadores que jogam xadrez pode ser invertida, e a impressão final de vitória e derrota pode ser colocada fora do loop while, portanto, não há necessidade de imprimir repetidamente

char ret = 0;
	while (1)
	{
    
    
		//电脑下棋
		ComputerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);

		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')		//只要不等于C结束游戏
			break;

		//玩家下棋
		playerMove(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");

Resumir

O código de xadrez de três luas é relativamente longo e a dificuldade é moderada. Ele pode testar o conhecimento aprendido antes. Se houver algo que não seja bem compreendido, por favor, avise!

Há muitas palavras e erros de digitação, você pode corrigi-los na área de comentários

Espero ajudá-lo

Acho que você gosta

Origin blog.csdn.net/m0_66977204/article/details/130590384
Recomendado
Clasificación