C++ Easyx 三子棋

news2025/1/19 16:55:38

目录

思路

框架​编辑

读取操作

数据操作

绘制画面

游戏的数据结构

用二维数组来模拟棋盘格

        赢的情况

        平局情况

Code

代码细节部分

  (1)初始化棋盘格

  (2) 初始化棋子类型​编辑

        事件处理部分 

             落子

框架内代码的完善

      数据处理框架代码的完善

检查是否赢了 (函数)

         绘制图形框架代码的完善

绘制棋盘网格(函数)

绘制棋子 (函数)

绘制提示信息  (函数)

DBUG

优化

代码托管

三子棋/Test.cpp · 孙鹏宇/孙鹏宇的第一个仓库 - 码云 - 开源中国 (gitee.com)


思路

我们遵循先框架,后思路得的思路

框架

首先是读取操作:

读取操作

读取鼠标单击之后的信息

接下来是数据操作:

数据操作

我们只需要对游戏胜负进行判断

胜的清空:一条线三颗棋子都一样

平的情况:棋格全部填满还未分出胜负。

游戏结束时使用弹出告诉玩家游戏结果,然后退出主循环。

绘制画面

我们使用line函数绘制一个3*3的棋盘格:

x玩家时使用line函数对角线画两个线,轮到O玩家落子时时使用cirlce函数画个圆:

游戏的数据结构

用二维数组来模拟棋盘格

棋盘内容为字符串,初始化为‘-'

赢的情况

我们对赢得情况进行穷举:

一共有八种

平局情况

如果9个网格均被棋子填满却没有获胜的一方,那么就是平局:

Code

写代码同样遵循先框架再细节的原则:

我们先把上面的内容转化为代码:

框架:

#include<easyx.h>
#include<iostream>
using namespace std;
	//处理数据
	// 
	//检测玩家是否赢了
bool Checkwin(char str)
{

}
//检测是否平局
bool Checkavg(char str)
{

}

//绘制图像
// 
//绘制棋盘格
void DrawBorad()
{

}
//绘制棋子
void DrawPiece()
{

}
//绘制提示信息
void DrawTipText()
{

}
int main()
{
	initgraph(60,600);//绘制窗口

	bool flag = true;//退出主循环的标识列
	ExMessage msg;//存储消息
	BeginBatchDraw();//渲染缓冲区
	//主循环
	while (flag)
	{
		//读取操作
		while(peekmessage(&msg))//读取消息
		{
			//读取到的细节如何处理稍息再说
		}
		cleardevice();//清屏
       
        //重新绘图
		DrawBorad();
		DrawPiece();
		DrawTipText();

		FlushBatchDraw();//刷新缓冲区
	}
	EndBatchDraw();//刷新缓冲区
	return 0;
}

代码细节部分

如果 x玩家赢了,我们可以用MessageBox()函数弹出了一个框,显示x玩家赢了:

代码如下:

 同样的,O玩家获胜的情况和平局的情况也写一下:

设置两个全局

(1)初始化棋盘格

(2) 初始化棋子类型

事件处理部分 

用msg来表示鼠标的位置:

 怎么把鼠标的位置映射到数组下标呢?我们绘制的棋盘格的大小为600x600,分成三等份之后每个格子的大小为200x200:

 所以我们求横坐标可以有这样一个公式:代码为:

落子

(1)首先判断是否可以落子

  (2)  落完子之后要切换下次落子的棋子类型

框架内代码的完善

把之前只写了框架没写实现的函数补全:

数据处理框架代码的完善

检查是否赢了 (函数)

按照我们之前列的八种赢的情况写:

Checkavg()函数

用两个for循环来遍历棋盘格中每一个元素,如果还有空格没有落子就返回false代表没有平局,最后如果没有返回false说明平局了,返回true:

绘制图形框架代码的完善

绘制棋盘网格(函数)

棋盘格的网格其实就是四条线:

我们可以通过图形绘制相关函数->line()函数来绘制:

首先棋盘格总大小是600x600,每个小格子是200x200:

绘制棋子 (函数)

(1)绘制棋子,首先用二维数组遍历一下棋盘,如果要落的棋子是'O',那就在棋格中间画圆。

(2)棋盘中心的求法:一个小格子长宽200x200,中心坐标为左上角坐标+100:

(3)画圆的方法:

 (4)当棋子为'x'时就按小格子对角线画两条线

 (5)对角线点求法:如下图(6)画对角线的方法:

(7)如果不是'O'或者',那就什么都不用做。

(8)代码:

绘制提示信息  (函数)

适用settextcolor()函数将提示文本设高亮:

outtextxy()函数用来在窗口指定位置输出提示信息:

 code:

DBUG

这样三子棋基本功能就做好了,但是有bug:

(1)闪退

(2)闪退过程中可以看见我们画的棋盘,发现棋盘网格线条错位:

原因:

