C++ Easyx 三子棋

目录

思路

框架​编辑

读取操作

数据操作

绘制画面

游戏的数据结构

用二维数组来模拟棋盘格

        赢的情况

        平局情况

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)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【bat】批处理脚本大全

目录 1.概述 2.变量 3.运算符 3.2.重定向运算符 3.3.多命名运算符 3.4.管道运算符 4.命令 4.1.基本命令 4.2.参数传递 4.3.查看脚本内容 4.4.注释 4.5.日期和时间 4.6.启动脚本 4.7.调用其他bat 4.8.任务管理 4.8.1.任务列表查看 4.8.2.任务终止 4.9.文件夹 …

免费最新6款热门SEO优化排名工具

网站的存在感对于业务和品牌的成功至关重要。在众多网站推广方法中&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;是提高网站可见性的关键。而SEO的核心之一就是关键词排名。为了更好地帮助您优化网站。 SEO关键词排名工具 在如今信息过载的互联网时代&#xff0c;用户…

CRM在设备制造行业的应用,优化资源配置

设备制造业竞争激烈&#xff0c;公司要以客户为中心&#xff0c;搞好售后服务。CRM管理软件是设备制造业客户关系管理的重要工具。以下是CRM在设备制造业里的典型应用。 1.营销管理 制订市场策略&#xff1a;设备制造通常涉及较长的决策周期和销售周期。客户可能会在多家供货商…

创意项目开源,文生图、排序/优选等...,持续开源更新!!

热烈欢迎大家在git上star&#xff01;&#xff01;&#xff01;冲鸭&#xff01;&#xff01;&#xff01; 1.dalle1在厨房家具中文场景上训练。 GitHub - leeguandong/DALLE1: dalle1在中文家具场景的微调&#xff0c;效果并不好dalle1在中文家具场景的微调&#xff0c;效果…

vite脚手架,手写实现配置动态生成路由

参考文档 vite的glob-import vue路由配置基本都是重复的代码&#xff0c;每次都写一遍挺难受&#xff0c;加个页面就带配置下路由 那就利用 vite 的 文件系统处理啊 先看实现效果 1. 考虑怎么约定路由&#xff0c;即一个文件夹下&#xff0c;又有组件&#xff0c;又有页面&am…

2 文本分类入门:TextCNN

论文链接&#xff1a;https://arxiv.org/pdf/1408.5882.pdf TextCNN 是一种用于文本分类的卷积神经网络模型。它在卷积神经网络的基础上进行了一些修改&#xff0c;以适应文本数据的特点。 TextCNN 的主要思想是使用一维卷积层来提取文本中的局部特征&#xff0c;并通过池化操…

拥抱变化,良心AI工具推荐

文章目录 &#x1f4a5; 简介&#x1f344; 工具介绍&#x1f353; 功能特点&#x1f957; 使用场景&#x1f389; 用户体验&#x1f9e9; 下载地址&#x1f36d; 总结 &#x1f4a5; 简介 我是一名资深程序员&#xff0c;但薪资缺对不起资深两个字&#xff0c;为了生存&#x…

【开源威胁情报挖掘3】开源威胁情报融合评价

基于开源信息平台的威胁情报挖掘综述 写在最前面5. 开源威胁情报关联分析5.1 开源威胁情报网络狩猎&#xff1a;技术、方法和最新研究应用实例和未来方向 5.2 开源威胁情报态势感知关键技术和方法应用实例和未来方向 5.3 开源威胁情报恶意检测关键技术和方法应用实例和未来方向…

系列十七、理解SpringBoot中的starter 自定义一个starter

一、概述 作为后端Java程序员&#xff0c;基本上公司的日常开发都是基于SpringBoot进行的&#xff0c;我们使用SpringBoot也是沉醉于它的各种各样的starter带给我们的便利&#xff0c;这些starter为我们带来了众多的自动化配置&#xff0c;通过这些自动化配置&#xff0c;我们可…

晨曦记账本:掌握技巧,轻松统计交通支出“

你是否曾经为了统计交通支出而烦恼&#xff1f;现在&#xff0c;我们为你推荐晨曦记账本&#xff0c;让你轻松掌握技巧&#xff0c;快速统计上个月交通支出。 首先第一步&#xff0c;我们要进入晨曦记账本并在上方功能栏里选择“查看方式”。并在弹出来的列表里选择“所有记录…

