C语言编写推箱子源代码

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include <windows.h> //这些头文件定义了Windows的所有资料型态、函数调用、资料结构和常数识别字
#include <stdio.h>
#include <conio.h> //从控制台无回显地取一个字符 用 法: int getch(void); 用 法: int getch(void);
#include <vector> //vector容器是一个模板类,可以存放任何类型的对象(但必须是同一类对象)。
#include <string> //string.h>是标准C提供的字符处理函数集。面向char
#include <iostream> //基本输入流
using namespace std; //std 是规定的(标识符)名字,它表示标准库的名字结合体.
#define ENTER 13
#define ESC 27
#define SPACE 32
#define UP 72
#define LEFT 75
#define RIGHT 77
#define DOWN 80
#define ARROW 224
class Man //在C++中用class定义的类中,其成员的默认存取权限为private
{
friend class Map; //C++中以关键字friend声明友元关系。友元可以访问与其有friend关系的类中的私有成员。
int getx(){
return x;
}
int gety(){
return y;
}
private: //private 私有型;自己的类可以访问,但派生类不能访问。
int x,y;
};
class Direction{
friend class Map;
public:
Direction();
Direction(int x,int y){
this->x=x;
this->y=y;
}
private:
int x;
int y;
};
class CException
{
public:
CException(string s){
r=s;
};
void Reason(){
cout<<endl<<r<<endl;
exit(0);
}
private:
string r;
};
class Map{
public:
Map();
void LoadMap(); // 从文件中载入地图
void ClearMap();// 地图清空
void NewMap();// 地图重置
void SelectMap();// 地图选关
void show(); // 地图显示
void JudgeMap();// 判断是否过关
void move(short heading);// 人和箱子的移动
void GetKey(); // 判断按键
private:
char map[100]; // 数组用来存储地图
int maxx; // 地图的横坐标
int maxy; // 地图的纵坐标
int level; // 关数
Man p; // 定义一个人的对象
vector<Direction> v1; // 定义目标地的对象的vector
HANDLE hOut;
COORD MainPos;
};
//地图初始构造
Map::Map()
{
hOut=GetStdHandle(STD_OUTPUT_HANDLE); //获得句柄
COORD size={80, 25};
COORD MainPos={0, 5};
COORD TopLeft={0,0};
level=1; //初始关卡为1。
SetConsoleOutputCP(936);
SetConsoleTitleA("简易推箱子");
SetConsoleScreenBufferSize(hOut, size);
SetConsoleTextAttribute(hOut, FOREGROUND_BLUE|FOREGROUND_GREEN); //黄色
SetConsoleCursorPosition(hOut, TopLeft);
WriteConsoleA(hOut, " 推箱子操作提示: \n\n", 20, 0, 0);
WriteConsoleA(hOut, " | ENTER——选关 |\n | SPACE——重新开始 |\n | ESC———退出 |\n", 80, 0, 0);
}
//地图读取
void Map::LoadMap()
{
int ch;
char *p=Map::map;
char flag=1;
FILE *f;
//选择读取的地图关卡(包含选择关卡异常的处理)
try{
switch(level)
{

case 1:
{if((f=fopen("box01.txt", "r"))==0) throw CException("Failed to
open the Map01无法显示,请从新再来!!!\n");
break;}
case 2:
{if((f=fopen("box02.txt", "r"))==0) throw CException("Failed to open the Map02无法显示,请从新再来!!!\n");
break;}
case 3:
{if((f=fopen("box03.txt", "r"))==0) throw CException("Failed to open the Map03无法显示,请从新再来!!!\n");
break;}
case 4:
{if((f=fopen("box04.txt", "r"))==0) throw CException("Failed to open the Map04无法显示,请从新再来!!!\n");
break;}
case 5:
{if((f=fopen("box05.txt", "r"))==0) throw CException("Failed to open the Map05 无法显示,请从新再来!!!\n");
break;}
default:
throw CException("没有此关卡!!\n");
}
}catch(CException e){
e.Reason();
}
maxy=1;
while ((ch=fgetc(f))!=EOF)
{
if (ch!='\r' && ch!='\n')
*p++=ch;
else
{maxx=p-map; break;}
}
while ((ch=fgetc(f))!=EOF)
{
if (ch!='\r' && ch!='\n')
{
if (flag)
{
maxy++;
flag=0;
}
*p++=ch;
}
else if (ch=='\n')
flag=1;
}
}
//地图清空
void Map::ClearMap()
{
v1.clear(); //清空容器
COORD MainPos={0, 5};
FillConsoleOutputCharacter(hOut, ' ', 1800, MainPos, 0);
}
//地图重置
void Map::NewMap()
{
Map::ClearMap ();
Map::LoadMap();
Map::show();
}
//地图选关
void Map::SelectMap()
{
COORD Set={25,12};
SetConsoleCursorPosition(hOut, Set);
cout<< "Please change the level:";
cin>>level;
Map::NewMap();
}
//地图显示
void Map::show()
{
COORD pos={0,7},MainPos={0, 5};
short i, j, p=0;
ClearMap();
SetConsoleCursorPosition(hOut, pos);
for (i=0; i<maxy; i++)
{
for (j=0; j<maxx; j++)
{
switch (map[i*maxx+j])
{
case 'B': //显示箱子
SetConsoleTextAttribute(hOut, FOREGROUND_BLUE|FOREGROUND_INTENSITY); //蓝色
WriteConsoleA(hOut, "■", 2, 0, 0);
break;
case 'D': //显示目标
{
Direction a(j,i);
v1.push_back(a);
SetConsoleTextAttribute(hOut, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY); //黄色
WriteConsoleA(hOut, "◆", 2, 0, 0);
break;}
case 'P': //显示推箱者
this->p.x=j;
this->p.y=i;
SetConsoleTextAttribute(hOut, FOREGROUND_RED|FOREGROUND_INTENSITY); //红色
WriteConsoleA(hOut, "★", 2, 0, 0);
break;
case 'W': //显示墙
SetConsoleTextAttribute(hOut, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); //白色
WriteConsoleA(hOut, "■", 2, 0, 0);
break;
default: //显示空地
SetConsoleTextAttribute(hOut, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); //白色
WriteConsoleA(hOut, " ", 2, 0, 0);
}
}
pos.Y++;
SetConsoleCurso

rPosition(hOut, pos);
}
SetConsoleCursorPosition(hOut, MainPos);
SetConsoleTextAttribute(hOut, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND
_BLUE); //白色
}
//判断是否过关
void Map::JudgeMap()
{
char win=1;
short p=0;
COORD Win={25,10};
vector<Direction>::iterator iter1;
iter1=v1.begin();
COORD pos;
SetConsoleTextAttribute(hOut, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY); //黄色
while (iter1!=v1.end())
{
if (map[iter1->y*maxx+iter1->x]!='B') //判断目标地上是否为箱子
{
win=0;
if (iter1->x!=this->p.x || iter1->y!=this->p.y)
{
pos.X=iter1->x<<1;
pos.Y=iter1->y+7;
SetConsoleCursorPosition(hOut, pos);
WriteConsoleA(hOut, "◆", 2, 0, 0);
}
}
iter1++;
}
SetConsoleCursorPosition(hOut, MainPos);
if (win)
{
SetConsoleCursorPosition(hOut, Win);
WriteConsoleA(hOut, "Congratulation! You Win. \n", 25, 0, 0);
Map::SelectMap();
}
}
//人和箱子的移动
void Map::move(short heading)
{
int x=p.getx();
int y=p.gety();
COORD pos={x<<1 ,y+7};
SMALL_RECT rc={x<<1, y+7, (x<<1)+1, y+7};
CHAR_INFO chFill;
chFill.Attributes=FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE; //白色
chFill.Char.AsciiChar=' ';
switch (heading)
{
case UP:
if (y>0)
{
if (map[(y-1)*maxx+x]!='B' && map[(y-1)*maxx+x]!='W') //人上面不是箱子或墙,人上移
{
p.y--;
pos.Y--;
}
else if (y>1 && map[(y-1)*maxx+x]=='B' && map[(y-2)*maxx+x]!='B' && map[(y-2)*maxx+x]!='W') //人的上面是箱子,箱子的上面不是箱子或墙,箱子和人上移
{
map[(y-1)*maxx+x]='P';
map[(y-2)*maxx+x]='B';
p.y--;
pos.Y-=2;
rc.Top--;
}
}
else return; //剩余的不动
break;
case LEFT:
if (x>0)
{
if (map[y*maxx+x-1]!='B' && map[y*maxx+x-1]!='W') //人左面不是箱子或墙,人左移
{
p.x--;
pos.X-=2;
}
else if (x>1 && map[y*maxx+x-1]=='B' && map[y*maxx+x-2]!='B' && map[y*maxx+x-2]!='W') //人的左面是箱子,箱子的左面不是箱子或墙,箱子和人左移
{
map[y*maxx+x-1]='P';
map[y*maxx+x-2]='B';
p.x--;
pos.X-=4;
rc.Left-=2;
}
}
else return;
break;
case RIGHT:
if (x<maxx-1)
{
if (map[y*maxx+x+1]!='B' && map[y*maxx+x+1]!='W') //人右面不是箱子或墙,人右移
{
p.x++;
pos.X+=2;
}
else if (x<maxx-2 && map[y*maxx+x+1]=='B' && map[y*maxx+x+2]!='B' && map[y*maxx+x+2]!='W') //人的右面是箱子,箱子的右面不是箱子或墙,箱子和人右移
{
map[y*maxx+x+1]='P';
map[y*maxx+x+2]='B';
p.x++;
pos.X+=2;
rc.Right+=2;
}
}

else return;
break;
case DOWN:
if (y<maxy-1)
{
if (y<maxy-1 && map[(y+1)*maxx+x]!='B' && map[(y+1)*maxx+x]!='W') //人下面不是箱子或墙,人下移
{
p.y++;
pos.Y++;
}
else if (y<maxy-2 && map[(y+1)*maxx+x]=='B' && map[(y+2)*maxx+x]!='B' && map[(y+2)*maxx+x]!='W') //人的下面是箱子,箱子的下面不是箱子或墙,箱子和人下移
{
ma
p[(y+1)*maxx+x]='P';
map[(y+2)*maxx+x]='B';
p.y++;
pos.Y++;
rc.Bottom++;
}
}
else return;
break;
}
ScrollConsoleScreenBuffer(hOut, &rc, 0, pos, &chFill);
JudgeMap();
}
//获取指令
void Map::GetKey()
{
switch (getch())
{
case ENTER: SelectMap(); break; //选关
case ESC: CloseHandle(hOut); exit(0); break; //退出
case SPACE: Map::NewMap(); break; //重置地图
case ARROW: //移动
switch (getch())
{
case UP: move(UP); break;
case LEFT: move(LEFT); break;
case RIGHT: move(RIGHT); break;
case DOWN: move(DOWN); break;
}
}
}
int main()
{
Map map1;
map1.LoadMap();
map1.show();
while(1)
{
map1.GetKey();
}
return 0;
}


相关文档
最新文档