(1)绘制棋盘时手误

 (2)闪退的原因是我们在判断是否平局用的else,没设条件,此刻没输值就直接平局了(只要不是'O',‘x’就直接平局了),这显示不是我们要的,我们想要的是棋盘满了还没赢才平局,因此我们应该引用checkagv()函数。

修改:

修改完之后运行:

发现有两个错误

(1)鼠标左键不用点击,就可以落子

(2)落子位置和我们鼠标落点位置不配置

鼠标左键不用点击,就可以落子的原因:

应该选择ExMessage的WM_LBUTTONDOWN表实列,我选成第一个了:

 落子位置不配置的原因:

(1)切换棋子类型应该包含在可以落子的前提下,如果不能落子也就没必要切换棋子类型了:

修改之后:

(2)

二维数组是按照横纵坐标系的:

 但是我们的窗口确是纵横坐标系:

 错误:

修改:

交互功能正常,但是渲染功能有问题,最后一颗棋子不会显示:

 原因:

我们把重新绘图放在判断胜负的后面,当玩家赢了的时候会执行flag=fale,此时会执行重新绘图。

当再次循环时,flag因为false,所以退出循环。也就是绘图只执行了一次,一闪而过。

 我们把绘图放到胜负判断之前,这样即便是不再进入循环,也是最后一次落子的下一次绘图不会显示,而最后一次落子的绘图会显示在当前窗口。

 正常运行:

优化

当我们的程序跑起来之后,查看任务管理器,发现我们的程序消耗内存空间特别大;

这是因为计算机在执行while循环时特别快,我们编写的主循环在顷刻间已经被执行了成千上万次。

因此,为了不避免的销毁,我们可以使用sleep()函数使循环休眠几毫秒。

我们可以在主循环开头写一个开始数获取GetTickCount(),主循环结束位置写一个结尾数获取GetTickCount()函数。 

通过计算 二者落差  可以得到  该主循环实际运行所需要的 毫秒数,简称实需数。

如果我们想在60帧率下刷新,那么就让1000/60=16,16为我们的期望值。

如果   实需数  < 期望值,说明不用休眠。

否则,实需数-期望值= 休眠数。

代码托管

三子棋/Test.cpp · 孙鹏宇/孙鹏宇的第一个仓库 - 码云 - 开源中国 (gitee.com)

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

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

相关文章

如何调用 API | 学习笔记

开发者学堂课程【阿里云 API 网关使用教程:如何调用 API】学习笔记&#xff0c;与课程紧密联系&#xff0c;让用户快速学习知识。 课程地址&#xff1a;阿里云登录 - 欢迎登录阿里云&#xff0c;安全稳定的云计算服务平台 如何调用 API 调用 API 的三要素 要调用 API 需要三…

Nginx 具体应用

1 Nginx 1.1 介绍 一款轻量级的 Web 服务器/反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器。它占有的内存少&#xff0c;并发能力强&#xff0c;中国大陆使用 nginx 的网站有&#xff1a;百度、京东、新浪、网易、腾讯、淘宝等。第一个公开版本发布于…

1.1卷积的作用

上图解释了1∗1卷积如何适用于尺寸为H∗W∗D的输入层&#xff0c;滤波器大小为1∗1∗D&#xff0c;输出通道的尺寸为H∗W∗1。如果应用n个这样的滤波器&#xff0c;然后组合在一起&#xff0c;得到的输出层大小为H∗W∗n。 1.1∗1卷积的作用 调节通道数 由于 11 卷积并不会改…

【vue】vue-slick-carousel插件,实现横向滚动列表手动左右滚动(也可设置为自动滚动)

需求&#xff1a;图片列表横向滚动的时候&#xff0c;隐藏原始滚动条&#xff0c;通过左右箭头控制滚动条往左右按一定的步长移动。 el-carousel走马灯一滚动就是一屏&#xff0c;不适合我的需求 在npm官网搜vue-slick-carousel&#xff0c;查看更详细的配置 vue-slick-caro…

matlab 路面裂缝检测识别系统设计GUI

1、内容简介 略 23-可以交流、咨询、答疑 2、内容说明 路面裂缝检测识别系统设计GUI 基于matlab的GUI设计路面裂缝检测识别系统 matlab、GUI、直方图、裂缝检测、二值化 3、仿真分析 4、参考论文 略 链接&#xff1a;https://pan.baidu.com/s/1AAJ_SlHseYpa5HAwMJlk…

十五届海峡两岸电视主持新秀大会竞赛流程

海峡两岸电视主持新秀会是两岸电视媒体共同举办的一项活动&#xff0c;旨在为两岸年轻的电视主持人提供一个展示才华的舞台&#xff0c;促进两岸文化交流和青年交流。本届新秀会是第十二届海峡两岸电视艺术节的重要活动之一。本次竞赛赛制流程如下&#xff1a; &#xff08;1&…

遥感方向期刊总结

开眼看期刊~ 期刊分区信息搜索网址中国科学院文献情报中心期刊分区表升级版科研通期刊查询&#xff1a; 遥感领域常见期刊Nature CommunicationsRemote Sensing of EnvironmentProceedings of the National Academy of Sciences &#xff08;PNAS&#xff09;ISPRS Journal of …