教你5步学会用Llama2:我见过最简单的大模型教学

在这篇博客中&#xff0c;Meta 探讨了使用 Llama 2 的五个步骤&#xff0c;以便使用者在自己的项目中充分利用 Llama 2 的优势。同时详细介绍 Llama 2 的关键概念、设置方法、可用资源&#xff0c;并提供一步步设置和运行 Llama 2 的流程。 Meta 开源的 Llama 2 包括模型权重和…

力扣每日一题day24[150. 逆波兰表达式求值]

给你一个字符串数组 tokens &#xff0c;表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意&#xff1a; 有效的算符为 、-、* 和 / 。每个操作数&#xff08;运算对象&#xff09;都可以是一个整数或者另一个表达式。两个…

oracle sql相关语法

SQL*PLUS 在SQL*PLUS执行&#xff0c;会在执行后显示查询的执行计划和统计信息 SET AUTOTRACE ON;SELECT * FROM your_table WHERE column_name value;SET AUTOTRACE OFF;PLSQL PLSQL查询sql界面&#xff0c;鼠标右键&#xff0c;点击执行计划&#xff0c;会出现sql的执行计…

非功能关键知识总结(一)

文章目录 一、稳定性(一)、服务级别协议1、SLA2、OLA3、UC (二)、可用性指标(三)、突发事件等级 三、质量(一)、千行代码缺陷数量(二)、软件质量模型的发展(三)、产品质量模型 四、安全(一)、网络安全 五、灾备(一)、灾备指标(二)、灾难恢复等级(三)、容灾技术分类 一、稳定性 …

V8引擎类型转换(VIP课程)

这一章是源于一道面试题 完成以下条件并且输出console if(a 1 && a 2 && a 3) {console.log(true) }好家伙 乍一看一个变量怎么可能等于三个值&#xff1f;带着疑问我们去深入了解 类型系统 在JavaScript中类型系统不同于别的语言&#xff0c;例如JavaSc…

【1】基于多设计模式下的同步异步日志系统-项目介绍

1. 项目介绍 本项⽬主要实现⼀个日志系统&#xff0c; 其主要支持以下功能: • 支持多级别日志消息 • 支持同步日志和异步日志 • 支持可靠写⼊日志到控制台、文件以及滚动文件中 • 支持多线程程序并发写日志 • 支持扩展不同的日志落地⽬标地 2. 开发环境 • CentOS 7 • vs…

免费网站快速收录工具,2023最新网站收录方法

在当今数字化时代&#xff0c;拥有一个被搜索引擎快速收录的网站对于个人、企业或机构而言至关重要。网站的快速收录意味着更广泛的曝光和更多的访问流量&#xff0c;这对于网络存在的任何实体都是非常有价值的。 网站快速收录的重要性 在庞大的互联网世界中&#xff0c;一切…

汇编学习记录

前言 这篇文章是自己在专升本录取~本科开学前学习记录&#xff0c;破解软件的学习在2022年4月 - 2022年5月&#xff0c;汇编学习时间大约为2022年7月 - 2022年9月&#xff0c;我将往期上传的博文整理为一篇文章&#xff0c;作为归纳总结。 以后若继续学习相关领域&#xff0c;此…

003、应用程序框架-UIAbility

之——UIAbility 目录 之——UIAbility 杂谈 正文 1.UIAbility 2.基本使用 2.1 创建Ability工程 2.2 添加基础功能 2.3 新建页面 2.4 页面间的跳转 3.生命周期 总结 杂谈 UIAbility&#xff0c;其中的页面创建、页面间的跳转、数据传递、生命周期。 正文 1.UIAbil…

【Android】MMKV实现本地持久化

引入 (测试操作机器是华为Mate 20 Pro 128G&#xff0c;Android 10&#xff0c;每组重复1k次&#xff0c;时间单位是ms) 可以看出MMKV的耗时比其他耗时少的离谱。再看多进程下的性能&#xff1a; 不必多说。再看和DataStore的对比&#xff1a; 简介 根据MMKV官方文档所言 MM…