C++打小怪游戏

发布于:2024-12-23 ⋅ 阅读:(14) ⋅ 点赞:(0)

开头

大家好,我叫这是我58

程序

Game.cpp

#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
using namespace std;
#include "Player.h"
#include "mosters.h"
#include "cmpm.h"
#include "isvp.h"
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <string>
#include <cstring>
#include <Windows.h>
#include "draw.h"
enum difficulty {//难度
	EASY,
	NORMAL,
	HARD,
	LIMIT
};
void MShow(moster*& mp) {
	('X' == mp->getm() || '*' != *mp->getcp()) && (*mp->getcp() = mp->getm());//左边条件防出bug
}
void del(moster*& mp) {
	delete mp;
}
void delvo(M_o*& mp) {
	delete mp;
}
void setMempty(moster*& mp) {
	'*' != *mp->getcp() && (*mp->getcp() = ' ');//左边条件也防出bug
}
void start(int ichoose) {//开始时打印大字函数
	switch (ichoose) {
	case 14:
		cout << "      *                  *          *           " << endl;
	case 13:
		cout << "      *                  *          * ********  " << endl;
	case 12:
		cout << "      *  ********        *          *  *     *  " << endl;
	case 11:
		cout << "   ******    *           *        * **  *   *   " << endl;
	case 10:
		cout << "      *      *           *        * * *  * *    " << endl;
	case 9:
		cout << "      * *    *        *  *  *     * *     **    " << endl;
	case 8:
		cout << "     ***     *       **  *   *   *  *   **  *   " << endl;
	case 7:
		cout << "   ** *      *      *    *    *     * **  *  ** " << endl;
	case 6:
		cout << "      *      *     *     *    **    *     *     " << endl;
	case 5:
		cout << "      *      *    *      *     *    *     *     " << endl;
	case 4:
		cout << "      *      *           *          *  *******  " << endl;
	case 3:
		cout << "      *      *           *          *     *     " << endl;
	case 2:
		cout << "      *      *           *          *     *     " << endl;
	case 1:
		cout << "    * *    * *         * *          * ********* " << endl;
	case 0:
		cout << "     *      *           *           *           " << endl;
	default:
		break;
	}
} 
void win(int ichoose) {//胜利后打印函数
	switch (ichoose) {
	case 14:
		cout << "      *   *            *           *  *                       *  *              *                     " << endl;
	case 13:
		cout << "      *   *       ************     *  *                       *  *        ************** *************" << endl;
	case 12:
		cout << "   ************        *           *  *                       *  *         *                        * " << endl;
	case 11:
		cout << "      *   *        **********     *  ********                *  ********   ************            *  " << endl;
	case 10:
		cout << "      *   *                       *  *      *                *  *      *    *       *            **   " << endl;
	case 9:
		cout << "  **************   **********    ** *      *                ** *      *     *********          **     " << endl;
	case 8:
		cout << "      *    *       *        *   * *     *                  * *     *                           *      " << endl;
	case 7:
		cout << "     *  *   *      **********     *     *                    *     *      *** ***** ***        *      " << endl;
	case 6:
		cout << "    *   *    *       *    *       *   * * *                  *   * * *    * * *   * * *        *      " << endl;
	case 5:
		cout << "  **    *     ** **************   *   * *  *      **         *   * *  *   *** *   * * *        *      " << endl;
	case 4:
		cout << "     *  **  *                     *  *  *  **     **         *  *  *  **  * * * * * ***        *      " << endl;
	case 3:
		cout << "    *   * *  *     *********      * *   *   *      *         * *   *   *  *** * * * * *        *      " << endl;
	case 2:
		cout << "   *    * *  *     *       *      *     *         *          *     *      * *   *   * *        *      " << endl;
	case 1:
		cout << "      * *          *********      *   * *        *           *   * *      * *  * * *  **     * *      " << endl;
	case 0:
		cout << "       *           *       *      *    *                     *    *      *  * *   *    *      *       " << endl;
	default:
		break;
	}
}
int main() {
	srand((unsigned int)time(NULL));
	char strmap[11][11] = {//地牢图
		'*','*','*','*','*','*','*','*','*','*','*',
		'*',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',
		'*',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',
		'*',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',
		'*',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',
		'*',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',
		'*',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',
		'*',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',
		'*',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',
		'P',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',
		'*','*','*','*','*','*','*','*','*','*','*',
	};
	bool ba = 1;
	bool bb = 1;
	bool bc = 1;
	char ch = 0;
	int iunmd = 0;
	vector<M_o*>vo;//小BOSS战时需要
	vector<draw>vmd[5] = { {{5,2,6,1}}, {{3,2,4,0}, {7,2,3,1}, {3,5,4,0}, {3,5,3,1}, {3,8,4,0}}, {{3,2,4,0},{3,5,4,0},{3,8,4,0},{7,2,6,1}}, {{3,2,3,1},{3,5,4,0},{7,2,6,1}}, {{5,3,4,1},{3,5,4,0}} };//<-画“#”时所需要的数组
	multimap<int, int>mwasd[4] = { {{9,1},{9,3},{3,3},{5,3},{7,3},{9,3},{8,4},{8,8},{6,8},{4,8}}, {{2,3},{9,9},{3,8},{5,8},{7,8},{9,2}}, {{2,2},{2,7},{1,9}}, {{1,1},{2,4},{4,3},{6,3},{8,3},{8,7}} };//<-画“#”时所需要的数组
	vo.reserve(99999);
	int i = 0;
	int temparr[6] = { 4, 8, 12, 15, 17, 18 };
	int ia = rand() % 10 + 1;// 后:+1 +1 +1 +1 +2 +2 +2 +2 +3 +3 +3 +3 +4 +4 +4 +5 +5 +6
	int tempir = rand() % 22;
	for (i = 0; i < 6; i++) {
		if (tempir < temparr[i]) {
			ia += (i + 1);
			break;
		}
	}
	Player p;
	char* cp = &strmap[9][0];
	vector<map<int, int>>vm;
	map<char**, WASD>m[3];
	map<char**, WASD>em;//追踪map
	char* cparr[45] = { NULL };
	char** cpp = cparr;
	for (WASD w = W; E != w; ++w) {//第5地牢的怪物移动路线
		switch (w) {
		case W:
			for (i = 1; i < 5; i++) {
				*cpp = &strmap[10 - i][i];
				m[0].insert({cpp++, W});
			}
			break;
		case A:
			for (i = 6; i < 10; i++) {
				*cpp = &strmap[i][i];
				m[0].insert({cpp++, A});
			}
			break;
		case S:
			for (i = 1; i < 5; i++) {
				*cpp = &strmap[i][10 - i];
				m[0].insert({cpp++, S});
			}
			break;
		case D:
			for (i = 1; i < 5; i++) {
				*cpp = &strmap[i][i];
				m[0].insert({cpp++, D});
			}
			break;
		default:
			break;
		}
		for (multimap<int, int>::iterator it = mwasd[w].begin(); mwasd[w].end() != it; it++) {
			*cpp = &strmap[it->first][it->second];
			m[1].insert({ cpp++, w });
		}
	}
	const int arr[4] = { 6,9,1,5 };
	for (i = 0; i < 4; i++) {
		*cpp = &strmap[arr[i]][i % 2 + 1];
		m[2].insert({ cpp++, (WASD)(i / 2 * 2) });//注意:i / 2 * 2 != i
	}
	char strmapr[11][11];
	isv ism;//用来布置怪物
	vector<isv> vism;//地牢布置与怪物布置,无时即BOSS战(+)(int为编号)
	vism.reserve(11000);//防bug出
	char* strcp[47] = { &strmap[9][5], &strmap[9][7], &strmap[9][3], &strmap[1][5], &strmap[1][5], &strmap[6][1], &strmap[4][9], &strmap[6][8], &strmap[3][3], &strmap[4][3], &strmap[5][3], &strmap[6][3], &strmap[7][3], &strmap[8][3], &strmap[9][3], &strmap[4][5], &strmap[5][4], &strmap[5][5], &strmap[5][6], &strmap[6][5], &strmap[1][5], &strmap[1][5], &strmap[9][5], &strmap[9][5], &strmap[1][9], &strmap[1][1], &strmap[8][2], &strmap[2][8], &strmap[8][8], &strmap[2][2], &strmap[5][5], &strmap[1][1], &strmap[2][2], &strmap[3][3], &strmap[4][4], &strmap[8][5], &strmap[5][2], &strmap[2][4], &strmap[4][9], &strmap[1][8], &strmap[9][2], &strmap[1][1], &strmap[9][9], &strmap[3][4], &strmap[5][1], &strmap[5][9], &strmap[5][5]};//生成时要的怪物坐标
	vector<moster*>mpv;//mpv里一共要有的怪物们
	char tempstr[9] = "color 0";//为告知你胜利的文字颜色
	char tempstra[10][2] = { "C", "E", "A", "9", "D", "9", "A", "E", "C" };//大文字动态彩色变化数组(system("color 0" + tempstra[x(0<=x<=9)])
	mpv.reserve(10000);//也防bug出
	//随机设置地牢布置与怪物布置
	for (i = 0; ch < 11; ch++) {
		vism.push_back(ism);
		vism.back().vmp.reserve(1000);//还防bug出
		vism[ch].id = ch;
		int itemp = 0;
		switch (ch) {//编号id对应的地牢怪物生成
		case 0:
			for (itemp = i + 8, vism[ch].str = "O&&^^OXX"; i < itemp; i++) {
				switch (vism[ch].str[8 - (itemp - i)]) {
				case '&':
					mpv.push_back(new Mand());
					break;
				case '^':
					mpv.push_back(new MUD());
					break;
				case 'O':
					mpv.push_back(new MO());
					break;
				case 'X':
					mpv.push_back(new MX());
					break;
				default:
					break;
				}
				vism[ch].vmp.push_back(mpv[i]);
				if (8 == itemp - i) {
					vism[ch].vmp.back()->set(p.sgetxyhs(), &strcp[8 - (itemp - i)], 5, &em, NULL, NULL, 9, 5);
				}
				else {
					switch (vism[ch].str[8 - (itemp - i)]) {
					case '&':
						vism[ch].vmp.back()->set(p.sgetxyhs(), &strcp[8 - (itemp - i)], 3, NULL, NULL, NULL, 0, 0, itemp - i - 6);
						break;
					case '^':
						vism[ch].vmp.back()->set(p.sgetxyhs(), &strcp[8 - (itemp - i)], 4, NULL, NULL, NULL, 0, 0, itemp - i - 4, true);
						break;
					case 'O':
						vism[ch].vmp.back()->set(p.sgetxyhs(), &strcp[8 - (itemp - i)], 5, &m[2], NULL, NULL, 5, 2);
						break;
					case 'X':
						vism[ch].vmp.back()->set(p.sgetxyhs(), &strcp[8 - (itemp - i)], 3, NULL, &cp, &strmap);
						break;
					default:
						break;
					}
				}
			}
			break;
		case 1:
			for (itemp = i + 7; i < itemp; i++) {
				mpv.push_back(new MO());
				vism[ch].vmp.push_back(mpv[i]);
				vism[ch].vmp.back()->set(p.sgetxyhs(), &strcp[7 - (itemp - i) + 8], 5, &m[1], NULL, NULL, 0, 0, 10 - (i - itemp), 3);
			}
			break;
		case 2:
			for (itemp = i + 5; i < itemp; i++) {
				mpv.push_back(new MUD());
				vism[ch].vmp.push_back(mpv[i]);
				vism[ch].vmp.back()->set(p.sgetxyhs(), &strcp[5 - (itemp - i) + 15], 3, NULL, NULL, NULL, 0, 0, 1, 1);
			}
			break;
		case 3:
			for (itemp = i + 6, vism[ch].str = "&&^^^^"; i < itemp; i++) {
				if ('&' == (vism[ch].str[6 - (itemp - i)])) {
					mpv.push_back(new Mand());
					vism[ch].vmp.push_back(mpv[i]);
					vism[ch].vmp.back()->set(p.sgetxyhs(), &strcp[6 - (itemp - i) + 20], 3, NULL, NULL, NULL, 0, 0, (i - itemp) % 2);
				}
				else {
					mpv.push_back(new MUD());
					vism[ch].vmp.push_back(mpv[i]);
					vism[ch].vmp.back()->set(p.sgetxyhs(), &strcp[6 - (itemp - i) + 20], 4, NULL, NULL, NULL, 0, 0, (6 - (itemp - i) - 2) & 1, (6 - (itemp - i) - 2) & 2);//qezc(键盘)
				}
			}
			break;
		case 4:
			for (itemp = i + 5, vism[ch].str = "XXXXO"; i < itemp; i++) {
				if ('X' == (vism[ch].str[5 - (itemp - i)])) {
					mpv.push_back(new MX());
					vism[ch].vmp.push_back(mpv[i]);
					vism[ch].vmp.back()->set(p.sgetxyhs(), &strcp[5 - (itemp - i) + 26], 3, NULL, &cp, &strmap);
				}
				else {
					mpv.push_back(new MO());
					vism[ch].vmp.push_back(mpv[i]);
					vism[ch].vmp.back()->set(p.sgetxyhs(), &strcp[5 - (itemp - i) + 26], 5, &em, NULL, NULL, 5, 5);
				}

			}
			break;
		case 5:
			for (itemp = i + 4; i < itemp; i++) {
				mpv.push_back(new MO());
				vism[ch].vmp.push_back(mpv[i]);
				vism[ch].vmp.back()->set(p.sgetxyhs(), &strcp[4 - (itemp - i) + 31], 5, &m[0], NULL, NULL, itemp - i, itemp - i);
			}
			break;
		case 6:
			for (itemp = i + 4; i < itemp; i++) {
				mpv.push_back(new MX());
				vism[ch].vmp.push_back(mpv[i]);
				vism[ch].vmp.back()->set(p.sgetxyhs(), &strcp[4 - (itemp - i) + 35], 3, NULL, &cp, &strmap);
			}
			break;
		case 7:
			for (itemp = i + 4; i < itemp; i++) {
				mpv.push_back(new MUD());
				vism[ch].vmp.push_back(mpv[i]);
				vism[ch].vmp.back()->set(p.sgetxyhs(), &strcp[4 - (itemp - i) + 39], 4, NULL, NULL, NULL, 0, 0, (itemp - i) % 2, (itemp - i + 1) % 2);
			}
			break;
		case 8:
			for (itemp = i + 3; i < itemp; i++) {
				mpv.push_back(new Mand());
				vism[ch].vmp.push_back(mpv[i]);
				vism[ch].vmp.back()->set(p.sgetxyhs(), &strcp[3 - (itemp - i) + 43], 3, NULL, NULL, NULL, 0, 0, !((itemp - i) % 2));
			}
			break;
		case 9:
		{
			char* tempcparr[20] = { NULL };
			for (itemp = i + ia; i < itemp; i++) {
				pair<bool, bool>pbb = { rand() % 2, rand() % 2 };
				pair<int, int>pxy = { rand() % 9 + 1, rand() % 9 + 1 };
				while ((7 == pxy.first || 5 == pxy.first) && 4 == pxy.second || 7 <= pxy.first && 3 >= pxy.second) {
					pxy = { rand() % 9 + 1, rand() % 9 + 1 };
				}
				tempcparr[itemp - i] = &strmap[pxy.first][pxy.second];
				switch (rand() % 7) {
				case 0:
				case 1:
					mpv.push_back(new Mand());
					vism[ch].vmp.push_back(mpv.back());
					vism[ch].vmp.back()->set(p.sgetxyhs(), tempcparr + itemp - i, 3, NULL, NULL, NULL, 0, 0, pbb.first);
					break;
				case 2:
				case 3:
					mpv.push_back(new MUD());
					vism[ch].vmp.push_back(mpv.back());
					vism[ch].vmp.back()->set(p.sgetxyhs(), tempcparr + itemp - i, 2, NULL, NULL, NULL, 0, 0, pbb.first, pbb.second);
					break;
				case 4:
				case 5:
					mpv.push_back(new MX());
					vism[ch].vmp.push_back(mpv.back());
					vism[ch].vmp.back()->set(p.sgetxyhs(), tempcparr + itemp - i, 3, NULL, &cp, &strmap);
					break;
				case 6:
					mpv.push_back(new MO());
					vism[ch].vmp.push_back(mpv.back());
					vism[ch].vmp.back()->set(p.sgetxyhs(), tempcparr + itemp - i, 5, &em, NULL, NULL, pxy.first, pxy.second);
					break;
				default:
					break;
				}
			}
		}
		break;
		default:
			break;
		}
	}
	random_shuffle(vism.begin(), vism.end());//使地牢随机化
	while (4 != vism.size()) {
		vism.pop_back();//删除本次游戏不需要的地牢
	}
	vism.push_back(ism);//小BOSS的创建
	vism.back().id = 10;
	mpv.push_back(new Mplus());
	vism.back().vmp.reserve(1000);
	vism.back().vmp.push_back(mpv.back());
	vism.back().vmp.back()->set(p.sgetxyhs(), &strcp[46], 10);
	int ishoot = 0;
	int bosswait = 0;
	bool b = 0;
	char str[9] = "color 0";
	difficulty d = EASY;//初始值(EASY)
	//开始界面
	for (i = 0; i < 15; i++) {//大文字缓缓出现
		system("cls");
		start(i);
		Sleep(10);
	}
	Sleep(10);
	for (i = 0; i < 9; i++) {//使大文字变成动态的彩色
		strcat(tempstr, tempstra[i]);
		system(tempstr);
		tempstr[7] = 0;
		Sleep(100);
	}
	system("color 07");
	Sleep(500);
	cout << endl << endl << endl;//游戏的开始界面
	cout << " \033[33m@---------------------------------------------@" << endl;
	cout << " |                                             |" << endl;
	cout << " |   \033[0m1. 游戏规则           \033[32;1m2. 开始游戏(简单)\033[0;33m   |" << endl;
	cout << " |                                             |" << endl;
	cout << " |   3. 开始游戏(普通)     \033[31;1m4. 开始游戏(困难)\033[0;33m   |" << endl;
	cout << " |                                             |" << endl;
	cout << " |   \033[31m5. 开始游戏(极限)\033[1m     0. 退出\033[0;33m             |" << endl;
	cout << " |                                             |" << endl;
	cout << " @---------------------------------------------@\033[0m" << endl;
	cout << endl << endl << endl;
	while ('1' == ch || '0' > ch || ch > '5') {//输入错误或者输入“1”(游戏规则时)重新输入
		cin >> ch;
		if ('1' == ch) {//1.游戏规则(打印游戏规则)
			cout << "游戏规则:" << endl;
			cout << "    “P”是你,“*”是墙,a键左移,d键右移,w键跳,s及其其他键让时间流逝,上面显示你的\033[32;1m生\033[0;33m命\033[31;1m值\033[0m,如果你生命值\033[31m归0\033[0m,那么你就\033[31;1m失败\033[0m,在遇到\033[31;1m怪物\033[0m的时候,你要按下z键用枪射出\033[33m子弹射\033[31;1m死\033[0m各种各样的\033[31;1m怪物\033[0m,\033[31;1m怪物\033[0m是怎么样的你自己看,如果你碰到了\033[31;1m怪物\033[0m,那么你就会被\033[31;1m怪物伤到\033[0m,\033[31;1m血量减1\033[0m,而打败\033[31;1m小BOSS\033[0m“\033[33m+\033[0m”并从\033[31;1m小BOSS\033[0m的房间中\033[32;1m走出去\033[0m即可\033[32;1m胜利\033[0m。而这个游戏有四种可游玩的模式:一种是\033[32;1m简单模式\033[0m,一种是\033[33m普通模式\033[0m,一种是\033[31;1m困难模式\033[0m,一种是\033[31m极限模式\033[0m,其中,\033[32;1m简单模式\033[0m会让你开始时有\033[32;1m8滴血\033[0m,\033[33m普通模式\033[0m会让你开始时有\033[33m5滴血\033[0m,\033[31;1m困难模式\033[0m会让你开始时有\033[31;1m3滴血\033[0m,而\033[31m极限模式\033[0m会让你开始时\033[31;4m只有1滴血\033[0m;同样,\033[4m我们也会根据你选择的\033[31;1m难度\033[0;4m来选择不同的告知你\033[32;1m胜利方式\033[0m:\033[4m如果你选择了\033[31;1m难玩的难度\033[0;4m,那么告知你\033[32;1m胜利方式\033[0;4m也更\033[32;1m新奇\033[0;4m;反之如果你选择了\033[32;1m易玩的难度\033[0;4m,那么告知你\033[32;1m胜利方式\033[0;4m也\033[31;1m更不新奇\033[0m,并且不同的\033[31;1m难度\033[0m也有不同的\033[32;1m战前回血概率\033[0m与\033[31;1m小BOSS\033[32m战前回血概率\033[0m,\033[4m越\033[31;1m难\033[0;4m这个概率就越\033[31;1m小\033[0m。这就是这个打小怪游戏的规则,你听明白了吗?" << endl << endl;
		}
		else if ('0' > ch || ch > '5') {//输入错误
			cout << "\033[31;1m输入错误,请重新输入\033[0m" << endl << endl;
		}
		rewind(stdin);
	}
	if ('0' == ch) {//退出
		cout << endl << "欢迎下次游玩" << endl;
		return 0;
	}
	d = (difficulty)(ch - '2');//难度选择('2'~'5') - '2' = (0~3)
	int temparra[4] = { 8, 5, 3, 1 };
	p.sgetxyhs(HEAL) = temparra[d];//根据玩家选的难度来设置玩家的生命
	system("cls");
	while (p.sgetxyhs(HEAL) && (bb || 'P' != strmap[9][10])) {
		MO mo;
		//如果玩家踏进新的地牢(具体位置:&strmap[9][1])(!b),b设为真,并重置怪物生成和地牢生成(vism无时BOSS战(+))
		if (!b && (&strmap[9][1] == cp || &strmap[8][1] == cp)) {
			b = 1;
			strmap[9][0] = '*';
			for (i = 1; i < 10; i++) {
				for (ch = 1; ch < 10; ch++) {
					'#' == strmap[i][ch] && (strmap[i][ch] = ' ');
				}
			}
			switch (vism.front().id) {//地牢的生成
			case 0:
				for (ch = 3; ch < 8; ch++) {
					for (i = 3; i < 8; i++) {
						strmap[ch][i] = '*';
					}
				}
				{
					int arr[10] = { 1, 2, 5, 2, 7, 1, 1, 8, 6, 7 };
					for (i = 0; i < 10; i += 2) {
						strmap[arr[i]][arr[i + 1]] = (8 != i ? '*' : strmap[7][7] = ' ');
					}
				}
				break;
			case 1:
				strmap[2][8] = '*';
				break;
			case 2:
				strmap[4][6] = '*';
				strmap[7][7] = '*';
				break;
			case 3:
			{
				char* cparr[6] = { &strmap[2][4], &strmap[4][1], &strmap[4][7], &strmap[8][1], &strmap[8][7], &strmap[6][4] };
				for (ch = 0; ch < 3; ch++) {
					for (i = 0; i < 6; i++) {
						*cparr[i]++ = '*';
					}
				}
			}
			break;
			case 4:
				for (i = 2; i < 9; i += 2) {
					for (ch = 2; ch < 9; ch += 2) {
						strmap[i][ch] = '*';
					}
				}
				{
					int arr[12] = { 8, 5, 6, 3, 6, 7, 4, 5, 8, 9, 4, 1 };
					for (i = 0; i < 12; i += 2) {
						strmap[arr[i]][arr[i + 1]] = '*';
					}
				}
				break;
			case 6:
			{
				int temparr[5] = { 8,5,2,4,9 };//8,5 5,2 2,4 4,9
				for (ch = 2; ch < 9; ch++) {
					strmap[ch][ch] = '*';
					strmap[ch][10 - ch] = '*';
					if (ch < 6) {
						strmap[temparr[ch - 2]][temparr[ch - 1]] = '*';
					}
				}
				break;
			}
			case 7:
				for (ch = 1; ch < 4; ch++) {
					strmap[2][ch] = '*';
					strmap[5][ch + 3] = '*';
					strmap[8][ch + 6] = '*';
				}
				break;
			case 8:
				for (ch = 2; ch < 5; ch++) {
					strmap[7][ch] = '*';
					strmap[7][ch + 4] = '*';
					strmap[4][ch + 1] = '*';
				}
				break;
			case 9:
				strmap[4][5] = '*';
				strmap[7][5] = '*';
				break;
			case 10:
				for (i = 1; i < 10; i++) {
					for (ch = 1; ch < 10; ch++) {
						'#' == strmap[i][ch] && (strmap[i][ch] = ' ');
					}
				}
				for (i = 2; i <= 8; i += 6) {
					for (ch = 4; ch < 7; ch++) {
						strmap[i][ch] = '+';
						strmap[ch][i] = '+';
					}
					for (ch = 2; ch <= 8; ch++) {
						'+' != strmap[i][ch] && (strmap[i][ch] = '-');
						'+' != strmap[ch][i] && (strmap[ch][i] = '-');
					}
				}
				for (i = 2; i <= 8; i++) {
					for (ch = 2; ch <= 8; ch++) {
						'-' == strmap[i][ch] && (strmap[i][ch] = '*');
						'+' == strmap[i][ch] && (strmap[i][ch] = ' ');
					}
				}
				strmap[5][1] = '*';
				strmap[5][9] = '*';
				break;
			default:
				break;
			}
			memcpy(strmapr, strmap, sizeof strmap);
			strmapr[9][1] = ' ';
			for (ch = 0; vism.front().vmp[ch] != vism.front().vmp.back(); ch++) {
				if ('X' == vism.front().vmp[ch]->getm()) {
					((MX*)vism.front().vmp[ch])->exset(strmap);
				}
			}
			if ('X' == vism.front().vmp[ch]->getm()) {
				((MX*)vism.front().vmp[ch])->exset(strmap);
			}
			for (ch = 0; vism.front().vmp.size() != ch; ch++) {
				*vism.front().vmp[ch]->getcp() = vism.front().vmp[ch]->getm();
			}
		}
		p.sgetxyhs(X) = (cp - &strmap[0][0]) / 11;
		p.sgetxyhs(Y) = (cp - &strmap[0][0]) % 11;
		mo.set_s_pxy(p.sgetxyhs(X), p.sgetxyhs(Y));
		p.shootmove(&strmap, 0);//子弹删
		if (vism.size()) {//开始前画“#”以用来告知人们地牢的变化
			for (vector<draw>::iterator it = vmd[5 - vism.size()].begin(); &strmap[9][0] == cp && vmd[5 - vism.size()].back().iwalk + 1; it++) {
				for (char* drawcp = &strmap[it->ix][it->iy]; it->iwalk + 1; drawcp += (1 + 10 * it->brd), it->iwalk--) {
					*drawcp = '#';
				}
			}
		}
		p.printmap(strmap, ba, iunmd);//显示游戏的游玩界面
		ba = 1;
		cin >> ch;
		rewind(stdin);
		'*' != *cp && (*cp = ' ');
		//玩弹怪依次动
		//玩动
		switch (ch) {
		case 'a':
			p.left_move(&cp);
			break;
		case 'd':
			p.right_move(&cp);
			break;
		case 'w':
			p.jump(&cp);
			break;
		case 'z':
			p.shoot(ishoot, &cp);
		default:
			break;
		}
		p.upOrDown(&cp);
		(iunmd || ' ' == *cp || '@' == *cp) || cout << (p.sgetxyhs(HEAL)--, iunmd = 2, "\a");
		//有怪物使你扣血
		ishoot > 0 && ishoot--;
		if (' ' != strmap[9][10]) {//怪物死
			sort(vism.front().vmp.begin(), vism.front().vmp.end(), cmpm());//对怪物血量进行升序排序
			while (!vism.front().vmp.empty() && vism.front().vmp.front()->getheal() < 1) {
				if (-1 == vism.front().vmp.front()->getheal()) {
					int ir = 0;
					//把怪物“o”转换成其他怪物
					switch (bc ? 2 : ir = rand() % 4) {
					case 0:
						mpv.push_back(new Mand());
						break;
					case 1:
						mpv.push_back(new MUD());
						break;
					case 2:
						mpv.push_back(new MO());
						break;
					case 3:
						mpv.push_back(new MX());
						break;
					default:
						break;
					}
					vism.front().vmp.push_back(mpv.back());
					char* cpa = NULL;
					int mx = 0;
					int my = 0;
					const int arr[8] = { -12, -11, -10, -1, 1, 10, 11, 12 };
					int isummon = 0;
					while (255 != isummon && (!cpa || ' ' != *cpa || ('X' == mpv.back()->getm() && (cpa == &strmap[9][1] || '@' == *cpa || '@' == *(cpa - 1) || '@' == *(cpa + 1) || cpa == cp || '*' == *(cpa - 1) || '*' == *(cpa + 1) || 'X' == *(cpa - 1) || 'X' == *cpa || 'X' == *(cpa + 1))))) {
						int ira = rand() % (cpa = vism.front().vmp.front()->getcp(), 8);
						(isummon >> ira & 1) || (isummon += (1 << ira));
						int imx = (vism.front().vmp.front()->getcp() - &strmap[0][0]) / 11;
						int imy = (vism.front().vmp.front()->getcp() - &strmap[0][0]) % 11;
						bool boolarr[8] = { (imx || imy), !!imx, (imx || 10 != imy), !!imy, 10 != imy, (10 != imx || imy), 10 != imx, (imx || 10 != imy) };
						boolarr[ira] && (cpa += arr[ira]);
					}
					if (255 != isummon) {
						mx = (cpa - &strmap[0][0]) / 11;
						my = (cpa - &strmap[0][0]) % 11;
						switch (bc ? (bc = 0, 2) : ir) {
						case 0:
							vism.front().vmp.back()->set(p.sgetxyhs(), &cpa, 3, NULL, NULL, NULL, 0, 0, rand() % 2);//怪物“&”
							break;
						case 1:
							vism.front().vmp.back()->set(p.sgetxyhs(), &cpa, 2, NULL, NULL, NULL, 0, 0, rand() % 2, rand() % 2);//怪物“^”
							break;
						case 2:
							vism.front().vmp.back()->set(p.sgetxyhs(), &cpa, 3, &em, NULL, NULL, mx, my);//怪物“O”
							break;
						case 3:
							vism.front().vmp.back()->set(p.sgetxyhs(), &cpa, 5, NULL, &cp, &strmap);//怪物“X”
							break;
						default:
							break;
						}
					}
					else {
						vism.front().vmp.pop_back();
					}
				}
				'*' != *vism.front().vmp.back()->getcp() && (*vism.front().vmp.back()->getcp() = vism.front().vmp.back()->getm());
				if ('X' == vism.front().vmp.back()->getm()) {
					((MX*)vism.front().vmp.back())->exset(strmapr);
				}
				//如果该地只有一个怪物,那么设怪物所在的位置为空格
				vector<moster*>::iterator it = vism.front().vmp.begin() + 1;
				for (; it != vism.front().vmp.end(); it++) {
					if (vism.front().vmp.front()->getcp() == (*it)->getcp()) {
						break;
					}
				}
				'*' != *vism.front().vmp.front()->getcp() && it == vism.front().vmp.end() && (*vism.front().vmp.front()->getcp() = ' ');
				'X' == vism.front().vmp.front()->getm() && (*vism.front().vmp.front()->getcp() = ((MX*)vism.front().vmp.front())->getm(0));
				'*' != *vism.front().vmp.front()->getcp() && (*vism.front().vmp.front()->getcp() = ' ');
				if ('+' == vism.front().vmp.front()->getm()) {
					for_each(vism.front().vmp.begin(), vism.front().vmp.end(), setMempty);
					vism.front().vmp.clear();
					bb = 0;
				} 
				bb && (vism.front().vmp.erase(vism.front().vmp.begin()), 0);//删除怪物
			}
		}
		p.shootmove(&strmap, 1);//子弹动
		if (b && '*' == strmap[9][10]) {//怪物动
			vector<moster*>::iterator vfvp = vism.front().vmp.begin();
			while (!vism.front().vmp.empty() && '+' != (*vfvp)->getm()) {
				if (vism.front().vmp.end() == ++vfvp) {
					break;
				}
			}
			if (1 == vism.size() && bb && (!bosswait || (bosswait--, 0))) {
				char* setcp = &strmap[5][5];
				vo.push_back(new M_o());
				vism.front().vmp.push_back(vo.back());
				vism.front().vmp.back()->set(p.sgetxyhs(), &setcp, 5);
				bosswait = 15;
			}//**会变**
			for (vector<moster*>::iterator it = vism.front().vmp.begin(); vism.front().vmp.end() != it; it++) {
				(*it)->hunt();
				(*it)->mosterdo();
				(*it)->hunt();
			}
			for (vector<trir>::iterator it = p.sgetxyhs()->begin(); p.sgetxyhs()->end() != it; it++) {
				-2 >= it->iy && it->iy++;
			}
			for_each(vism.front().vmp.begin(), vism.front().vmp.end(), MShow);
		}
		(iunmd || ' ' == *cp || '@' == *cp) || cout << (p.sgetxyhs(HEAL)--, iunmd = 2, "\a");
		'*' != *cp && (*cp = 'P');
		system("cls");//清屏
		//如果vism的第0项vmp或者vism为空,那么开门,并头删
		if ((vism.empty() || vism.front().vmp.empty()) && '*' == strmap[9][10]) {
			strmap[9][10] = ' ';
			vism.erase(vism.begin());
		}
		//如果进门,那么重置地牢('*'  -->  ' '),并把b设为假
		if (bb && 'P' == strmap[9][10]) {
			b = 0;
			for (vector<trir>::iterator it = p.sgetxyhs()->begin(); p.sgetxyhs()->end() != it; it++) {
				'*' != *it->cp && (*it->cp = ' ');
			}
			p.sgetxyhs()->clear();
			for (i = 0; i < 10; i++) {
				p.printmap(&strmap, ba, i, iunmd);
				!i && (strmap[9][0] = ' ');
				Sleep(100);
				system("cls");
			}
			//下一地牢初始化
			( <- 分界 )
			strmap[9][10] = '*';
			strmap[9][0] = 'P';
			
			p.printmap(&strmap, ba, 11, iunmd);
			Sleep(100);
			system("cls");
			bool temparrb[8] = { 1, 1, !(rand() % 2), 1, !(rand() % 4), !(rand() % 2), 0, 0};
			if (1 != vism.size()) {//恢复血量
				temparrb[d * 2] && temparra[d] > p.sgetxyhs(HEAL) && (p.sgetxyhs(HEAL)++, ba = 0);
		    }
		    else {
				temparrb[d * 2 + 1] && temparra[d] > p.sgetxyhs(HEAL) && (p.sgetxyhs(HEAL)++, ba = 0);
			}
			//并把cp设为&strmap[9][0]
			cp = &strmap[9][0];
		}
		iunmd && iunmd--;
	}
	char tempstrb[6] = "C2AA7";//胜利
	str[7] = tempstrb[(!bb) * (d + 1)];
	system(str);
	switch ((!bb) * (d + 1)) {//告知你胜利的方式
	case 0:
		cout << "很遗憾,你输了" << endl;
		break;
	case 1:
	case 2:
		cout << "恭喜你,你赢了" << endl;
		break;
	case 3:
		cout << "@------------------@" << endl;
		cout << "|                  |" << endl;
		cout << "|  恭喜你,你赢了  |" << endl;
		cout << "|                  |" << endl;
		cout << "@------------------@" << endl;
		break;
	case 4:
		for (i = 0; i < 15; i++) {
			system("cls");
			win(i);
			Sleep(10);
		}
		for (i = 0; i < 27; i++) {
			strcat(tempstr, tempstra[i % 9]);
			system(tempstr);
			tempstr[7] = 0;
			Sleep(100);
		}
		system("color 0A");
		break;
	default:
		break;
	}
	for_each(mpv.begin(), mpv.end(), del);//释放mpv和vo里new出来的怪物对象
	for_each(vo.begin(), vo.end(), delvo);//释放mpv和vo里new出来的怪物对象
	return 0;
}

