C++、easyx组合的五子棋界面版(适合新手)

点击进入五子棋控制台版本

文章目录

  • C++、easyx组合的五子棋界面版(适合新手)
  • 前言
  • 效果图
  • 一、游戏规则
  • 二、实现逻辑
    • 1.绘制棋盘
    • 2.落子
      • 2.1 鼠标坐标的获取
      • 2.2 绘制棋子
  • 三、输赢判定算法
  • 四、其他小细节
    • 1.音效
    • 2.悔棋
  • 源代码以及素材

前言

贴主大概什么水平呢?目前大二,C++学完了STL(会用函数)、数据结构、C++ primer看了一半。大概就这样的水平2333。相信大部分人跟我一样,对于C++很迷茫,我们不像Java,调个自带GUI就可以实现界面了,我们需要调用第三方库。C++图形库有很多,这里以easyx为例,讲解一下如何实现五子棋界面版。


效果图

一、游戏规则

哈哈哈哈很简单呀,五个字相连,就可以判定谁赢谁输了√
1.黑棋先
2.五子相连,游戏结束。
3.相较于控制台版本 新增了悔棋功能。

二、实现逻辑

接下来就跟着我的思路一起来学习一下如何写这样一个程序叭!

1.绘制棋盘

控制台版本我们是严格计算过之后,通过cout竖线和横线来完成棋盘绘制的。
那么在图形版本里面,我们easyx提供了相应的绘图函数。
通过翻阅easyx官网的帮助文档:绘图方法
我们可以用一下代码实现:

void draw_chessboard()
{                               setlinecolor(BLACK);for (int i = 0; i < MAX; i++){line(1 + i * unit, 1, 1 + i * unit, unit * (MAX - 1));line(1, 1 + i * unit, unit * (MAX - 1), 1 + i * unit);}}

先将线设定为黑色,随后调用line函数绘制桌面。其中MAX是线条数,unit是单元格的宽度。

2.落子

2.1 鼠标坐标的获取

控制台版本是通过手动输入坐标来实现落子的,那么界面版则有点复杂了。
我们需要调用easyx里面的鼠标方法。详见帮助文档:鼠标方法
这里稍微讲一下,通过调用easyx里面的鼠标类,我们就可以获取到鼠标当前位置的横纵坐标:
我们来看官方文档的示例程序:

// 编译环境:Visual C++ 6.0,EasyX 20190314(beta)
// http://www.easyx.cn
//
#include <graphics.h>
#include <conio.h>int main()
{// 初始化图形窗口initgraph(640, 480);MOUSEMSG m;      // 定义鼠标消息while(true){// 获取一条鼠标消息m = GetMouseMsg();switch(m.uMsg){case WM_MOUSEMOVE:// 鼠标移动的时候画红色的小点putpixel(m.x, m.y, RED);break;case WM_LBUTTONDOWN:// 如果点左键的同时按下了 Ctrl 键if (m.mkCtrl)// 画一个大方块rectangle(m.x-10, m.y-10, m.x+10, m.y+10);else// 画一个小方块rectangle(m.x-5, m.y-5, m.x+5, m.y+5);break;case WM_RBUTTONUP:return 0; // 按鼠标右键退出程序}}// 关闭图形窗口closegraph();
}

我们清晰的知道:m.x和m.y就是鼠标当前位置的横纵坐标
switch负责判断鼠标当前状态,是按下,还是按下弹起等等。
知道原理后,我们就可以这样写:

