栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言实现三子棋(初级)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言实现三子棋(初级)

序言

序言
这是一个用C语言写的多文件小游戏,代码的判断函数只适合三子棋的规则,后面我会一一补充。

成果

我们写代码一定要看我们的要求是什么,上图我们可以看出,我们打印的是3 × 3的棋盘,数据类型是char,而且玩家用的是 ‘ * ’,电脑是 ‘ #’。

实现 第一步 – 创建文件

这里我们会定义三个文件,一个头文件和一个用于函数实现的文件和一个测试文件。
头文件

#include
#include
#include

#define ROW 3       
#define COL 3

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

//打印棋盘
extern void Show_board(char board[ROW][COL], int row, int col);

//玩家走
extern void PlayerMove(char board[ROW][COL], int row, int col);

//电脑走
extern void ComputerMove(char board[ROW][COL], int row, int col);

//判断输赢
extern char Is_win(char board[ROW][COL], int row, int col);

这里的函数我们都会一个个实现

第二步 – 搭建框架(测试文件)

写出一个主函数

#include"game.h"
int main()
{
	test();
	return 0;
}

在写程序的时候我们很少在main函数内书写,那样会显得嘈杂。

test函数

void test(void)
{
	srand((unsigned int)time(NULL));//后面会说

	int input = 0;
	do
	{

		menu();           //目录函数
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("下棋n");
			PlayGame();
			break;
		case 0:
			printf("退出游戏n");
			break;
		default:
			printf("选择错误,请重新选择n");
			break;
		}
	} while (input);
}

do while的作用是当你运行这个程序时,首先打印出目录,选择0才会退出程序

menu函数

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

这个大家都知道,没什么可以说的,记住打印美观就好

玩游戏

void PlayGame(void)
{
	char ret = 0;
	char board[ROW][COL] = { 0 };

	Init_board(board, ROW, COL);

	Show_board(board, ROW, COL);

	while (1)
	{
		//printf("玩家走>n");
		PlayerMove(board, ROW, COL);

		Show_board(board, ROW, COL);
		ret = Is_win(board, ROW, COL);
		  //玩家 *
          //电脑 #
          //平局 Q
          //继续 C
		if (ret != 'C')
		{
			break;
		}

	   // printf("电脑走>n");
		ComputerMove(board, ROW, COL);
	
		Show_board(board, ROW, COL);
		ret = Is_win(board, ROW, COL);

		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == '*')
	{
		printf("玩家赢n");
	}
	else if (ret == '#')
	{
		printf("电脑赢n");
	}
	else
	{
		printf("平局n");
	}

}

到这里框架就搭建的差不多了,第二步的代码全部放到测试文件内

第三步 – 函数实现

初始化棋盘

void Init_board(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] = ' ';  //初始化为空字符
		}
	}
}

这一步很简单

打印棋盘

void Show_board(char board[ROW][COL], int row, int col)
{


	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}

		printf("n");

		if (i < row - 1)
		{
        for (int j = 0; j < col; j++)
		   {
			  printf("---");

			  if (j < col - 1)
				printf("|");
		   }
		}
		
		printf("n");
		
	}
}

我们一步一步分析

//模块1
for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}

我们将红色框内但做一个整体,最左侧没有 ‘ | ’ ,代码中
if (j < col - 1)
printf("|");

//模块2
if (i < row - 1)
		{
        for (int j = 0; j < col; j++)
		   {
			  printf("---");

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

这里是有与由于最后一行没有**‘—’**,所以加上了 if (i < row - 1) 语句

玩家走

void PlayerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家走>n");
	printf("请输入你的坐标 :");

	while (1)
	{
		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");
				printf("请输入你的坐标 :");
			}
		}
		else
		{
			printf("坐标非法,请重输入!n");
			printf("请输入你的坐标 :");
		}
	}


}

这里使用board[x - 1][y - 1] = '*' 是因为用户不知道数组是从0开始的,他只会知道第几行第几列,我们要考虑用户的感受。

电脑走

void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑走>n");
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % ROW;  //0 ~ ROW-1
		y = rand() % COL;  //0 ~ COL-1
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

这个函数写的很不好,电脑是在随机生成数字,没有竞争意识,后面我会写一个好一点的来完善它
rand是一个生成随机数函数,不过之前要引用srand((unsigned int)time(NULL));这就是他在测试文件的作用

判断输赢

实际上,每走一步,我们都需要判断一下输赢和打印初棋盘

char Is_win(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][0] == board[i][2] && board[i][0] != ' ')
		return  board[i][0];

	}
	//判断列
	for (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[0][j] == board[2][j] && board[0][j] != ' ')
		return  board[0][0];
	}
	//判断对角线
	if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] != ' ')
	{
		return  board[0][0];
	}

	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return  board[1][1];
	}
	
	//判断满了没有  满了 1  未满 0
	if (0 == Is_full(board ,row,col))
	{
		return 'C';
	}
	return 'Q';

}

这个函数已经被写死了,只能判断3×3的棋盘。其中该函数内部有调用了Is_full函数,这个函数我没在主文件列出来,是因为用户不需要知道这个函数。

int Is_full(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;
}

现在整个程序我们都写好了,自己可以尝试一下把。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/458162.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号