天天看點

程式設計思維與實踐 第三月 模拟題 爐石傳說

題目描述:

《爐石傳說:魔獸英雄傳》(Hearthstone: Heroes of Warcraft,簡稱爐石傳說)是暴雪娛樂開發的一款集換式卡牌遊戲(如下圖所示)。遊戲在一個戰鬥棋盤上進行,由兩名玩家輪流進行操作,本題所使用的爐石傳說遊戲的簡化規則如下:

 * 玩家會控制一些角色,每個角色有自己的生命值和攻擊力。當生命值小于等于 0 時,該角色死亡。角色分為英雄和随從。

  * 玩家各控制一個英雄,遊戲開始時,英雄的生命值為 30,攻擊力為 0。當英雄死亡時,遊戲結束,英雄未死亡的一方獲勝。

  * 玩家可在遊戲過程中召喚随從。棋盤上每方都有 7 個可用于放置随從的空位,從左到右一字排開,被稱為戰場。當随從死亡時,它将被從戰場上移除。

  * 遊戲開始後,兩位玩家輪流進行操作,每個玩家的連續一組操作稱為一個回合。

  * 每個回合中,目前玩家可進行零個或者多個以下操作:

  1) 召喚随從:玩家召喚一個随從進入戰場,随從具有指定的生命值和攻擊力。

  2) 随從攻擊:玩家控制自己的某個随從攻擊對手的英雄或者某個随從。

  3) 結束回合:玩家聲明自己的目前回合結束,遊戲将進入對手的回合。該操作一定是一個回合的最後一個操作。

  * 當随從攻擊時,攻擊方和被攻擊方會同時對彼此造成等同于自己攻擊力的傷害。受到傷害的角色的生命值将會減少,數值等同于受到的傷害。例如,随從 X 的生命值為 HX、攻擊力為 AX,随從 Y 的生命值為 HY、攻擊力為 AY,如果随從 X 攻擊随從 Y,則攻擊發生後随從 X 的生命值變為 HX - AY,随從 Y 的生命值變為 HY - AX。攻擊發生後,角色的生命值可以為負數。

  本題将給出一個遊戲的過程,要求編寫程式模拟該遊戲過程并輸出最後的局面。

input:

輸入第一行是一個整數 n,表示操作的個數。接下來 n 行,每行描述一個操作,格式如下:

  <action> <arg1> <arg2> ...

  其中<action>表示操作類型,是一個字元串,共有 3 種:summon表示召喚随從,attack表示随從攻擊,end表示結束回合。這 3 種操作的具體格式如下:

  * summon <position> <attack> <health>:目前玩家在位置<position>召喚一個生命值為<health>、攻擊力為<attack>的随從。其中<position>是一個 1 到 7 的整數,表示召喚的随從出現在戰場上的位置,原來該位置及右邊的随從都将順次向右移動一位。

  * attack <attacker> <defender>:目前玩家的角色<attacker>攻擊對方的角色 <defender>。<attacker>是 1 到 7 的整數,表示發起攻擊的本方随從編号,<defender>是 0 到 7 的整數,表示被攻擊的對方角色,0 表示攻擊對方英雄,1 到 7 表示攻擊對方随從的編号。

  * end:目前玩家結束本回合。

  注意:随從的編号會随着遊戲的程序發生變化,當召喚一個随從時,玩家指定召喚該随從放入戰場的位置,此時,原來該位置及右邊的所有随從編号都會增加 1。而當一個随從死亡時,它右邊的所有随從編号都會減少 1。任意時刻,戰場上的随從總是從1開始連續編号。

output:

輸出共 5 行。

  第 1 行包含一個整數,表示這 n 次操作後(以下稱為 T 時刻)遊戲的勝負結果,1 表示先手玩家獲勝,-1 表示後手玩家獲勝,0 表示遊戲尚未結束,還沒有人獲勝。

  第 2 行包含一個整數,表示 T 時刻先手玩家的英雄的生命值。

  第 3 行包含若幹個整數,第一個整數 p 表示 T 時刻先手玩家在戰場上存活的随從個數,之後 p 個整數,分别表示這些随從在 T 時刻的生命值(按照從左往右的順序)。

  第 4 行和第 5 行與第 2 行和第 3 行類似,隻是将玩家從先手玩家換為後手玩家。

思路:

模拟題,難度并不大,主要考察玩家随從的存儲以及随從的增加、删除操作。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int id,win=-1;//0表示玩家1,1表示玩家2 
string s;
struct node
{
  int blood=30;
  int sum;
  int attack[9];
  int health[9];
  void put(int pos,int a,int h)
  {
    if(pos==sum+1)
    {
      attack[++sum]=a;
      health[sum]=h;
    }
    else
    {
      for(int i=7;i>pos;i--)
      {
        attack[i]=attack[i-1];
        health[i]=health[i-1];
      }
      attack[pos]=a;
      health[pos]=h;
      sum++;
    }
  }
  void del()
  {
    int flag=-1;
    for(int i=1;i<=sum;i++)
    if(health[i]<=0)
    flag=i;
    if(flag==7)
    {
      sum--;
      health[flag]=0;
      attack[flag]=0;
      return;
    }
    else if(flag==-1) return;
    for(int i=flag;i<=7;i++)
    {
      health[i]=health[i+1];
      attack[i]=attack[i+1];
    }
    sum--;
  }
}a[2];
void atk(int id,int at,int de)
{
  if(de==0)
  {
    a[1-id].blood-=a[id].attack[at];
    if(a[1-id].blood<=0)
    {
      win=id;
    }
    return;
  }
  a[id].health[at]-=a[1-id].attack[de];
  a[1-id].health[de]-=a[id].attack[at];
  a[id].del();
  a[1-id].del();
}
void output()
{
  if(win==-1) cout<<0;
  else if(win==0) cout<<1;
  else if(win==1) cout<<-1;
  cout<<endl;
  cout<<a[0].blood<<endl<<a[0].sum<<" ";
  for(int i=1;i<=a[0].sum;i++)
  cout<<a[0].health[i]<<" ";
  cout<<endl;
  cout<<a[1].blood<<endl<<a[1].sum<<" ";
  for(int i=1;i<=a[1].sum;i++)
  cout<<a[1].health[i]<<" ";
}
int main()
{
  int n,x,y,z;
  cin>>n;
  for(int i=1;i<=n;i++)
  {
    cin>>s;
    if(s=="summon")
    {
      cin>>x>>y>>z;
      a[id].put(x,y,z);
    }
    else if(s=="attack")
    {
      cin>>x>>y;
      atk(id,x,y);
    }
    else if(s=="end") id=1-id;
  }
  output();
  return 0;
}