这次我把代码写完了,但是:
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <iostream>
#include <unordered_map>
#undef _CRT_SECURE_NO_WARNINGS
using namespace std;
int n, k;
class Command;
class Trigger;
class Robot
{
public:
int Index = -1, LeftHand = -1, RightHand = -1;
vector<Command*> commands;
unordered_map<string, priority_queue<Trigger>> triggers;
void print() const
{
printf("Index = %d\tLeftHand = %d\tRightHand = %d\nCommand:", Index, LeftHand, RightHand);
for (size_t i = 0; i < commands.size(); i++)
{
printf("Command id=%d on %p\n", i, commands[i]);
}
}
void run()
{
for (Command* it : commands)
{
if(it->data.COMMANDNAME != "None") it->run(); //如果是TRIGGER不执行
}
}
};
Robot robots[105];
class Tools
{
public:
static int &LorR(Robot &rbt, int h)
{
if (h == 0) return rbt.LeftHand;
else if (h == 1) return rbt.RightHand;
else
{
printf("Error in function 'LorR'!\n'h' = %d is invaild!\n'h' must in {0,1}!\nRobot infomation:\n", h);
rbt.print();
while (true)
{
printf("");
}
}
}
static int &LorR(int id, int h) { return LorR(robots[id], h); }
static long long readll() { long long num; scanf("%lld", &num); return num; }
static int readint() { int num; scanf("%d", &num); return num; }
static string readstr() { string str; cin >> str; return str; }
static void getcheck() { k--; if (k == 0) exit(0); }
};
class CommandData
{
public:
int robotid = -1, h = -1, x = -1, y = -1, z = -1;
string COMMANDNAME = "None";
Command* COMMAND = nullptr;
string MyName = "COMMAND";
void print()
{
printf("robotid = %d, h = %d, x = %d, y = %d, z = %d, <COMMANDNAME> = %s, <COMMAND> = %p", robotid, h, x, y, z, COMMANDNAME.c_str(), COMMAND);
}
};
class Command
{
public:
CommandData data;
Command() = delete;
Command(const CommandData &dt) : data(dt) {}
virtual void run()
{
printf("Error!\nCommand{");
data.print();
printf("}::run() shouldn't be called!\n");
while (true)
{
printf("");
}
}
virtual void do_trigger() const
{
Robot& rbt = robots[data.robotid];
if (rbt.triggers.count(data.MyName))
{
priority_queue<Trigger> Triggers = rbt.triggers[data.MyName];
while (!Triggers.empty() && Triggers.top().deleted)
{
Triggers.pop();
}
if (Triggers.empty())
{
rbt.triggers.erase(data.MyName);
return;
}
Triggers.top().realrun();
}
}
};
class SlackOff : public Command
{
public:
using Command::Command;
void run() { printf("Robot %d slacks off.\n", data.robotid); Tools::getcheck(); do_trigger(); }
};
class Move : public Command
{
public:
using Command::Command;
void run()
{
int h = data.h, z = data.z;
Robot& rbt = robots[data.robotid];
printf("Robot %d moves its ", rbt.Index);
int& rbtHand = Tools::LorR(rbt, h);
rbtHand = (rbtHand + z) % n;
if (h == 0) printf("left");
else printf("right");
printf(" hand towards Robot %d.\n", h == 0 ? rbt.LeftHand : rbt.RightHand);
Tools::getcheck();
do_trigger();
}
};
class Swap : public Command
{
public:
using Command::Command;
void run()
{
int h = data.h, x = data.x, y = data.y;
Robot& me = robots[data.robotid];
Robot& it = robots[Tools::LorR(data.robotid, h)];
swap(me.commands[y - 1], it.commands[x - 1]);
printf("Robot %d swaps a line of command with Robot %d.\n", me.Index, it.Index);
Tools::getcheck();
do_trigger();
}
};
class Mirror : public Command
{
public:
using Command::Command;
void run()
{
int h = data.h, x = data.x;
Robot& it = robots[Tools::LorR(data.robotid, h)];
Command& cmd = *it.commands[x];
if (cmd.data.COMMANDNAME != "None") cmd = *cmd.data.COMMAND;//说明是TRIGGER
cmd.data.h ^= 1;
printf("Robot %d modifies a line of command of Robot %d.\n", data.robotid, it.Index);
Tools::getcheck();
do_trigger();
}
};
class Replace : public Command
{
public:
using Command::Command;
void run()
{
int h = data.h, x = data.x;
Command* COMMAND = data.COMMAND;
Robot& it = robots[Tools::LorR(data.robotid, h)];
Command *cmd = it.commands[x];
delete cmd;
it.commands[x] = COMMAND;
printf("Robot %d replaces a line of command of Robot %d.\n", data.robotid, it.Index);
Tools::getcheck();
do_trigger();
}
};
class Activate : public Command
{
public:
using Command::Command;
void run()
{
Robot& it = robots[Tools::LorR(data.robotid, data.h)];
printf("Robot %d activates Robot %d.\n", data.robotid, it.Index);
Tools::getcheck();
it.run();
do_trigger();
}
};
class Trigger : public Command
{
public:
using Command::Command;
int CommandLine;
bool deleted = false;
void run() const
{
printf("Robot %d t-tr-tri-trig-trigg-trigge-trigger-trigger!\n", data.robotid);
}
void realrun() const
{
data.COMMAND->run();
do_trigger();
}
friend bool operator<(const Trigger& x, const Trigger& y) { return x.CommandLine > y.CommandLine; }
};
Command *ReadCommand(int index, int cmdline)
{
string CmdName;
cin >> CmdName;
Command* cmd = nullptr;
if (CmdName == "SLACKOFF") cmd = new SlackOff({ index });
if (CmdName == "MOVE") cmd = new Move({ index, Tools::readint(), -1, -1, Tools::readint() });
if (CmdName == "SWAP") cmd = new Swap({ index, Tools::readint(), Tools::readint(), Tools::readint() });
if (CmdName == "MIRROR") cmd = new Mirror({ index, Tools::readint(), Tools::readint() });
if (CmdName == "REPLACE")
{
//于是,好玩的事情发生了。
cmd = new Replace({ index, Tools::readint(), Tools::readint() });
cmd->data.COMMAND = ReadCommand(Tools::LorR(index, cmd->data.h), cmd->data.x);
}
if (CmdName == "ACTIVATE") cmd = new Activate({ index, Tools::readint() });
if (CmdName == "TRIGGER")
{
Trigger* tmp = new Trigger(
CommandData{ index, -1, -1, -1, -1,
Tools::readstr(), ReadCommand(index, -1) });
tmp->CommandLine = cmdline;
cmd = tmp;
}
cmd->data.MyName = CmdName;
return cmd;
}
int main()
{
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
for (int i = 0; i < n; i++)
{
Robot& rbt = robots[i];
rbt.Index = i;
scanf("%d%d", &rbt.LeftHand, &rbt.RightHand);
for (int j = 1; j <= m; j++)
{
rbt.commands.push_back(ReadCommand(i, j));
}
}
while (true)
{
for (int i = 0; i < n; i++)
{
robots[i].run();
}
}
return 0;
}
但是……
1>E:\.cppProgram\完美实验\完美实验\main.cpp(37,7): error C2027: 使用了未定义类型“Command”
.......
1>E:\.cppProgram\完美实验\完美实验\main.cpp(103,44): error C2027: 使用了未定义类型“Trigger”
怎么办?应该是依赖关系的问题,我实在不想手动拓扑排序(?)……