推箱子小游戏

//K.h
#pragma once
class K {  //抽象化机器人K
//地图大小
#define cx 10
#define cy 10
#define wall1 0xA8   //▓占2个字节 WINDOWS下
#define wall2 0x88   //
//为K定义方向,方向符号请无视。
public:
enum FX {
     y = ‘>‘, //朝右Y
     z = ‘<‘, //左 -Y
     s = ‘^‘, //上 -X
     x = ‘V‘  //下  X
};

protected:
    int map[cx][cy];      //0 代表平地可活动;
                          //1 表示墙
                          //2 表示箱子
                          //3 箱子的归属
    int bakmap[cx][cy];   //做一个备用地图
    int ix,iy;              //机器人现在的坐标(iy行,第ix列)
    int fx;                  //机器人现在的方向

private:
    void gotoxy(int x,int y){    //移动当前的IX,IY的坐标
        ix=x;
        iy=y;
        showmap();
    }

public:
    K(int tx,int ty,int ifx){    //类构造函数
        loadmap();               //机器人K的初使化位置与方向
        ix=tx;
        iy=ty;
        fx=ifx;
        showmap();
    }
    void setfx(int sfx){         //设置机器人朝向
        fx=sfx;
        showmap();
    }
    void move(int bstep=1) {       //向前走,默认一格
        if (bwallinface()) return;
        if (bboxinface()) { handbox(); return;}
         if (fx==FX::z) {
            iy-=bstep;
            gotoxy(ix, iy);
        }else if (fx==FX::y)
        {
            iy+=bstep;
            gotoxy(ix, iy);
        }else if (fx==FX::s){
            ix-=bstep;
            gotoxy(ix,iy);

        }else if (fx==FX::x){
            ix+=bstep;
            gotoxy(ix, iy);
        }
    }
private:
    void handbox()  //推箱子
    {
        if (bwallinface2()) return;   //箱子前面被墙挡了
        if (fx==FX::z) {
            if (bakmap[ix][iy-1]==3)  //如果我们移开的地方,在备用地图上是3(家)则恢复到新地图,其它情况无视
                map[ix][iy-1]=bakmap[ix][iy-1];
            else
                map[ix][iy-1]=0;
            map[ix][iy-2]=2;
        }else if (fx==FX::y)
        {
            if (bakmap[ix][iy+1]==3)
                map[ix][iy+1]=bakmap[ix][iy+1];
            else
                map[ix][iy+1]=0;
            map[ix][iy+2]=2;

        }else if (fx==FX::s){
            if (bakmap[ix-1][iy]==3)
                map[ix-1][iy]=bakmap[ix-1][iy];
            else
                map[ix-1][iy]=0;
            map[ix-2][iy]=2;

        }else if (fx==FX::x){
            if (bakmap[ix+1][iy]==3)
                map[ix+1][iy]=bakmap[ix+1][iy];
            else
                map[ix+1][iy]=0;
            map[ix+2][iy]=2;
        }
        move();
        if (bcheckwin())   //赢了...地图格式like this,1是墙,2是箱,3是放箱子的。下面这样就行
            /*
                00000000
                01221000
                01331000
                01111000
            */
        {
            printf("恭喜你,你赢了!");

        }

    }

    int bwall(int wb,int step=1,int bj=0){  //检测前面的物品wb,step步数,bj离墙距离
        int bw=0;
        if (fx==FX::z && (iy-bj<=0 || map[ix][iy-step]==wb))
            bw +=  1;   //1左有
        if (fx==FX::y && (iy>=cy-step || map[ix][iy+step]==wb))
            bw += 10;  //10 右有 11 左右都有
        if (fx==FX::s && (ix-bj<=0 || map[ix-step][iy]==wb))
            bw += 100; //101 左上有 110 右上有 111左右上
        if (fx==FX::x && (ix>=cx-step || map[ix+step][iy]==wb))
            bw += 1000; //1001 左和下 1010 右和下 1011 右下左 1111 被包围
        return bw;

    }
    int bwallinface2(){         //检测箱子前面有墙或箱子吗
        switch (fx)
        {
        case FX::z:
            if (bwall(1,2,1)==1 || bwall(2,2,1)==1)
                return true;
             break;
        case FX::s:
                  if (bwall(1,2,1)==100 || bwall(2,2,1)==100)
                return true;
             break;
        case FX::y:
               if (bwall(1,2,1)==10 ||bwall(2,2,1)==10)
                return true;
             break;
        case FX::x:
                  if (bwall(1,2,1)==1000 || bwall(2,2,1)==1000)
            return true;
        }
        return false;
    }
    int bboxinface(){         //面前有箱子吗
        switch (fx)
        {
        case FX::z:
            if (bwall(2)==1)
                return true;
             break;
        case FX::s:
                  if (bwall(2)==100)
                return true;
             break;
        case FX::y:
               if (bwall(2)==10)
                return true;
             break;
        case FX::x:
                  if (bwall(2)==1000)
            return true;
        }
        return false;
    }
    bool bcheckwin(){       //查检胜利条件,没有空家了(全被塞进箱子了。。)
        int count=0;
        for (int i=0;i<cy;i++)
        {
            for (int j=0;j<cx;j++)
            {
                if (map[i][j]==3)
                    count++;
            }
        }
        if (count>=1)
            return false;
        else
            return true;
    }
    int bwallinface()    //检测面前有墙吗
    {
        switch (fx)
        {
        case FX::z:
            if (bwall(1)==1)
                return true;
             break;
        case FX::s:
                  if (bwall(1)==100)
                return true;
             break;
        case FX::y:
               if (bwall(1)==10)
                return true;
             break;
        case FX::x:
                  if (bwall(1)==1000)
                return true;
        }
        return false;
    }