moster.h

#pragma once
#include <iostream>
using namespace std;
#include "Player.h"
#include "WASD.h"
#include <map>
class moster {
protected:
	char** m_cpp;//怪物的位置
	int m_iheal;//怪物的血量数
	vector<trir>* m_v;//指向玩家射出的子弹
	char* tempcp;//用于在移动怪物的位置的时候防出bug
public:
	moster();//moster抽象基类的构造函数
	virtual void set(vector<trir>* v = NULL, char** cpp = NULL, int iheal = 3, map<char**, WASD>* = NULL, char** = NULL, char(*)[11][11] = NULL, int = 0, int = 0, bool = 0, bool = 0);//设置怪物的一些属性
	void hunt();//受伤函数
	int getheal();//获取怪物的血量数
	virtual void mosterdo() = 0;//执行每种怪物要做的事
	virtual char getm() = 0;//获取怪物的类型,用多态实现
	char*& getcp();//获取怪物的位置
};

moster.cpp

#include <iostream>
using namespace std;
#include "moster.h"
//构造函数
moster::moster(){
	vector<trir>v;
	m_v = &v;
}
//怪物对象的设置函数
void moster::set(vector<trir>* v, char** cpp, int iheal, map<char**, WASD>*, char**, char(*)[11][11], int, int, bool, bool) {
	m_v = v;
	m_cpp = cpp;
	m_iheal = iheal;
}
//受伤
void moster::hunt() {
	for (vector<trir>::iterator it = m_v->begin(); m_v->end() != it; it++) {
		(!it->bk && (*m_cpp == it->cp || *m_cpp == (it->cp - (1 - 2 * it->b)))) && (m_iheal--, it->bk = 1);
	}//检测扣血(如果子弹没杀过怪物并且子弹在怪物正中或者前面就扣怪物的血)
	//Game.cpp的main函数中检测怪物的死亡
}
int moster::getheal() {
	return m_iheal;
}
char*& moster::getcp() {
	return *m_cpp;
}

