三子棋(C语言)

前言

本次项目仅个人练习即见解,并没有过多优化,作为一个编程初学者,欢迎各位来一起学习交流,批评指正。


首先写代码之前要有一个很好的思路,画图的方法也是可以弥补思维缺陷的。

先来描述一下具体的思路是如何的,再逐步去完成

目录

前言

第一部分打印主菜单包括选择游戏:

第二部分初始化棋盘和打印棋盘内容

第三部分实现玩家下棋与电脑下棋

第四部分判断游戏是否结束

完整代码如下:

game.h

game.c

test.c


第一部分打印主菜单包括选择游戏:

所有头文件都写入到'game.h'里,'test.c'再去包含'game.h'就会方便很多

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

//菜单内容
void meun()
{
	printf("**************************\n");
	printf("******* 三子棋游戏 *******\n");
	printf("****** 1.play 2.exit *****\n");
	printf("**************************\n");
}

//主函数
int main()
{
	//打印菜单
	meun();
	int input = 0;
	do
	{
		printf("请选择1/0是否进入游戏\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("三子棋游戏开始\n");
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}

	} while (input);
	
	return 0;
}

第二部分初始化棋盘和打印棋盘内容

//实现游戏内容
void game()
{
	//初始化数组
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印棋盘内容
	DipiayBoard(board, ROW, COL);
}

函数声明在game.h头文件中创建

#include <stdio.h>
#define ROW 3
#define COL 3
#include <time.h>

//初始化棋盘声明
void InitBoard(char board[ROW][COL], int row, int col);

//打印棋盘声明
void DipiayBoard(char board[ROW][COL], int row, int col);

函数实现在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 DipiayBoard(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 < row; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}
			}
			printf("\n");
		}
	}
}

效果如下:

第三部分实现玩家下棋与电脑下棋

玩家先下棋,然后电脑再下棋并打印出各自下棋后的棋盘

   while (1)
{
	//1.玩家下并打印出棋盘
	player_down(board, ROW, COL);
	DipiayBoard(board, ROW, COL);

	//2.电脑下并打印出棋盘
	PlayerMove(board, ROW, COL);
	DipiayBoard(board, ROW, COL);
}

头文件中继续声明函数

//玩家下棋声明
void player_down(char board[ROW][COL], int row, int col);

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

在game.c源文件中进行实现

下棋之前首先要判断坐标是否合法,不合法则重新输入,如果合法需要继续判断坐标是否被占用

//玩家下棋实现
void player_down(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋:>\n");
	int x, y;
	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 PlayerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋:>\n");
	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;
		//判断坐标是否被占用
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}

	}
}

电脑下棋需要生成随机坐标,rand是生成随机1-1024数字的库函数,这里将它% row或% col,是将它的随机值控制在1-3之间,同时为了保证它在每次启动程序的时候随机值都不一样,它会配合srand函数一起使用,如上述使用方法,因为是库函数要引用头文件,这里是#include<time.h>

第四部分判断游戏是否结束

假设游戏结束 情况1:玩家赢返回-'*'  电脑赢返回-'#'  平局返回 - 'Q'情况2:假设游戏继续返回 - 'C'

定义一个ret变量记录它的返回值,来判断游戏是那两种情况,最后并打印出棋盘

void game()
{
	//初始化数组
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印棋盘内容
	DipiayBoard(board, ROW, COL);

	//开始游戏
	char ret = 0;
	while (1)
	{
		//1.玩家下并打印出棋盘
		player_down(board, ROW, COL);
		DipiayBoard(board, ROW, COL);
		//判断玩家是否赢得游戏
		ret = Iiwin(board, ROW, COL);

		//2.电脑下并打印出棋盘
		PlayerMove(board, ROW, COL);
		DipiayBoard(board, ROW, COL);
		//判断电脑是否赢得游戏
		ret = Iiwin(board, ROW, COL);


		if (ret == '*')
		{
			printf("玩家获胜\n");
			break;
		}
		if (ret == '#')
		{
			printf("电脑获胜\n");
			break;
		}
		else if (ret == 'Q')
		{
			printf("平局\n");
			break;
		}
	}
	DipiayBoard(board, ROW, COL);
}
//判断游戏是否结束
//1.假设游戏结束
//玩家赢返回-'*'
//电脑赢返回-'#'
//平局返回 - 'Q'
//2.假设游戏继续
//游戏继续返回 - 'C'
//
char Iiwin(char board[ROW][COL], int row, int col);

