• 【C语言】用c语言实现简单的五子棋


    
    

    用c语言实现简单的五子棋

    这个小游戏是从零开始的实现的,框架灵感来自于小游戏《走迷宫》。

    游戏代码配置: 二维数组+简单逻辑+getch读取键盘+windows函数(刷屏,改颜色,改窗口大小)

     

    画面演示

    <!--more-->

    胜利画面

    娱乐画面

     

     

    整体代码

    代码太长
    移步paste

    https://paste.ubuntu.com/p/PjwdHs7Vtq/


    实现过程

    o设计棋盘 |

    o实现棋子选点下落|  (主要难点)

    o设定交叉下棋|

    o设定胜利规则|

     


     

    ■设计棋盘

    搭建框架

    char map[1000][1000]= {      "||==================================||",
                                "||   x     ||欢乐五子棋||     o   ||",
                                "||         ==============         ||",
                                "[====================================]",
                                "[[==================================]]",
                                "[[                                 ]]",
                                "[[                                 ]]",
                                "[[                                 ]]",
                                "[[                                 ]]",
                                "[[                                 ]]",
                                "[[                                 ]]",
                                "[[                                 ]]",
                                "[[                                 ]]",
                                "[[                                 ]]",
                                "[[                                 ]]",
                                "[[                                 ]]",
                                "[[                                 ]]",
                                "[[                                 ]]",
                                "[[                                 ]]",
                                "[[                                 ]]",
                                "[[                                 ]]",
                                "[[==================================]]",
                                "[====================================]"
    本来中间想用“ + ”填充就和棋盘一样,但太密了。就还是空格代替。

    印象中五子棋棋盘应该是横竖线交纵的,但好像仅仅以键盘上的字符很难实现布线。尝试了各种符号填充(理论上'+'能实现但成像很花),jpg,最后选择了空格,视觉效果好点**

    ■实现棋子选点下落(如何下棋这是个大问题)

    首先要在已有棋盘框架上下棋要解决以下几个问题

    1.棋子在指定棋盘内

    棋子要是下在外边可就不好判断了

    2.棋子不可覆盖已有棋子

    还记得玩贪吃蛇删了一些代码,结果边界被我给吃完了。

    3.棋子能下在任何符合规定的棋盘内

    因为一开始我设置棋子作为实体不可覆盖,那假若指针被棋子围起来了那该如何出去是个大问题。

    1.一开始要构思一种控制选点下棋的思路
    首先我考虑了

    1.<鼠标确定下点>
    这是最理想的方法,鼠标点一下,棋盘上就出现对应棋子,但问题在于就目前所学而言,鼠标来选点下棋太难实现。

    于是马上转变另一种控制途径

    2.<键盘控制虚拟指针来选点>
    这里我不由的想起了《啊哈c》这本书最后的游戏教学部分:走迷宫小游戏。

    这个小游戏实现wasd上下左右控制小球移动,并碰到“#”可判断不能执行移动。(简单的if判断该坐标是否为“#”而决定是否移动,这可以将#理解成实体了)

    下面简单说下原理,自行可以了解下小球是如何移动的,并认清问题1.2为什么存在;

    ch = getch();                     //获取键盘命令
           if ( ch == 's')           //下移
          {                        
               if( map[x+1][y]!= '#')//如果不是”#“那就能移动(#变成实体)
              {
                   map[x][y] = ' ';  //原坐标还原空格
                   x++;
                   map[x][y] = 'o';  //更新下一坐标
              }  //看懂原理后就知道如果没有if判断
               //小球可以随意移动,并进过的地方都变成空格(即问题2)
          }

     

    受此启发,假若把已有棋子和边界都设定不可触碰的实体,小球改成我所需要的“鼠标”,用wasd控制移动,设置键盘按下“L”为确认下棋,这样问题1.2就都完美解决了。(但此时你能想到让棋子也变成实体变成这样会造成什么大bug嘛-后文说明)

    ■实现交叉下棋

    很简单的思路,如果我设定 键盘 “l”是下棋,那么每次按下 “l”后num++,下一步鼠标储存的棋子就在“x”,“o”间交换。

     while(num)                                     
      {                          
           if(num % 2 != 0)
               turn = 'x';      //用turn 保存状态,并依次转变
           else
               turn = 'o';
        xxxxxx程序 然后 num++;    
      }

    ###

    本游戏的指针可视为走迷宫的小球 “o”,按下键盘的“L”即会在棋盘上留下“o”的痕迹并在下一次移动时变为另一个状态“x”即可实现交叉下棋于留下棋盘痕迹。

    ■设计胜利规则

    走到这一步了,后面判断胜利就不用说啦,处理水平,垂直,斜线判断五子连珠的能力还是绰绰有余的。这里就不介绍了。

    ■后期找bug (这个游戏的灵魂。。)

    此时看似理论已实现只需敲代码了,结果。。。

    这个局面,假设鼠标指针在小圈圈外面,,那我要下里面呢。

    问题来的很突然,也很致命,我要思考如何让鼠标移动进入实体围成的区域内。

    但恰恰是这个问题让我想到个很巧的解决方法,

    甚至实现了我预期外的效果。

    解决如何思路如下

    建立在上面小球移动原理上

     

    我想到了一个用一个temp巧妙地存储指标所在坐标之前的状态的方法,

    指标移动到一个新的坐标,先用temp储存坐标原有状态,再将指标存储在坐标上打印呈现出来(作为鼠标指针显示出来);

    然后执行下一次移动时,将temp所存值还给原有坐标,新坐标重复规则。`

    ch = getch();
           if ( ch == 's')         //下移
          {                       //turn是该次鼠标指针的状态('x' or 'o');
                      //此时除棋盘界线 棋盘上任何坐标都是可移动的
               if( map[x+1][y]!= '=' &&map[x+1][y]!= ']' &&map[x+1][y]!= '[')//防越界
              {
                   map[x][y] = temp;   //原坐标恢复原来的状态
                   x++; //移动x++到新的坐标
                   temp = map[x][y];   //储存新的坐标的状态
                   map[x][y] = turn;   //在新的坐标上打印鼠标
              }        
          }                         //可以对比上面小球移动原理观察temp的妙用

    再在这个基础上加入按下”L“才能改变状态(下棋),这样下来,除了棋盘边界,每个位置都能访问,每一个

    坐标状态都是可改动的(按下“L”更改状态即下棋,加上判断语句又可避免在原有基础上下棋),所以整个棋

    盘都是稳定的动态状态。

    然后猛然发现,这个temp本质不就是程序: a 与 b交换值的升级版嘛!!虽然原理简单,但这个仅仅靠巧妙的改动,

    一下子全部解决了 3 大问题,也让我感觉打开了新世界大门。

     

     

     

    后续

    就此我的五子棋就搞完了。从有想法到做完也只用一天,想加入更多元素,但后面马上有了个更有趣的东西“折磨”了我两三天——搭建博客。从周二到周五三天,我忙前忙后,美化主题时在各种小问题上摔跤,三两次把我的博客搞崩溃,最终才在今天有空在原来五子棋基础上加入了一些细节。也写下了这篇文章。。。

    这是2019.10.18 周五的晚上

    回顾起来这周收获了很多,学了许多新东西。

    做了个小游戏,在学长帮忙下用了hexo搭了一个满意的博客,周五还初步被c语言老师教了用linux系统写代码,晚上又用markdown写了一篇博客。

    所以完成这篇博客这周的忙碌也告一阶段了。

    希望下周也能很充实

    希望后续能记录更多有趣的东西~

    但好像一个星期没有碰过oj系统做题了。。。尴尬。周末赶快去刷刷题找找感觉。顺便补补其他科目。

  • 相关阅读:
    C#后台利用正则表达式查找匹配字符
    C# Dictionary 的几种遍历方法
    eval解析JSON中的注意点
    jquery datatables api (转)
    Replication--镜像+复制
    Replication--分区+复制
    Replication--进程无法在“xxxx”上执行“sp_replcmds”
    Replication--无法将事务提升为分布式事务,因为在事务中有活动的保存点
    Replication--使用MSlogreader_history查看日志读起的延迟和事务命令
    Partition--分区拆分和分区合并
  • 原文地址:https://www.cnblogs.com/404name/p/12176601.html
Copyright © 2020-2023  润新知