推箱子小游戏

这一生的挚爱 提交于 2020-01-20 13:16:12
//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;
    }

    
}

    

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!