三子棋小程序

news2024/11/16 4:13:39

一.自定义头文件(game.h)

放入源文件需要用到的标准库头文件函数的声明

ROW 和COL为棋盘的行和列,三子棋嘛,肯定为3啦

#pragma once
#include<stdio.h>
#include<String.h>
#include<stdlib.h>
#include<time.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 ComputerBoard(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL], int row, int col);

二.源文件(test.c和game.c)

1.test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

void menu() {
	printf("***********************************\n");
	printf("************1.开始游戏*************\n");
	printf("************0.退出游戏*************\n");
	printf("***********************************\n");
}
void game() {
    char board[ROW][COL] = {0};
	InitBoard(board,ROW,COL);//初始化棋盘
	DisplayBoard(board, ROW, COL);//显示棋盘
	while (1) {
		PlayerMove(board, ROW, COL);//玩家输入坐标
		DisplayBoard(board, ROW, COL);//然后显示一边棋盘当前的情况
		if (IsWin(board, ROW, COL) != 'C') {//满了或者有一方赢了就break
			break;
		}
		ComputerBoard(board, ROW, COL);//人机输入坐标
		DisplayBoard(board, ROW, COL);//再显示一边棋盘当前的情况
		if (IsWin(board, ROW, COL) != 'C') {//人机输入坐标后再判断一下满没满或者双方有没有赢的,满足就break
			break;
		}
	}
	if (IsWin(board, ROW, COL) == '*') {
		printf("玩家赢\n");
		
	}
	else if (IsWin(board, ROW, COL) == '#') {
		printf("电脑玩家赢\n");
		
	}
	else if (IsWin(board, ROW, COL) == 'D') {
		printf("平局\n");
		
	}
	
}
int main() {
	int input=0;
	srand((unsigned int)time(NULL));
	do {
		menu();
		printf("请输入:");
		scanf("%d", &input);
		switch(input){
		case 1:
			printf("进入游戏\n");
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入:\n");
		}

	} while (input);
	return 0;
}

(1)void game()解释

1.先创建一个游戏面板二维数组

字符型的

char board[ROW][COL] = {0};
2.初始化棋盘
InitBoard(board,ROW,COL);
3.显示棋盘

在真正开始游戏之前肯定得先给玩家看一下棋盘滴啦

DisplayBoard(board, ROW, COL);//显示棋盘
4.while()循环

在玩家输入坐标之后

判断一下棋盘是否满了或者有一方赢了就break

同理,人机输入坐标后也是如此

(每次执行IsWin都会返回一个字符)

while (1) {
	PlayerMove(board, ROW, COL);//玩家输入坐标
	DisplayBoard(board, ROW, COL);//然后显示一边棋盘当前的情况
	if (IsWin(board, ROW, COL) != 'C') {
		break;
	}
	ComputerBoard(board, ROW, COL);//人机输入坐标
	DisplayBoard(board, ROW, COL);//再显示一边棋盘当前的情况
	if (IsWin(board, ROW, COL) != 'C') {
		break;
	}
}

注意:符号' C '说明没满并且没有一方赢

5.判赢

在while()循环出来后,肯定是有一方赢了或者满了

如果返回的符号为‘ * ’则玩家赢

如果返回的符号为‘ # ’则人机(电脑玩家)赢

如果返回的符号为‘ D ’则平局

具体可以看一下下文的IsWin函数具体实现,有注解

if (IsWin(board, ROW, COL) == '*') {
	printf("玩家赢\n");
	
}
else if (IsWin(board, ROW, COL) == '#') {
	printf("电脑玩家赢\n");
	
}
else if (IsWin(board, ROW, COL) == 'D') {
	printf("平局\n");
	
}

2.game.c

(1)初始化棋盘(InitBoard)

void InitBoard(char board[ROW][COL], int row, int col) {
	//InitBoard(board,ROW,COL);//初始化棋盘
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			board[i][j] = ' ';
		}
		
	}
	/*或者直接写这一行代码也可以memset(&board[0][0], ' ', row * col * sizeof(board[0][0]));*/
}

(2)显示棋盘(DisplayBoard)

void DisplayBoard(char board[ROW][COL], int row, int col) {
	//DisplayBoard(board, ROW, COL);//显示棋盘
	for (int i = 0; i < row; i++) {
		if (i < 2) {
			printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
			printf("---|---|---\n");
		}
		else {
			printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
		}
	}

}

效果如图:

(3)玩家输入坐标(PlayerMove)

玩家的棋子是' * '号

void PlayerMove(char board[ROW][COL], int row, int col) {
	//PlayerMove(board, ROW, COL);//玩家输入坐标
	int x, y;
	printf("玩家下棋:>\n");
	printf("请输入棋子的坐标:");
	scanf("%d %d", &x, &y);
	while (1) {
		if (x <= 0 && x >= 4 && y <= 0 && y >= 4) {
			printf("坐标非法,请重新输入\n");
		}
		else if (board[x - 1][y - 1] == ' ') {
			board[x - 1][y - 1] = '*';
			break;
		}
		else {
			printf("坐标已经被占用,请重新输入坐标\n");
			break;
		}
	}
}

