C语言 ——— 在控制台实现三子棋游戏(适用于五子棋、十子琪…………)

目录

实现三子棋游戏的简介

三子棋游戏代码的测试文件、实现文件、头文件

实现三子棋游戏

[打印菜单,让玩家选择是否玩游戏 --- game.c](#打印菜单,让玩家选择是否玩游戏 --- game.c)

[玩家对局完后多次选择是否再次进行游戏 --- test.c](#玩家对局完后多次选择是否再次进行游戏 --- test.c)

三子棋棋子的存储

[将二维数组board的行和列定义为常变量 --- game.h](#将二维数组board的行和列定义为常变量 --- game.h)

[初始化二维数组board --- game.h](#初始化二维数组board --- game.h)

[打印棋盘 --- game.c](#打印棋盘 --- game.c)

[玩家下棋 --- game.c](#玩家下棋 --- game.c)

[电脑下棋 --- game.c](#电脑下棋 --- game.c)

[判断棋盘是否填满 --- game.c](#判断棋盘是否填满 --- game.c)

[判断输赢 --- game.c](#判断输赢 --- game.c)

代码总览

test.c

game.h

game.c

小结


实现三子棋游戏的简介

1. 在控制台上生成三子棋棋盘

2. 和电脑对局,玩家走一步,电脑走一步

3. 判断输赢后能让玩家选择是否再次进行游戏


三子棋游戏代码的测试文件、实现文件、头文件

实现三子棋游戏时创建:test.c文件game.c文件Tic_Tac_Toe.h文件

game.h文件 用来声明函数和包含函数所需的头文件

game.c文件 用来定义实现函数

test.c文件 用来测试 game.c文件,并完成三子棋游戏逻辑

且 test.c文件game.c文件 只需要包含game.h文件即可


实现三子棋游戏

打印菜单,让玩家选择是否玩游戏 --- game.c

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

玩家对局完后多次选择是否再次进行游戏 --- test.c

int main()
{
	int input = 0;
	
	do
	{
		menu();

		printf("请输入:");
		scanf("%d", &input);

		if (input == 1)
		{
			game();
		}
		else if(input == 0)
		{
			printf("退出游戏\n");
		}
		else
		{
			printf("输入错误,请重新输入\n");
		}
		
	} while (input);

	return 0;
}

三子棋棋子的存储

创建一个三行三列的二维数组board[3][3],用来存储棋子,但如果需要更换为五子棋的时候,所有使用了3的地方都需要更改,使用可以使用 #define 将 3 重命名为常变量

将二维数组board的行和列定义为常变量 --- game.h

#define ROW 3
#define COL 3

初始化二维数组board --- game.h

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

打印棋盘 --- game.c

/*
  1   2   3
    |   |    1   
 ---|---|---
    |   |    2
 ---|---|---
    |   |    3
*/
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	// 打印横坐标
	for (int i = 1; i <= row; i++)
	{
		printf(" %d ", i);
		printf(" ");
	}
	printf("\n");

	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			// 打印每一行
			printf(" %c ", board[i][j]);

			if (j < row - 1)
			{
				printf("|");
			}
		}

		// 打印纵坐标
		printf(" %d\n", i + 1);

		// 打印分割线
		if (i < col - 1)
		{
			for (int k = 0; k < row; k++)
			{
				printf("---");

				if (k < row - 1)
				{
					printf("|");
				}
			}
			printf("\n");
		}

	}
}

玩家下棋 --- game.c

void PlayerMove(char board[ROW][COL], int row, int col)
{
	// 创建横纵坐标
	int x = 0;
	int y = 0;

	while (1)
	{
		printf("\n请输入要落子的横纵坐标(用空格隔开):");
		scanf("%d %d", &x, &y);

		if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
		{
			if (board[x - 1][y - 1] != ' ')
			{
				printf("坐标已被占用,请重新输入\n");
			}
			else
			{
				board[x - 1][y - 1] = '*';
				break;
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}

}

电脑下棋 --- game.c

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

判断棋盘是否填满 --- game.c

此函数是用来判断是否为平局

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

	return 1;
}

判断输赢 --- game.c

// 玩家赢返回 '*'
// 电脑赢返回 '#'
// 平局赢返回 'P'
// 继续返回 'J'
char IsWin(char board[ROW][COL], int row, int col)
{
	// 判断行赢
	for (int i = 0; i < row; i++)
	{
		int j = 0;
		int flag = 1;
		
		while (j < col - 1)
		{
			if ((board[i][j] == board[i][j + 1]) && board[i][j] != ' ')
			{
				j++;
			}
			else
			{
				flag = 0;
				break;
			}
		}

		if (flag)
			return board[i][j];
	}

	// 判断列赢
	for (int j = 0; j < col; j++)
	{
		int i = 0;
		int flag = 1;

		while (i < row - 1)
		{
			if ((board[i][j] == board[i + 1][j]) && board[i][j] != ' ')
			{
				i++;
			}
			else
			{
				flag = 0;
				break;
			}
		}

		if (flag)
			return board[i][j];
	}

	// 判断从左上到右下赢
	int x = 0;
	int y = 0;
	int flag = 1;
	while (x < row - 1 && y < col - 1)
	{
		if ((board[x][y] == board[x + 1][y + 1]) && board[x][y] != ' ')
		{
			x++;
			y++;
		}
		else
		{
			flag = 0;
			break;
		}
	}
	if (flag)
		return board[x][y];

	// 判断从右上到左下赢
	x = 0;
	y = col - 1;
	flag = 1;
	while (x < row - 1 && y > 0)
	{
		if ((board[x][y] == board[x + 1][y - 1]) && board[x][y] != ' ')
		{
			x++;
			y--;
		}
		else
		{
			flag = 0;
			break;
		}
	}
	if (flag)
		return board[x][y];

	// 判断平局
	if (IsFull(board, ROW, COL))
		return 'P';

	// 以上判断都没返回时,说明游戏还需继续
	return 'J';
}

代码总览

test.c

#include"Tic_Tac_Toe.h"

void game()
{
	char board[ROW][COL];

	// 初始化棋盘为空格
	InitBoard(board, ROW, COL);

	// 打印棋盘
	DisplayBoard(board, ROW, COL);

	// 下棋
	char ret = 0;
	while (1)
	{
		// 玩家下棋
		PlayerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		
		// 判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'J')
			break;

		// 电脑下棋
		ComputerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);

		// 判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'J')
			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);

		if (input == 1)
		{
			game();
		}
		else if(input == 0)
		{
			printf("退出游戏\n");
		}
		else
		{
			printf("输入错误,请重新输入\n");
		}
		
	} while (input);

	return 0;
}

game.h

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

#define ROW 3
#define COL 3

// 打印菜单
void menu();

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

game.c

#include"Tic_Tac_Toe.h"

// 打印菜单
void menu()
{
	printf("*******************************************\n");
	printf("*****     1.play           0.next     *****\n");
	printf("*******************************************\n");
}

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

// 打印棋盘
/*
  1   2   3
    |   |    1   
 ---|---|---
    |   |    2
 ---|---|---
    |   |    3
*/
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	// 打印横坐标
	for (int i = 1; i <= row; i++)
	{
		printf(" %d ", i);
		printf(" ");
	}
	printf("\n");

	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			// 打印每一行
			printf(" %c ", board[i][j]);

			if (j < row - 1)
			{
				printf("|");
			}
		}

		// 打印纵坐标
		printf(" %d\n", i + 1);

		// 打印分割线
		if (i < col - 1)
		{
			for (int k = 0; k < row; k++)
			{
				printf("---");

				if (k < row - 1)
				{
					printf("|");
				}
			}
			printf("\n");
		}

	}
}

// 玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
	// 创建横纵坐标
	int x = 0;
	int y = 0;

	while (1)
	{
		printf("\n请输入要落子的横纵坐标(用空格隔开):");
		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;
		}
	}
}

