C语言三子棋游戏代码+思路分析

1.测试页面的代码

#define _CRT_SECURE_NO_WARNINGS 1
# include<stdio.h>
#include"game.h"
#include<stdlib.h>
#include<time.h>
//菜单
void menu() {
	printf("**********欢迎来到三子棋游戏***********\n");
	printf("******1.play.**********0.exit.*********\n");
	printf("***************************************\n");
}

//游戏
void game() {
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	char ret = 0;

	while (1) {
		//玩家下棋
		PlayerMove(board, ROW, COL);
		//判断输赢
		ret = Is_Wins(board, ROW, COL);
		if (ret != 'C') {//若是不继续游戏则跳出while循环
			break;
		}
		//下完棋打印
		DisplayBoard(board, ROW, COL);

		//电脑下棋
		ComputerMove(board, ROW, COL);
		ret = Is_Wins(board, ROW, COL);
		if (ret != 'C') {//若是不继续游戏则跳出while循环
			break;
		}
		//下完棋打印
		DisplayBoard(board, ROW, COL);
	}

	//打印出最终结果图
	DisplayBoard(board, ROW, COL);
	if (ret == '*') {
		printf("玩家赢\n");
	}
	else if (ret == '#') {
		printf("电脑赢\n");
	}
	else if (ret == 'Q') {
		printf("平局\n");
	}
}

int main() {
	int input = 0;
	//给电脑下棋的随机性做一个时间戳
	srand((unsigned int)time(NULL));
	do {
		menu();
		printf("请输入你的选择:>\n");
		scanf("%d", &input);
		switch (input) {
		case 1:
			game();
			break;
		case 0:
			printf("即将退出程序!\n");
			exit(0);
			break;
		default:
			printf("输入错误!\n");
			break;
		}
	} while (input);
	return 0;
}

2.头文件game.h代码--函数声明

#pragma once
#pragma once
#include<stdio.h>
#define ROW 3
#define COL 3
//初始化棋盘的函数声明
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘函数声明
void DisplayBoard(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);
//判断输赢
char Is_Wins(char board[ROW][COL], int row, int col);

3.game.c函数代码

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

//初始化棋盘的函数
void InitBoard(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++) {
			board[i][j] = ' ';
		}
	}
}

//打印棋盘的函数
void DisplayBoard(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) {//不打印第三行的---
			int j = 0;
			for (j = 0; j < col; j++) {
				printf("---");
				if (j < col - 1) {//第三列不打印 |
					printf("|");
				}
			}
			printf("\n");
		}
	}
}

//玩家下棋函数
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);
		//玩家不懂数组下标从0开始,所以他认为的2 2就是第二行第二个元素,按玩家认知来
		if (x >= 1 && x <= row && y >= 1 && y <= col) {
			if (board[x - 1][y - 1] == ' ') {//但在表格中要将玩家输入的横纵坐标各减一
				board[x - 1][y - 1] = '*';
				break;//下棋是回合制游戏,你一下,我一下的,所以输入一步后就停止继续下棋。
			}
			else {
				printf("格子已被占用,请重新输入!\n");
			}
		}

		//若玩家输入的坐标不符合数组内容,例如输入:2 5(数组越界),就会弹出警告,需要重新输入
		else {
			printf("非法输入坐标\n");
		}
	}
}

//电脑下棋函数--电脑肯定是知道数组下标为0开始,所以横纵坐标不需要-1
void ComputerMove(char board[ROW][COL], int row, int col) {
	int x = 0;
	int y = 0;
	printf("电脑下棋:>\n");
	while (1) {
		//给电脑下棋做一个随机性,随便下棋
		x = rand() % row;//rand产生0-32767的随机一个数,但%row(3)后随机数的范围在0-2三个数之间
		y = rand() % col;//同理
		if (board[x][y] == ' ') {
			board[x][y] = '#';
			break;
		}
	}
}

//判断棋盘是否满了
int Is_fall(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;//说明满了,平局
}


//判断输赢
char Is_Wins(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];
		}
		//列三子连城
		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][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') {
		return board[1][1];
	}
	if (1 == Is_fall(board, ROW, COL)) {
		return 'Q';
	}
	else
		return 'C';
}

        对于井字棋游戏,我们并不陌生,小时候经常与同学,朋友之间玩的一种游戏,它是在一个3*3大小的正方形棋盘中进行,好比五子棋一般,执行回合制,一人走一步,若谁先把下好的棋连成一条线,谁就赢得比赛的胜利。注:这里的一条线指的是某一行,某一列,或者两条对角线上的任意一种达成即可。

        1.首先,我们可以在主函数中创建一个游戏的基础写法,利用do..while语句可以先执行一次循环体,再进行判断条件,若判断条件一直为真,那么我们便可以一直玩这个游戏。这种写法应该是所有游戏都会用到的写法了。之后我们设计菜单界面,进行游戏界面的美化,输入相应的文字功能,教给用户如何玩这个游戏。

        2.在game游戏中,根据游戏的核心,创建出一个宏定义的行列矩阵数组,这样做方便我们以后改成5*5,10*10大小的界面时,不需要大费周章改各种数据,只需要修改头文件中define的行列数字即可!然后就该给数组界面建立边界,例:

                                           空格  |  空格   | 空格
        
                                           空格  |  空格   | 空格
        
                                           空格  |  空格   | 空格  

