1. 程式人生 > >CCF CSP 程式設計題目和解答-----試題名稱:爐石傳說 -------201609-3

CCF CSP 程式設計題目和解答-----試題名稱:爐石傳說 -------201609-3

#include<iostream>
#include<algorithm>
#include<vector>
#include<string>

using namespace std;
bool endgame = false;//遊戲是否結束的標誌位

typedef struct follower {//定義隨從的資料結構
	int health;
	int attack;
};

typedef struct hero {  //定義英雄的資料結構
	int health=30;
	int attack=0;
};

typedef struct Player {//定義玩家的資料結構
	hero h;
	vector<follower> flist;
};


vector<string> split(string in, string sp)//分割字串,解析引數
{
	vector<string> rt;
	while (in.find(sp) != -1)
	{
		string tem = in.substr(0, in.find(sp));
		if (tem != "")
			rt.push_back(tem);
		in = in.substr(in.find(sp) + 1);
	}
	if (in != "")
		rt.push_back(in);
	return rt;
}


void one_step(Player& p1, Player& p2, string action,int func)//表示一步操作,p1是當前局玩家,p2是被動玩家
{
	vector<string> para = split(action, " ");//解析得到引數
	switch (func)//根據不同的操作來選擇
	{
	case 1: {//召喚隨從操作
		int position = atoi(para[1].c_str())-1;//記憶體中編號從0開始
		int attack = atoi(para[2].c_str());
		int health = atoi(para[3].c_str());
		follower tf;
		tf.attack = attack;
		tf.health = health;
		p1.flist.insert(p1.flist.begin() + position, tf);
		break;
	}


	case 2://攻擊操作
	{
		int attackerNum = atoi(para[1].c_str())-1;  //vector從0開始編號,所以要減去1
		int defenderNum = atoi(para[2].c_str())-1;
		
		follower attacker = p1.flist[attackerNum];  //得到攻擊的隨從
		int attacker_attack = attacker.attack;
		int attacker_health = attacker.health;
		
		if (defenderNum == -1)                       //如果攻擊的是英雄
		{
			hero temp_hero = p2.h;               //得到原先的生命值
			temp_hero.health -= attacker_attack;//英雄生命減少
			p2.h = temp_hero;                  //更新英雄狀態
			if (temp_hero.health <= 0)           //如果英雄生命值小於0結束遊戲
				endgame = true;
			return;

		}
		else {                                     //如果被攻擊的是隨從
			follower defender = p2.flist[defenderNum];
			int defender_attack = defender.attack;
			int defender_health = defender.health;

			defender_health -= attacker_attack;
			attacker_health -= defender_attack;
			
			if (defender_health <= 0)//如果守衛死亡
				p2.flist.erase(p2.flist.begin() + defenderNum);
			else
			{
				defender.health = defender_health;//更新生命值
				p2.flist[defenderNum] = defender;
			}
			
			if (attacker_health <= 0)//如果攻擊者死亡
				p1.flist.erase(p1.flist.begin() + attackerNum);
			else
			{
				attacker.health = attacker_health;
				p1.flist[attackerNum] = attacker;
			}


		}
		break;
	}
	}
}


int main()
{

	//初始化兩個玩家
	Player p1, p2;
	hero h1, h2;
	p1.h = h1;
	p2.h = h2;
	int flag = 1;//表示當前玩家,初始為1,表示1號玩家為先手,-1為2號玩家
	
	
	int n=1;
	vector<string> actions;
	for (int i = 0; i < n; i++)
	{
		string tem;
		getline(cin, tem);
		n += atoi(tem.c_str());
		actions.push_back(tem);
	}

	actions.erase(actions.begin());//去掉第一行的引數,因為其表示操作次數
	int func = 0;//表示一次的操作的功能選擇
	for (int i = 0; i < actions.size(); i++)
	{
		func = 0;
		string a_action = actions[i];
		if (a_action.find("summon") != -1)
			func = 1;
		else if (a_action.find("attack") != -1)
			func = 2;
		else if (a_action.find("end") != -1)
			func = 3;


		switch (func)
		{
		 case 1:
		 {
			if (flag == 1)
			{
				one_step(p1, p2, a_action, func);
			}
			else
			{
				one_step(p2, p1, a_action, func);
			}
			break;
		 }
		 case 2:
		 {
			 if (flag == 1)
			 {
				 one_step(p1, p2, a_action, func);
				
			 }
			 else
			 {
				 one_step(p2, p1, a_action, func);
			 }
			break;
		 }
		 case 3:
		 {
			 flag = flag*-1;
			 break;
		 }		
		}

		if (endgame)
			break;
	}

	//輸出最後結果
	if (p1.h.health <= 0)
		cout << -1 << endl;
	else if (p2.h.health <= 0)
		cout << 1 << endl;
	else
		cout << 0 << endl;

	cout << p1.h.health << endl;

	cout << p1.flist.size()<<" ";//先手守衛存活個數;
	for (int i = 0; i < p1.flist.size(); i++)
		cout << p1.flist[i].health << " ";

	cout << endl;

	cout << p2.h.health << endl;

	cout << p2.flist.size()<<" ";//先手守衛存活個數;
	for (int i = 0; i < p2.flist.size(); i++)
		cout << p2.flist[i].health << " ";

	

	//system("pause");
}