在代码中需要判断三行三列,还有对角线交叉三个字符分别相等则返回该字符,InFin函数的返回值进行判断,如果是0返回'C',游戏继续,返回'Q'说明棋盘已经满了,平局结束游戏

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

}
//判断获胜方
char Iiwin(char board[ROW][COL], int row, int col)
{
	//判断三行三列
	int i = 0;
	int j = 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 (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
		{
			return board[0][j];
		}
	}
	//判断交叉线
	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][0] != ' ')
	{
		return board[0][2];
	}
	if (InFin(board,ROW,COL) == 1)
	{
		return 'Q';
	}
	return 'C';
}

完整代码如下:

game.h

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define ROW 3
#define COL 3
#include <time.h>

//初始化棋盘声明
void InitBoard(char board[ROW][COL], int row, int col);

//打印棋盘声明
void DipiayBoard(char board[ROW][COL], int row, int col);

//玩家下棋声明
void player_down(char board[ROW][COL], int row, int col);

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

//判断游戏是否结束
//1.假设游戏结束
//玩家赢返回-'*'
//电脑赢返回-'#'
//平局返回 - 'Q'
//2.假设游戏继续
//游戏继续返回 - 'C'
//
char Iiwin(char board[ROW][COL], int row, int col);


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 DipiayBoard(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 < row; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}
			}
			printf("\n");
		}
	}
}
//玩家下棋实现
void player_down(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋:>\n");
	int x, y;
	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 PlayerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋:>\n");
	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;
		//判断坐标是否被占用
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}

	}
}



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

}
//判断获胜方
char Iiwin(char board[ROW][COL], int row, int col)
{
	//判断三行三列
	int i = 0;
	int j = 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 (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
		{
			return board[0][j];
		}
	}
	//判断交叉线
	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][0] != ' ')
	{
		return board[0][2];
	}
	if (InFin(board,ROW,COL) == 1)
	{
		return 'Q';
	}
	return 'C';
}

test.c

#include "game.h"

//菜单内容
void meun()
{
	printf("**************************\n");
	printf("******* 三子棋游戏 *******\n");
	printf("****** 1.play 2.exit *****\n");
	printf("**************************\n");
}
//实现游戏内容
void game()
{
	//初始化数组
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印棋盘内容
	DipiayBoard(board, ROW, COL);

	//开始游戏
	char ret = 0;
	while (1)
	{
		//1.玩家下并打印出棋盘
		player_down(board, ROW, COL);
		DipiayBoard(board, ROW, COL);
		//判断玩家是否赢得游戏
		ret = Iiwin(board, ROW, COL);

		//2.电脑下并打印出棋盘
		PlayerMove(board, ROW, COL);
		DipiayBoard(board, ROW, COL);
		//判断电脑是否赢得游戏
		ret = Iiwin(board, ROW, COL);

		if (ret == '*')
		{
			printf("玩家获胜\n");
			break;
		}
		if (ret == '#')
		{
			printf("电脑获胜\n");
			break;
		}
		else if (ret == 'Q')
		{
			printf("平局\n");
			break;
		}
	}
	DipiayBoard(board, ROW, COL);
}
//主函数
int main()
{
	//打印菜单
	meun();
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		printf("请选择1/0是否进入游戏\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("三子棋游戏开始\n");
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值