// 判断棋盘是否填满
// 填满返回1
// 未填满返回0
int IsFull(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}

	return 1;
}

// 判断输赢
// 玩家赢返回 '*'
// 电脑赢返回 '#'
// 平局赢返回 'P'
// 继续返回 'J'
char IsWin(char board[ROW][COL], int row, int col)
{
	// 判断行赢
	for (int i = 0; i < row; i++)
	{
		int j = 0;
		int flag = 1;
		
		while (j < col - 1)
		{
			if ((board[i][j] == board[i][j + 1]) && board[i][j] != ' ')
			{
				j++;
			}
			else
			{
				flag = 0;
				break;
			}
		}

		if (flag)
			return board[i][j];
	}

	// 判断列赢
	for (int j = 0; j < col; j++)
	{
		int i = 0;
		int flag = 1;

		while (i < row - 1)
		{
			if ((board[i][j] == board[i + 1][j]) && board[i][j] != ' ')
			{
				i++;
			}
			else
			{
				flag = 0;
				break;
			}
		}

		if (flag)
			return board[i][j];
	}

	// 判断从左上到右下赢
	int x = 0;
	int y = 0;
	int flag = 1;
	while (x < row - 1 && y < col - 1)
	{
		if ((board[x][y] == board[x + 1][y + 1]) && board[x][y] != ' ')
		{
			x++;
			y++;
		}
		else
		{
			flag = 0;
			break;
		}
	}
	if (flag)
		return board[x][y];

	// 判断从右上到左下赢
	x = 0;
	y = col - 1;
	flag = 1;
	while (x < row - 1 && y > 0)
	{
		if ((board[x][y] == board[x + 1][y - 1]) && board[x][y] != ' ')
		{
			x++;
			y--;
		}
		else
		{
			flag = 0;
			break;
		}
	}
	if (flag)
		return board[x][y];

	// 判断平局
	if (IsFull(board, ROW, COL))
		return 'P';

	// 以上判断都没返回时,说明游戏还需继续
	return 'J';
}

小结

未将代码写死,以上代码适用于三子棋、五子棋、十子琪............

只需更改 #define ROW 3 以及 #define COL 3 即可

相关推荐
a0023450015 分钟前
判断矩阵是否为上三角矩阵
c语言
OTWOL1 小时前
两道数组有关的OJ练习题
c语言·开发语言·数据结构·c++·算法
一只自律的鸡2 小时前
C语言项目 天天酷跑(上篇)
c语言·开发语言
悲伤小伞3 小时前
C++_数据结构_详解二叉搜索树
c语言·数据结构·c++·笔记·算法
佳心饼干-6 小时前
C语言-09内存管理
c语言·算法
物联网牛七七6 小时前
4、数据结构与算法解析(C语言版)--栈
c语言·栈操作
F-2H8 小时前
C语言:指针4(常量指针和指针常量及动态内存分配)
java·linux·c语言·开发语言·前端·c++
余额不足1213812 小时前
C语言基础十六:枚举、c语言中文件的读写操作
linux·c语言·算法
罗伯特祥14 小时前
C调用gnuplot绘图的方法
c语言·plot
嵌入式科普15 小时前
嵌入式科普(24)从SPI和CAN通信重新理解“全双工”
c语言·stm32·can·spi·全双工·ra6m5