    void loadmap(){   //手工地图,下一个版本可以改关卡文件
            //map[x][y]
            map[0][0]=0;map[0][1]=0;map[0][2]=0;map[0][3]=0;map[0][4]=0;map[0][5]=1;map[0][6]=0;map[0][7]=0;map[0][8]=0;map[0][9]=0;
              map[1][0]=0;map[1][1]=1;map[1][2]=1;map[1][3]=0;map[1][4]=0;map[1][5]=1;map[1][6]=0;map[1][7]=0;map[1][8]=0;map[1][9]=0;
            map[2][0]=0;map[2][1]=0;map[2][2]=0;map[2][3]=0;map[2][4]=0;map[2][5]=1;map[2][6]=0;map[2][7]=0;map[2][8]=0;map[2][9]=0;
              map[3][0]=0;map[3][1]=0;map[3][2]=2;map[3][3]=0;map[3][4]=0;map[3][5]=0;map[3][6]=0;map[3][7]=2;map[3][8]=0;map[3][9]=0;
            map[4][0]=0;map[4][1]=0;map[4][2]=2;map[4][3]=0;map[4][4]=0;map[4][5]=0;map[4][6]=0;map[4][7]=0;map[4][8]=0;map[4][9]=0;
              map[5][0]=1;map[5][1]=1;map[5][2]=0;map[5][3]=1;map[5][4]=0;map[5][5]=0;map[5][6]=0;map[5][7]=0;map[5][8]=0;map[5][9]=0;
            map[6][0]=0;map[6][1]=0;map[6][2]=0;map[6][3]=0;map[6][4]=1;map[6][5]=0;map[6][6]=1;map[6][7]=0;map[6][8]=0;map[6][9]=0;
              map[7][0]=0;map[7][1]=0;map[7][2]=3;map[7][3]=0;map[7][4]=0;map[7][5]=0;map[7][6]=0;map[7][7]=1;map[7][8]=0;map[7][9]=0;
            map[8][0]=0;map[8][1]=0;map[8][2]=3;map[8][3]=3;map[8][4]=0;map[8][5]=0;map[8][6]=0;map[8][7]=1;map[8][8]=0;map[8][9]=0;
            map[9][0]=0;map[9][1]=0;map[9][2]=0;map[9][3]=0;map[9][4]=0;map[9][5]=0;map[9][6]=0;map[9][7]=1;map[9][8]=0;map[9][9]=0;
            for (int i=0;i<cx;i++)
            {
                for (int j=0;j<cy;j++)
                {
                    bakmap[i][j]=map[i][j];
                }
            }
    }
    void printawall(bool breturn=false) //画一个墙
    {
        if (!breturn)
            printf("%c%c",wall1,wall2);
        else
            printf("%c%c\n",wall1,wall2);
    }
    void printwall()   //画一行墙
    {
        for (int i=0;i<cy+2;i++)
            printawall();
        printf("\n");
    }
    void printbox()  //画箱子
    {
        printf("%c%c",0xA1,0xF6);
    }

    void printdot()  //画个点代表家
    {
        printf("%c%c",0xA1,0xA4);
    }

    void showmap(){           //show map显示地图
        system("cls");          //清屏
        printwall();          //打印一行墙
        for (int i=0; i<cx; i++) {
             printawall();
            for (int j=0; j<cy; j++) {
                 if (i==ix && j==iy)
                    printf("%c%c",1,2); //fx);  //精灵
                 else
                    printmap(map[i][j]);
            }
             printawall(true);
        }
         printwall();
    }

    void printmap(int numb)  //打印物品
    {
        switch (numb)
        {
        case 1:
            printawall();
            break;
        case 2:
            printbox();
            break;
        case 3:
            printdot();
            break;

        default:
            printf("%c%c",numb,numb);
        }

    }
};

//main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>

#include "k.h"

#define RIGHT  77
#define LEFT   75
#define UP     72
#define DOWN   80
#define REST   114

void main ()
{
reset:
    K k001(0,0,K::FX::y);
    int key =0;

    while (1) {
    if(kbhit())
        key=getch();
    if (key!=0 && key!=224){
        switch(key){
        case RIGHT:
            k001.setfx (K::FX::y);
            k001.move ();
            break;
        case UP:
            k001.setfx (K::FX::s);
            k001.move ();
            break;
        case LEFT:
            k001.setfx (K::FX::z);
            k001.move ();
            break;
        case DOWN:
             k001.setfx (K::FX::x);
             k001.move ();
            break;
        case REST:  //r键复位
            goto reset;
            break;
        default:

            break;

        }
    }
        key=0;
    }

}
时间: 2024-10-07 23:26:55

