ACM PKU 2729 -- Robocode (…

这题是模拟题,算道难题.我主要想练习一下自己考虑问题的全面性和严谨性,事实证明,功夫还不够.题目是模拟FC上的坦克大决战游戏(当然没那么复杂),通过执行一系列命令后判断场上最后的坦克.
其实用C完全可以做,但我想练习一下类(我用C++写的代码少之又少),就用C++写了.写了个300多行的程序后交上是错.我仔细检察后也没找出问题.在POJ上问了过这题的人,他告我"实际上只要把模拟的单位时间变成原来的1/6,把整个战场扩大6倍就保证不会有问题了",我照做,通过了.
其实我还是不能理解:虽然我没有扩大6倍.但我确实仔细考虑了1/3s,1/2s/2/3s的情况.现在我还是不知我哪里没有考虑到(看题太晕,放弃).看来我设计的模型不够好,写出的程序既复杂又容易出错.教训呐.用离散的点来代表连续的时间是这题的关键.
PS:北京赛区还有道更难的模拟题I题,如果能通过网上预赛的话,我一定拿来做做.
 
程序如下:(由于C++用的不多肯定有很多不足之处)

#include<iostream>
#include<cstring>
using namespace std;
struct Shot{
    int x;
    int y;
    bool be;
    int degree;
}shot[1000];
struct Command{
    int time;
    int name;
    int content;
    int angle;
}command[1000];
int qshot,n;
void shotmove();
class Tank
{
public:
    Tank(int lx,int ly,int ldegree);
    Tank();
    ~Tank();
    void settank(int lx,int ly,int ldegree);
    void bemoving();
    void stop();
    void turn(int d);
    void moving();
    void shooting();
    void killing();
    void bomb();
    bool getbe();
private:
    int x;
    int y;
    int degree;
    bool move;
    bool be;
};
Tank tank[10];
int main()
{
    int m,i,j,x,y,degree,qcommand,time,c,d;
    char name[10][11],strna[11],strco[6];
    scanf("%d%d",&n,&m);
    while (n!=0 || m!=0)
    {
          c=0;
          for (i=0;i<n;i++)
          {
                scanf("%s%d%d%d",name[i],&x,&y,&degree);
                x*=6;
                y*=6;
                tank[i].settank(x,y,degree);
          }
          for (i=0;i<m;i++)
          {
                scanf("%d%s%s",&command[i].time,strna,strco);
                command[i].time*=6;
                for (j=0;j<n;j++)
                      if (strcmp(strna,name[j])==0)
                            break;
                command[i].name=j;
                if (strcmp(strco,"MOVE")==0)
                      command[i].content=1;
                else if (strcmp(strco,"STOP")==0)
                      command[i].content=0;
                else if (strcmp(strco,"TURN")==0)
                {
                      scanf("%d",&command[i].angle);
                      command[i].content=2;
                }
                else if (strcmp(strco,"SHOOT")==0)
                      command[i].content=3;
          }
          qshot=0;
          qcommand=0;
          for (time=0;time<=258;time++)
          {
                while (qcommand<m && command[qcommand].time==time)
                {
                      if (command[qcommand].content==1)
                            tank[command[qcommand].name].bemoving();
                      else if (command[qcommand].content==0)
                            tank[command[qcommand].name].stop();
                      else if (command[qcommand].content==2)
                          tank[command[qcommand].name].turn(command[qcommand].angle);
                      else if (command[qcommand].content==3)
                            tank[command[qcommand].name].shooting();
                      qcommand++;
                }
                for (i=0;i<n;i++)
                      tank[i].moving();
                shotmove();
                for (i=0;i<n;i++)
                      tank[i].killing();
          }
          for (i=0;i<n;i++)
          {
                if (tank[i].getbe()==true)
                {
                      d=i;
                      c++;
                }
          }
          if (c==0 || c>1)
                printf("NO WINNER!n");
          else printf("%sn",name[d]);
          scanf("%d%d",&n,&m);
    }
    return 0;
}
Tank::Tank(int lx,int ly,int ldegree)
{
    x=lx;
    y=ly;
    degree=ldegree;
    move=false;
    be=true;
}
Tank::Tank()
{
    x=0;
    y=0;
    degree=0;
    move=false;
    be=false;
}
Tank::~Tank()
{
}
void Tank::settank(int lx,int ly,int ldegree)
{
    x=lx;
    y=ly;
    degree=ldegree;
    move=false;
    be=true;
}
void Tank::bemoving()
{
    if (be==true)
          move=true;
}
void Tank::stop()
{
    if (be==true)
          move=false;
}
void Tank::turn(int d)
{
    if (be==true)
          degree=(degree+d+360)%360;
}
void Tank::moving()
{
    if (be==true && move==true)
    {
          if (degree==0)
          {
                if (x==720)
                      move=false;
                else x+=10;
          }
          else if (degree==90)
          {
                if (y==720)
                      move=false;
                else y+=10;
          }
          else if (degree==180)
          {
                if (x==0)
                      move=false;
                else x-=10;
          }
          else {
                if (y==0)
                      move=false;
                else y-=10;
          }
    }
}
void Tank::shooting()
{
    if (be==true)
    {
          shot[qshot].x=x;
          shot[qshot].y=y;
          shot[qshot].degree=degree;
          shot[qshot].be=true;
          qshot++;
    }
}
bool Tank::getbe()
{
    return be;
}
void Tank::killing()
{
    int i;
    if (be==false)
          return;
    for (i=0;i<qshot;i++)
    {
          if (shot[i].be==false)
                continue;
          if (shot[i].x==x && shot[i].y==y)
          {
                shot[i].be=false;
                be=false;
          }
    }
}
void shotmove()
{
    int i;
    for (i=0;i<qshot;i++)
    {
          if (shot[i].be==true)
          {
                if (shot[i].degree==0)
                {
                      if (shot[i].x>700)
                            shot[i].be=false;
                      else shot[i].x+=20;
                }
                else if (shot[i].degree==90)
                {
                      if (shot[i].y>700)
                            shot[i].be=false;
                      else shot[i].y+=20;
                }
                else if (shot[i].degree==180)
                {
                      if (shot[i].x<20)
                            shot[i].be=false;
                      else shot[i].x-=20;
                }
                else {
                      if (shot[i].y<20)
                            shot[i].be=false;
                      else shot[i].y-=20;
                }
          }
    }
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值