SHAP(六):使用 XGBoost 和 HyperOpt 进行信用卡欺诈检测

SHAP&#xff08;六&#xff09;&#xff1a;使用 XGBoost 和 HyperOpt 进行信用卡欺诈检测 本笔记本介绍了 XGBoost Classifier 在金融行业中的实现&#xff0c;特别是在信用卡欺诈检测方面。 构建 XGBoost 分类器后&#xff0c;它将使用 HyperOpt 库&#xff08;sklearn 的 …

Mybatis 的操作(要结合上个博客一起)续集

Mybatis 是一款优秀的 持久性 框架,用于简化 JDBC 的开发 持久层 : 指的就是持久化操作的层,通常指数据访问层(dao),是用来操作数据库的 简单来说 Mybatis 是更简单完成程序和数据库交互的框架 Mybatis 的写法有两种 : 1.xml 2.注解 这两者各有利弊,后面进行总结 Mybati…

使用Java语言实现变量互换

一、 java运算 通过异或运算符实现两个变量的互换 import java.util.Scanner;public class ExchangeValueDemo {public static void main(String[] args){try (Scanner scan new Scanner(System.in)) {System.out.println("请输入A的值&#xff1a;");long A sca…

Kafka 的特点和优势

Apache Kafka 作为一款分布式流处理平台&#xff0c;以其独特的特点和卓越的优势成为实时数据处理领域的瑰宝。本文将深入研究 Kafka 的各项特点和优势&#xff0c;并通过详实的示例代码展示其在不同场景下的强大应用。 高吞吐量和水平扩展 Kafka 的设计注重高吞吐量和水平扩…

9-4 函数输入信息,函数输出信息

#include<stdio.h>struct student{char name[10];int num;char score[3]; }stu[5]; //结构体输入信息int main(){void input(struct student stu[]);void print(struct student stu[]);input(stu);print(stu);return 0; }void input(struct student stu[5]) { int i,j;fo…

JVM虚拟机:JVM参数之标配参数

本文重点 本文我们将学习JVM中的标配参数 标配参数 从jdk刚开始就有的参数&#xff0c;比如&#xff1a; -version -help -showversion

万界星空科技灯具行业MES介绍

中国是LED照明产品最大的生产制造国&#xff0c;如今&#xff0c;我国初步形成了包括LED外延片的生产、LED芯片的制备、LED芯片的封装以及LED产品应用在内的较为完超为产业链&#xff0c;随着LED照明市场渗诱率的快速警升&#xff0c;LED下游应用市场将会越来越广阔。这也将推动…

30、LCD1602

LCD1602介绍 LCD1602&#xff08;Liquid Crystal Display&#xff09;液晶显示屏是一种字符型液晶显示模块&#xff0c;可以显示ASCII码的标准字符和其它的一些内置特殊字符&#xff0c;还可以有8个自定义字符 显示容量&#xff1a;162个字符&#xff0c;每个字符为5*7点阵 …

机器视觉最全面试题总结

文章目录 1. 为什么需要做特征归一化、标准化&#xff1f;2. 常用常用的归一化和标准化的方法有哪些&#xff1f;3. 介绍一下空洞卷积的原理和作用4. 怎么判断模型是否过拟合&#xff0c;有哪些防止过拟合的策略&#xff1f;5. 除了SGD和Adam之外&#xff0c;你还知道哪些优化算…

【Vulnhub 靶场】【Momentum: 2】【简单】【20210628】

1、环境介绍 靶场介绍&#xff1a;https://www.vulnhub.com/entry/momentum-2,702/ 靶场下载&#xff1a;https://download.vulnhub.com/momentum/Momentum2.ova 靶场难度&#xff1a;简单 发布日期&#xff1a;2021年06月28日 文件大小&#xff1a;698 MB 靶场作者&#xff1…

蓝桥杯每日一题2023.12.3

题目描述 1.移动距离 - 蓝桥云课 (lanqiao.cn) 题目分析 对于此题需要对行列的关系进行一定的探究&#xff0c;所求实际上为曼哈顿距离&#xff0c;只需要两个行列的绝对值想加即可&#xff0c;预处理使下标从0开始可以更加明确之间的关系&#xff0c;奇数行时这一行的数字需…

PointNet代码详解

PointNet代码详解 这里只看下分类网络 input transform class STN3d(nn.Module):def __init__(self):super(STN3d, self).__init__()self.conv1 torch.nn.Conv1d(3, 64, 1)self.conv2 torch.nn.Conv1d(64, 128, 1)self.conv3 torch.nn.Conv1d(128, 1024, 1)self.fc1 nn.L…

人工智能轨道交通行业周刊-第67期(2023.11.27-12.3)

本期关键词&#xff1a;列车巡检机器人、城轨智慧管控、制动梁、断路器、AICC大会、Qwen-72B 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通RailMetro…