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

news2024/11/15 20:37:48

首先我们先看一下一个传统的三子棋长什么样子,再来模仿

1bb8910e6fc143ec9d48f30bcbb3044c.png

其中里面有一个棋盘,并且有分隔符,那么开始你就得定义个二维数组,先初始化,放空格,然后打印出来看一下,注意右边界是没有竖杠分割,最后一层也是没有分割的,用个if判断即可。接着就是下棋,这里我们通过键盘输入,横坐标和纵坐标,因为我们所认为的(1,1)就是第一行第一个,而数组是从0开始的,因此,需要将我们从键盘中输入的再减去1。我们输入一次就得打印一次棋盘看一下,然后判断是否继续。基于以上工程量大,我们这里分成三个文件进行,这样看起来逻辑清晰,一个头文件"game.h",一个"game.c",一个"test.c"。

首先啊就是"game.h"用来写一些预处理的文件,以及自定义的声明,需要的头文件的声明

#pragma once
#define ROW 3
#define COL 3
#include<stdio.h>
#include<time.h>
#pragma warning(disable:4996)
void nenu();
void game();
void innitiaboard(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);
int iswin(char board[ROW][COL], int row, int col);
int isfull(char board[ROW][COL], int row, int col);

然后就是game.c,用来写自定义函数的具体代码

#include"game.h"
#pragma warning(disable:4996)
void nenu()
{
	printf("|----------------------|\n");
	printf("|        1.play        |\n");
	printf("|        0.exit        |\n");
	printf("|----------------------|\n");
	printf("请输入:>\n");
}
void innitiaboard(char board[ROW][COL],int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}
void displayboard(char board[ROW][COL], int  row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < row - 1)
				printf("|");
		}
		printf("\n");
		for (int 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, y;
	printf("玩家走:");
	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");
	}
}

void computermove(char board[ROW][COL], int row, int col)
{
	int x, y;
	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)
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			if (board[ROW][COL] == ' ');
			return 0;
		}
	}
	return 1;
}

int iswin(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < ROW; i++)
	{
		//行数
		if (board[i][0] == board[i][1] == board[i][2] && board[i][0] =='*')
			return '*';
	}
	//列
	for (int j = 0; j < COL; j++)
	{
		if (board[0][j] == board[1][j] == board[2][j] && board[0][j] =='#')
			return '#';
	}
	//对角线
	if (board[0][0] == 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 (isfull(board, row, col))
	{
		return 'Q';
	}
	return 'C';
}

最后就是test.c用来写游戏的主体代码

//总体的一个思路,先想清楚如何实现,先来一个大体的框架,
//如何就是先初始化棋盘,然后打印,然后玩家下棋,电脑下棋,每一次下棋注意判断
//谁赢谁输还是平局,所以一步步来实现
#include"game.h"
#pragma warning(disable:4996)
void game()
{
	
	char ret = 0;
	char board[ROW][COL];
	innitiaboard(board, ROW, COL);//初始化棋盘
	displayboard(board, ROW, COL);//打印初始棋盘
	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");
}

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

这样使得代码更具可读性和整洁,

首先我们用do while 循环进行一局游戏,将input 的值作为while判断条件,输入1开始游戏,0则退出游戏,退出循环。如果进入游戏那么先定义一个二维数组用来存放棋盘,赋值为空格,当玩家和电脑走的时候将其赋值为字符即可。代码中还有很多的细节,感兴趣的可以朋友可以拷贝研究一下。

 

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

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

相关文章

【C/PTA —— 10.函数1(课外实践)】

C/PTA —— 10.函数1&#xff08;课外实践&#xff09; 一.函数题6-1 符号函数6-2 求排列数6-3 求一个大于10的n位整数w的后n-1位的数&#xff0c;并作为函数值返回。6-4 其右上三角&#xff08;含主对角线&#xff09;元素之和。6-5 字符串比较6-6 使用函数求素数和6-7 使用函…

@RequestMapping

目录 作用&#xff1a; 位置&#xff1a; 属性 1.value 2.method 3.params 4.header 作用&#xff1a; 该注解是一个用来处理请求地址映射的注解。 位置&#xff1a; 可用于映射一个请求或一个方法&#xff0c;可以用在类或方法上。 用于方法上&#xff0c;表示在类的…

N皇后问题解的个数

暴力递归 #include <stdio.h>int count0,a[15],flag; void queen(int,int); int main(){int n;scanf("%d",&n);queen(n,n);printf("%d",count); } void queen(int n,int n0){if(n<1){flag1;for(int i1;i<n0;i){for(int j1;j<n0;j){if(…

搜索引擎语法

演示自定的Google hacking语法&#xff0c;解释含意以及在渗透过程中的作用 Google hacking site&#xff1a;限制搜索范围为某一网站&#xff0c;例如&#xff1a;site:baidu.com &#xff0c;可以搜索baidu.com 的一些子域名。 inurl&#xff1a;限制关键字出现在网址的某…

Java对象逃逸

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 未经允许不得转载 目录 一、导读二、概览三、相关知识3.1 逃逸…

C# 时间计算(一)

目录 一、概述 二、时间的基本用法 1.实例化 DateTime 2.获取当前的时间 3.获取当前时间的时分秒 三、格式化时间 1.将时间转换为特定字符串 1&#xff09;拼接字符串方式 2&#xff09;格式化字符串方式 2.将字符串转换为时间 1&#xff09;DateTime.Parse 2&…

