C 语言是面向过程的, 而 C++是面向对象的
C 和 C++ 的区别:
C 是一个结构化语言, 它的重点在于算法和数据结构 C 程序的设计首要考虑的是如何通过一个过程, 对输入 (或环境条件) 进行运算处理得到输出 (或实现过程(事务) 控制)
C++, 首要考虑的是如何构造一个对象模型, 让这个模型能够契合与之对应的问题域, 这样就可以通过获取对象的状态信息得到输出或实现过程 (事务) 控制 所以 C 与 C++ 的最大区别在于它们的用于解决问题的思想方法不一样之所以说 C++ 比 C 更先进, 是因为 设计这个概念已经被融入到 C++ 之中
C 与 C++ 的最大区别: 在于它们的用于解决问题的思想方法不一样之所以说 C++ 比 C 更先进, 是因为 设计这个概念已经被融入到 C++ 之中 , 而就语言本身而言, 在 C 中更多的是算法的概念那么是不是 C 就不重要了, 错! 算法是程序设计的基础, 好的设计如果没有好的算法, 一样不行而且, C 加上好的设计也能写出非常好的东西
一直说写个几百行的小项目, 于是我写了一个控制台的扫雷, 没有想到精简完了代码才 200 行左右, 不过考虑到这是我精简过后的, 浓缩才是精华嘛, 我就发出来大家一起学习啦, 看到程序跑起来能玩, 感觉还是蛮有成就感的~ 哈哈
扫雷应该属于一款大众游戏, 从我初中使用计算机开始, 它就被集成到了 windows 系统中, 虽然他是这么经典, 我还是要介绍一下他的玩法, 然后再考虑在控制台中怎么实现它
小编推荐一个学 C 语言 / C++ 的学习裙 二六三, 六八八, 二七六 , 无论你是大牛还是小白, 是想转行还是想入行都可以来了解一起进步一起学习! 裙内有开发工具, 很多干货和技术资料分享!
1 游戏的主界面, 是一个一个小方格, 在小方格上单击左键, 可以翻开小方格看看后面有什么
2 在这些小方格的背后隐藏着雷, 如果不幸点中了雷, 那么就 GameOver 了
2 如果点中的不是一个雷, 那么就是一块空地, 这个时候会出现两种情况:
1)用鼠标点中的空地周围八个点内有雷, 那么就显示雷的个数
2)用鼠标点中的空地周围没有雷, 这个时候就将周围的空地全部显示出来, 遇到该显示数字的空地, 就将数字显示出来(仔细观察你会发现, 数字会将空地围起来, 这是一句废话, 但是也值得想一想这是为什么)
3 在小方格上, 点击鼠标的右键, 可以将一个空地标记为雷, 当然这个功能只是为了方便你记忆你之前确定是雷的地方(还有左右键都点, 和点击右键出现? 标记, 这里就不谈啦)
4 当空地上剩余的格子数和雷的个数一样多, 那么这个时候就应该算是胜利啦
OK~ 游戏流程说完了, 这个时候该谈谈如何实现了
1 首先需要一张地图, 一般情况下我们都可以用一个二维数组表示一个地图, 每一个元素代表着扫雷中的一个小方格相应元素存储 0, 那么地图上的这个位置就是空地, 相应元素存储 1, 那么就代表这个位置就一颗雷
2 在控制台上依照二维数组长度和宽度, 打印相应的小方块
3 然后就用鼠标点击那些小方块, 对于控制台来讲, 在黑框框的区域中是有坐标的, 可以使用一些函数捕获到你点击了屏幕的哪一个坐标
4 对于控制台来说, 打印一个字符, 有的字符横向占一个位置比如普通的字母数字, 有的字符横向占两个位置比如一些图形字符: 等等, 这点在控制台编程的时候要注意
5 当点击屏幕的时候, 获取到点击的坐标后, 去二维数组中查看相应的位置是雷还是空地, 从而做相应的处理
1)假如点击到了雷, 那么就控制游戏结束
2)假如点击到了空地有两种情况
1)点击的空地周围有雷, 那么就将雷的个数显示出来
2)假如点击的空地周围没有雷, 那么就使用递归的方法去探测周围的点, 探测出与其相连的所有周围有雷的点
这个是我实现的效果:
下面就是代码啦:
- // saolei.cpp : 定义控制台应用程序的入口点
- //
- #include "stdafx.h"#include#include#include#define Boom 10 int a[10][10] = {
- 0
- };
- COORD TempPos[100] = {
- 0
- };
- int nSign = 0;
- /************************************
- 函数名 : WriteWchar
- 函数作用: 在控制台相应的坐标上显示一串字符
- 返回值 : void
- 参数 : int x 横坐标
- 参数 : int y 纵坐标
- 参数 : char szString[] 要显示的字符串
- 说明 :
- ************************************/
- void WriteWchar(int x, int y, char szString[]) {
- HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
- COORD pos = {
- x * 2,
- y
- };
- SetConsoleCursorPosition(hOut, pos);
- printf("%s", szString);
- }
- /************************************
- 函数名 : DrawNumber
- 函数作用: 在相应的坐标上, 根据传入的数字, 打印相应的数字字符
- 返回值 : void
- 参数 : COORD pos 要打印的位置
- 参数 : int nNumber 要打印的数字
- 说明 :
- ************************************/
- void DrawNumber(COORD pos, int nNumber) {
- switch (nNumber) {
- case 1:
- WriteWchar(pos.X, pos.Y, "");
- break;
- case 2:
- WriteWchar(pos.X, pos.Y, "");
- break;
- case 3:
- WriteWchar(pos.X, pos.Y, "");
- break;
- case 4:
- WriteWchar(pos.X, pos.Y, "");
- break;
- case 5:
- WriteWchar(pos.X, pos.Y, "");
- break;
- case 6:
- WriteWchar(pos.X, pos.Y, "");
- break;
- case 7:
- WriteWchar(pos.X, pos.Y, "");
- break;
- case 8:
- WriteWchar(pos.X, pos.Y, "");
- break;
- default:
- break;
- }
}小编推荐一个学 C 语言 / C++ 的学习裙 二六三, 六八八, 二七六 , 无论你是大牛还是小白, 是想转行还是想入行都可以来了解一起进步一起学习! 裙内有开发工具, 很多干货和技术资料分享!
- /************************************
- 函数名 : GetNumber
- 函数作用: 获取一个点的四周有几颗雷
- 返回值 : int
- 参数 : COORD pos 要探测的点的坐标
- 说明 :
- ************************************/
- int GetNumber(COORD pos)
- {
- int nCount = 0;
- for(int i = pos.X-1;i<=pos.X+1;i++)
- for (int j = pos.Y-1;j<=pos.Y+1;j++)
- {
- if (a[j][i] == Boom)
- {
- nCount++;
- }
- }
- return nCount;
- }
- /************************************
- 函数名 : Drawmap
- 函数作用: 打印一下地图
- 返回值 : void
- 说明 :
- ************************************/
- void Drawmap()
- {
- for (int i =0;i<10;i++)
- {
- for (int j =0;j<10;j++)
- {
- WriteWchar(j,i,"");
- }
- }
- }
- /************************************
- 函数名 : Init
- 函数作用: 随机生成 10 个地雷, 然后存到数组中
- 返回值 : void
- 说明 :
- ************************************/
- void Init()
- {
- srand(time(NULL));
- for (int i =0;i<10;i++)
- {
- int Temp_x = rand()%10;
- int Temp_y = rand()%10;
- // 判断这个地方是不是已经生成一个雷了, 如果没有, 赋值为雷
- if (a[Temp_x][Temp_y]!=Boom)
- {
- a[Temp_x][Temp_y] = Boom;
- }
- // 如果是雷, 就相当于本次生成没有发生过
- else
- {
- i--;
- }
- }
- Drawmap();
- }
- /************************************
- 函数名 : IsClose
- 函数作用: 判断是不是已经探测过的点, 由于使用的 8 方向递归的探测, 这样避免重复
- 返回值 : bool
- 参数 : COORD posTemp
- 说明 :
- ************************************/
- bool IsClose(COORD posTemp)
- {
- for (int i =0;i
- {
- if(TempPos[i].X == posTemp.X&&TempPos[i].Y == posTemp.Y)
- return true;
- }
- return false;
- }
- /************************************
- 函数名 : IsKongdi
- 函数作用: 判断一个点是空地, 还是雷, 如果是空地, 需要做其他处理
- 返回值 : void
- 参数 : COORD pos
- 说明 :
- ************************************/
- bool IsKongdi(COORD pos)
- {
- int nNumber = 0;
- //1 如果是雷, 就直接返回一个 false 说明要挂了
- if (a[pos.Y][pos.X] == Boom)
- {
- return false;
- }
- //2 如果不是雷, 那么就做后续处理
- else
- {
- //2.1 先判断一下周围有几颗雷
- nNumber = GetNumber(pos);
- if (nNumber!=0){
- // 有几颗雷, 就打印这个数字
- DrawNumber(pos,nNumber);
- return true;
- }
- else
- {
- // 如果没有雷, 那就先画空地出来, 然后向周围扩散去探测其他点
- WriteWchar(pos.X,pos.Y," ");
- }
- }
- //2.2 点到了空地, 但是周围没有雷的情况的处理, 继续去探测周围 8 个点
- for(int i = -1;i<=1;i++)
- for (int j = -1;j<=1;j++)
- {
- COORD posTemp = {pos.X+i,pos.Y+j};
- // 是不是越界了
- if (i==0&&j==0||posTemp.X==-1||posTemp.Y==-1||posTemp.X==10||posTemp.Y==10)
- continue;
- // 这个点是不是已经探测过了
- if (IsClose(posTemp))
- continue;
- // 这个点没有探测过, 就将其加入到数组中, 然后使其在以后的探测中, 存入
- TempPos[nSign++] =posTemp;
- IsKongdi(posTemp);
- }
- return true;
- }
- /************************************
- 函数名 : GetMousePosition
- 函数作用: 获取鼠标点击的位置, 假如没有获取到, 就返回(-1,-1)
- 返回值 : COORD 鼠标点击的坐标
- 说明 :
- ************************************/
- COORD GetMousePosition()
- {
- HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
- INPUT_RECORD stcInput = {0};
- DWORD buffer;
- COORD pos = {-1,-1};
- ReadConsoleInput(hIn,&stcInput,1,&buffer);
- if (stcInput.EventType == MOUSE_EVENT)
- {
- MOUSE_EVENT_RECORD stcMouseEnent = stcInput.Event.MouseEvent;
- if (stcMouseEnent.dwButtonState ==FROM_LEFT_1ST_BUTTON_PRESSED )
- {
- pos = stcMouseEnent.dwMousePosition;
- pos.X/=2;
- }
- }
- return pos;
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- Init();
- COORD pos;
- // 开始游戏
- while(1)
- {
- // 获取鼠标点击位置
- pos = GetMousePosition();
- if (pos.X!=-1)
- {
- // 如果鼠标点击的位置被探测过了, 就开始下一次循环
- if (IsClose(pos))
- {
- continue;
- }
- TempPos[nSign++] =pos;
- bool bIskongdi = IsKongdi(pos);
- // 点到雷了, 就直接退出游戏了
- if (false ==bIskongdi)
- {
- system("cls");
- WriteWchar(20,10,"you lose");
- getchar();
- break;
- }
- // 检测是不是赢了, 赢的条件就是没有被探测的点的个数和雷的个数相等
- if (nSign ==90)
- {
- system("cls");
- WriteWchar(20,10,"you win");
- }
- }
- }
- return 0;
}小编推荐一个学 C 语言 / C++ 的学习裙 二六三, 六八八, 二七六 , 无论你是大牛还是小白, 是想转行还是想入行都可以来了解一起进步一起学习! 裙内有开发工具, 很多干货和技术资料分享!
来源: http://www.jianshu.com/p/aaea4fd9ffe0