推箱子小游戏的相关文章

Qt实现推箱子小游戏

学习Qt有一个月了,想要实现一个推箱子的游戏来检验一下自己.今天先设计一下将要完成的具体表现,因为是第一次做,所以设计的稍微简单点,以后逐渐修改.首先要创建菜单栏,分为三个主菜单: ①游戏 ②选择关卡 ③关于 (1)游戏主菜单下分为: ①开始游戏 ②重新开始 ③结束游戏 (2)选择关卡分为 ①前一关卡 ②后一关卡 ③选择关卡, (3)关于则弹出游戏的信息 主要使用以下几个类: 1.QPainter绘制地图 2.QMenu.QAction制作菜单栏 3.QKeyEvent接收键盘事件 控制人物行走

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

下载了一款推箱子小游戏,第13关的时候怎么也破不了最佳纪录(最少步数是9而我们最好的方案是10步),因为数据比较小(6*8的方阵),所以写了个BFS来找最短路. 游戏的目标是把小黄人推到黄色球,小绿人推到绿色球,有个限制是,小黄/绿人运动时会沿某一个方向一直走直到遇到边界或者障碍物,如果途中遇到传送带还会改变运动方向. -----------------------------------------------------------------------------------------

来点福利,看二维数组如何打造推箱子小游戏

C语言学好,通杀C++.这就是方向之一. 前面看过的读者,是不是觉得很鸡肋的知识,全是基本的运用,可是呢?还是看不出能干吗. 那么下面就用二维数组打造,推箱子小游戏.首先,得问问,有何思路? 光写没有用,没到一部分内容觉得可以了,最好先打印下看看效果,要不然写到都不知道自己有没有写错! 效果如图: 打印这部成功后,可以继续了,没有成功者,仔细检查,错误超出一百以上那肯定是头文件的问题. 这步很关键,没有定位,很难移动,几乎全是报错 这步也能首先打印初始化的坐标. 既然定位坐标的情况已经做好,是不

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

/* 推箱子小游戏 1.定义绘制样式 用二维数组的方式 2.绘制图像 3.找出当前位置 4.逻辑判断,制造动作 根据数学xy轴的规律,这里使用ij 上移,行轴上升,行数减少 下移,行数下降,函数增加 左移,列数向左,列数减少 右移,列数向右,列数增加 */ #include <stdio.h> #include <stdlib.h> #include <conio.h> #define ROWS 8 //行数 #define COLS 9 //列数 int i = 0;

用C#制作推箱子小游戏

思路分析: 一.制作一个地图 二.地图中放置墙.箱子.人.目标等 三.让小人动起来完成推箱子动作 游戏制作: 1.按照上述地图制作一个地图  (12行×13列) 地图可以看做是行和列组成的,即可以看做是由二维数组组成的 2.实体化:将0转换为空格,1转换为黑色方块 3.设置箱子.人.目标点 4.先让小人动起来,实现小人向上移动,因为坐标的交换,所以箱子向下移动了,同理,改变坐标可以实现向左.向下.向右移动 向下移动:y+1;向左移动:x-1;向右移动:x+1; 5.实现推箱子,以向上移动为例,其

c语言实现的推箱子小游戏-1

本次游戏是个推箱子第一关最简单的小游戏 有详细注释,下面是做出来的游戏界面 游戏操作说明和功能说明: 按wasd控制小人的上下左右移动. 按 r 重新开始游戏 游戏开始有操作介绍 游戏结束有胜利提示 游戏原理分析 游戏开始时的星星个数 = 箱子在星星上的个数时 , 游戏胜利. 按 r 键重新开始游戏, 我们需要定义一个量 map_1[8][8] 来保存游戏初始时的界面, 操作时我们将其赋值给 map[8][8] 来进行操作,以便重新归位, 这里就用到了memcpy()函数. wasd 代表上下左

Java实现推箱子小游戏

package Test1; //用于调用Test2包 import Test2.*; import java.awt.*; import javax.swing.*; public class APP extends JFrame{ public static void main(String[] args) { // TODO Auto-generated method stub APP a = new APP(); } public APP() { new Members(); } } p

15-07-09 二维数组-- 推箱子小游戏

1 int a = 2, b = 1;//人的初始坐标 2 #region 造地图 3 int[,] map = new int[10,10]{ 4 {8,8,8,8,8,8,8,8,8,8}, 5 {8,0,0,0,0,0,8,8,0,8}, 6 {8,1,2,0,0,8,8,8,0,8}, 7 {8,0,0,0,0,8,8,8,0,8}, 8 {8,0,0,0,0,0,8,8,0,8}, 9 {8,0,8,0,0,0,8,8,0,8}, 10 {8,0,8,8,0,0,8,8,0,8}, 1

js+Jquery 制作推箱子小游戏

<!DOCTYPE html> <html> <head> <title>Sokaban</title> <meta charset="utf-8"> <style type="text/css"> .roads { width: 50px; height: 50px; background: url(img/roods.png); background-size: 100% 100