2023.4.5 魔兽世界(三)开战

卡着时间没测,应该没大问题

#include <bits/stdc++.h>
using namespace std;
int current_time = -5;
map<char*, int> m;
void print_time() {
	printf("%03d:%02d ", current_time / 60, current_time % 60);
}
int game_over;

class Weapon {
public:
	int type, unbreaking;
	const char *get_name() { return type == 0 ? "sword" : type == 1 ? "bomb" : "arrow"; }
	Weapon(int x = 0) : type(x), unbreaking(x == 2 ? 2 : x == 1 ? 1 : 2147483647) { }
};
class Warrior {
	const static int _kind = -1;
public:
	const static int _attack = 0;
	vector<Weapon *> w;
	int health, id;
	const static int init_health = 0;
	Warrior(int id, int health) : id(id), health(health) { }
	virtual int get_init_health() { return init_health; }
	virtual int generate(int id, int n, float m) { }
	virtual int generate(int id, int n) { }
	virtual int generate(int id) { }
	virtual int kind() = 0;
	virtual int attack() = 0;
	virtual void show() { }
	virtual void one_step() { }
	virtual ~Warrior() {
		for (auto x : w) delete x;
	}
};

class WarriorDragon : public Warrior {
	const static int _kind = 0;
public:
	float morale;
	static int init_health, _attack;
	WarriorDragon(int id, float m) : Warrior(id, init_health), morale(m) {
		w.emplace_back(new Weapon(id % 3));
	}
	virtual void set_init_health(int x) { init_health = x; }
	virtual int get_init_health() { return init_health; }
	virtual int kind() { return _kind; }
	virtual int attack() { return _attack; }
};
class WarriorNinja : public Warrior {
	const static int _kind = 1;
public:
	static int init_health, _attack;
	WarriorNinja(int id) : Warrior(id, init_health) {
		w.emplace_back(new Weapon(id % 3));
		w.emplace_back(new Weapon((id + 1) % 3));
	}
	virtual void set_init_health(int x) { init_health = x; }
	virtual int get_init_health() { return init_health; }
	virtual int kind() { return _kind; }
	virtual int attack() { return _attack; }
};
class WarriorIceman : public Warrior {
	const static int _kind = 2;
public:
	static int init_health, _attack;
	WarriorIceman(int id) : Warrior(id, init_health) {
		w.emplace_back(new Weapon(id % 3));
	}
	virtual void set_init_health(int x) { init_health = x; }
	virtual int get_init_health() { return init_health; }
	virtual void one_step() {
		health -= health / 10;
	}
	virtual int kind() { return _kind; }
	virtual int attack() { return _attack; }
};
class WarriorLion : public Warrior {
	const static int _kind = 3;
public:
	int loyalty;
	static int init_health, _attack, k;
	WarriorLion(int id, int l) : Warrior(id, init_health), loyalty(l) {
		w.emplace_back(new Weapon(id % 3));
	}
	virtual void set_init_health(int x) { init_health = x; }
	virtual int get_init_health() { return init_health; }
	virtual void one_step() {
		loyalty -= k;
	}
	virtual int kind() { return _kind; }
	virtual int attack() { return _attack; }
};
class WarriorWolf : public Warrior {
	const static int _kind = 4;
public:
	static int init_health, _attack;
	WarriorWolf(int id) : Warrior(id, init_health) { }
	virtual void set_init_health(int x) { init_health = x; }
	virtual int get_init_health() { return init_health; }
	virtual void show() { }
	virtual int kind() { return _kind; }
	virtual int attack() { return _attack; }
};
WarriorDragon dragon_obj(0, 0);
int WarriorDragon::init_health = 0, WarriorDragon::_attack = 0;
WarriorNinja ninja_obj(0);
int WarriorNinja::init_health = 0, WarriorNinja::_attack = 0;
WarriorIceman iceman_obj(0);
int WarriorIceman::init_health = 0, WarriorIceman::_attack = 0;
WarriorLion lion_obj(0, 0);
int WarriorLion::init_health = 0, WarriorLion::_attack = 0, WarriorLion::k = 0;
WarriorWolf wolf_obj(0);
int WarriorWolf::init_health = 0, WarriorWolf::_attack = 0;