MOUSEMSG m;                      // 鼠标类 从easyx.h里面调用
m = GetMouseMsg();switch (m.uMsg){case WM_LBUTTONDOWN:cout<<m.x << " " << endl;//随便举个例子    break;}

2.2 绘制棋子

知道如何去获取鼠标坐标后,我们就可以手动添加其他响应事件了
我们首先要做的就是:鼠标按下之后,我们要在当前位置绘制一个棋子,对吧。
上代码:

         switch (m.uMsg){case WM_LBUTTONDOWN:x_sim = (int)((double)m.x / unit + 0.5);y_sim = (int)((double)m.y / unit + 0.5);//cout << x_sim << " " << y_sim << endl;          // 用于看坐标用if (chess_pos[y_sim][x_sim] == ' ' && y_sim >= 0 && y_sim < MAX && x_sim >= 0 && x_sim < MAX){chess_pos[y_sim][x_sim] = 'b';fillcircle(x_sim * unit, y_sim * unit, chess_r);step++;}break;}

这里就有人有疑问了:我明明已经从鼠标类里面获取到横纵坐标的位置了,为什么还要搞个x_sim呢?
首先,我们落子,是不是必须要落到棋盘的十字点上?对吧,我们不能哪里都下棋,那不就乱套了。
所以这里通过小公式,计算出了当前坐标下,最近一个十字点的位置,并且提供了一个误差范围。
计算好落点后,我们还得判断一下。
1.当前点有没有下过棋子?也就是当前点对应的数组内是不是“ ”(空格)?
2.当前点是否在棋盘内
满足这两个条件后,我们就可以落子了。
将数组内的值替换成对应棋子的颜色“b”“w,然后绘制棋子。
这里依旧是easyx的绘制方法,详见文档。

三、输赢判定算法

到这里,基本上一个图形界面就成型了。
我们接下来要考虑游戏规则了。
如何判定胜利?
网上有很多好方法,甚至还有KMP的。
这里我用一个炒鸡炒鸡通俗易懂的方法来写如何判定输赢。
首先:赢的条件是,当前落点,其横纵坐标,以及两个斜方向上有包含它并且与它连续相同的五个棋子。
上代码:

int Judge(int x, int y)          // 五连子判断
{   //横向cnt = 0;for (int i = 0; i < MAX; i++){   if (chess_pos[x][i] == chess_pos[x][y]){for (int j = 1; j <= 4; j++){if (chess_pos[x][i + j] == chess_pos[x][y])cnt++;elsecnt = 0;}}if (cnt >= 4)return 1;}//纵向cnt = 0;for (int i = 0; i < MAX; i++){ if (chess_pos[i][y] == chess_pos[x][y]){for (int j = 1; j <= 4; j++){if (chess_pos[i+j][y] == chess_pos[x][y])cnt++;elsecnt = 0;}}if (cnt >= 4)return 1;}//左斜cnt = 0;next_x = x + 1;next_y = y - 1;while (next_x<MAX && next_y>-1 && chess_pos[next_x][next_y] == chess_pos[x][y]){next_x++;next_y--;cnt++; }next_x = x - 1;next_y = y + 1;while (next_x > -1 && next_y < MAX && chess_pos[next_x][next_y] == chess_pos[x][y]){next_x--;next_y++;cnt++; }if (cnt >= 4)return 1; //右斜cnt = 0;next_x = x - 1;next_y = y - 1;while (next_x > -1 && next_y > -1 && chess_pos[next_x][next_y] == chess_pos[x][y]){next_x--;next_y--;cnt++; }next_x = x + 1;next_y = y + 1;while (next_x < MAX && next_y < MAX && chess_pos[next_x][next_y] == chess_pos[x][y]){next_x++;next_y++;cnt++; }if (cnt >= 4)return 1; return 0;
}

对于横纵方向,我用for循环+计数来判定是否是五连子,代码很好懂。
对于斜方向,由于每个点的下一个点,其横坐标纵坐标都会变,所以套for就有点力不从心,于是,这里我用了while循环。对于确定次数的循环,我们用for,对于不确定的,我们用while。
需要说明的是,Judge函数的两个形参,分别是鼠标的m.y(x_sim)和m.x(y_sim)。
为什么会反过来?
因为我们数组的下标是xx行xx列,先行后列。
而easyx的绘图,是先列后行,是反过来的。
所以传进去参数的时候,需要更改一下顺序。

四、其他小细节

1.音效

C++放音乐有很多方法,这里用一种比较简单的playsound()方法。
头文件:

// 以下三个为PlaySound()函数的头文件 顺序不能错
#include <Windows.h>
#include <mmsystem.h>
#pragma comment(lib,"WINMM.LIB")

如何使用:

void music()                 // 下每一步棋的音效
{PlaySound(TEXT("chess.wav"), NULL, SND_FILENAME | SND_ASYNC);
}

如何使用详见其他博主的playsound详解。

2.悔棋

悔棋思路:
将上一步坐标对应的数组重新置为“ ”。
调用easyx的clearcircle()函数清除当前绘制的棋子。
代码:

     if (_kbhit()) {             // 当键盘按下R键 执行悔棋char input = _getch();if (input == 'r'){    step--;regret(x_sim,y_sim);}}
void regret(int x_sim,int y_sim)         // 悔棋函数
{                                           chess_pos[y_sim][x_sim] = ' ';                       // 如果悔棋 先将棋子坐标重置clearcircle(x_sim * unit, y_sim * unit, chess_r);   //再清除原来绘制的圆
}

值得一提的是,由于easyx的问题,清除绘图后,会出现这个情况:

大家可能会是其他颜色。
这是由于清除的时候直接把背景图案也给清除了,这个暂时想不到什么解决办法,有好方法的评论区可以留言。

源代码以及素材

代码和素材我放Github里面了,大家点击下载即可。

``

C++、easyx组合的界面版五子棋(适合新手)相关推荐

  1. python基础教程第二版和第三版哪个好-python基础教程 2版和3版哪个适合新手?!...

    python基础教程 2版和3版哪个适合新手? 现在学是学python3. 两者的差异发者本身影响并不大,个别语法细微的差比如python3的print数方式使用,一些常用模块的名称差异,一些机制的差 ...

  2. python基础教程第三版和第二版选哪个-python基础教程 2版和3版哪个适合新手?!...

    python基础教程 2版和3版哪个适合新手? 现在学是学python3. 两者的差异发者本身影响并不大,个别语法细微的差比如python3的print数方式使用,一些常用模块的名称差异,一些机制的差 ...

  3. 400行代码实现双人对战五子棋(适合新手入门)

    400行代码实现双人对战五子棋(适合新手入门) 跟上一篇博客一样,都是看了慕课网的视频之后写的学习记录,记录一下实现的思路,大部分内容比较简单,但也从中学到了很多东西. 按惯例首先看一下效果:(素材都 ...

  4. 高仿小米计算器界面UI 适合新手学习 [附源码]

    初学Android尝试着做一些布局,看到手机上的小米计算器界面简洁,适合新手尝试,于是做了一下,但是未实现逻辑,只是高仿界面. 小米计算器UI 高仿小米计算器UI 源码:https://downloa ...

  5. 适合新手的音乐制作软件有哪些,适合新手的音乐制作教程有哪些

    音乐是人们表达自身情感的一种方式,而听音乐更是我们生活中常见的事情.音乐表达的是我们的情感,这也就意味着我们其实也可以自己创作音乐.那么我们今天就来说一说适合新手的音乐制作软件有哪些以及适合新手的音乐 ...

  6. JAVA联机版五子棋——源码(一个类一个main暴力开发)

    第一次写博客,排版啥的都比较乱,大家不要嫌弃啊. 所谓暴力开发,其实是啥也不会,硬怼哈哈哈.只是刚学会一点JAVA编程,参考网络资源写了个联机版五子棋(支持单机),来这里记录一下学习过程,而且我也是靠 ...

  7. JAVA课设单人版五子棋小游戏

    内容介绍:该程序为Java课设的单人版五子棋小游戏,通过eclipse编辑,实现了动作事件的监听与处理,以及JavaSwing的界面编程.  编辑排行榜,包含局数,结果,步数,以及"关于我们 ...

  8. linux控制台单人五子棋简书,Java控制台版五子棋的简单实现方法

    这篇文章主要给大家介绍了关于Java控制台版五子棋的简单实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 设计一个10*1 ...

  9. 单机版五子棋java功能_java实现单机版和网络对战版五子棋程序

    [实例简介] java实现单机版和网络对战版五子棋,功能包括计时.悔棋.聊天.显示双方状态等等.详细见https://blog.csdn.net/qq_37913997/article/details ...

最新文章

  1. 【c语言】蓝桥杯算法提高 P0402
  2. input框必填星号*垂直居中变大设置
  3. 借助Spring站点开始一个spring项目
  4. Collection和Collections之间的使用与区别
  5. 开心哲理---您的妻子! --转by yp
  6. c语言中如何使用面向对象编程,如何使用C语言的面向对象
  7. android P OTA差分升级时报错记录
  8. DictionaryTKey,TValue
  9. java模拟双向链表实现
  10. android小游戏模版—重力感应
  11. 分享自TERRY-V 《Qt Creator生成带图标的exe文件》
  12. Service,测试
  13. 初探Linux内核态——通过proc文件系统作快速问题定位
  14. 推荐系统实践学习笔记(一)
  15. VS2015卸载经过
  16. L298N驱动模块---51单片机代码
  17. 笛卡尔心形函数表达式_笛卡尔爱心函数表达式 笛卡尔形式
  18. Python地理数据处理 一 :地理空间数据入门
  19. delphi显示jpg、png、gif图片
  20. macOS Big Sur 11.7.1 (20G918) 正式版 ISO、PKG、DMG、IPSW 下载

热门文章

  1. 冰雪传奇刷怪计时器_冰雪传奇最新前期攻略
  2. 前端手机本地调试小技巧
  3. DKR-NT1医用注射针管(针)刚性测试仪
  4. c++中extern用法总结
  5. ASP.NET中使用JObject和JArray解析Json数据
  6. 工具类二十 基于oshi的运行环境监控工具类
  7. 删除oracle卸载后window服务中残留的oracle服务
  8. PostMan持续集成
  9. 第七天之回顾函数指针
  10. Linux中rmp安装mysql