手把手教你如何用C语言实现三字棋(超详细 分享思路)

目录

三字棋介绍

思路

怎么实现

总代码


三字棋介绍

       说起三字棋,很多小伙伴在小时候课堂上或者课间一定和同学朋友玩过无数次了,但为了照顾没玩过的少数老铁,我们还是在这里回顾一下三字棋的规则

       在一个3*3的9宫格棋盘上下棋,双方依次在棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利。

(三字棋)

话不多说,接下来让我介绍一下如何用C语言实现三字棋小游戏吧!


思路

大纲:

一、创建三个文件:

  • game.c  存放实现本游戏的各个功能(棋盘、电脑玩家、游戏规则等...)的函数
  • game.h  作为一种包含功能函数、数据接口声明
  • test.c     存放主函数(main函数)控制游戏进程、引入game.h

作为本游戏存放主函数的.c文件,按我的设定,test.c的作用相当于搭建房屋时的框架,而game.cgame.h的作用是给这个房屋添砖加瓦,因此我们首先要把test.c文件搭建好再按需编写game.c文件,在通过game.h文件将他们组装成一个完整的“房屋”


二、功能及其实现

我们需要清楚实现一个三字棋小游戏需要解决的问题

  1. 棋盘的实现。
  2. 玩家下棋方式(输入坐标)。
  3. 电脑下棋方式(随机生成坐标)。
  4. 输赢判定方法。

怎么实现

第一步:创建test.c文件,构建框架

这里我们运用 do while循环switch选择语句实现玩家根据meanu选择是否进行游戏,当输入为1时进行游戏,输入为0时结束游戏。

代码如下

void meanu()
{
	printf("***********************************************\n");
	printf("***********      1.开始游戏       *************\n");
	printf("***********      0.结束游戏       *************\n");
	printf("***********************************************\n");
}//打印菜单

void game()
{}//游戏函数
int main()
{
	 int input = 0;
	do
	{
		meanu();
		printf("请选择是否进行游戏:>\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			break;
		default:
			printf("输入错误,请重新输入:\n");
			break;
		}
	} while (input);
	return 0;
}

第二步:实现游戏功能

创建game.c文件,分别实现打印棋盘、玩家下棋、电脑下棋、输赢判定。

打印棋盘

       我们需要一个3*3的棋盘,可以用二维字符数组实现,一般情况下我们会选择用board[3][3]直接创建一个3行3列的字符数组,这没有错,但假如我们需要改变行列数时我们要把所有的board[3][3]改为我们所需要的board[x][y]因此我们可以定义宏变量a b控制行列数,当我们需要改变行列数时,只需要把a和b的值改变就可以达到目的。这个思路适用于很多代码,这个习惯可以帮助你未来的代码更容易操作和改动。

        打印以下3*3棋盘,我们首先在game.h文件里定义宏变量a 和 b,再在game.c文件里用intit_board初始化棋盘(每个棋子的位置放置' '空格符号),接着我们在display_board采用-和|符号打印棋盘,详见代码。

 game.h下定义宏变量

#define a 3//定义行
#define b 3//定义列

intit_board初始化棋盘

void intit_board(char board[a][b])//初始化棋盘(二维字符数组内存放的全为' '(空格)字符)
{
	int i = 0;
	for (i = 0; i < a; i++)
	{
		int j = 0;
		for (j = 0; j < b; j++)
		{
			board[i][j] =' ';
		}
	}
}

display_board打印棋盘

void display_board(char board[a][b], int x, int y)//打印棋盘
{
int i = 0;
for (i = 0; i < x; i++)
{
	int j = 0;
	for (j = 0; j < y; j++)
	{
		printf(" %c ", board[i][j]);
		if (j < y - 1)
			printf("|");
	}//最后一列没有|
	printf("\n");
	if (i < x - 1)
	{
		for (j = 0; j < y; j++)
		{
			printf("---");
			if (j < y - 1)
				printf("|");
		}//---|一个循环 但是每行的最后一个---|不打印|
	}
	printf("\n");
}
}

玩家下棋

         逻辑很简单,玩家的棋子为 * 符号,只需要让玩家输入棋盘内某一坐标,如果该坐标没有棋子,就可以把棋子落在该位置。即输入字符数组下标,判定该字符是否为‘ ’,如果是落下棋子,如果不是则重新输入坐标。另外考虑到玩家可能不了解代码下标相关知识,我们需要在玩家输入坐标的基础上减1作为输入的下标。

代码如下

player_move

void player_move(char board[a][b], int x, int y)//玩家下棋
{
	printf("玩家下棋:\n");
	printf("请输入棋子位置:>");
	int i = 0;
	int j = 0;
	do {
		scanf("%d %d", &i, &j);
		if (i - 1 < y && j - 1 < x)
		{
			if (board[j-1][i-1] == ' ')
			{
				board[j - 1][i - 1] = '*';
				break;
			}
			else
				printf("该位置已有其他棋子,请重新输入:\n");
		}
		else
			printf("位置非法,请重新输入:\n");
	} while (1);
	}

电脑下棋

        由于电脑玩家需要一定的随机性,所以我们引用rand函数和time控制电脑输入的下标。电脑的棋子为#符号。

computer_move(char board[a][b], int x, int y)
{
	printf("电脑下棋:\n");
	while (1)
	{
		int m = rand(time(NULL)) % a;
		int n = rand(time(NULL)) % b;
		if (board[m][n] == ' ')
		{
			board[m][n] = '#';
			break;
		}
	}
}

输赢判定

        回顾三字棋的规则:在一个3*3的9宫格棋盘上下棋,双方依次在棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利除了输赢还有把棋盘下满且无法判断输赢的情况,即为平局。我们在test.c文件下创建一个is_full函数判断棋盘是否下满,再创建一个is_win函数确定游戏规则并根据情况返回值,最后在test.c文件下的game()函数内根据返回值判断游戏胜负。