const char *getname(Warrior *p) {
	switch(p->kind()) {
		case 0: return "dragon";
		case 1: return "ninja";
		case 2: return "iceman";
		case 3: return "lion";
		case 4: return "wolf";
	}
}
class HeadQuarter {
private:
	vector<Warrior*> wr;
	vector<int> ct;
	int tot;
	Warrior *_generate_warrior() {
		if (wr[now] == &dragon_obj) return new WarriorDragon(tot, 1.0 * health / dragon_obj.get_init_health());
		else if (wr[now] == &ninja_obj) return new WarriorNinja(tot);
		else if (wr[now] == &iceman_obj) return new WarriorIceman(tot);
		else if (wr[now] == &lion_obj) return new WarriorLion(tot, health);
		else return new WarriorWolf(tot);
	}
public:
	int health, now;
	HeadQuarter(int health) : health(health), now(-1), tot(0) { }
	template<typename T> void add_warrior_type(T &instance) {
		wr.emplace_back(&instance);
		ct.emplace_back(0);
	}
	Warrior *generate_warrior() {
		if (now == -2) return nullptr;
		now = now == wr.size() - 1 ? 0 : now + 1;
		if (health >= wr[now]->get_init_health()) {
			++tot;
			++ct[now];
			health -= wr[now]->get_init_health();
			return _generate_warrior();
		} else
			now = -2;
		return nullptr;
	}
	void show_warrior() {
		wr[now]->show();
	}
};
class BattleField {
	int n;
public:
	Warrior **city[2];
	BattleField(int n) : n(n) {    // city_num = n 
		city[0] = new Warrior *[n + 2]();
		city[1] = new Warrior *[n + 2]();
	}
	void event_5() {
		for (int i = 0; i <= n + 1; ++i) {
			if (city[0][i] != nullptr && city[0][i]->kind() == 3 && ((WarriorLion *)city[0][i])->loyalty <= 0) {
				print_time();
				printf("red lion %d ran away\n", city[0][i]->id);
				delete city[0][i];
				city[0][i] = nullptr;				
			}
			if (city[1][i] != nullptr && city[1][i]->kind() == 3 && ((WarriorLion *)city[1][i])->loyalty <= 0) {
				print_time();
				printf("blue lion %d ran away\n", city[1][i]->id);
				delete city[1][i];
				city[1][i] = nullptr;			
			}
		}			
	} // lions flee
	void event_10() {
		Warrior *x = city[1][1];
		if (x != nullptr) {
			x->one_step();
			print_time(); printf("blue %s %d reached red headquarter with %d elements and force %d\n", getname(x), x->id, x->health, x->attack());
			print_time(); puts("red headquarter was taken");
			game_over = 1;
		}
		for (int i = 1; i <= n; ++i) {
			x = city[0][i - 1];
			if (x != nullptr) {
				x->one_step();
				print_time(); printf("red %s %d marched to city %d with %d elements and force %d\n", getname(x), x->id, i, x->health, x->attack());				
			}
			x = city[1][i + 1];
			if (x != nullptr) {
				x->one_step();
				print_time(); printf("blue %s %d marched to city %d with %d elements and force %d\n", getname(x), x->id, i, x->health, x->attack());				
			}
		}
		x = city[0][n];
		if (x != nullptr) {
			x->one_step();
			print_time(); printf("red %s %d reached blue headquarter with %d elements and force %d\n", getname(x), x->id, x->health, x->attack());
			print_time(); puts("blue headquarter was taken");
			game_over = 1;
		}
		for (int i = n; i >= 1; --i) city[0][i] = city[0][i - 1];
		city[0][0] = nullptr;
		for (int i = 1; i <= n; ++i) city[1][i] = city[1][i + 1];
		city[1][n + 1] = nullptr;
	}	// one step forward
	int capture(Warrior *x, Warrior *y) {
		int count = 0;
		sort(y->w.begin(), y->w.end(), [](Weapon *p, Weapon *q) { return p->type > q->type || p->type == q->type && p->unbreaking < q->unbreaking; });
		for (auto e = y->w.rbegin(); e != y->w.rend() && x->w.size() < 10; ++e) {
			x->w.emplace_back(*e);
			++count;
		}
		for (int i = 0; i < count; ++i) y->w.pop_back(); 
		return count;
	}
	int capture_wolf(Warrior *x, Warrior *y) {
		int count = 0;
		sort(y->w.begin(), y->w.end(), [](Weapon *p, Weapon *q) { return p->type > q->type || p->type == q->type && p->unbreaking < q->unbreaking; });
		for (auto e = y->w.rbegin(), s = e; e != y->w.rend() && x->w.size() < 10 && (*e)->type == (*s)->type; ++e) {
			x->w.emplace_back(*e);
			++count;
		}
		for (int i = 0; i < count; ++i) y->w.pop_back(); 
		return count;
	}	
	void event_35() {
		for (int i = 1; i <= n; ++i) {
			Warrior *x = city[0][i];
			Warrior *y = city[1][i];
			if (x != nullptr && y != nullptr) {
				if (x->kind() == 4 && y->kind() == 4) continue;
				int count = 0;
				if (x->kind() == 4) {
					if (count = capture_wolf(x, y)) {
						print_time(); printf("red wolf %d took %d %s from blue %s %d in city %d\n", x->id, count, x->w.back()->get_name(), getname(y), y->id, i);
					}
				} else if (y->kind() == 4) {
					if (count = capture_wolf(y, x)) {
						print_time(); printf("blue wolf %d took %d %s from red %s %d in city %d\n", y->id, count, y->w.back()->get_name(), getname(x), x->id, i);
					}
				}
			}
		}
	}
	int attack_process(Warrior *x, Weapon *w, Warrior *y) {
		int u;
		switch(w->type) {
			case 0:
				u = x->attack() * 2 / 10;
				y->health -= u;
				return u > 0;
			case 1:
				u = x->attack() * 4 / 10;
				y->health -= u;
				if (x->kind() != 1)
					x->health -= u >> 1;
				--w->unbreaking;
				return u > 0;
			case 2:
				u = x->attack() * 3 / 10;
				y->health -= u;
				--w->unbreaking;
				return u > 0;
		}
	}
	void event_40() {
		for (int i = 1; i <= n; ++i) {
			Warrior *x = city[0][i];
			Warrior *y = city[1][i];
			if (x == nullptr || y == nullptr) continue;
			sort(x->w.begin(), x->w.end(), [](Weapon *p, Weapon *q) { return p->type < q->type || p->type == q->type && p->unbreaking < q->unbreaking; });
			sort(y->w.begin(), y->w.end(), [](Weapon *p, Weapon *q) { return p->type < q->type || p->type == q->type && p->unbreaking < q->unbreaking; });
			if (i & 1) {
				auto px = 0, py = 0;
				bool effective = 1;
				while (1) {
					if (x->health <= 0) break;
					if (y->health <= 0) break;
					if (x->w.empty() && y->w.empty()) break;
					if (!effective && (x->w.empty() || x->w.back()->type == 0) && (y->w.empty() || y->w.back()->type == 0)) break; // ״̬²»·¢Éú±ä»¯ 
					effective = 0;
					if (!x->w.empty()) {
						effective |= attack_process(x, x->w[px], y);
						if (x->w[px]->unbreaking == 0) {
							delete *(x->w.begin() + px);
							x->w.erase(x->w.begin() + px);
						} else
							++px;
						if (px == x->w.size()) px = 0;
					}
					if (x->health <= 0) break;
					if (y->health <= 0) break;
					if (!y->w.empty()) {
						effective |= attack_process(y, y->w[py], x);
						if (y->w[py]->unbreaking == 0) {
							delete *(y->w.begin() + py);
							y->w.erase(y->w.begin() + py);
						} else
							++py;
						if (py == y->w.size()) py = 0;
					}
				}
			} else {
				auto px = 0, py = 0;
				bool effective = 1;
				while (1) {
					if (y->health <= 0) break;
					if (x->health <= 0) break;
					if (x->w.empty() && y->w.empty()) break;
					if (!effective && (x->w.empty() || x->w.back()->type == 0) && (y->w.empty() || y->w.back()->type == 0)) break; // ״̬²»·¢Éú±ä»¯ 
					effective = 0;
					if (!y->w.empty()) {
						effective |= attack_process(y, y->w[py], x);
						if (y->w[py]->unbreaking == 0) {
							delete *(y->w.begin() + py);
							y->w.erase(y->w.begin() + py);
						} else
							++py;
						if (py == y->w.size()) py = 0;
					}
					if (y->health <= 0) break;
					if (x->health <= 0) break;			
					if (!x->w.empty()) {
						effective |= attack_process(x, x->w[px], y);
						if (x->w[px]->unbreaking == 0) {
							delete *(x->w.begin() + px);
							x->w.erase(x->w.begin() + px);
						} else
							++px;
						if (px == x->w.size()) px = 0;
					}
				}
			}
			print_time();
			if (x->health > 0 && y->health > 0) {
				printf("both red %s %d and blue %s %d were alive in city %d\n", getname(x), x->id, getname(y), y->id, i);
				if (x->kind() == 0) {
					print_time();
					printf("red dragon %d yelled in city %d\n", x->id, i);
				}
				if (y != nullptr && y->health > 0 && y->kind() == 0) {
					print_time();
					printf("blue dragon %d yelled in city %d\n", y->id, i);
				}
			} else if (x->health > 0) {
				printf("red %s %d killed blue %s %d in city %d remaining %d elements\n", getname(x), x->id, getname(y), y->id, i, x->health);
				if (x->kind() == 0) {
					print_time();
					printf("red dragon %d yelled in city %d\n", x->id, i);
				}
				capture(x, y);
				delete city[1][i];
				city[1][i] = nullptr;
			} else if (y->health > 0) {
				printf("blue %s %d killed red %s %d in city %d remaining %d elements\n", getname(y), y->id, getname(x), x->id, i, y->health);
				if (y != nullptr && y->health > 0 && y->kind() == 0) {
					print_time();
					printf("blue dragon %d yelled in city %d\n", y->id, i);
				}
				capture(y, x);
				delete city[0][i];
				city[0][i] = nullptr;
			} else {
				printf("both red %s %d and blue %s %d died in city %d\n", getname(x), x->id, getname(y), y->id, i);
				delete city[0][i];
				city[0][i] = nullptr;
				delete city[1][i];
				city[1][i] = nullptr;
			}
		}
	}
	void event_55() {
		for (int i = 0; i <= n + 1; ++i) {
			Warrior *x = city[0][i];
			if (x != nullptr) {
				int u = 0, v = 0, w = 0;
				for (auto e : x->w) {
					switch(e->type) {
						case 0: ++u; break;
						case 1: ++v; break;
						case 2: ++w; break;
					}
				}
				print_time(); printf("red %s %d has %d sword %d bomb %d arrow and %d elements\n", getname(x), x->id, u, v, w, x->health);
			}
			x = city[1][i];
			if (x != nullptr) {
				int u = 0, v = 0, w = 0;
				for (auto e : x->w) {
					switch(e->type) {
						case 0: ++u; break;
						case 1: ++v; break;
						case 2: ++w; break;
					}
				}
				print_time(); printf("blue %s %d has %d sword %d bomb %d arrow and %d elements\n", getname(x), x->id, u, v, w, x->health);
			}
		}
	}
	
	
	~BattleField() {
		delete city[0];
		delete city[1];
	}
};
int main() {
	freopen("dd.txt", "w", stdout);
	for (int T, _ = (scanf("%d", &T), 1); _ <= T; ++_) {
		int hp, n, time_limit;
		scanf("%d%d%d%d", &hp, &n, &WarriorLion::k, &time_limit);
		BattleField bf(n);
		HeadQuarter red(hp);
		red.add_warrior_type(iceman_obj), red.add_warrior_type(lion_obj);
		red.add_warrior_type(wolf_obj), red.add_warrior_type(ninja_obj), red.add_warrior_type(dragon_obj);
		HeadQuarter blue(hp);
		blue.add_warrior_type(lion_obj), blue.add_warrior_type(dragon_obj);
		blue.add_warrior_type(ninja_obj), blue.add_warrior_type(iceman_obj), blue.add_warrior_type(wolf_obj);
		scanf("%d", &WarriorDragon::init_health);
		scanf("%d", &WarriorNinja::init_health);
		scanf("%d", &WarriorIceman::init_health);
		scanf("%d", &WarriorLion::init_health);
		scanf("%d", &WarriorWolf::init_health);
		scanf("%d", &WarriorDragon::_attack);
		scanf("%d", &WarriorNinja::_attack);
		scanf("%d", &WarriorIceman::_attack);
		scanf("%d", &WarriorLion::_attack);
		scanf("%d", &WarriorWolf::_attack);
		printf("Case %d:\n", _);
		game_over = 0;
		current_time = -5;
		while (1) {
			current_time += 5;
			if (current_time > time_limit || game_over) break;
			Warrior *x = red.generate_warrior();
			if (x != nullptr) {
				bf.city[0][0] = x;
				print_time(); printf("red %s %d born\n", getname(x), x->id);
				if (x->kind() == 3) {
					printf("Its loyalty is %d\n", ((WarriorLion *)x)->loyalty);
				}
			}
			x = blue.generate_warrior();
			if (x != nullptr) {
				bf.city[1][n + 1] = x;
				print_time(); printf("blue %s %d born\n", getname(x), x->id);
				if (x->kind() == 3) {
					printf("Its loyalty is %d\n", ((WarriorLion *)x)->loyalty);
				}
			}
			current_time += 5;
			if (current_time > time_limit || game_over) break;
			bf.event_5();
			current_time += 5;
			if (current_time > time_limit || game_over) break;
			bf.event_10();
			current_time += 25;
			if (current_time > time_limit || game_over) break;
			bf.event_35(); // ÇÀ×°±¸ 
			current_time += 5;
			if (current_time > time_limit || game_over) break;
			bf.event_40();
			current_time += 10;
			if (current_time > time_limit || game_over) break;
			print_time(); printf("%d elements in red headquarter\n", red.health);
			print_time(); printf("%d elements in blue headquarter\n", blue.health);
			current_time += 5;
			if (current_time > time_limit || game_over) break;
			bf.event_55();
		}
	}
	return 0;
}
posted @ 2023-04-05 00:46  chenyilei  阅读(88)  评论(0编辑  收藏  举报