用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语言实现简单的五子棋的更多相关文章

  1. 李洪强漫谈iOS开发[C语言-042]-简单计算器

    李洪强漫谈iOS开发[C语言-042]-简单计算器

  2. 谁说C语言很简单?

    前两天,Neo写了一篇<语言的歧义>其使用C语言讨论了一些语言的歧义.大家应该也顺便了解了一下C语言中的很多不可思异的东西,可能也是你从未注意到的东西. 是的,C语言并不简单,让我们来看看 ...

  3. Linux 用C语言实现简单的shell(2)

    不知不觉两周没有发文了,因为“一万美金的福特奖学金答辩”,ACM比赛,网络论文阅读和网络大作业一大堆事把时间冲散了,所以先写一篇博文补上之前一坑. 之前发了一篇关于linux 用C语言实现简单shel ...

  4. Java语言实现简单FTP软件------>FTP软件主界面的实现(四)

    首先看一下该软件的整体代码框架                        1.首先介绍程序的主入口FTPMain.java,采用了一个漂亮的外观风格 package com.oyp.ftp; im ...

  5. Java语言实现简单FTP软件------>源码放送(十三)

    Java语言实现简单FTP软件------>FTP协议分析(一) Java语言实现简单FTP软件------>FTP软件效果图预览之下载功能(二) Java语言实现简单FTP软件----- ...

  6. Java语言实现简单FTP软件------>上传下载管理模块的实现(十一)

    1.上传本地文件或文件夹到远程FTP服务器端的功能. 当用户在本地文件列表中选择想要上传的文件后,点击上传按钮,将本机上指定的文件上传到FTP服务器当前展现的目录,下图为上传子模块流程图 选择好要上传 ...

  7. C语言,简单计算器【上】

    由于工作需要最近在研究PHP扩展,无可避免的涉及到了C语言.从出了学校以后C语言在实际工作中还没有用到过,所以必须要先进行一点复习工作.个人认为对于熟悉一样东西说最好的方法是上手实践.于是便想起了当时 ...

  8. 008_用go语言实现简单的冒泡排序

    冒泡排序是各个语言中的基本排序算法,本次我们用go语言实现简单的冒泡排序 package main import "fmt" // [13,10,5,7,2] // [10,13, ...

  9. 实验报告系列:实验一 HTML语言的简单网页制作

    实验一 HTML语言的简单网页制作 一.实验目的: 1.掌握常用的HTML语言标记: 2.利用文本编辑器建立HTML文档,制作简单网页. 3.学习将其它格式的文档转换成HTML格式的文档 二.实验内容 ...

随机推荐

  1. Centos 7安装 Mysql

    Mysql数据库的安装与配置 CentOS7的yum源中默认好像是没有mysql的,所有我们采用从官方下载的方式进行安装. 为了节省时间,下面的步骤参考网络上的教程,根据最新情况进行了修改. ①卸载M ...

  2. git branch stash

    一.branch(分支) 1.创建分支 git branch dev 2.切换分支 git branch dev 3.合并分支 git merge bug 4.查看分支 git branch 5.删除 ...

  3. linux操作系统下调试python代码方法

    一.python有调试工具pdb,可以用来进行代码调试. pdb的常用命令说明: l #查看运行到哪行代码 n #单步运行,跳过函数 s #单步运行,可进入函数 p 变量 #查看变量值 b 行号 #断 ...

  4. 之前见汤姆大叔 写过一系列的 js 深入理解 呢 很是感觉经典

    最近要把这些给翻个遍 加油  js 隐式全局变量 读后感 1:js 没有变量名称是否重复定义的检查,在cshrp里有这样的检查, 没有变量名称重复的检查,这样 当变量名称 重复定义的时候 相同命名的变 ...

  5. SSM前后端分离/不分离对比Demo

    之前某些原因,整理了一个小的Demo,用于演示.个人认为在SSM前后端不分离的基础上在前端处理上比较麻烦一点之后就是注解的使用.总结一些对比,仅是自己掌握的,不够严谨,不足之处请大佬批评指正. 路由控 ...

  6. Collections.synchronizedList 、CopyOnWriteArrayList、Vector介绍、源码浅析与性能对比

    ## ArrayList线程安全问题 众所周知,`ArrayList`不是线程安全的,在并发场景使用`ArrayList`可能会导致add内容为null,迭代时并发修改list内容抛`Concurre ...

  7. Qt下Armadillo矩阵函数库的添加

    其实本文严格说只能算VS2013添加Armadillo教程,因为为了省事,用的是VS2013编译器版本的Qt,Armadillo也直接用了自带例子中的blas_win64_MT.dll.blas_wi ...

  8. STM32学习笔记:基础例子

    本例子代码参考了STM32库开发实战指南中的代码,由于使用的板子是尚学STM32F103ZET6,为了配合板上已有资源,也参考了其配套代码.为了便于书写文本,我尽量将代码都写到了一个文件中,这种方式是 ...

  9. BOM DOM 注意事項

    setTimeout(js,時間)  js处 应该放一个函数 不能放 alert  confirm 等 (否则延时会失效) setTimeout()   和 setInterval() 的区别:    ...

  10. P4452 [国家集训队]航班安排(最大费用最大流)

    P4452 [国家集训队]航班安排 题目传送门 解题思路: 感觉题面让人有很多误解,就是说有k架飞机在0点从0号机场起飞,在t时刻返回机场,给出空载飞行的时间和花费以及m个包机请求的花费和起始时间和终 ...