代码如下

is_full

        用for循环按序检索二维数组内的值,遇到' '时返回1,代表棋盘没有满。

int is_full(char board[a][b], int x, int y)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < a; i++)
	{
		for (j = 0; j < b; j++)
		{
			if (board[i][j] == ' ')
			{
				return 1;
			}
		}
	}
	return 0;
}

is_win  

        通过for循环语句if判断行、列、斜方向的赢棋情况,并根据赢的棋子确定返回值,根据最后根据is_full的值返回‘Y’或者‘N’

char is_win(char board[a][b], int x, int y)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < a; 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 < b; 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[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][2] != ' ')
	{
		return board[0][2];
	}
	if (is_full(board, a, b) == 0)
	{
		return 'N';
	}
	return 'Y';
}

game()

void game()
{

	char board[a][b] = { 0 };//初始化二维字符数组
	char x = 0;
	intit_board(board);//初始化棋盘
	display_board(board, a, b);//打印棋盘
	while (1)
	{
		player_move(board, a, b);
		display_board(board, a, b);
		x = is_win(board, a, b);//接收is_win返回值
		if (x != 'Y')
			break;
		computer_move(board, a, b);
		display_board(board, a, b);

		x = is_win(board, a, b);
		if (x != 'Y')
			break;
	}

	if (x == '*')
	{
		printf("恭喜你!赢得了本局游戏!!!\n");
	}
	else if (x == '#')
	{
		printf("很遗憾!你输掉了本局游戏!!!\n");
	}
	else if (x == 'N')
	{
		printf("平局!\n");
	}
}

实现以上所有功能后,三字棋小游戏即可实现

-----------------------------------------------------------分割线-------------------------------------------------------------

总代码

所有代码如下所示

test.c

#include<stdio.h>
#include"game.h"
void meanu()
{
	printf("***********************************************\n");
	printf("***********      1.开始游戏       *************\n");
	printf("***********      0.结束游戏       *************\n");
	printf("***********************************************\n");
}

void game()
{

	char board[a][b] = { 0 };
	char x = 0;
	intit_board(board);
	display_board(board, a, b);
	while (1)
	{
		player_move(board, a, b);
		display_board(board, a, b);
		x = is_win(board, a, b);
		if (x != 'Y')
			break;
		computer_move(board, a, b);
		display_board(board, a, b);

		x = is_win(board, a, b);
		if (x != 'Y')
			break;
	}

	if (x == '*')
	{
		printf("恭喜你!赢得了本局游戏!!!\n");
	}
	else if (x == '#')
	{
		printf("很遗憾!你输掉了本局游戏!!!\n");
	}
	else if (x == 'N')
	{
		printf("平局!\n");
	}
}
int main()
{
	int input = 0;
	do
	{
		meanu();
		printf("请选择是否进行游戏:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			break;
		default:
			printf("输入错误,请重新输入:\n");
			break;
		}
	} while (input);
	return 0;
}

game.h

#include<stdio.h>
#define a 3
#define b 3
#include<stdio.h>
void display_board(char board[a][b], int x, int y);
void intit_board(char board[a][b]);
void player_move(char board[a][b],int x,int y);
computer_move(char board [a][b], int x, int y);
char is_win(char board[a][b], int x, int y);

game.c

#include"game.h"
#include<stdlib.h>
#include<time.h> 
void intit_board(char board[a][b])//初始化棋盘
{
	int i = 0;
	for (i = 0; i < a; i++)
	{
		int j = 0;
		for (j = 0; j < b; j++)
		{
			board[i][j] = ' ';
		}
	}
}
void display_board(char board[a][b], int x, int y)//打印棋盘
{
	int i = 0;
	for (i = 0; i < x; i++)
	{
		int j = 0;
		for (j = 0; j < y; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < y - 1)
				printf("|");
		}
		printf("\n");
		if (i < x - 1)
		{
			for (j = 0; j < y; j++)
			{
				printf("---");
				if (j < y - 1)
					printf("|");
			}
		}
		printf("\n");
	}
}
void player_move(char board[a][b], int x, int y)//玩家下棋
{
	printf("玩家下棋:\n");
	printf("请输入棋子位置:>");
	int i = 0;
	int j = 0;
	do {
		scanf("%d %d", &i, &j);
		if (i - 1 < y && j - 1 < x)
		{
			if (board[j - 1][i - 1] == ' ')
			{
				board[j - 1][i - 1] = '*';
				break;
			}
			else
				printf("该位置已有其他棋子,请重新输入:\n");
		}
		else
			printf("位置非法,请重新输入:\n");
	} while (1);
}
computer_move(char board[a][b], int x, int y)
{
	printf("电脑下棋:\n");
	while (1)
	{
		int m = rand(time(NULL)) % a;
		int n = rand(time(NULL)) % b;
		if (board[m][n] == ' ')
		{
			board[m][n] = '#';
			break;
		}
	}
}
//判断棋盘有没有满,如果满了返回0,没满返回1

int is_full(char board[a][b], int x, int y)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < a; i++)
	{
		for (j = 0; j < b; j++)
		{
			if (board[i][j] == ' ')
			{
				return 1;
			}
		}
	}
	return 0;
}

char is_win(char board[a][b], int x, int y)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < a; 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 < b; 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[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][2] != ' ')
	{
		return board[0][2];
	}
	if (is_full(board, a, b) == 0)
	{
		return 'N';
	}
	return 'Y';
}

代码运行截图:

 

本篇文章到此结束,欢迎提出建议~

如果对你有帮助,请点赞支持!

比心ღ(〃'▽'〃)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jenbin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值