M&.h

#pragma once
#include <iostream>
using namespace std;
#include "moster.h"
class Mand: public moster {
private:
	bool mblr;//朝向(0< 1>)
public:
	void set(vector<trir>* v = NULL, char** cpp = NULL, int iheal = 3, map<char**, WASD>* = NULL, char** = NULL, char(*)[11][11] = NULL, int = 0, int = 0, bool b = 0, bool = 0);//设置怪物M&的一些属性
	Mand();//构造函数
	void mosterdo();//执行怪物M&要做的事
	char getm();//获取怪物M&的类型
};

M&.cpp

#include <iostream>
using namespace std;
#include "M&.h"
Mand::Mand() {
	this->set();
}
void Mand::set(vector<trir>* v, char** cpp, int iheal, map<char**, WASD>*, char**, char(*)[11][11], int, int, bool b, bool) {
	m_v = v;
	m_cpp = cpp;
	m_iheal = iheal;
	mblr = b;
}
void Mand::mosterdo() {
	'*' != **m_cpp && (**m_cpp = ' ');//便于移动之后的显示
	if (!mblr && '*' == (*m_cpp)[-1]) {//如果怪物M&往左移动,并且左边有墙
		mblr = 1;//怪物M&就往右移动
	}
	else if (mblr && '*' == (*m_cpp)[1]) {//如果怪物M^往右移动,并且左边有墙
		mblr = 0;//怪物M&就往左动
	}//撞墙换方向
	tempcp = *m_cpp;//防指针的链式带动
	m_cpp = NULL;
	'*' != tempcp[-(1 - 2 * mblr)] && (tempcp -= (1 - 2 * mblr));//左右移
	'*' != tempcp[11] && (tempcp += 11);//下落
	m_cpp = &tempcp;
	//后面main函数中用Mshow函数使见
}//撞墙换方向,会自然下落
char Mand::getm() {
	return '&';
}