效果如图:

(4)人机下棋(ComputerBoard)

人机的棋子是' # '号

void ComputerBoard(char board[ROW][COL], int row, int col) {
	//ComputerBoard(board, ROW, COL);//人机输入坐标
	//DisplayBoard(board, ROW, COL);//然后显示一边棋盘当前的情况
	printf("电脑下棋:>\n");
	int x, y;
	while (1) {
		x = rand() % row;//模上一个3之后得到的数的范围肯定为0~2
		y = rand() % col;
		if (board[x][y] == ' ') {
			board[x][y] = '#';
			break;
		}
	}
}

效果如图:

可以看到我们在输入坐标后紧跟着人机也输入了坐标

(5)判定双方是否赢了(IsWin)

char IsWin(char board[ROW][COL], int row, int col) {
	//IsWin(board, ROW, COL) 判定双方是否赢了

    //判断行是否相等(注意不为空),相等的话就返回其对应的棋子,再下定论谁赢了
	for (int i = 0; i < row; i++) {
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2]&&board[i][2]!=' ') {
			return board[i][0];//返回
		}
    }

    //判断列是否相等(注意不为空),相等的话就返回其对应的棋子,再下定论谁赢了
	for (int j = 0; j < col; j++) {
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[2][j] != ' ') {
			return board[0][j];//返回
		}
	}

    //判断两对角线是否相等(注意不为空),相等的话就返回其对应的棋子,再下定论谁赢了
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] != ' ') {
		return board[0][0];//返回
    }
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] != ' ') {
		return board[0][2];//返回
	}

    
    //判断是否满了,返回不同的字符执行不同的效果
	if (IsFull(board, ROW, COL)) {
		return 'D';//返回
	}
	else {
		return 'C';//返回
	}
}

大致效果:

(6)判满(对应(5)中的函数IsFull())

注意该函数写在IsWin()函数的上边,否则加上声明

int IsFull(char board[ROW][COL], int row, int col) {
	//IsFull(board, ROW, COL)判满
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			if (board[i][j] == ' ') {
				return 0;//返回0说明没满,if(0)相当于false
			}
		}
	}
	return 1;//相当于true
}

一键三连哦,感谢大家的阅读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1956524.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中国少女徐可昕心怀爱豆梦 为实现梦想勇赴韩国

如今MZ世代(MZ世代是‌Millennial世代和‌Z世代的合成词,用来描述1980至2000年间出生的人)小伙伴们追求着怎样的梦想呢?随着韩国K-POP热潮和娱乐产业的发展,越来越多的年轻人希望可以在娱乐圈工作,例如成为爱豆或经理人。通过抖音或YouTube等,可以发现很多才华横溢的年轻人创作…

malloc 对比验证 posix_memalign 的功能

1&#xff0c;函数说明 posix_memalign 是一个 POSIX 标准定义的函数&#xff0c;用于在内存中分配对齐的内存块。这个函数可以确保分配的内存块满足特定的对齐要求&#xff0c;通常用于需要对齐内存访问的情况&#xff0c;比如 SIMD 指令集的使用或者特定硬件要求的内存对齐。…

瑞派明星医生:技术深耕教学指导,燃动当代名校兽医双效技能Buff

名校精进&#xff0c;攻破技术堡垒 从动物保护、环境保护的最初理想&#xff0c;到兽医学专业领域深耕&#xff0c;天津瑞派长江宠物医院的唐玉洁医生正用自己的实际行动展现着当代兽医人才背后的奉献、良知、超越与传承。 享受了东北林业大学带来的短暂而有趣的大学生活&…

聊聊RNN与Attention

前言 Attention Mechanism&#xff0c;称为注意力机制。基于Attention机制&#xff0c;seq2seq可以像我们人类一样&#xff0c;将“注意力”集中在必要的信息上。 Attention的结构 seq2seq存在的问题 seq2seq中使用编码器对时序数据进行编码&#xff0c;然后将编码信息传递…

JS:JavaScript 简介

前言 在当今数字时代&#xff0c;JavaScript已然成为了现代Web开发的基石。从最初作为浏览器中的一个小型脚本语言&#xff0c;到如今成为驱动全球互联网的强大引擎&#xff0c;JavaScript的发展历程本身就是一个令人着迷的故事。 好了开始学习JS吧 1. 如果刚开始了解js&#…

Node.js自动化处理TOML文件

在软件开发过程中&#xff0c;自动化处理配置文件是一种常见的需求。TOML&#xff08;Tom’s Obvious, Minimal Language&#xff09;是一种用于配置文件的简单易读的格式。本文将展示如何使用Node.js和一些流行的库来自动化读取、修改并写入TOML文件。 1. 准备工作 在开始之前…

IAR工程设置

