c++、c实现推箱子小游戏
经过四次的修改和优化,终于将推箱子这个游戏完整的写出来了,今天就像大家分享一下这个游戏的编写。
这个游戏界面的编写总的来说不困难,主要是推动箱子的算法。
(1)利用数组和windows api 即可写出界面
- #define N 15
- #define M 15
- int map[N][M] = {
- { , , , , , , , , , , , , , , },
- { , , , , , , , , , , , , , , },
- { , , , , , , , , , , , , , , },
- { , , , , , , , , , , , , , , },//0->空白
- { , , , , , , , , , , , , , , },//1->墙
- { , , , , , , , , , , , , , , },//2->人
- { , , , , , , , , , , , , , , },//3->箱子
- { , , , , , , , , , , , , , , },//4->位置
- { , , , , , , , , , , , , , , },
- { , , , , , , , , , , , , , , },
- { , , , , , , , , , , , , , , },
- { , , , , , , , , , , , , , , },
- { , , , , , , , , , , , , , , },
- { , , , , , , , , , , , , , , },
- { , , , , , , , , , , , , , , },
- void PushBox::Color(int m)//封装到PushBox类里
- {
- HANDLE consolehwnd;//创建句柄,详细句柄知识,请百度一下或查MSDN
- consolehwnd = GetStdHandle(STD_OUTPUT_HANDLE);//实例化句柄
- SetConsoleTextAttribute(consolehwnd, m);
- }
- void PushBox::Drop(int map[N][M])
- {
- int i, j;
- for (i = ; i < N; i++)
- {
- for (j = ; j < M; j++)
- switch (map[i][j])
- {
- case : Color(); std::cout << " "; break;
- case : Color(); std::cout << "■"; break;
- case : Color(); std::cout << "△"; break;
- case : Color(); std::cout << "□"; break;
- case : Color(); std::cout << "☆"; break;
- case : Color(); std::cout << "◆"; break;//箱子到达目标位置
- case : Color(); std::cout << "△"; break;//表示人与位置重叠
- }
- std::cout << "\n";
- }
- }
(2)推箱子算法:本人比较笨,没有找到捷径,所以就穷举了推箱子步骤,分析如下:
以人为中心,出现两种可能:①人在空位 ②人在目标位置上
①有六种可能:(注:x1,y1, x2, y2为坐标的偏移量,i ,为人所在的坐标 )
②人在目标位置上 同样也有六种可能:
用if语句进行对这12中可能进行判断,除了处理这几种能够移动的外,其他没有可能移动,分析清楚,则很容写出移动算法:
- int PushBox::push(int map[N][M],int x1,int x2,int y1,int y2)
- {
- int i, j;
- Postion(map, &i, &j);
- /*******************人在空格处*/
- if (map[i][j] == )
- {
- //人前是箱子,箱子在空格处
- if (map[i + x1][j + y1] == )
- { //箱子前面为空格S
- if (map[i + x2][j + y2] == )
- {
- map[i][j] = ;
- map[i + x1][j + y1] = ;
- map[i + x2][j + y2] = ;
- return ;
- }
- //箱子前面为位置
- if (map[i + x2][j + y2] == )
- {
- map[i][j] = ;
- map[i + x1][j + y1] = ;
- map[i + x2][j + y2] = ;
- return ;
- }
- }
- //人前为箱子,箱子在位置上
- if (map[i + x1][j + y1] == )
- {
- //箱子前面为空
- if (map[i + x2][j + y2] == )
- {
- map[i + x2][j + y2] = ;
- map[i + x1][j + y1] = ;
- map[i][j] = ;
- return ;
- }
- //箱子前面为位置
- if (map[i + x2][j + y2] == )
- {
- map[i][j] = ;
- map[i + x1][j + y1] = ;
- map[i + x2][j + y2] = ;
- return ;
- }
- }
- /*--------------------*/
- //人前为空格
- if (map[i + x1][j + y1] == )
- {
- map[i + x1][j + y1] = ;
- map[i][j] = ;
- return ;
- }
- //人前为位置
- if (map[i + x1][j + y1] == )
- {
- map[i + x1][j + y1] = ;
- map[i][j] = ;
- return ;
- }
- return ;
- }
- /*******************人在位置上*/
- if (map[i][j] == )
- {
- //位置前面是箱子,箱子在空格
- if (map[i + x1][j + y1] == )
- {
- //箱子前面为空格
- if (map[i + x2][j + y2] == )
- {
- map[i][j] = ;
- map[i + x1][j + y1] = ;
- map[i + x2][j + y2] = ;
- return ;
- }
- //箱子前面为位置
- if (map[i + x2][j + y2] == )
- {
- map[i][j] = ;
- map[i + x1][j + y1] = ;
- map[i + x2][j + y2] = ;
- return ;
- }
- }
- //位置前面是箱子,箱子在位置
- if (map[i + x1][j + y1] == )
- {
- //箱子前面是空格
- if (map[i + x2][j + y2] == )
- {
- map[i][j] = ;
- map[i + x1][j + y1] = ;
- map[i + x2][j + y2] = ;
- return ;
- }
- //箱子前面是位置
- if (map[i + x2][j + y2] == )
- {
- map[i][j] = ;
- map[i + x1][j + y1] = ;
- map[i + x2][j + y2] = ;
- return ;
- }
- }
- /*-----------------*/
- //人前为位置
- if (map[i + x1][j + y1] == )
- {
- map[i + x1][j + y1] = ;
- map[i][j] = ;
- return ;
- }
- //人前为空格
- if (map[i + x1][j + y1] == )
- {
- map[i + x1][j + y1] = ;
- map[i][j] = ;
- return ;
- }
- return ;
- }return ;
- }
这里写返回1值既可以减少系统的判断,还可以判断是否执行了移动操作,方便统计移动的步数
(3)编写获取人的位置函数、判断是否获胜
获取人的位置,只需要判断得到地图中6或者2其中一个坐标,由于需要横坐标和纵坐标,所以利用指针得到位置
- void PushBox::Postion(int map[N][M], int *cl, int *cow)
- {
- int i, j;
- for (i = ; i < N; i++)
- {
- for (j = ; j < M; j++)
- {
- if (map[i][j] == || map[i][j] == )goto ML;
- }
- }ML:
- *cl = i;
- *cow = j;
- }
判断是否获胜:即地图中没有目标位置,就获胜,若胜利返回1值,否则返回0;
- int PushBox::juide(int map[N][M])
- {
- int i, j;
- for (i = ; i < N; i++)
- {
- for (j = ; j < M; j++)
- {
- if (map[i][j] == )return ;
- if (map[i][j] == )return ;
- }
- if (i == N - && j == M - )return ;
- }
- }
(4)编写移动方向算法,并统计执行步数
- int PushBox::move(int map[N][M], char ch)
- {
- static int step = ;
- int x1, x2, y1, y2;
- switch (ch)
- {
- case 's':
- case 'S': x1 = ; x2 = ; y1 = ; y2 = ;
- if (push(map, x1, x2, y1, y2)) step++; return step;
- case 'w':
- case 'W': x1 = -; x2 = -; y1 = ; y2 = ;
- if (push(map,x1,x2,y1,y2)) step++; return step;
- case 'A':
- case 'a': x1 = ; x2 = ; y1 = -; y2 = -;
- if (push(map,x1,x2,y1,y2)) step++; return step;
- case 'D':
- case 'd': x1 = ; x2 = ; y1 = ; y2 = ;
- if (push(map,x1,x2,y1,y2)) step++; return step;
- }
- }
(5)Push类的封装,将以上的几个方法封装到类里,建立头文件
- #include <iostream>
- using namespace std;
- #include <windows.h>
- #include <string.h>
- #include <conio.h>
- #include <fstream>
- #pragma warning(disable:4996)
- #define N 15
- #define M 15
- //建立一个推箱子相关操作的类
- /*--------------------------PushBox类编写--------------------------------------*/
- /****************************************************************************/
- class PushBox{
- public:
- int move(int map[N][M], char ch);//移动箱子
- void Drop(int map[N][M]);//箱子界面编写
- int juide(int map[N][M]);//判断是否全部移入位置,成功返回1,失败返回0
- private:
- int push(int map[N][M],int x1,int x2,int y1,int y2);
- void Color(int m);
- void Postion(int map[N][M], int *i, int *j);
- };
(6)主函数的编写:这里我将地图放入外部txt文件中,方便以后添加地图
- #include <iostream>
- using namespace std;
- #include <windows.h>
- #include <string.h>
- #include <conio.h>
- #include "Push.h"
- #pragma warning(disable:4996)
- #define N 15
- #define M 15
- int read_map(int *p);
- void change_map(int *p, char *temp);
- //主函数
- int main()
- {
- int map[N][M] = { };
- PushBox box;
- int *p = &map[][];
- int select = read_map(p);
- int step = ;
- while ()
- {
- cout << "你选择的关卡是:" << select << endl;
- cout << "你走了:" << step << "步";
- box.Drop(map);
- cout << "W-----向上 S------向下" << endl;
- cout << "A-----向左 S------向右" << endl;
- char ch;
- ch = _getch();
- step = box.move(map, ch);
- system("cls");
- if (box.juide(map))break;
- }
- std::cout << "你赢了!";
- std::cout << "共走:" << step << "步";
- getchar();
- getchar();
- }
- /*选择关卡*/
- int read_map(int *p)
- {
- int ch;
- cout << "请输入关卡:";
- cin >> ch;
- char temp[];
- switch (ch)
- {
- case :strcpy(temp, "map/map_1.txt"); change_map(p, temp); system("cls"); return ;
- case :strcpy(temp, "map/map_2.txt"); change_map(p, temp); system("cls"); return ;
- }
- }
- /*打开关卡*/
- void change_map(int *p, char *temp)
- {
- ifstream infile;
- infile.open(temp);
- while (!infile.eof())
- {
- infile >> *p;
- p++;
- }
- infile.close();
- }
程序分析图:
经过调试运行,暂时还没有发现BUG,一下是源代码,希望大家发现了以后给我留言,写得不好的地方希望大家能够指出
源文件
- /**************************************************
- * Name : 推箱子
- * FileName : PushBox.cpp
- * Author : 和导
- * Version : V4.0
- * Date :
- *Description : 制作一个简单的推箱子
- *Function List : (1)void read_map(int *p);
- (2)void change_map(int *p, char *temp);
- --------------
- History:
- <author> <time> <reviseInf>
- 和导 2016/4/1 把类封装到头文件中,重写推函数,添加地图
- ****************************************************/
- #include <iostream>
- using namespace std;
- #include <windows.h>
- #include <string.h>
- #include <conio.h>
- #include "Push.h"
- #pragma warning(disable:4996)
- #define N 15
- #define M 15
- int read_map(int *p);
- void change_map(int *p, char *temp);
- //主函数
- int main()
- {
- int map[N][M] = { };
- PushBox box;
- int *p = &map[][];
- int select = read_map(p);
- int step = ;
- while ()
- {
- cout << "你选择的关卡是:" << select << endl;
- cout << "你走了:" << step << "步";
- box.Drop(map);
- cout << "W-----向上 S------向下" << endl;
- cout << "A-----向左 S------向右" << endl;
- char ch;
- ch = _getch();
- step = box.move(map, ch);
- system("cls");
- if (box.juide(map))break;
- }
- std::cout << "你赢了!";
- std::cout << "共走:" << step << "步";
- getchar();
- getchar();
- }
- /*选择关卡*/
- int read_map(int *p)
- {
- int ch;
- cout << "请输入关卡:";
- cin >> ch;
- char temp[];
- switch (ch)
- {
- case :strcpy(temp, "map/map_1.txt"); change_map(p, temp); system("cls"); return ;
- case :strcpy(temp, "map/map_2.txt"); change_map(p, temp); system("cls"); return ;
- }
- }
- /*打开关卡*/
- void change_map(int *p, char *temp)
- {
- ifstream infile;
- infile.open(temp);
- while (!infile.eof())
- {
- infile >> *p;
- p++;
- }
- infile.close();
- }
头文件
- #include <iostream>
- using namespace std;
- #include <windows.h>
- #include <string.h>
- #include <conio.h>
- #include <fstream>
- #pragma warning(disable:4996)
- #define N 15
- #define M 15
- //建立一个推箱子相关操作的类
- /*--------------------------PushBox类编写--------------------------------------*/
- /****************************************************************************/
- class PushBox{
- public:
- int move(int map[N][M], char ch);//移动箱子
- void Drop(int map[N][M]);//箱子界面编写
- int juide(int map[N][M]);//判断是否全部移入位置,成功返回1,失败返回0
- private:
- int push(int map[N][M],int x1,int x2,int y1,int y2);
- void Color(int m);
- void Postion(int map[N][M], int *i, int *j);
- };
- int PushBox::move(int map[N][M], char ch)
- {
- static int step = ;
- int x1, x2, y1, y2;
- switch (ch)
- {
- case 's':
- case 'S': x1 = ; x2 = ; y1 = ; y2 = ;
- if (push(map, x1, x2, y1, y2)) step++; return step;
- case 'w':
- case 'W': x1 = -; x2 = -; y1 = ; y2 = ;
- if (push(map,x1,x2,y1,y2)) step++; return step;
- case 'A':
- case 'a': x1 = ; x2 = ; y1 = -; y2 = -;
- if (push(map,x1,x2,y1,y2)) step++; return step;
- case 'D':
- case 'd': x1 = ; x2 = ; y1 = ; y2 = ;
- if (push(map,x1,x2,y1,y2)) step++; return step;
- }
- }
- void PushBox::Drop(int map[N][M])
- {
- int i, j;
- for (i = ; i < N; i++)
- {
- for (j = ; j < M; j++)
- switch (map[i][j])
- {
- case : Color(); std::cout << " "; break;
- case : Color(); std::cout << "■"; break;
- case : Color(); std::cout << "△"; break;
- case : Color(); std::cout << "□"; break;
- case : Color(); std::cout << "☆"; break;
- case : Color(); std::cout << "◆"; break;
- case : Color(); std::cout << "△"; break;
- }
- std::cout << "\n";
- }
- }
- int PushBox::juide(int map[N][M])
- {
- int i, j;
- for (i = ; i < N; i++)
- {
- for (j = ; j < M; j++)
- {
- if (map[i][j] == )return ;
- if (map[i][j] == )return ;
- }
- if (i == N - && j == M - )return ;
- }
- }
- int PushBox::push(int map[N][M],int x1,int x2,int y1,int y2)
- {
- int i, j;
- Postion(map, &i, &j);
- /*******************人在空格处*/
- if (map[i][j] == )
- {
- //人前是箱子,箱子在空格处
- if (map[i + x1][j + y1] == )
- { //箱子前面为空格S
- if (map[i + x2][j + y2] == )
- {
- map[i][j] = ;
- map[i + x1][j + y1] = ;
- map[i + x2][j + y2] = ;
- return ;
- }
- //箱子前面为位置
- if (map[i + x2][j + y2] == )
- {
- map[i][j] = ;
- map[i + x1][j + y1] = ;
- map[i + x2][j + y2] = ;
- return ;
- }
- }
- //人前为箱子,箱子在位置上
- if (map[i + x1][j + y1] == )
- {
- //箱子前面为空
- if (map[i + x2][j + y2] == )
- {
- map[i + x2][j + y2] = ;
- map[i + x1][j + y1] = ;
- map[i][j] = ;
- return ;
- }
- //箱子前面为位置
- if (map[i + x2][j + y2] == )
- {
- map[i][j] = ;
- map[i + x1][j + y1] = ;
- map[i + x2][j + y2] = ;
- return ;
- }
- }
- /*--------------------*/
- //人前为空格
- if (map[i + x1][j + y1] == )
- {
- map[i + x1][j + y1] = ;
- map[i][j] = ;
- return ;
- }
- //人前为位置
- if (map[i + x1][j + y1] == )
- {
- map[i + x1][j + y1] = ;
- map[i][j] = ;
- return ;
- }
- return ;
- }
- /*******************人在位置上*/
- if (map[i][j] == )
- {
- //位置前面是箱子,箱子在空格
- if (map[i + x1][j + y1] == )
- {
- //箱子前面为空格
- if (map[i + x2][j + y2] == )
- {
- map[i][j] = ;
- map[i + x1][j + y1] = ;
- map[i + x2][j + y2] = ;
- return ;
- }
- //箱子前面为位置
- if (map[i + x2][j + y2] == )
- {
- map[i][j] = ;
- map[i + x1][j + y1] = ;
- map[i + x2][j + y2] = ;
- return ;
- }
- }
- //位置前面是箱子,箱子在位置
- if (map[i + x1][j + y1] == )
- {
- //箱子前面是空格
- if (map[i + x2][j + y2] == )
- {
- map[i][j] = ;
- map[i + x1][j + y1] = ;
- map[i + x2][j + y2] = ;
- return ;
- }
- //箱子前面是位置
- if (map[i + x2][j + y2] == )
- {
- map[i][j] = ;
- map[i + x1][j + y1] = ;
- map[i + x2][j + y2] = ;
- return ;
- }
- }
- /*-----------------*/
- //人前为位置
- if (map[i + x1][j + y1] == )
- {
- map[i + x1][j + y1] = ;
- map[i][j] = ;
- return ;
- }
- //人前为空格
- if (map[i + x1][j + y1] == )
- {
- map[i + x1][j + y1] = ;
- map[i][j] = ;
- return ;
- }
- return ;
- }return ;
- }
- void PushBox::Postion(int map[N][M], int *cl, int *cow)
- {
- int i, j;
- for (i = ; i < N; i++)
- {
- for (j = ; j < M; j++)
- {
- if (map[i][j] == || map[i][j] == )goto ML;
- }
- }ML:
- *cl = i;
- *cow = j;
- ;
- }
- void PushBox::Color(int m)
- {
- HANDLE consolehwnd;//创建句柄,详细句柄知识,请百度一下或查MSDN
- consolehwnd = GetStdHandle(STD_OUTPUT_HANDLE);//实例化句柄
- SetConsoleTextAttribute(consolehwnd, m);
- }
两个地图张
文件放置如图:
c++、c实现推箱子小游戏的更多相关文章
- 完整版本的推箱子小游戏,最简单的纯C语言打造
/* 推箱子小游戏 1.定义绘制样式 用二维数组的方式 2.绘制图像 3.找出当前位置 4.逻辑判断,制造动作 根据数学xy轴的规律,这里使用ij 上移,行轴上升,行数减少 下移,行数下降,函数增加 ...
- C++ 控制台推箱子小游戏
// 游戏菜单.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #in ...
- 推箱子小游戏《格鲁的实验室》13关 - bfs最短路径
下载了一款推箱子小游戏,第13关的时候怎么也破不了最佳纪录(最少步数是9而我们最好的方案是10步),因为数据比较小(6*8的方阵),所以写了个BFS来找最短路. 游戏的目标是把小黄人推到黄色球,小绿人 ...
- C/C++编程笔记:C语言写推箱子小游戏,大一学习C语言练手项目
C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...
- 每个人都可以用C语言写的推箱子小游戏!今天你就可以写出属于自己项目~
C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...
- 用C#制作推箱子小游戏
思路分析: 一.制作一个地图 二.地图中放置墙.箱子.人.目标等 三.让小人动起来完成推箱子动作 游戏制作: 1.按照上述地图制作一个地图 (12行×13列) 地图可以看做是行和列组成的,即可以看做 ...
- 【面试笔试算法】Program 5 : 推箱子 (网易游戏笔试题)
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 推箱子是一款经典游戏.如图所示,灰色格子代表不能通过区域,蓝色方格是箱子,黑色圆形代表玩家,含有圆点的格子代表目标点. 规 ...
- C语言小游戏: 推箱子 支线(一)--1
好家伙,考完试了 回顾一下2021 回顾一下某次的作业 妙啊 所以, 做一个推箱子小游戏 1.先去4399找一下关卡灵感 就它了 2.在百度上搜几篇推箱子, 参考其中的"■ ☆"图 ...
- c语言游戏推箱子
前两天做了推箱子小游戏,看似简单的一个小游戏背后却 有巨大的秘密,这秘密就是一大堆逻辑. 自从学习了函数过后,的确是解决了很多问题,而且调用很方便,尽管我现在都不是很会调用. 写完一个函数,准备测试一 ...
随机推荐
- javascript中对象的每个实例都具有的属性和方法
- HTML5几种常见的错误写法
本文介绍了HTML5常见的6种错误写法,包括:1.不要使用section作为div的替代品 2.只在需要的时候使用header和hgroup 3.不要把所有列表式的链接放在nav里 4.figure元 ...
- UVaLive 6858 Frame (水题)
题意:给定一个矩形框架,给定一个小矩形,问你能不能正好拼起来. 析:很简单么,就三种情况,如果是1*1的矩形,或者是1*2的一定可以,然后就是上面和下面正好能是小矩形的整数倍,左右是少一,两个就是整数 ...
- java commons-lang 工具包 逃脱工具 转unicode 及其他
<dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</ar ...
- ZendFramework2 与MongoDB的整合
从网上找了很多文章,先是直接搜关键字找zf2与mongoDB的文章,然后回到源头先学习了一下mongoDB是什么,以及纯PHP环境下怎么用,又从github上找了几个mongoDB的zf2模块,还FQ ...
- Spring MVC 的视图转发
Spring MVC 默认采用的是转发来定位视图,如果要使用重定向,可以如下操作 1.使用RedirectView public ModelAndView login(){ RedirectView ...
- Vieta定理
一元$n$次方程$$P(x)=a_{n}x^{n}+a_{n-1}x^{n-1}+\cdots+a_{a}x+a_{0}=a_{n}(x-x_{1})(x-x_{2})\cdots (x-x_{n}) ...
- VS2012开发ActiveX插件 尝试1
今天闲来无聊研究了下 ActiveX插件开发,以前一直以为很牛逼,然后发现还是比较简单的东西.. 首先: 在开始前 准备好 VS12开发工具,cabarc.exe 工具(注:这是 用来 将文件打包成c ...
- Unable to automatically debug "XXXXX“
I solved this issue by going to C:\Program Files\Microsoft VisualStudio10.0\Common7\IDE then running ...
- org.apache.hadoop.fs-ChecksumException
当ChecksumFileSystem出现问题时抛出 package org.apache.hadoop.fs; import java.io.IOException; /** Thrown for ...