M^.h

#pragma once
#include <iostream>
using namespace std;
#include "moster.h"
class MUD : public moster {
private:
	bool mblr;//水平朝向(0< 1>)
	bool mbud;//垂直朝向(0^ 1v)
public:
	MUD();//构造函数
	void set(vector<trir>* v = NULL, char** cpp = NULL, int iheal = 3, map<char**, WASD>* = NULL, char** = NULL, char(*)[11][11] = NULL, int = 0, int = 0, bool b = 0, bool ba = 0);//设置怪物M^的一些属性
	void mosterdo();//执行怪物M^要做的事
	char getm();//获取怪物M^的类型
};

M^.cpp

#include <iostream>
using namespace std;
#include "M^.h"
//构造函数
MUD::MUD() {
	set();
}
//M^的设置函数
void MUD::set(vector<trir>* v, char** cpp, int iheal, map<char**, WASD>*, char**, char(*)[11][11], int, int, bool b, bool ba) {
	m_v = v;
	m_cpp = cpp;
	m_iheal = iheal;
	mblr = b;
	mbud = ba;
}
void MUD::mosterdo() {
	'*' != **m_cpp && (**m_cpp = ' ');//便于移动之后的显示
	if (!mblr && '*' == (*m_cpp)[-1]) {//如果怪物M^往左移动,并且左边有墙
		mblr = 1;//怪物M^就往右移动
	}
	else if(mblr && '*' == (*m_cpp)[1]){//如果怪物M^往右移动,并且右边有墙
		mblr = 0;//怪物M^就往左移动
	}//撞墙换方向
	tempcp = *m_cpp;//防指针的链式带动
	m_cpp = NULL;
	'*' != tempcp[-(1 - 2 * mblr)] && (tempcp -= (1 - 2 * mblr));//左右移
	if (mbud && '*' == tempcp[11]) {//如果怪物M^往下移动,并且下边有墙
		mbud = 0;//怪物M^就往上落
	}
	else if (!mbud && '*' == tempcp[-11]) {//如果怪物M^往上落,并且上边有墙
		mbud = 1;//怪物M^就往下落
	}//碰地会反转
	'*' != tempcp[-(11 * (1 - 2 * mbud))] && (tempcp -= 11 * (1 - 2 * mbud));//上下落
	m_cpp = &tempcp;
	//后面main函数中Mshow函数使见
}//撞墙换方向,碰地会反落
char MUD::getm() {
	if (mbud) {
		return 'v';
	}
	else {
		return '^';
	}
}

