当前位置: 首页 > article >正文

三子棋游戏

目录

1.创建项目

2.主函数编写

3.菜单函数编写

4.宏定义棋盘行和列

5.棋盘初始化

6.打印棋盘

7.玩家下棋

8.电脑下棋

9.平局判断

10.输赢判断

11.game函数


三子棋游戏,玩家与电脑下棋

1.创建项目

新建项目,并在源文件中添加test.c、game.c文件,在头文件中添加game.h文件。

2.主函数编写

int main()
{
	srand((unsigned int)time(NULL));//设置随机数的生成起点
	int input = 0;
	do
	{
		menu();//菜单打印
		printf("请选择\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
				printf("开始游戏\n");
				game();
				break;
		case 0:
				printf("退出游戏\n");
				break;
		default:
			printf("选择错误\n");
		}
	} while (input);
	return 0;
}

3.菜单函数编写

打印菜单栏

//菜单打印
void menu()
{
	printf("*******   三子棋   ******\n");
	printf("*****1. play 0. exit*****\n");
	printf("************************\n");

}

4.宏定义棋盘行和列

通过更改ROW、COL后面数字可以改变棋盘的行列。改变CON后面的数组可以更改为棋数限制,可以改成4子棋,五子棋。

#define ROW 3
#define COL 3
#define CON 3

5.棋盘初始化

初始化棋盘,使棋盘内容为”

//棋盘初始化
void board_Init(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++)
		{
			board[i][j] = ' ';
		}
	}
}

6.打印棋盘

第一种写法,这种写法将行和列写死了,后续无法通过宏定义控制行列。

//打印棋盘
//第一个版本
void board_Display(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//打印数据
		printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
		//打印分隔符
		if (i < row-1)
		printf("---|---|---\n");
	}
}

版本二:

用循环的方式写,这种方法可以使用宏定义棋盘数

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

7.玩家下棋

//玩家下棋
void Player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家下棋\n");
	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");
	}
}

8.电脑下棋

//电脑下棋
//找没有下棋的位置随机下棋
void Computer_move(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % row;//0-2
		y = rand() % col;//0-2
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}

}

9.平局判断

//平局判断
//满了返回1
//不满返回0
int IsFull(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;
}

10.输赢判断

方案一:这种判断方法不能用宏定义更改行列。将程序写死了。

//判断输赢
//
//玩家赢-'*'
//电脑赢-'#'
//平局-'Q'
//游戏继续-'c'
//
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][1] != ' ')
			return board[i][1];
	}
	//列
	int j = 0;
	for (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
		{
			return board[1][j];
		}
	}
	//对角线
	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 (IsFull(board,row,col))
	{
		return 'Q';
	}
	//游戏继续
	return 'C';
}

方案二:

这种方法可以使用宏定义通过更改count的值来更改棋数限制(可以改成四子棋,五子棋)。

//判断输赢Mark2
char IsWin2(char board[ROW][COL], int row, int col, char tmp)//判断输赢,返回字符
{
	int i = 0;
	int j = 0;
	int count = 0;
	for (i = 0; i < ROW; i++)//判断一是否有三个字符相同
	{
		int count = 0;
		for (j = 0; j < COL; j++)
		{
			if (board[i][j] != tmp)//有一个不同就break跳出本次循环
				break;
			else
				count++;//有一个相同count就+1
			if (count == CON)//当count等于3时就代表一行中有三个相同
				return tmp;//当一行中有三个相同的字符时就代表该字符所对应的赢了返回该字符
		}

	}
	for (j = 0; j < COL; j++)//同理判断一列中是否有三个字符相同
	{
		int count = 0;

		for (i = 0; i < ROW; i++)
		{
			if (board[i][j] != tmp)
				break;
			else
				count++;
			if (count == CON)
				return tmp;
		}

	}
	for (count = 0, i = 0; i < ROW; i++)//判断从左往右的直线三个字符是否相同
	{

		if (board[i][i] != tmp)
			break;
		else
			count++;
		if (count == CON)
			return tmp;
	}

	for (count = 0, j = COL - 1, i = 0; j >= 0, i <ROW; j--, i++)//判断从左往右的直线
	{

		if (board[i][j] != tmp)
			break;
		else
			count++;
		if (count == CON)
			return tmp;
	}
	//平局
	if (IsFull(board, row, col))
	{
		return 'Q';
	}
	//游戏继续
	return 'C';
}

