三子棋详解(附代码)(保姆级教学)

前言

我们都知道三子棋的玩法,那怎么通过C语言来实现呢?希望通过阅读这篇文章可以给你带来帮助,我们从创建头文件,源文件开始,到最后实现整个游戏,全程一步一步手拿把掐的分享博主的经验,以下内容是详细过程及代码。话不多说,直接上货!

一·创建源文件 头文件

我们在vs2019中创建一个头文件,两个源文件,头文件用来声明函数,两个源文件一个用来写游戏实现的代码,一个用来写主函数。例如这样:

在头文件中,我们首先要声明我们棋盘的大小,行和列都为三。

在写三子棋的时候,我们必须要有一个清晰的思路,第一步要干什么,第二步要干什么,想清楚了再写,首先我们要初始化棋盘,然后打印棋盘,打印完棋盘以后玩家下棋,此时要判断输赢,若无事发生,则继续,若胜负已分,则结束游戏,玩家下完棋之后,电脑下棋,同样的也需要判断输赢。

怎么判断输赢呢?玩家赢用‘ * ’表示,电脑赢则用‘ # ’表示,平局用‘ Q ’表示,继续则用‘ C ’表示。

想到这里我们就可以开始写代码啦~

头文件代码如下展示:

#pragma once

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

#define ROW 3
#define COL 3

//初始号棋盘
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void DispalyBoard(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);

//判断输赢
//玩家赢- '* '
//电脑赢- '# '
//平局- 'Q '
//继续- 'C '

char IsWin(char board[ROW][COL], int row, int col);

创建好源文件和头文件以后,我们继续进行下一步;

二.游戏的创建

第一步,我们要在主函数的源文件中写一个菜单代码,如下展示:

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

第二步,我们进入主函数, 因为此游戏涉及到电脑下棋,所以加入一个随机数。

再后,我们可以通过上面的代码可以看到,当我们选择1的时候,进入游戏,选择0的时候,退出游戏,选择其他的数字,则不能识别到,这时候要提醒玩家输入错误,所以我们这时候用到了Switch-case语句,但我们不是只玩一次游戏,这时候我们可以就使用do-while语句来循环是否要继续进行三子棋,代码如下:

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do 
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输出\n");
			break;
		}
	} while (input);
	return 0;
}

下图为代码运行成功的结果图:

 

 

 第三步,当我们选择1进入游戏的时候,我们写一个游戏的函数,game(),接下来博主要讲的是game()具体实现的步骤:

首先我们设置一个二维数组,数据类型为char,char board[ROW][COL] = { 0 },ROW为行,COL为列,然后我们初始化棋盘,然后把棋盘打印下来,接下来我们就可以下棋了,这时我们设置一个变量ret来储存判断是否还需要下棋的结果,每下一次棋判断一次(电脑每下一步棋也会执行相同的步骤),那这种情况我们用while语句,只有当ret这个变量不等于继续‘ C ’这个条件时,while语句才会跳出下棋的这个操作。

之后判断输赢,‘ * ’ 玩家赢,‘ # ’ 电脑赢,‘ Q ’ 平局。

下面是game()函数的具体代码:

void game()
{
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	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 != 'C')
			break;
		//电脑下棋
		ComputerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
		printf("玩家赢\n");
	else if (ret == '#')
		printf("电脑赢\n");
	else
		printf("平局\n");
}

三.游戏的实现

我们之前提到了六个函数,分别是初始化棋盘,打印棋盘,玩家下棋,电脑下棋,棋盘是否已经被下满返回平局,以及判断输赢的六个函数。

3.1初始化棋盘函数

首先我们要让棋盘上的每个位置都为空,但是不能真的没有任何内容,所以我们设置空格来满足这个条件,用for循环来遍历棋盘的每一个位置。

代码如下展示:

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] = ' ';
		}
	}
}

3.2打印棋盘函数

在这一步中,我们首先要想清楚要打印一个什么样的棋盘,如图所示,棋盘示例:

然后我们要想清楚怎么打印棋盘,打印什么内容,第一步我们要打印下棋的位置及是谁下棋,为了美观,我们在第一行第一列的位置设置“空格 符号 空格”的格式,如“ %c ” ,之后的每个位置都按照这样的形式来设置,此时我们用for循环来遍历每个位置。因为我们是三子棋,棋盘是一个3X3的大小,那这时我们在第一列和第二列打印分割线,如上图所示。第二步打印分割线,只在第一行和第二行打印---,然后 | 分割线同上面一样。

代码如下展示:

void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//1.打印数据
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		//2.打印分割线
		if (i < row - 1)
		{
			int j = 0;
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}

3.3玩家下棋函数

同样的,玩家下棋不可能只下一次棋,那我们依旧使用while函数,此时我们设置两个变量X Y,输入X和Y的值,这时我们要对输入的值进行判断,如输入合法则进行下一步,如不合法则提醒玩家重新输入。

因为是3X3的棋盘,玩家只能输入1~3之间的数字,当超出这个范围时,我们判断不合理,要求重新输入,只有当输入的数字对应棋盘的位置为空格时,玩家方能下棋,否则则不能,玩家下棋以后,空格赋值为‘ * ’。 

代码如下展示:

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 >= 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");
		}
	}
}

3.4电脑下棋函数

因为电脑是随机下棋,这时我们引入一个随机数函数,同样的,我们设置一个X Y变量,电脑下的位置存到X和Y中,用rand % 行和列,此时的余数一定在0~2之间,所以不需要判断电脑输入的数字是否合法,我们只需要判断电脑下的位置是不是空格就OK了,如果是空格就下,这时把‘ # ’赋值给空格。

代码如下展示:

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

3.5判断棋盘是否被下满函数

这块函数没什么好说的,用for循环遍历每个位置就好,如果棋盘有位置是空格,则返回0,若棋盘没有位置是空格,则返回1。

代码如下展示:

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.6判断输赢函数

赢无非有四种情况,行连成三子,列连成三子,两条对角线连成三子;

或者是平局;

再或者既没有决出胜负,又没有平局,则继续下棋。

想清楚这个关系就好办了,对于行来说,我们用for循环遍历每一行,假如说,有一行三子都为相同的元素,且此位置不为空格,那我们则判断胜利,相同的,判断列,判断两条对角线也是这样的情况,依次用for循环遍历就好啦~

当平局发生的时候,我们看第五个的函数返回值是否为1,当为1的时候,结局为平局,当不为1的时候,游戏继续。

代码如下展示:

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][0] != ' ')
		{
			return board[i][0];
		}
	}
	//列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
			return board[0][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 'Q';
	}
	//继续
	return 'C';
}

四.游戏结果展示

1.玩家赢的情况:

2.电脑赢的情况:

 

 3.平局的情况

 五.结束语

这就是三子棋有关的全部内容啦~希望这篇文章可以给你带来实质性的帮助,最后也祝你早日写出自己的三子棋代码哦~

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值