经过四次的修改和优化,终于将推箱子这个游戏完整的写出来了,今天就像大家分享一下这个游戏的编写。

  这个游戏界面的编写总的来说不困难,主要是推动箱子的算法。

  (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实现推箱子小游戏的更多相关文章

  1. 完整版本的推箱子小游戏,最简单的纯C语言打造

    /* 推箱子小游戏 1.定义绘制样式 用二维数组的方式 2.绘制图像 3.找出当前位置 4.逻辑判断,制造动作 根据数学xy轴的规律,这里使用ij 上移,行轴上升,行数减少 下移,行数下降,函数增加 ...

  2. C++ 控制台推箱子小游戏

              // 游戏菜单.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #in ...

  3. 推箱子小游戏《格鲁的实验室》13关 - bfs最短路径

    下载了一款推箱子小游戏,第13关的时候怎么也破不了最佳纪录(最少步数是9而我们最好的方案是10步),因为数据比较小(6*8的方阵),所以写了个BFS来找最短路. 游戏的目标是把小黄人推到黄色球,小绿人 ...

  4. C/C++编程笔记:C语言写推箱子小游戏,大一学习C语言练手项目

    C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...

  5. 每个人都可以用C语言写的推箱子小游戏!今天你就可以写出属于自己项目~

    C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...

  6. 用C#制作推箱子小游戏

    思路分析: 一.制作一个地图 二.地图中放置墙.箱子.人.目标等 三.让小人动起来完成推箱子动作 游戏制作: 1.按照上述地图制作一个地图  (12行×13列) 地图可以看做是行和列组成的,即可以看做 ...

  7. 【面试笔试算法】Program 5 : 推箱子 (网易游戏笔试题)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 推箱子是一款经典游戏.如图所示,灰色格子代表不能通过区域,蓝色方格是箱子,黑色圆形代表玩家,含有圆点的格子代表目标点. 规 ...

  8. C语言小游戏: 推箱子 支线(一)--1

    好家伙,考完试了 回顾一下2021 回顾一下某次的作业 妙啊 所以, 做一个推箱子小游戏 1.先去4399找一下关卡灵感 就它了 2.在百度上搜几篇推箱子, 参考其中的"■ ☆"图 ...

  9. c语言游戏推箱子

    前两天做了推箱子小游戏,看似简单的一个小游戏背后却 有巨大的秘密,这秘密就是一大堆逻辑. 自从学习了函数过后,的确是解决了很多问题,而且调用很方便,尽管我现在都不是很会调用. 写完一个函数,准备测试一 ...

随机推荐

  1. log4j中的MDC和NDC

    NDC和MDC NDC(Nested Diagnostic Context)和MDC(Mapped Diagnostic Context)是log4j种非常有用的两个类,它们用于存储应用程序的上下文信 ...

  2. 转载Repository 和Unit of work的使用说明

    利用Repository and Unit of Work重构项目 文章索引和简介 项目最基础的东西已经结束了,但是现在我们的项目还不健全  不利于测试 重复性代码多   层与层之间耦合性高  不利于 ...

  3. 关于cocoapods添加静态库的奇葩配置

    不多说,直接上代码 当引入这个静态库时,一开始死活在编辑时找不到这个静态库. 直到看到这个贴子:http://stackoverflow.com/questions/19189463/cocoapod ...

  4. python crawler0723.py

    #!/usr/env  python #-*- coding: utf-8  -*- import urllib import urllib2 import random import request ...

  5. [PoC]某B2B网站的一个反射型XSS漏洞

    Author: Charlie 个人微博:http://YinYongYou.com 转载请注明出处. 工作过程纯粹手贱,测试了一下.然后发现了这么一个东西.有心利用能造成大范围影响.如可以自由修改用 ...

  6. Java Thread Basic

    一.Java的多线程有三种实现方式. 1.继承创建. a.定义子类,重写run方法 b.创建Thread子类的实例(即现成对象) c.调用start() 方法启动现成 特征:不可以共享变量. publ ...

  7. js字符串常用判断方法

    转自:http://blog.sina.com.cn/s/blog_6819fa800100j5t6.html 一.方法介绍 function obj$(id)                     ...

  8. C# 解压RAR压缩文件

    此方法适用于C盘windows文件夹中有WinRAR.exe文件 /// 解压文件(不带密码) RAR压缩程序 返回解压出来的文件数量 /// </summary> /// <par ...

  9. 2014广州Java岗位面试汇总

    本文记录了最近一些朋友提供的面试经历,真实数据,仅供广州求职的朋友参考.为行文方便,一律用主语”我“进行.部分词语可能造成读者不良反应,敬请留意. 1  广州沣首信息科技有限公司 公司所在区域相对较偏 ...

  10. CUDA从入门到精通

    http://blog.csdn.net/augusdi/article/details/12833235 CUDA从入门到精通(零):写在前面 在老板的要求下.本博主从2012年上高性能计算课程開始 ...