11.game函数

game()
{
	char ret = 0;
	char board[ROW][COL] = { 0 };
	//棋盘初始化
	board_Init(board,ROW ,COL );
	board_Display2(board, ROW, COL);
	//下棋
	while (1)
	{
		//玩家下棋
		Player_move(board,ROW,COL);
		//判断输赢
		//ret = IsWin(board,ROW,COL);
		ret = IsWin2(board, ROW, COL, '*');

		if (ret != 'C')
		{
			break;
		}
		board_Display2(board, ROW, COL);
		//电脑下棋
		Computer_move(board, ROW, COL);
		//判断输赢
		//ret = IsWin(board, ROW, COL);
		ret = IsWin2(board, ROW, COL, '#');
		if (ret != 'C')
		{
			break;
		}
		board_Display2(board, ROW, COL);
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢\n");
	}
	else
	{
		printf("平局\n");
	}
	board_Display2(board, ROW, COL);
}

12.源程序代码

test.c文件代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include "game.h"

game()
{
	char ret = 0;
	char board[ROW][COL] = { 0 };
	//棋盘初始化
	board_Init(board,ROW ,COL );
	board_Display2(board, ROW, COL);
	//下棋
	while (1)
	{
		//玩家下棋
		Player_move(board,ROW,COL);
		//判断输赢
		//ret = IsWin(board,ROW,COL);
		ret = IsWin2(board, ROW, COL, '*');

		if (ret != 'C')
		{
			break;
		}
		board_Display2(board, ROW, COL);
		//电脑下棋
		Computer_move(board, ROW, COL);
		//判断输赢
		//ret = IsWin(board, ROW, COL);
		ret = IsWin2(board, ROW, COL, '#');
		if (ret != 'C')
		{
			break;
		}
		board_Display2(board, ROW, COL);
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢\n");
	}
	else
	{
		printf("平局\n");
	}
	board_Display2(board, ROW, COL);
}

//菜单打印
void menu()
{
	printf("*******   三子棋   ******\n");
	printf("*****1. play 0. exit*****\n");
	printf("************************\n");

}

int main()
{
	srand((unsigned int)time(NULL));//设置随机数的生成起点
	int input = 0;
	do
	{
		menu();//菜单打印
		printf("请选择\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
				printf("开始游戏\n");
				game();
				break;
		case 0:
				printf("退出游戏\n");
				break;
		default:
			printf("选择错误\n");
		}
	} while (input);
	return 0;
}

game.c文件代码

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"



//棋盘初始化
void board_Init(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++)
		{
			board[i][j] = ' ';
		}
	}
}



//打印棋盘
//第一个版本
void board_Display(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//打印数据
		printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
		//打印分隔符
		if (i < row-1)
		printf("---|---|---\n");
	}
}



//打印棋盘Mark2
void board_Display2(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//打印数据
		//printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
		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)
		{
			//printf("---|---|---\n");
			int j = 0;
			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("玩家请选择下棋位置\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 Computer_move(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % row;//0-2
		y = rand() % col;//0-2
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}

}





//平局判断
//满了返回1
//不满返回0
int IsFull(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;
}




//判断输赢
//
//玩家赢-'*'
//电脑赢-'#'
//平局-'Q'
//游戏继续-'c'
//
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][1] != ' ')
			return board[i][1];
	}
	//列
	int j = 0;
	for (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
		{
			return board[1][j];
		}
	}
	//对角线
	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 (IsFull(board,row,col))
	{
		return 'Q';
	}
	//游戏继续
	return 'C';
}