MO.h

#pragma once
#include <iostream>
using namespace std;
#include <map>
#include "Player.h"
#include "moster.h"
class MO : public moster {
private:
	WASD m_wasd;//方向
	map<char**, WASD>m_m;//[strmap point, wasd]...
	pair<int, int> m_pxy;//怪物 xy坐标
	static pair<int, int> s_m_pxy;//玩家 xy坐标
	int imove;//追踪的时候充当定时器用,每到这个数模MOWAIT这个宏加1的结果为宏MOWAIT,就开始移动
public:
	void set(vector<trir>* v = NULL, char** cpp = NULL, int iheal = 3, map<char**, WASD>* m = NULL, char** = NULL, char(*)[11][11] = NULL, int ix = 0, int iy = 0, bool = 0, bool = 0);//设置怪物MO的一些属性
	MO();//构造函数
	void set_s_pxy(int ix, int iy);//监听玩家的xy坐标
	void mosterdo();//执行怪物MO要做的事
	char getm();//获取怪物MO的类型
};

MO.cpp

#include <iostream>
using namespace std;
#include "MO.h"
#define NNEG(A, B) ((A) < (B) ? 1 : (A) > (B) ? -1 : 0)//判断宏
#define MOWAIT 1//怪物MO等待的回合数
pair<int, int> MO::s_m_pxy = {0, 0};//玩家坐标的初始化
//构造函数
MO::MO() {
	set();
}
//MO的设置函数
void MO::set(vector<trir>* v, char** cpp, int iheal, map<char**, WASD>*m, char**, char(*)[11][11], int ix, int iy, bool, bool) {
	m_v = v;
	m_cpp = cpp;
	m_iheal = iheal;
	m_pxy.first = ix;
	m_pxy.second = iy;
	imove = 0;
	if (nullptr != m) { 
		m_m = *m;
	}
}
void MO::mosterdo() {
	'*' != **m_cpp && (**m_cpp = ' ');//便于移动之后的显示
	tempcp = *m_cpp;//防指针的链式带动
	m_cpp = NULL;
	if (!m_m.empty()) {//沿路模式
		int arr[4] = { -11, -1, 11, 1 };//怪物MO可能会移动的四个方位
		for (map<char**, WASD>::iterator it = m_m.begin(); m_m.end() != it; it++) {//改变怪物MO的方向
			E != it->second && tempcp == *it->first && (m_wasd = it->second);
		}
		switch (tempcp += (arr[m_wasd]), m_wasd) {//怪物的移动与xy坐标的变化
		case W:
			m_pxy.second--;
			break;
		case A:
			m_pxy.first--;
			break;
		case S:
			m_pxy.second++;
			break;
		case D:
			m_pxy.first++;
			break;
		default:
			break;
		}
	}
	else {//追踪模式
		MOWAIT == imove % (MOWAIT + 1)/*如果MO等待了MOWAIT回合*/ && ('*' != *(tempcp + 11 * NNEG(m_pxy.first, s_m_pxy.first))/*并且垂直移动的方向上没有墙*/ && (tempcp += 11 * NNEG(m_pxy.first, s_m_pxy.first)/*那么怪物MO就往玩家垂直地移动*/, m_pxy.first += NNEG(m_pxy.first, s_m_pxy.first)/*怪物的x坐标也随之变化*/));//根据怪物的xy坐标和玩家的xy坐标来移动
		MOWAIT == imove++ % (MOWAIT + 1) && ('*' != *(tempcp + NNEG(m_pxy.second, s_m_pxy.second)/*并且水平移动的方向上没有墙*/) && (tempcp += NNEG(m_pxy.second, s_m_pxy.second)/*那么怪物MO就往玩家水平地移动*/, m_pxy.second += NNEG(m_pxy.second, s_m_pxy.second)/*怪物的y坐标也随之变化*/));
	}
	m_cpp = &tempcp;
}//遇向则转,看路前行(1),或追玩者(2)
//设置玩家的坐标
void MO::set_s_pxy(int ix, int iy) {
	s_m_pxy = { ix, iy };
}
char MO::getm() {
	return 'O';
}