这篇记录一下工作中对IARide的工程设置的配置步骤。 所以这不是一篇通用的文章&#xff0c;只是个人记录。 目的&#xff1a;为了是ARM仿真器能够下载调试锐能微的芯片 一、工程设置 1、更改boot文件的工程设置&#xff1a; 2、编译boot文件 3、配置8213B的工程设置&#x…

iPhone 16 Pro Max电池大揭秘,听说迎来了有史以来最持久的续航

智能手机市场的竞争日益激烈&#xff0c;各大厂商都在寻求创新以保持领先地位。而苹果公司即将推出的iPhone 16 Pro Max&#xff0c;则以其革命性的不锈钢电池壳和电诱导粘合剂脱离技术&#xff0c;再次刷新了我们对智能手机电池技术的认知。 一、不锈钢电池壳的突破 苹果公司…

Windows系统编程API 学习之路

目录 I. 基础 进程 动态链接库 线程 Windows应用程序开发 初入Windows编程 使用strings C/C运行时中的字符串 安全字符串函数 32位与64位开发 定义自定义错误代码 I. 基础 Windows NT操作系统系列有着悠久的历史&#xff0c;从1993年推出的3.1版本开始。今天的Windo…

如何主持收集故事研讨会

如何主持收集故事研讨会 引言 在文化的长河中,故事是传承知识、情感与智慧的桥梁。收集故事不仅是对过去的回顾,更是对未来灵感的启迪。组织一场收集故事研讨会,旨在汇聚各界人士,共同挖掘、整理并分享那些触动人心、富有意义的故事。作为这样一场活动的主持人,您的角色…

C++开源界面库duilib的使用细节与实战技巧总结(实战经验分享)

目录 1、使用CEditUI编辑框 2、使用CLabelUI或CTextUI的Html文本效果 3、使用CTextUI控件对文字宽度自适应的特性 4、CRichEditUI富文本控件使用注意点 4.1、指定CRichEditUI加在2.0版本的Riched20.dll库 4.2、解决向CRichEditUI中插入文字后显示空白的问题 5、设置窗口…

拓扑排序+dp(消除主观臆断)

这题一开始写错的原因就是搞错了&#xff0c;处于西边的节点的编号不一定小&#xff0c;不能直接dp&#xff0c;要先进行拓扑排序 写到一般我才发现&#xff0c;其实可以一边dp&#xff0c;一边进行dp #define _CRT_SECURE_NO_WARNINGS #include<bits/stdc.h> using name…

信息安全工程师下午题

试题一(共 20 分) 阅读下列说明和图&#xff0c;回答问题 1 至问题 5&#xff0c;将解答填入答题纸的对应栏内。【说明】已知某公司网络环境结构主要由三个部分组成&#xff0c;分别是 DMZ 区、内网办公区和生产区&#xff0c;其拓扑结构如图 1-1 所示。信息安全部的王工正在按…

无人机像素经纬度识别

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

代码随想录——组合总和 Ⅳ(Leetcode377)

题目链接 动态规划 class Solution {public int combinationSum4(int[] nums, int target) {int[] dp new int[target 1];dp[0] 1;for(int i 0; i < target; i){for(int j 0; j < nums.length; j){if(i > nums[j]){dp[i] dp[i - nums[j]];} }}return dp[targ…

【原创】java+ssm+mysql医生信息管理系统设计与实现

个人主页&#xff1a;程序员杨工 个人简介&#xff1a;从事软件开发多年&#xff0c;前后端均有涉猎&#xff0c;具有丰富的开发经验 博客内容&#xff1a;全栈开发&#xff0c;分享Java、Python、Php、小程序、前后端、数据库经验和实战 开发背景&#xff1a; 随着信息技术的…

【Golang 面试 - 基础题】每日 5 题(七)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…

ajax请求成功但不执行success-function回调函数

目录 一、问题分析 二、处理问题 一、问题分析 在测试员工管理系统的登录和注册代码时&#xff0c;登录一切正常&#xff0c;就是注册成功后没有跳转页面&#xff0c;后面发现是success-function回调函数没有正常执行。原因主要是前端和后端交流的数据格式不一致&#xff0c;…

GNSS位移监测站:毫米级位移监测

推荐型号&#xff1a;TH-WY1】GNSS位移监测站是一种利用全球导航卫星系统&#xff08;GNSS&#xff09;进行高精度位移监测的设备。这些系统能够实现毫米级甚至亚毫米级的位移监测&#xff0c;广泛应用于大坝安全监测、桥梁健康检测、滑坡预警等领域。以下是GNSS位移监测站的主…

电力红外热成像手持终端是什么?有什么作用?

电力红外热成像手持终端&#xff0c;即手持红外热成像仪&#xff0c;在电力行业中扮演着重要角色。这种设备利用红外辐射技术实时捕捉物体&#xff08;特别是电力设备&#xff09;表面的热能分布&#xff0c;并将其转化为可视化的热像图&#xff0c;从而帮助用户进行非接触式的…