数组应用实例1 —— 三子棋

本文介绍了如何使用C语言实现一个简单的三子棋游戏,涉及常量定义、头文件包含、主函数、菜单设计、游戏逻辑、棋盘初始化、下棋操作及判断输赢规则。
摘要由CSDN通过智能技术生成

数组应用实例1 —— 三子棋

本章目标

利用所学知识,编写一个简易的三子棋游戏。

本章内容

  1. 标识符常量的定义和头文件的包含

  2. 主函数 main()

  3. 测试游戏逻辑 test()

  4. 菜单界面 menu()

  5. 游戏实现 game()

  6. 初始化棋盘 InitBoard()

  7. 打印棋盘 DisplayBoard()

  8. 玩家下棋 PlayerMove()

  9. 电脑下棋 ComputerMove()

  10. 判断输赢 IsWin()

正文


一、标识符常量的定义和头文件的包含

库函数所需要的头文件的包含,标识符常量的定义。

//game.h

#include<stdio.h>//printf()、scanf()
#include<stdlib.h>//rand()、srand()、system()
#include<time.h>//time()
#include<windows.h>//Sleep()

#define ROW 3
#define COL 3


二、主函数 main()

主函数里调用测试游戏逻辑的函数,避免主函数的臃肿。

//test.c

int main()
{
	//数组应用实例-三子棋
    
	test();//测试游戏逻辑

	return 0;
}


三、测试游戏逻辑 test()

测试函数会调用菜单界面函数,提供进入游戏和退出游戏的选择。

//test.c

//测试游戏逻辑函数
void test()
{
	srand((unsigned int)time(NULL));//设置随机数种子

	int select = 0;
	do
	{
		menu();//菜单界面
		printf("请输入你的选择:>");
		scanf("%d", &select);

		switch (select)
		{
		case 1:
			game();//游戏逻辑
			break;
		case 0:
			printf("退出游戏!\n");
			break;
		default:
			printf("选择错误,请重新输入!\n");
			break;
		}
	} while (select);
}


四、菜单界面 menu()

提供游戏菜单界面的显示。

//test.c

//菜单界面函数
void menu()
{
	printf("**************************\n");
	printf("********  1.play  ********\n");
	printf("********  0.exit  ********\n");
	printf("**************************\n");
}


五、游戏实现 game()

包括创建棋盘数组、初始化棋盘、打印显示棋盘、回合制下棋(玩家下棋、电脑下棋)、判断输赢状态。

//test.c

//游戏逻辑函数
void game()
{
	char board[ROW][COL] = { 0 };//棋盘数组

	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印显示棋盘
	DisplayBoard(board, ROW, COL);

	//回合制下棋
	int ret = 0;
	while (1)
	{
		//玩家下棋
		PlayerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);

		//每落一子就判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;//如果返回值不是'C',就退出回合制下棋,判断输赢平局
		}

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

		//每落一子就判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;//如果返回值不是'C',就退出回合制下棋,判断输赢平局
		}
	}

	//判断棋盘输赢状态
	if ('*' == ret)
		printf("玩家赢了!\n");
	else if ('#' == ret)
		printf("电脑赢了!\n");
	else
		printf("本场平局!\n");

	//本局棋盘最终情况
	printf("\n该局最终结果:>\n");
	DisplayBoard(board, ROW, COL);
	system("pause");//请按任意键继续
	system("cls");//清屏操作
}

//
//什么情况游戏结束?(返回值)
//玩家赢  --  '*'
//电脑赢  --  '#'
//平局    --  'D'
//继续    --  'C'
//


六、初始化棋盘 InitBoard()

将棋盘元素初始化为空格。

1 函数原型

//game.h

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


2 函数实现

//game.c

//初始化棋盘函数实现
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] = ' ';//将棋盘初始化为空格
		}
	}
}


七、打印棋盘 DisplayBoard()

打印显示棋盘数据。

1 函数原型

//game.h

//打印显示棋盘函数声明
void DisplayBoard(char noard[ROW][COL], int row, int col);


2 函数实现

//game.c

//打印显示棋盘函数实现
//版本1
//void DisplayBoard(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");
//	}
//	printf("\n");
//}
//版本2
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	printf("\n");
	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");
		}
	}
	printf("\n");
}


八、玩家下棋 PlayerMove()

玩家回合,玩家输入棋盘坐标进行下棋。

1 函数原型

//game.h

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


2 函数实现

//game.c

//玩家下棋函数实现
void PlayerMove(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 > 0 && x <= row) && (y > 0 && y <= col))
		{
			//如果坐标合法,检查坐标是否未被占用
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';//玩家落子:*
				break;//退出本回合下棋
			}
			else
			{
				printf("该坐标被占用,请重新落子!\n");
			}
		}
		else
		{
			printf("坐标非法,请重新输入!\n");
		}
	}
}


九、电脑下棋 ComputerMove()

电脑回合,电脑随机生成坐标下棋。

1 函数原型

//game.h

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


2 函数实现

//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;//0 ~ row-1
		y = rand() % col;//0 ~ col-1

		//检查坐标是否被未占用
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';//电脑落子:#
			break;
		}
	}
}


十、判断输赢 IsWin()

通过检验行是否相等、列是否相等或者对角线是否相等且是否是非空格字符判断输赢;以及通过棋盘是否已满判断本局游戏是否继续还是最终平局。

1 函数原型

//game.h

//判断输赢函数声明
int IsWin(char board[ROW][COL], int row, int col);


2 IsFull() 函数实现

判断棋盘坐标是否已满。

//game.c

//判断棋盘是否已满函数实现
//使用static限定函数只在本文件中使用
static 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;//满了,棋盘已被填满
}


3 IsWin() 函数实现

//game.c

//判断输赢函数实现
int 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];//返回坐标信息
		}
	}

	//判断列
	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 (IsFull(board, ROW, COL) == 1)
	{
		return 'D';//平局(draw)
	}
	else
	{
		return 'C';//继续(continue)
	}
}


总结:

  本节给出了数组应用实例——三子棋的简单实现,分文件编写了函数声明、函数定义和游戏实现。


感谢您的阅读,如有任何错误,欢迎您的批评指正!

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值