MX.h

#pragma once
#include <iostream>
using namespace std;
#include "moster.h"
class MX : public moster {
private:
	char** m_pcpp;//玩家的地点,不用xy坐标
	char(*m_strmap)[11][11];//地牢的指针
	char m_strmapr[11][11];//刚刚创建完成之后的地牢
	char m_cc;//盖住的块
	pair<int, int>pxy;//怪物的xy坐标
	bool setb;//帮助设置怪物的一些属性
public:
	MX();//构造函数
	void set(vector<trir>* v = NULL, char** cpp = NULL, int iheal = 3, map<char**, WASD>* = NULL, char** pcpp = NULL, char(*strmap)[11][11] = NULL, int = 0, int = 0, bool = 0, bool = 0);//设置怪物MX的一些属性
	void mosterdo();//执行怪物MX要做的事
	void exset(char strmapr[11][11]);//额外设置怪物MX的一些属性
	char getm();//获取怪物MX的类型
	char getm(bool);//获取怪物MX的盖住的块
};

MX.cpp

#include <iostream>
using namespace std;
#include <cstring>
#include "MX.h"
//怪物MX的设置函数
void MX::set(vector<trir>* v, char** cpp, int iheal, map<char**, WASD>*, char** pcpp, char(*strmap)[11][11], int, int, bool, bool) {
	m_v = v;
	if (nullptr == cpp) {
		m_cpp = cpp;
	}
	else {
		tempcp = *cpp;
		cpp = NULL;
		m_cpp = &tempcp;
	}
	m_pcpp = pcpp;
	nullptr != strmap && (m_strmap = strmap);
	m_iheal = iheal;
	setb = 1;
	
}
//怪物MX的额外设置函数
void MX::exset(char strmapr[11][11]) {
	memcpy(m_strmapr, strmapr, sizeof m_strmapr);
}
//构造函数
MX::MX() {
	set();
}
void MX::mosterdo() {
	vector<trir>::iterator it = m_v->begin();
	if (setb) {
		pxy = { (*m_cpp - &(*m_strmap)[0][0]) / 11, (*m_cpp - &(*m_strmap)[0][0]) % 11 };//设置怪物MX的坐标
		m_cc = m_strmapr[pxy.first][setb = 0, pxy.second];//设置盖住的块
	}
	for (; m_v->end() != it; it++) {
		if (*m_cpp == it->cp || *m_cpp == it->cp - (1 - it->b * 2)) {//如果怪物受伤了就停止这个循环
			break;
		}
	}
	if (m_iheal > 0 && (*m_cpp == *m_pcpp || m_v->end() != it)) {//如果刚才的这个循环停止了,并且还有生命且不在玩家的位置上
		tempcp = *m_cpp;//防指针的链式移动
		char* tempcpb = tempcp;
		bool tempb = 1;//防误覆盖空位
		m_cpp = NULL;
		do {
			tempb && m_v->end() != it && (*tempcp = ' ');//便于移动之后的显示
			tempcp = &(*m_strmap)[pxy.first = rand() % 9 + 1][pxy.second = rand() % 9 + 1];//怪物MX的移动
		} while ((tempcp == &(*m_strmap)[9][1] || '@' == (*m_strmap)[pxy.first][pxy.second] || '@' == (*m_strmap)[pxy.first][pxy.second - 1] || '@' == (*m_strmap)[pxy.first][pxy.second + 1] || tempcp == *m_pcpp || '*' == tempcp[-1] || '*' == tempcp[1] || 'X' == (tempcp)[-1] || 'X' == *tempcp || 'X' == (tempcp)[1]) && (tempb = 0, 1));//如果满足上述的条件,就把误覆盖空位的“开关”启动
		m_cpp = &tempcp;
		*tempcpb = m_cc;
		('@' != m_strmapr[pxy.first][pxy.second] || 'X' != m_strmapr[pxy.first][pxy.second] && 'P' != m_strmapr[pxy.first][pxy.second]) && (m_cc = m_strmapr[pxy.first][pxy.second]);//记录盖住的块,不记录“@”子弹,“P”玩家和“X”怪物MX自己
	}
	//main函数使见
}//被玩家碰到传,受伤传(两旁有砖不传),并见
char MX::getm() {
	return 'X';
}
char MX::getm(bool) {
	return m_cc;
}

