C语言学习-数组应用-简易三子棋

本文详细描述了如何使用C语言实现三子棋游戏,包括菜单设计、游戏逻辑、棋盘初始化、打印及判断胜负的过程。通过main函数调用测试代码,逐步展示了游戏的完整流程。
摘要由CSDN通过智能技术生成

三子棋的设计思路:

我们拆分三子棋的实现过程,生成了以下三个文件:

  1. 测试文件(test.c):用于测试三子棋的功能和正确性。
  2. 游戏实现文件(game.c):包含了三子棋游戏的具体实现代码。
  3. 头文件(game.h):定义了与三子棋游戏相关的函数和数据结构的声明。

1. 三子棋菜单功能的实现

所有的程序,当然离不开在test.c中写入一个主函数

int main()//主函数里尽量只是调用函数
{
	test();//创建一个菜单,并且实现基本逻辑
	return 0;
}

我们可以利用刚刚编写的test函数来实现一些功能:

  1. 玩一把不过瘾,再玩一把

  2. 设计并创建游戏菜单,以便用户更方便地操作和选择。

  3. 编写游戏的具体实现函数,确保游戏逻辑能够顺利执行。

void test()
{
	int input = 0;
	do
	{
		menu();
		printf("请输入(1/0)>:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			//printf("游戏\n");
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入非法,请重新输入>:\n");
			break;
		}

	} while (input);
}

menu(菜单函数)入下:

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

写到这里,我们可以先测试一下代码运行的结果,养成边写边测试的习惯 

到这里,我们完成了游戏的菜单逻辑

2. 三子棋的具体实现

2.1棋盘的初始化和打印

首先,我们要建立一个用于记录玩家和电脑落子情况的数据结构。通过分析,我们知道可供落子的位置有九个,因此可以创建一个3x3的数组来表示棋盘,记录每个位置的状态。

在头文件中,我们可以使用#define来定义一些常量,这样有助于日后的观察和修改。例如,我们可以定义棋盘的大小为3x3,并为玩家和电脑分别定义落子的标记。这样可以提高代码的可读性和维护性。

在头文件中声明了,要在.c文件中包含对应的头文件

#include "game.h"//引用自己的头文件
 
void game()//三子棋的实现
{
	char board[ROW][COL];//存放玩家或电脑的落子情况
}

接下来,我们需要初始化落子位置,并将三子棋的棋盘打印出来。我们可以将这两个步骤分别封装成两个函数,并在game.c中实现它们

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

	Init_board(board, ROW, COL);
	Print_board(board, ROW, COL);
}

  为了能够使用这两个函数,我们要在对应头文件中加入函数声明:

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

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

初始化棋盘(Init_board函数)的具体实现:

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

打印棋盘(Print_board函数)的具体实现:

void Print_board(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++)
		{
			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");
		}


	}
}

运行结果是这样的: 

2.2玩家与电脑PK具体实现

下棋我们把它分为两步:

  1.  玩家回合
  2.  电脑回合

并且每次下完要把棋盘打印出来~

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

	Init_board(board, ROW, COL);
	Print_board(board, ROW, COL);

    Player_move(board, ROW, COL);
	Print_board(board, ROW, COL);

    Computer_move(board, ROW, COL);
	Print_board(board, ROW, COL);
}

我们需要将Player_move,Computer_move在头文件中加入声明

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

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

玩家下棋:

void Player_move(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("玩家走\n");
	printf("请输入坐标>:");

	while (1)
	{
		scanf("%d %d", &i, &j);
		if (i > row || i <= 0 || j > col || j <= 0)
		{
			printf("输入坐标非法,请重新输入:>");
		}
		else
		{
			if (board[i - 1][j - 1] == ' ')
			{
				board[i - 1][j - 1] = '*';
				break;
			}
			else
			{
				printf("该坐标已被占用,请重新输入:>");

			}
		}


	}

}

电脑下棋(我们使用随机数生成来模拟电脑下棋):

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

还不会随机数的宝子可以另外学习,这里不细讲~

现在我们就到了最后一步判断输赢了

2.3判断胜负或平局

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

	Init_board(board, ROW, COL);
	Print_board(board, ROW, COL);
	while (1)
	{
		Player_move(board, ROW, COL);
		Print_board(board, ROW, COL);
		ret = Iswin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		Computer_move(board, ROW, COL);
		Print_board(board, ROW, COL);
		ret = Iswin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}

	else if (ret == '#')
	{
		printf("电脑赢\n");
	}
	else
	{
		printf("平局\n");
	}
}

我们人为规定,当ret返回 * 是玩家获胜,返回 # 时电脑获胜,都不返回则平局。

接下来我们需要实现 Iswin 函数:

(实现函数时,别忘了在头文件中声明哦~)

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[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
	{
		return board[1][1];

	}
	//判断是否继续
	if (1 == Isfull(board, ROW, COL))
	{
		return 'C';
	}
	else
		return 'Q';
}

Iswin 函数中,我们使用了Isfull函数来判断棋盘是否被下满

(实现函数时,别忘了在头文件中声明哦~)

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 1;
			}

		}
	}
	return 0;
}

到此为止,我们就大功告成啦~~~

让我们看看效果吧~

 学会了吗?

快去试试吧~~~

3.三子棋文件源码

  • game.h
#pragma once
#define ROW 3
#define COL 3

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

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

void Print_board(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);
//'*'玩家赢
//'#'电脑赢
//'C'继续
//'Q'平局
char Iswin(char board[ROW][COL], int row, int col);
  • game.c
#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"

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

void Print_board(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++)
		{
			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");
		}


	}
}

void Player_move(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("玩家走\n");
	printf("请输入坐标>:");

	while (1)
	{
		scanf("%d %d", &i, &j);
		if (i > row || i <= 0 || j > col || j <= 0)
		{
			printf("输入坐标非法,请重新输入:>");
		}
		else
		{
			if (board[i - 1][j - 1] == ' ')
			{
				board[i - 1][j - 1] = '*';
				break;
			}
			else
			{
				printf("该坐标已被占用,请重新输入:>");

			}
		}


	}

}

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

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 1;
			}

		}
	}
	return 0;
}

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[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
	{
		return board[1][1];

	}
	//判断是否继续
	if (1 == Isfull(board, ROW, COL))
	{
		return 'C';
	}
	else
		return 'Q';
}
  • test.c
#define _CRT_SECURE_NO_WARNINGS 1


#include"game.h"

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

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

	Init_board(board, ROW, COL);
	Print_board(board, ROW, COL);
	while (1)
	{
		Player_move(board, ROW, COL);
		Print_board(board, ROW, COL);
		ret = Iswin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		Computer_move(board, ROW, COL);
		Print_board(board, ROW, COL);
		ret = Iswin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}

	else if (ret == '#')
	{
		printf("电脑赢\n");
	}
	else
	{
		printf("平局\n");
	}
}


void test()
{
	int input = 0;
	do
	{
		menu();
		printf("请输入(1/0)>:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			//printf("游戏\n");
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入非法,请重新输入>:\n");
			break;
		}

	} while (input);
}

int main()
{
	srand((unsigned int)time(NULL));
	test();
	return 0;
}

总结:

以上便是全部内容,感谢您的阅读!

如果您喜欢这篇文章,请不吝点赞和留下您的评论,分享您的观点。

如果您有兴趣一起学习编程,欢迎关注我的更新,我们可以一同学习,共同进步。

未来我将继续输出更多高质量的内容,期待您的继续关注。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

每天进步亿丢丢

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

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

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

打赏作者

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

抵扣说明:

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

余额充值