其次,还需要行与行之间建立分割的符合“---”与“|”两种符合

                                                ---|---|---

                                                ---|---|---  ​​

最终形成数组打印后如下: 

        3. 井字棋作为两方博弈游戏,自然是要创立双方的函数,在这里我使用了玩家(主动操控下棋处的)函数和电脑(计算机下棋)函数,若想玩双人小游戏,则需要将我的电脑函数代码改为玩家函数即可。我设立的规则是玩家使用‘ * '号下棋,电脑使用'#'号下棋,考虑到玩家并不懂数组的下标位置从0开始,所以正常输入,代码中是将玩家输入的坐标行列都减1就行。若是玩家输入的坐标不符合条件,就提示警告;对于电脑函数,就没有那么多的限制,电脑函数的核心在于输入坐标的随机性,函数中用到了rand函数:在0—32767之间产生一个随机数;

 

        rand函数调用
rand()函数每次调用前都会查询是否调用过srand,是否给srand设定了一个值,如果有那么它会自动调用srand一次来初始化它的起始值.
若之前没有调用srand,那么系统会自动给srand赋初始值,即srand(1)自动调用它一次。

        想要使rand随机的生成一个随机数就要用到srand函数。

 

 strand函数:设置随机数的起点,让rand()产生的随机数随机化,用时间作种子 srand(time(NULL)),这样每次运行程序的时间肯定是不相同的,产生的随机数肯定就不一样了。代码如下:

srand((unsigned int) time(NULL));//time--时间戳(与系统从1970-0-0 0时0分至今的时间,时时刻刻在变化),增强随机数的随机性(使系统在输出随机数的时候能保持随机性)

       

        4.接下来就是需要创建判断输赢的函数了。在井字棋中,我设立游戏的输赢方案是在于一方优先达到行三连、列三连、正副对角线三连成线,若是‘ * ’先连成则表明玩家赢,若是‘ # ’号先连成,则是电脑赢,若是棋盘都下满,双方没有分出胜负则表明是平局‘Q’。

1.玩家赢图片展示        

2.电脑赢图片展示

3.平局展示

 

感谢观看,点个关注再走吧谢谢!

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
很抱歉,我不能提供完整的代码文件,因为我无法提供文件上传功能。但是,你可以根据引用和引用中提供的代码片段来编写三子的C语言代码。引用中提供了一个包含源代码的zip文件,你可以下载并查看其中的代码。而引用则提供了一个关于三子的完整代码示例,你可以参考其中的实现思路和函数声明来编写你自己的代码。 在编写代码之前,你需要先了解三子的规则和逻辑。一般来说,三子是在一个3x3的盘上进行,玩家和电脑轮流下,目标是先将自己的子连成一行、一列或一条对角线获胜。你需要定义一个盘的数据结构,用来表示盘的状态,然后实现玩家和电脑的落子函数以及判断胜负的函数。 参考引用中提供的函数声明,你可以按照以下步骤来编写三子的C语言代码: 1. 定义一个3x3的二维数组来表示盘,可以命名为board。 2. 实现InitBoard函数,用于初始化盘,将所有格子都设置为空。 3. 实现DisplayBoard函数,用于打印当前盘的状态,可以将空格用空白字符表示,玩家的子用X表示,电脑的子用O表示。 4. 实现PlayerMove函数,用于获取玩家的输入,并在盘上落子。 5. 实现ComputerMove函数,用于生成电脑的落子策略,并在盘上落子。 6. 实现IsWin函数,用于判断当前的局是否已经分出胜负,如果玩家获胜,则返回*;如果电脑获胜,则返回#;如果平局,则返回Q;如果游戏尚未结束,则返回C。 通过以上步骤,你可以完成一个简单的三子游戏的C语言代码。请根据实际需要进行调整和完善。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [c语言三子的项目源代码.zip](https://download.csdn.net/download/chengxuyuanlaow/86775916)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [C语言零基础手把手三子代码完整版](https://download.csdn.net/download/qq_58242352/88244594)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [笔记13-1(C语言 三子)](https://blog.csdn.net/w_pab/article/details/123497533)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

橙予清的zzz~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值