推箱子小游戏
//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 = '>', //朝右Yz = '<', //左 -Ys = '^', //上 -Xx = '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];elsemap[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];elsemap[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];elsemap[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];elsemap[ix+1][iy]=0;map[ix+2][iy]=2;}move();if (bcheckwin()) //贏了...地圖格式like this,1是墻,2是箱,3是放箱子的。下面這樣就行/*00000000012210000133100001111000*/{ 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;elsereturn 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);elseprintf("%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); //精靈elseprintmap(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 114void 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;}}
?
轉載于:https://www.cnblogs.com/wwl188/p/5165006.html
總結
- 上一篇: C++中,引用作为函数参数
- 下一篇: .NET Core 和 .NET Fra