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

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

  (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. Flask框架获取用户IP地址的方法

    本文实例讲述了python使用Flask框架获取用户IP地址的方法.分享给大家供大家参考.具体如下: 下面的代码包含了html页面和python代码,非常详细,如果你正使用Flask,也可以学习一下最 ...

  2. SQLite数据库连接方式

    http://blog.csdn.net/ZF101201/archive/2010/05/26/5626365.aspx SQLite.NET Type:    .NET Framework Cla ...

  3. CSS关键字

    1.initial initial 关键字用于设置 CSS 属性为它的默认值. initial 关键字可用于任何 HTML 元素上的任何 CSS 属性. 版本: CSS3 JavaScript 语法: ...

  4. 来自JavaScript Garden摘取

    1.数字类型不能用作对象,因为javascript解析器会将点号(.)解析成浮点型(as a floating point literal),比如:2.toString();会导致语法从错误,解决方法 ...

  5. Line去年营收超5亿美元 远超竞争对手WhatsApp

    原文地址: http://news.cnblogs.com/n/206072/ 凭借着修改表情取悦国际用户的做法,日本移动消息应用 Line 在全球的用户总数已经超过 4 亿.Line.微信.What ...

  6. cocos2d-x 让精灵按照自己设定的运动轨迹行动

    转自:http://blog.csdn.net/ufolr/article/details/7447773 在cocos2d中,系统提供了CCMove.CCJump.CCBezier(贝塞尔曲线)等让 ...

  7. 参数对象Struts2中Action的属性接收参数

    题记:写这篇博客要主是加深自己对参数对象的认识和总结实现算法时的一些验经和训教,如果有错误请指出,万分感谢. Action中三种传递并接受参数: 1.  在Action添加成员属性接受参数 例如请求的 ...

  8. Ectouch修改虚拟销售数量的方法

    1.参考:http://zhidao.baidu.com/link?url=5OEkRlKqtRcmnO6iyW2pq-gw1aj-1S6QdImmBkQZHHt6tcvT50aIf_1nibP3T6 ...

  9. Codeforces Round #313 (Div. 2) B. Gerald is into Art 水题

    B. Gerald is into Art Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/560 ...

  10. HDU 4587 B - TWO NODES tarjan

    B - TWO NODESTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view ...