代码拉取完成,页面将自动刷新
同步操作将从 Anbang24/cgames 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
//https://gitee.com/devcpp/cgames anbangli@foxmail.com GNU GPL v3
//cgame4(boxes)v1 推箱子游戏第1版:实现推箱子基本功能
#include <iostream>
#include <windows.h>
#include <conio.h>
using namespace std;
const int HT = 20, WD = 24; //表示地图高度和宽度的整型常量
char map[HT][WD] = {""}; //关卡地图二维数组
bool initMap(int level, int &x, int &y) {//初始化第 level 关,并获得人的坐标(x, y)
char st[HT][WD + 1] = {""};
// @ 人 + 人在目标点 $ 箱子 * 箱子在目标点 # 墙 . 目标点 _ 空地
if (level == 1) {
strcpy(st[0], "__###___");//snail 1
strcpy(st[1], "__#.#___");
strcpy(st[2], "__#_####");
strcpy(st[3], "###$_$.#");
strcpy(st[4], "#._$@###");
strcpy(st[5], "####$#__");
strcpy(st[6], "___#.#__");
strcpy(st[7], "___###__");
} else if (level == 2) {
strcpy(st[0], "#####____");//snail 2
strcpy(st[1], "#@__#____");
strcpy(st[2], "#_$$#_###");
strcpy(st[3], "#_$_#_#.#");
strcpy(st[4], "###_###.#");
strcpy(st[5], "_##____.#");
strcpy(st[6], "_#___#__#");
strcpy(st[7], "_#___####");
strcpy(st[8], "_#####___");
} else if (level == 3) {
strcpy(st[0], "_####_");//snail 3
strcpy(st[1], "##__#_");
strcpy(st[2], "#_@$#_");
strcpy(st[3], "##$_##");
strcpy(st[4], "##_$_#");
strcpy(st[5], "#.$__#");
strcpy(st[6], "#..*.#");
strcpy(st[7], "######");
} else if (level == 4) {
strcpy(st[0], "_####___");//snail 4
strcpy(st[1], "_#__###_");
strcpy(st[2], "_#@$__#_");
strcpy(st[3], "###_#_##");
strcpy(st[4], "#.#_#__#");
strcpy(st[5], "#.$__#_#");
strcpy(st[6], "#.___$_#");
strcpy(st[7], "########");
} else if (level == 5) {
strcpy(st[0], "_#######__");//boxxle 1 5
strcpy(st[1], "_#_____###");
strcpy(st[2], "##$###___#");
strcpy(st[3], "#_@_$__$_#");
strcpy(st[4], "#_..#_$_##");
strcpy(st[5], "##..#___#_");
strcpy(st[6], "_########_");
} else {
return false;
}
int ix, iy;
//找出新地图的高度和宽度(非空格点的二维最大下标值+1)
int hgt = 0, wid = 0;
for (iy = 0; iy < HT; iy++)
for (ix = 0; ix < WD; ix++) {
if (st[iy][ix] == '-' || st[iy][ix] == ' ' )
st[iy][ix] == '_'; //把'-'和' '替换为'_'
if (st[iy][ix] > 0 && st[iy][ix] != '_') {
hgt = (hgt > iy + 1 ? hgt : iy + 1);
wid = (wid > ix + 1 ? wid : ix + 1);
}
}
//原地图全部清空
for (iy = 0; iy < HT; iy++)
for (ix = 0; ix < WD; ix++)
map[iy][ix] = '_';
//把新地图的信息复制到数组的中央部分
int yup = (HT - hgt) / 2;
int xleft = (WD - wid) / 2;
for (iy = 0; iy < hgt; iy++)
for (ix = 0; ix < wid; ix++) {
map[iy + yup][ix + xleft] = st[iy][ix];
if (map[iy + yup][ix + xleft] == '@') {
x = ix + xleft;
y = iy + yup;
}
}
return true;
}
void gotoxy(short x, short y) { //控制台窗口光标定位
COORD crd = {x, y}; //定义 COORD 类型(窗口坐标)的变量 crd 并以形参x和y初始化
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), crd);
//GetStdHandle获取控制台输出句柄并用SetConsoleCursorPosition设置光标位置
return;
}
void drawMap(int level) { //绘制地图
gotoxy(0, 0); //定位到窗口左上角
cout << "\n\t\t推箱子 第【" << level << "】关\n";
int ix, iy;
for (iy = 0; iy < HT; iy++) { //行循环
for (ix = 0; ix < WD; ix++) { //列循环
if (map[iy][ix] == '#')
cout << "█"; //墙
else if (map[iy][ix] == '$')
cout << "□"; //箱子
else if (map[iy][ix] == '.')
cout << "☆"; //目标点
else if (map[iy][ix] == '@')
cout << "@"; //人
else if (map[iy][ix] == '+')
cout << "◎"; //人站在目标点上
else if (map[iy][ix] == '*')
cout << "★"; //箱子在目标点上
else //空地:空格、'-' 或 '_'
cout << " ";
}
cout << endl;
}
gotoxy(0, 0); //光标移到窗口左上角
return;
}
bool isWin() { //判断是否胜利
int ix, iy;
for (iy = 0; iy < HT; iy++)
for (ix = 0; ix < WD; ix++)
if (map[iy][ix] == '$') //若有空闲箱子则尚未胜利
return false;
return true; //没有空闲箱子为胜利
}
int main() {
int x, y, dx = 1, dy = 1; //(x,y)是人的位置坐标,dx和dy是移动量(初始化为非0值)
int x2, y2, x3, y3; //(x2, y2)和(x3, y3)是两个位置坐标
char key;
int level = 0; //关卡编号
if (!initMap(++level, x, y)) { //初始化地图并找出初始坐标(x, y),处理可能的出错
cout << "\n\t\t读取第 " << level << " 关地图出错。" << endl;
return 0;
}
while (true) {
if (dx != 0 || dy != 0)
drawMap(level); //绘制地图
if (isWin()) { //胜利通过本关
cout << "\n\n\t\t恭喜你过了第 " << level << " 关!\a";
getch();
if (!initMap(++level, x, y)) { //初始化地图并找出初始坐标(x, y),处理出错
cout << "\n\t\t读取第 " << level << " 关地图出错。" << endl;
break;
}
continue; //结束此次循环,开始新的循环
}
dx = dy = 0;
key = getch(); //获得字符输入
if (key <= 0 || key > 127) //读取方向键时,第一次读得的不是实际键值
key = getch(); //读取方向键时,第二次才读得实际键值
if (key == 75 || key == 'a' || key == 'A') //left
dx = -1;
else if (key == 77 || key == 'd' || key == 'D') //right
dx = 1;
else if (key == 72 || key == 'w' || key == 'W') //up
dy = -1;
else if (key == 80 || key == 's' || key == 'S') //down
dy = 1;
else if (key == 'z' || key == 'Z') //撤消(留待后面处理)
;
else if (key == 27) { //ESC
gotoxy(0, HT);
cout << "\t\t结束游戏(Y/N)?";
if ((key = getch()) == 'Y' || key == 'y') {
break;
} else
cout << "\r ";
break;
}
if (dx == 0 && dy == 0)
continue;
x2 = x + dx;
y2 = y + dy;
x3 = x2 + dx;
y3 = y2 + dy;
if ((map[y2][x2] == '$' || map[y2][x2] == '*') && (map[y3][x3] == '_' || map[y3][x3] == '.')) {
//小人前面是箱子或 箱子+目标点,而且箱子前面是空地或目标点,箱子可推动
map[y3][x3] = (map[y3][x3] == '_' ? '$' : '*'); //箱子新位置
map[y2][x2] = (map[y2][x2] == '$' ? '_' : '.'); //箱子原位置
}
if (map[y2][x2] == '_' || map[y2][x2] == '.') { //小人前面是空地或目标点,可移动
map[y2][x2] = (map[y2][x2] == '_' ? '@' : '+'); //新位置变为人或"人+目标点"
map[y][x] = (map[y][x] == '@' ? '_' : '.'); //原位置变为空地或目标点
y = y + dy; //更新人的位置坐标y
x = x + dx; //更新人的位置坐标x
}
}
cout << "\n\t\t游戏结束,谢谢使用";
getchar();
return 0;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。