M+.h

#pragma once
#include <iostream>
using namespace std;
#include "moster.h"
#include <vector>
class Mplus : public moster {
public:
	void mosterdo();//执行小BOSSM+要做的事
	char getm();//获取小BOSSM+的类型
};

M+.cpp

#include <iostream>
using namespace std;
#include "M+.h"
void Mplus::mosterdo() {
	**m_cpp = '+';//后面根据**m_cpp的内容来执行summon方法
}
char Mplus::getm() {
	return '+';
}

M_o.h

#pragma once
#include <iostream>
#include "moster.h"
using namespace std;
class M_o : public moster {
private:
	void near();//检测是否旁边有墙
public:
	void mosterdo();//执行怪物M_o要做的事
	char getm();//获取怪物M_o的类型
};

M_o.cpp

#include <iostream>
#include <ctime>
#include "M_o.h"
using namespace std;
void M_o::near() {
	int arr[8] = { -12, -11, -10, -1, 1, 10, 11, 12 };//根据向量来检测是否旁边有墙
	int i = 0;
	for (; i < 8; i++) {
		if ('*' == (*m_cpp)[arr[i]]) {
			m_iheal = -1;//去死,并生其他怪物(main函数)
			break;
		}
	}
}
void M_o::mosterdo() {
	int arr[8] = { -12, -11, -10, -1, 1, 10, 11, 12 };//可能的移动方向
	int ir = 0;//随机数
	'*' != **m_cpp && (**m_cpp = ' ');//便于移动之后的显示
	tempcp = (near(), *m_cpp);//临时一级指针,无可用二级指针
	m_cpp = NULL;//防指针的链式移动
	'*' != tempcp[arr[ir = rand() % 8]] && (tempcp -= arr[ir]);//曾有bug点:一级指针会“带动”二级指针
	m_cpp = &tempcp;//移动
}//随便移动,有墙不动
char M_o::getm() {
	return 'o';
}

Player.h

#pragma once
#include <iostream>
using namespace std;
#include <vector>
#define JUMPHIGH 3
#ifndef oncea
#define oncea
enum XYHS {
	X,//x坐标
	Y,//y坐标
	HEAL,//玩家的血量
};
struct trir {//子弹
	char* cp;//子弹的位置
	int iy;//子弹的y坐标
	bool b;//子弹的朝向(0< 1>)
	bool bk;//是否杀过怪物
};
class Player {
private:
	int ix;//x坐标
	int iy;//y坐标
	int ijh;//跳跃高度
	int iheal;//生命值
	bool blr;//朝向
	vector<trir> v;//玩家射出的子弹
public:
	Player();//构造函数
	void printmap(const char strmap[11][11], const bool bwait, const int iunmd);//打印地牢
	void printmap(char(*strmap)[11][11], const bool bwait, const int ir, const int iunmd);//打印地牢(右偏版本)
	void jump(char** cpp);//跳跃
	void left_move(char** cpp);//左移
	void right_move(char** cpp);//右移
	int& sgetxyhs(XYHS xyhsmode);//设置或获得玩家的x坐标,y坐标或血量
	vector<trir>* sgetxyhs();//设置或获得玩家射出的子弹
	void upOrDown(char** cpp);//上升或下坠
	void shoot(int& i, char** cpp);//射击
	void shootmove(const char(*strmap)[11][11], bool bmode);//子弹移动
};
#endif

Player.cpp