微服务测试怎么做,看看这篇文章就懂了!

开发团队越来越多地选择微服务架构而不是单体结构&#xff0c;以提高应用程序的敏捷性、可扩展性和可维护性。随着决定切换到模块化软件架构——其中每个服务都是一个独立的单元&#xff0c;具有自己的逻辑和数据库&#xff0c;通过 API 与其他单元通信——需要新的测试策略和新…

【Apache Doris】一键实现万表MySQL整库同步 | 快速体验

【Apache Doris】一键实现万表MySQL整库同步 | 快速体验&#xff09; 一、 环境信息1.1 硬件信息1.2 软件信息 二、 流程介绍三、 前提概要3.1 安装部署3.2 JAR包准备3.2.1 数据源3.2.2 目标源 3.3 脚本模版 四、快速体验五、常见问题5.1 Mysql通信异常5.2 MySQL无Key同步异常5…

PC分页操作以及loading效果

page-size 每页显示条目个数 current-page 当前页数 total 数据总数 current-change【currentPage 改变时会触发】 切换分页时会先加载&#xff0c;等在接口数据&#xff0c;接口返回&#xff0c;加载会关闭&#xff08;在获取接口数据完毕哪里加上this.loadingfalse&#xff0…

多模态——使用stable-video-diffusion将图片生成视频

多模态——使用stable-video-diffusion将图片生成视频 0. 内容简介1. 运行环境2. 模型下载3. 代码梳理3.1 修改yaml文件中的svd路径3.2 修改DeepFloyDataFiltering的vit路径3.3 修改open_clip的clip路径3.4 代码总体结构 4. 资源消耗5. 效果预览 0. 内容简介 近期&#xff0c;…

ArkTS-自定义组件学习

文章目录 创建自定义组件页面和自定义组件生命周期自定义组件和页面的区别页面生命周期(即被Entry修饰的组件)组件生命周期(即被Component修饰的组件) Builder装饰器&#xff1a;自定义构建函数按引用传递参数按值传递参数 BuilderParam装饰器&#xff1a;引用Builder函数 这个…

Leetcode刷题笔记题解(C++):1008. 前序遍历构造二叉搜索树

思路&#xff1a; 1.树中的第一个值为根&#xff08;数组的第一个值&#xff09;&#xff0c;小于根的值存放在左子树中&#xff0c;大于根的值存放在右子树中&#xff1b; 2.利用递归对左右子树 /*** Definition for a binary tree node.* struct TreeNode {* int val;*…

msvcp71.dll,msvcr71.dll丢失怎么办?教你如何快速解决此问题

msvcp71.dll是Microsoft Visual C 2003运行库中的一个组件&#xff0c;它是Microsoft Visual C 2003编译的程序在运行时所需要的动态链接库文件。它包含了许多C标准库函数的实现&#xff0c;如字符串处理、数学计算等。当程序运行时&#xff0c;如果缺少这个文件&#xff0c;就…

python实现存款日利息计算器(窗口界面形式)

输入存款金额&#xff0c;7日年化收益率&#xff0c;输出每日利息 完整源码如下&#xff1a; import tkinter as tk from tkinter import messageboxdef calculate_interest():deposit float(entry_deposit.get())interest_rate float(entry_interest_rate.get())daily_int…

初始linux:文件操作

目录 提示&#xff1a;以下指令均在Xshell 7 中进行 linux的理念 一、echo echo "字符串" 二、输出重定向 > > [文件] echo "字符串" > [文件] echo "字符串" > > [文件] 制作大文件 三、< 输入重定向与ca…

HEADER请求头都有哪些,作用是什么?

HTTP 请求头是在客户端向服务器发送 HTTP 请求时&#xff0c;包含有关请求的附加信息的部分。以下是一些常见的 HTTP 请求头及其作用&#xff1a; Accept&#xff1a; 作用&#xff1a; 客户端通知服务器可以接受哪些媒体类型&#xff08;如 text/html、application/json&…

Linux:Ubuntu实现远程登陆

1、查看sshd服务是否存在 Ubuntu默认是没有安装sshd服务的&#xff0c;所以&#xff0c;无法远程登陆。 检查22端口是否存在 netstat -anp 该命令执行后&#xff0c;查看不到22端口的进程。 如果netstat无法使用&#xff0c;我们需要安装一下netstat服务 sudo apt-get install…

【电路笔记】-分压器

分压器 文章目录 分压器1、概述2、负载分压器3、分压器网络4、无功分压器4.1 电容分压器4.2 感应分压器 5、总结 有时&#xff0c;需要精确的电压值作为参考&#xff0c;或者仅在需要较少功率的电路的特定阶段之前需要。 分压器是解决此问题的一个简单方法&#xff0c;因为它们…

001、First_blood-Hello World

之——start 目录 之——start 杂谈 正文 1.内容 2.DevEco Studio 3.运行hello world 4.微调 5.工程目录 总结 杂谈 开启学习之旅&#xff0c;记录学习点滴。应用开发基础知识&#xff0c;新版本新技术新特征&#xff0c;十分友好&#xff0c;十分期待。另外有&#…

UML建模图文详解教程07——活动图

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl本文参考资料&#xff1a;《UML面向对象分析、建模与设计&#xff08;第2版&#xff09;》吕云翔&#xff0c;赵天宇 著 活动图概述 活动图(activity diagram)是 UML中一种重…