//判断输赢Mark2
char IsWin2(char board[ROW][COL], int row, int col, char tmp)//判断输赢,返回字符
{
	int i = 0;
	int j = 0;
	int count = 0;
	for (i = 0; i < ROW; i++)//判断一是否有三个字符相同
	{
		int count = 0;
		for (j = 0; j < COL; j++)
		{
			if (board[i][j] != tmp)//有一个不同就break跳出本次循环
				break;
			else
				count++;//有一个相同count就+1
			if (count == CON)//当count等于3时就代表一行中有三个相同
				return tmp;//当一行中有三个相同的字符时就代表该字符所对应的赢了返回该字符
		}

	}
	for (j = 0; j < COL; j++)//同理判断一列中是否有三个字符相同
	{
		int count = 0;

		for (i = 0; i < ROW; i++)
		{
			if (board[i][j] != tmp)
				break;
			else
				count++;
			if (count == CON)
				return tmp;
		}

	}
	for (count = 0, i = 0; i < ROW; i++)//判断从左往右的直线三个字符是否相同
	{

		if (board[i][i] != tmp)
			break;
		else
			count++;
		if (count == CON)
			return tmp;
	}

	for (count = 0, j = COL - 1, i = 0; j >= 0, i <ROW; j--, i++)//判断从左往右的直线
	{

		if (board[i][j] != tmp)
			break;
		else
			count++;
		if (count == CON)
			return tmp;
	}
	//平局
	if (IsFull(board, row, col))
	{
		return 'Q';
	}
	//游戏继续
	return 'C';
}

game.h文件代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3
#define COL 3
#define CON 3
//棋盘初始化
void board_Init(char board[ROW][COL], int row, int col);
//打印棋盘
void board_Display(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 IsWin(char board[ROW][COL], int row, int col);
char IsWin2(char board[ROW][COL], int row, int col, char tmp);

13.结语:

以上就是用C语言做的简单的三子棋游戏,这个不止是三子棋游戏,可以通过更改宏定义让他变成五子棋等等,缺点是对手电脑是用随机数生成的,它所下的位置是随机的,所以我们想输都难,后续可以尝试写一个让电脑聪明点的函数,体验会更好一些。


http://www.kler.cn/a/467716.html

相关文章:

  • Redis--高可用(主从复制、哨兵模式、分片集群)
  • 如何利用人工智能算法优化知识分类和标签?
  • Docker 容器内部如何访问本机的服务
  • 小程序租赁系统开发的优势与应用前景分析
  • Vue2中使用Echarts
  • MySQL UNION 的用法与实例
  • centos双网卡不能上网
  • Nginx:安装部署和升级(平滑升级)
  • js-19-手写题
  • 软件逆向之标志位
  • 【测试工具】 Postman 基本使用
  • 【Linux】调度优先级(谦让度)
  • spring、spring boot、Springmvc 的区别和关系
  • k8s集群部署 - Dashboard v2.7
  • MySQL 8 主从同步配置(Master-Slave Replication)
  • ESP32移植Openharmony外设篇(7)土壤湿度传感器YL-69
  • Python进阶-08-继承性
  • 编译 C++ 程序:分离与保留调试信息以支持 GDB 对 Core 文件的调试
  • 如何自行解锁 ATamp;T 手机
  • UE5 slate创建SDockTab标签页的过程理解
  • Megatron - LM 怎么进行模型切分的,怎么匹配服务器的
  • 量子力学复习
  • STM32学习之MPU6050芯片 及 软件I2C读写MPU6050实验
  • linux命令行连接Postgresql常用命令
  • 【高阶数据结构】哈希表封装unordered_map、unordered_set
  • 【论文阅读】Anchor-based fast spectral ensemble clustering