#include <iostream>
#include "Player.h"
#include "cmp.h"
#include <algorithm>
#include <Windows.h>
using namespace std;
//构造函数
Player::Player(){
	ijh = 0;
	blr = 1;
}
//打印地牢fa
void Player::printmap(const char strmap[11][11], const bool bwait, const int iunmd) {
	int i = 0;
	int ia = 0;
	cout << "\033[" << (!bwait || 5 < iheal ? "32;1m" : 2 < iheal ? "33m" : "31;1m") << "P * " << iheal << "\033[0m" << endl << endl << endl;//打印玩家的血量
	for (cout << "-----------@" << endl; i < 11; i++) {
		for (ia = 0; ia < 11; ia++) {
			cout << "\033[" << ('G' == strmap[i][ia] ? "32;1m" : 'v' == strmap[i][ia] ? "36m" : '&' == strmap[i][ia] || '^' == strmap[i][ia] || 'o' == strmap[i][ia] || 'O' == strmap[i][ia] || 'X' == strmap[i][ia] ? "31;1m" : '+' == strmap[i][ia] || '#' == strmap[i][ia] || '@' == strmap[i][ia] ? "33m" : 'P' == strmap[i][ia] && iunmd ? "30;1m" : "0m") << strmap[i][ia] << "\033[0m";///打印地图
		}
		cout << "|" << endl;//竖的外边框
	}
	cout << "-----------@" << endl;//底下的外边框
}
//打印地牢函数(右偏版本)
void Player::printmap(char(*strmap)[11][11], const bool bwait, const int ir, const int iunmd) {
	int i = 0;
	int ia = 0;
	cout << "\033[" << (!bwait || 5 < iheal ? "32;1m" : 2 < iheal ? "33m" : "31;1m") << "P * " << iheal << "\033[0m" << endl << endl << endl;//打印血量
	for (cout << "-----------@" << endl; i < 11; i++) {
		for (ia = ir; 11 > ia - ir; ia++) {
			21 > ia && ia >= 12 && i && 10 != i && ((*strmap)[i][ia % 11] = ' ');//清空左边的墙(除边框)
			cout << "\033[" << ('P' == (*strmap)[i][ia % 11] && iunmd ? "40;1m" : "0m") << (*strmap)[i][ia % 11] << "\033[0m";//打印右偏之后的地图
		}
		cout << "|" << endl;//竖的外边框
	}
	cout << "-----------@" << endl;//底下的外边框
}//跳跃函数
void Player::jump(char** cpp) {
	10 == ix || '*' == (*cpp)[11] && (ijh = JUMPHIGH);
}
//左移函数
void Player::left_move(char** cpp) {
	(iy && '*' != *(*cpp - 1) && ((*cpp)--));
	blr = false;
}
//右移函数
void Player::right_move(char** cpp) {
	10 != iy && '*' != *(*cpp + 1) && ((*cpp)++);
	blr = true;
}
//用于设置或获得玩家的x坐标,y坐标或血量
int& Player::sgetxyhs(XYHS xyhsmode) {
	switch (xyhsmode) {
	case X:
		return ix;
		break;
	case Y:
		return iy;
		break;
	case HEAL:
		return iheal;
		break;
	default:
		break;
	}
}
//设置或获得玩家射出的子弹
vector<trir>* Player::sgetxyhs() {
	return &v;
}
//使玩家上升或下坠
void Player::upOrDown(char** cpp) {
	if (ijh > 0 && ix && '*' != (*cpp)[-11]) {//跳跃后
		ijh--, *cpp -= 11;
	}
	else if ('*' != (*cpp)[11] && (!ix || '*' == (*cpp)[-11])) {//撞墙或跳好后
		ijh = 0, *cpp += 11;
	}
	else if ('*' != (*cpp)[11] && 10 != ix) {//落下时
		*cpp += 11;
	}
	if (ijh > 0 && '*' == (*cpp)[11]) {//防磕头后还能跳
		ijh = 0;
	}
}
//射击函数
void Player::shoot(int& i, char** cpp) {
	if ((!i) && (iy && (!blr) || 10 != iy && blr)) {//检测冷却时间已过并且是否在地牢的边界射过
		v.push_back({ *cpp, iy, blr, 0 });
		i = 3;
	}
}
//子弹的移动函数
void Player::shootmove(const char(*strmap)[11][11], bool bmode) {
	if (bmode) {
		for (vector<trir>::iterator it = v.begin(); v.end() != it; it++) {
			(' ' == *it->cp || '@' == *it->cp) && (*it->cp = ' ');///编译显示之前子弹的移动
			if ('*' == *it->cp || it->bk || (!it->iy && (!it->b)) || (21 == it->iy && it->b)) {
				it->iy = -1;//子弹的销毁
			}
			if (0 <= it->iy) {
				it->cp -= (1 - it->b * 2);//子弹的移动
				it->iy -= (1 - it->b * 2);//子弹y坐标的移动
				(' ' == *it->cp || '@' == *it->cp) && (*it->cp = '@');//显示
			}
		}
	}
	else {
		sort(v.begin(), v.end(), cmp());//按子弹的y坐标进行升序排列
		while ((!v.empty()) && 0 > v.begin()->iy) {
			v.erase(v.begin());//销毁子弹
		}
	}
}

Cmp.h

#pragma once
#include <iostream>
#include <vector>
#include "Player.h"
using namespace std;
class cmp {
public:
	bool operator()(trir t, trir ta);//用于升序排列的假函数
};

Cmp.cpp

#include <iostream>
#include "Cmp.h"
#include "Player.h"
using namespace std;
bool cmp::operator()(trir t, trir ta) {
	return t.iy < ta.iy;//比较两个子弹的y坐标
}

cmpm.h

#pragma once
#ifndef oncec
#define oncec
#include <iostream>
using namespace std;
#include "moster.h"
class cmpm {
public:
	bool operator()(moster* mp, moster* mpa);//用于升序排列的假函数
};
#endif

cmpm.cpp

#include <iostream>
#include "cmpm.h"
#include "moster.h"
using namespace std;
bool cmpm::operator()(moster* mp, moster* mpa) {
	return mp->getheal() < mpa->getheal();//比较两个怪物的生命值
}

WASD.h

#pragma once
#include <iostream>
using namespace std;
#ifndef onceb
#define onceb
enum WASD {
	W,
	A,
	S,
	D,
	E
};
WASD& operator++(WASD& w);//枚举WASD类型数据的前置++,无后置++
#endif

WASD.cpp

#include <iostream>
using namespace std;
#include "WASD.h"
WASD& operator++(WASD& w) {
	WASD warr[5] = { W,A,S,D,E };//把WASD枚举类型的每一种东西都转化成数字
	w < E && (w = warr[w + 1]);//warr[w + 1](WASD) == w + 1(int)
	return w;
}

draw.h

#pragma once
#include <iostream>
using namespace std;
struct draw {
	int iy;//画“#”的画笔起始y坐标
	int ix;//画“#”的画笔起始x坐标
	int iwalk;//画笔往哪个方向走几步
	bool brd;//画壁画的方向(0> 1v)
};

isvp.h

#pragma once
#include <iostream>
using namespace std;
#include <vector>
#include <string>
#include "moster.h"
struct isv {//地牢怪物
	string str;//判断怪物的生成
	vector<moster*> vmp;//生成的怪物
	int id;//地牢怪物所代表的id
};

mosters.h

#pragma once
#include <iostream>
using namespace std;
#include "moster.h"//怪物们的头文件
#include "M_o.h"
#include "M&.h"
#include "M^.h"
#include "MO.h"
#include "M+.h"
#include "MX.h"

程序的流程图

主文件

开始
把_CRT_SECURE_NO_WARNINGS宏定义为1
导入io流
释放std作用域下的所有东西
导入Player.h头文件
导入mosters.h头文件
导入cmpm.h头文件
导入isvp.h头文件
导入cstdlib头文件
导入ctime头文件
导入algorithm文件
导入string类文件
导入cstring头文件
导入Windows.h头文件
导入draw.h头文件
定义枚举类型difficulty并初始化该类型里的EASY为0,NORMAL为1,HARD为2,LIMIT为3%难度(被百分号包住的为注释)%
定义MShow函数
定义del函数
定义delvo函数
定义setMempty函数
定义start函数%开始时打印大字函数%
定义win函数%胜利后打印函数%
把随机数的种子设为当前的时间刻
把有11行11列的二维字符数组strmap初始化为下面的图片



网站公告

今日签到

点亮在社区的每一天
去签到