|
@@ -18,7 +18,136 @@ Position Simulator::calcPosition(Position position, Direction direction, int32_t
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void Simulator::decodeInstructionParameters(Task& task, const Instruction& instruction) {
|
|
|
|
|
|
|
+void Simulator::decode(Program& program, Task& task, int& v, int*& var_v, int param) {
|
|
|
|
|
+ var_v = nullptr;
|
|
|
|
|
+
|
|
|
|
|
+ switch(param) {
|
|
|
|
|
+ case Local_0: v = program.vars[0]; var_v = &program.vars[0]; break;
|
|
|
|
|
+ case Local_1: v = program.vars[1]; var_v = &program.vars[1]; break;
|
|
|
|
|
+ case Local_2: v = program.vars[2]; var_v = &program.vars[2]; break;
|
|
|
|
|
+ case Local_3: v = program.vars[3]; var_v = &program.vars[3]; break;
|
|
|
|
|
+ case Local_4: v = program.vars[4]; var_v = &program.vars[4]; break;
|
|
|
|
|
+ case Local_5: v = program.vars[5]; var_v = &program.vars[5]; break;
|
|
|
|
|
+ case Local_6: v = program.vars[6]; var_v = &program.vars[6]; break;
|
|
|
|
|
+ case Local_7: v = program.vars[7]; var_v = &program.vars[7]; break;
|
|
|
|
|
+ case Local_8: v = program.vars[8]; var_v = &program.vars[8]; break;
|
|
|
|
|
+ case Local_9: v = program.vars[9]; var_v = &program.vars[9]; break;
|
|
|
|
|
+ case Local_10: v = program.vars[10]; var_v = &program.vars[10]; break;
|
|
|
|
|
+ case Local_11: v = program.vars[11]; var_v = &program.vars[11]; break;
|
|
|
|
|
+ case Local_12: v = program.vars[12]; var_v = &program.vars[12]; break;
|
|
|
|
|
+ case Local_13: v = program.vars[13]; var_v = &program.vars[13]; break;
|
|
|
|
|
+ case Local_14: v = program.vars[14]; var_v = &program.vars[14]; break;
|
|
|
|
|
+ case Local_15: v = program.vars[15]; var_v = &program.vars[15]; break;
|
|
|
|
|
+ case Local_16: v = program.vars[16]; var_v = &program.vars[16]; break;
|
|
|
|
|
+ case Local_17: v = program.vars[17]; var_v = &program.vars[17]; break;
|
|
|
|
|
+ case Local_18: v = program.vars[18]; var_v = &program.vars[18]; break;
|
|
|
|
|
+ case Local_19: v = program.vars[19]; var_v = &program.vars[19]; break;
|
|
|
|
|
+ case LocalActive:
|
|
|
|
|
+ v = program.active;
|
|
|
|
|
+ var_v = &program.active;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case LocalBanks:
|
|
|
|
|
+ v = program.banks.size();
|
|
|
|
|
+ break;
|
|
|
|
|
+ case LocalInstrSet:
|
|
|
|
|
+ v = program.instructionSet;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case LocalMobile:
|
|
|
|
|
+ v = program.mobile;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case LocalAge:
|
|
|
|
|
+ v = cycle - program.creationCycle;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case LocalTasks:
|
|
|
|
|
+ v = program.tasks.size();
|
|
|
|
|
+ break;
|
|
|
|
|
+ case LocalGeneration:
|
|
|
|
|
+ v = program.generation;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case LocalId:
|
|
|
|
|
+ v = program.team->id;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case RemoteActive: {
|
|
|
|
|
+ auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
+ auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
+ if(remoteProgram) {
|
|
|
|
|
+ v = remoteProgram->active;
|
|
|
|
|
+ var_v = &remoteProgram->active;
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ v = 0;
|
|
|
|
|
+ var_v = nullptr;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case RemoteBanks: {
|
|
|
|
|
+ auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
+ auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
+ v = remoteProgram ? remoteProgram->banks.size() : 0;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case RemoteInstrSet: {
|
|
|
|
|
+ auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
+ auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
+ v = remoteProgram ? remoteProgram->instructionSet : 0;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case RemoteMobile: {
|
|
|
|
|
+ auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
+ auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
+ v = remoteProgram ? remoteProgram->mobile: 0;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case RemoteAge: {
|
|
|
|
|
+ auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
+ auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
+ v = remoteProgram ? (cycle - remoteProgram->creationCycle) : 0;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case RemoteTasks: {
|
|
|
|
|
+ auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
+ auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
+ v = remoteProgram ? remoteProgram->tasks.size() : 0;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case RemoteGeneration: {
|
|
|
|
|
+ auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
+ auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
+ v = remoteProgram ? remoteProgram->generation : 0;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case GlobalPub:
|
|
|
|
|
+ v = pub;
|
|
|
|
|
+ var_v = &pub;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case GlobalTeam:
|
|
|
|
|
+ v = program.team->var;
|
|
|
|
|
+ var_v = &program.team->var;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case GlobalOwn:
|
|
|
|
|
+ v = program.team->programCount;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case GlobalOthers:
|
|
|
|
|
+ v = 0;
|
|
|
|
|
+ for(auto& team : teams) {
|
|
|
|
|
+ if(team != program.team) {
|
|
|
|
|
+ v += team->programCount;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case GlobalFields:
|
|
|
|
|
+ v = FIELDS_XY * FIELDS_XY;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case GlobalTime:
|
|
|
|
|
+ v = cycle;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case GlobalTimeout:
|
|
|
|
|
+ v = CYCLE_TIMEOUT;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void Simulator::decodeInstructionParameters(Program& program, Task& task, const Instruction& instruction) {
|
|
|
task.a = instruction.a;
|
|
task.a = instruction.a;
|
|
|
task.b = instruction.b;
|
|
task.b = instruction.b;
|
|
|
task.c = instruction.c;
|
|
task.c = instruction.c;
|
|
@@ -33,7 +162,7 @@ void Simulator::decodeInstructionParameters(Task& task, const Instruction& instr
|
|
|
task.a = instruction.a;
|
|
task.a = instruction.a;
|
|
|
break;
|
|
break;
|
|
|
case V:
|
|
case V:
|
|
|
-
|
|
|
|
|
|
|
+ decode(program, task, task.a, task.var_a, instruction.a);
|
|
|
break;
|
|
break;
|
|
|
case LL:
|
|
case LL:
|
|
|
task.a = instruction.a;
|
|
task.a = instruction.a;
|
|
@@ -41,15 +170,15 @@ void Simulator::decodeInstructionParameters(Task& task, const Instruction& instr
|
|
|
break;
|
|
break;
|
|
|
case LV:
|
|
case LV:
|
|
|
task.a = instruction.a;
|
|
task.a = instruction.a;
|
|
|
-
|
|
|
|
|
|
|
+ decode(program, task, task.b, task.var_b, instruction.b);
|
|
|
break;
|
|
break;
|
|
|
case VL:
|
|
case VL:
|
|
|
-
|
|
|
|
|
|
|
+ decode(program, task, task.a, task.var_a, instruction.a);
|
|
|
task.b = instruction.b;
|
|
task.b = instruction.b;
|
|
|
break;
|
|
break;
|
|
|
case VV:
|
|
case VV:
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+ decode(program, task, task.a, task.var_a, instruction.a);
|
|
|
|
|
+ decode(program, task, task.b, task.var_b, instruction.b);
|
|
|
break;
|
|
break;
|
|
|
case LLL:
|
|
case LLL:
|
|
|
task.a = instruction.a;
|
|
task.a = instruction.a;
|
|
@@ -59,64 +188,63 @@ void Simulator::decodeInstructionParameters(Task& task, const Instruction& instr
|
|
|
case LLV:
|
|
case LLV:
|
|
|
task.a = instruction.a;
|
|
task.a = instruction.a;
|
|
|
task.b = instruction.b;
|
|
task.b = instruction.b;
|
|
|
-
|
|
|
|
|
|
|
+ decode(program, task, task.c, task.var_c, instruction.c);
|
|
|
break;
|
|
break;
|
|
|
case LVL:
|
|
case LVL:
|
|
|
task.a = instruction.a;
|
|
task.a = instruction.a;
|
|
|
-
|
|
|
|
|
|
|
+ decode(program, task, task.b, task.var_b, instruction.b);
|
|
|
task.c = instruction.c;
|
|
task.c = instruction.c;
|
|
|
break;
|
|
break;
|
|
|
case LVV:
|
|
case LVV:
|
|
|
task.a = instruction.a;
|
|
task.a = instruction.a;
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+ decode(program, task, task.b, task.var_b, instruction.b);
|
|
|
|
|
+ decode(program, task, task.c, task.var_c, instruction.c);
|
|
|
break;
|
|
break;
|
|
|
case VLL:
|
|
case VLL:
|
|
|
-
|
|
|
|
|
|
|
+ decode(program, task, task.a, task.var_a, instruction.a);
|
|
|
task.b = instruction.b;
|
|
task.b = instruction.b;
|
|
|
task.c = instruction.c;
|
|
task.c = instruction.c;
|
|
|
break;
|
|
break;
|
|
|
case VLV:
|
|
case VLV:
|
|
|
-
|
|
|
|
|
|
|
+ decode(program, task, task.a, task.var_a, instruction.a);
|
|
|
task.b = instruction.b;
|
|
task.b = instruction.b;
|
|
|
-
|
|
|
|
|
|
|
+ decode(program, task, task.c, task.var_c, instruction.c);
|
|
|
break;
|
|
break;
|
|
|
case VVL:
|
|
case VVL:
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+ decode(program, task, task.a, task.var_a, instruction.a);
|
|
|
|
|
+ decode(program, task, task.b, task.var_b, instruction.b);
|
|
|
task.c = instruction.c;
|
|
task.c = instruction.c;
|
|
|
break;
|
|
break;
|
|
|
case VVV:
|
|
case VVV:
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+ decode(program, task, task.a, task.var_a, instruction.a);
|
|
|
|
|
+ decode(program, task, task.b, task.var_b, instruction.b);
|
|
|
|
|
+ decode(program, task, task.c, task.var_c, instruction.c);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- //@todo: remove dummy!
|
|
|
|
|
- task.var_a = &task.a;
|
|
|
|
|
- task.var_b = &task.b;
|
|
|
|
|
- task.var_c = &task.c;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Simulator::loadProgram(QColor color, size_t x, size_t y) {
|
|
void Simulator::loadProgram(QColor color, size_t x, size_t y) {
|
|
|
shared_ptr<Team> team = make_shared<Team>(color);
|
|
shared_ptr<Team> team = make_shared<Team>(color);
|
|
|
|
|
+ teams.push_back(team);
|
|
|
|
|
|
|
|
programs.push_back(Program(team, Right, Position{x, y}, 2, 50, 1));
|
|
programs.push_back(Program(team, Right, Position{x, y}, 2, 50, 1));
|
|
|
|
|
+ ++team->programCount;
|
|
|
|
|
|
|
|
programs.back().banks[0] = make_shared<Bank>(team, vector<Instruction>{
|
|
programs.back().banks[0] = make_shared<Bank>(team, vector<Instruction>{
|
|
|
- Instruction(BJUMP, LL, 1, 0)
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ Instruction(BJUMP, LL, 1, 0)
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
programs.back().banks[1] = make_shared<Bank>(team, vector<Instruction>{
|
|
programs.back().banks[1] = make_shared<Bank>(team, vector<Instruction>{
|
|
|
- Instruction(SCAN, V, 1),
|
|
|
|
|
- Instruction(CREATE, LLL, 2, 50, 1),
|
|
|
|
|
- Instruction(TRANS, LL, 0, 0),
|
|
|
|
|
- Instruction(TRANS, LL, 1, 1),
|
|
|
|
|
- Instruction(TURN, L, 0),
|
|
|
|
|
- Instruction(AJUMP, L, 0)
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ Instruction(SCAN, V, 1),
|
|
|
|
|
+ Instruction(CREATE, LLL, 2, 50, 1),
|
|
|
|
|
+ Instruction(TRANS, LL, 0, 0),
|
|
|
|
|
+ Instruction(TRANS, LL, 1, 1),
|
|
|
|
|
+ Instruction(SET, VL, RemoteActive, 1),
|
|
|
|
|
+ Instruction(TURN, L, 0),
|
|
|
|
|
+ Instruction(AJUMP, L, 0)
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ programs.back().active = team->id;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Program* Simulator::findProgram(Position position) {
|
|
Program* Simulator::findProgram(Position position) {
|
|
@@ -131,6 +259,11 @@ Program* Simulator::findProgram(Position position) {
|
|
|
|
|
|
|
|
void Simulator::removeErroneousPrograms() {
|
|
void Simulator::removeErroneousPrograms() {
|
|
|
auto it = std::remove_if(programs.begin(), programs.end(), [](const Program& program){ return program.error != NoError; });
|
|
auto it = std::remove_if(programs.begin(), programs.end(), [](const Program& program){ return program.error != NoError; });
|
|
|
|
|
+
|
|
|
|
|
+ for(auto itr = it; itr != programs.end(); ++itr) {
|
|
|
|
|
+ --(itr->team->programCount);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
programs.erase(it, programs.end());
|
|
programs.erase(it, programs.end());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -140,6 +273,11 @@ void Simulator::simulate() {
|
|
|
for (auto& program : programs) {
|
|
for (auto& program : programs) {
|
|
|
auto& taskIndex = program.taskIndex;
|
|
auto& taskIndex = program.taskIndex;
|
|
|
|
|
|
|
|
|
|
+ // do nothing if not active
|
|
|
|
|
+ if(!program.active) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// error if no active task exists
|
|
// error if no active task exists
|
|
|
if(find_if(program.tasks.begin(), program.tasks.end(), [](const Task& task){ return !task.paused; }) == program.tasks.end()) {
|
|
if(find_if(program.tasks.begin(), program.tasks.end(), [](const Task& task){ return !task.paused; }) == program.tasks.end()) {
|
|
|
program.error = Unemployment;
|
|
program.error = Unemployment;
|
|
@@ -189,8 +327,10 @@ void Simulator::beginInstruction(Program& program, Task& task) {
|
|
|
|
|
|
|
|
auto& instruction = program.banks[task.bankIndex]->instructions[task.instIndex];
|
|
auto& instruction = program.banks[task.bankIndex]->instructions[task.instIndex];
|
|
|
|
|
|
|
|
- decodeInstructionParameters(task, instruction);
|
|
|
|
|
|
|
+ // decode instruction parameters
|
|
|
|
|
+ decodeInstructionParameters(program, task, instruction);
|
|
|
|
|
|
|
|
|
|
+ // calculate cycle durations and check preconditions
|
|
|
switch(instruction.command) {
|
|
switch(instruction.command) {
|
|
|
case CREATE:
|
|
case CREATE:
|
|
|
if(program.instructionSet < 2) {
|
|
if(program.instructionSet < 2) {
|
|
@@ -391,8 +531,10 @@ void Simulator::endInstruction(Program& program, Task& task) {
|
|
|
auto remoteProgram = findProgram(remotePosition);
|
|
auto remoteProgram = findProgram(remotePosition);
|
|
|
if(!remoteProgram) {
|
|
if(!remoteProgram) {
|
|
|
programs.push_back(Program(program.team, task.direction, remotePosition, task.a, task.b, task.c));
|
|
programs.push_back(Program(program.team, task.direction, remotePosition, task.a, task.b, task.c));
|
|
|
|
|
+ ++program.team->programCount;
|
|
|
}
|
|
}
|
|
|
task.instIndex += 1;
|
|
task.instIndex += 1;
|
|
|
|
|
+ break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
case MOVE: {
|
|
case MOVE: {
|
|
@@ -538,389 +680,34 @@ void Simulator::endInstruction(Program& program, Task& task) {
|
|
|
case RANDOM:
|
|
case RANDOM:
|
|
|
*task.var_a = task.b + (rand() % (task.c - task.b + 1));
|
|
*task.var_a = task.b + (rand() % (task.c - task.b + 1));
|
|
|
task.instIndex += 1;
|
|
task.instIndex += 1;
|
|
|
- break;
|
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
case IF:
|
|
case IF:
|
|
|
task.instIndex += ((task.a == task.b) ? 1 : 2);
|
|
task.instIndex += ((task.a == task.b) ? 1 : 2);
|
|
|
- break;
|
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
case IFN:
|
|
case IFN:
|
|
|
task.instIndex += ((task.a != task.b) ? 1 : 2);
|
|
task.instIndex += ((task.a != task.b) ? 1 : 2);
|
|
|
- break;
|
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
case IFG:
|
|
case IFG:
|
|
|
task.instIndex += ((task.a > task.b) ? 1 : 2);
|
|
task.instIndex += ((task.a > task.b) ? 1 : 2);
|
|
|
- break;
|
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
case IFL:
|
|
case IFL:
|
|
|
task.instIndex += ((task.a < task.b) ? 1 : 2);
|
|
task.instIndex += ((task.a < task.b) ? 1 : 2);
|
|
|
- break;
|
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
case IFGE:
|
|
case IFGE:
|
|
|
task.instIndex += ((task.a >= task.b) ? 1 : 2);
|
|
task.instIndex += ((task.a >= task.b) ? 1 : 2);
|
|
|
- break;
|
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
case IFLE:
|
|
case IFLE:
|
|
|
task.instIndex += ((task.a <= task.b) ? 1 : 2);
|
|
task.instIndex += ((task.a <= task.b) ? 1 : 2);
|
|
|
- break;
|
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
default:
|
|
default:
|
|
|
task.instIndex += 1;
|
|
task.instIndex += 1;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-#if 0
|
|
|
|
|
-void Simulator::simulatex() {
|
|
|
|
|
- for (auto& program : programs) {
|
|
|
|
|
- auto& taskIndex = program.taskIndex;
|
|
|
|
|
-
|
|
|
|
|
- if(program.error != NoError) {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(program.tasks.empty()) {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- if (taskIndex < program.tasks.size()) {
|
|
|
|
|
- auto& task = program.tasks[taskIndex];
|
|
|
|
|
-
|
|
|
|
|
- if(task.bankIndex >= program.banks.size()) {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const auto bank_ptr = program.banks[task.bankIndex].get();
|
|
|
|
|
-
|
|
|
|
|
- if(bank_ptr == nullptr || task.instIndex >= bank_ptr->instructions.size()) {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const auto& bank = *bank_ptr;
|
|
|
|
|
- const auto& inst = bank.instructions[task.instIndex];
|
|
|
|
|
-
|
|
|
|
|
- //prevent overrideing of instuctions...
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- auto mapParameters = [this](Program& program, Task& task, const Instruction& inst) {
|
|
|
|
|
- task.p_a = &task.a;
|
|
|
|
|
- task.p_b = &task.b;
|
|
|
|
|
- task.p_c = &task.c;
|
|
|
|
|
-
|
|
|
|
|
- auto decode = [&](int32_t*& v) {
|
|
|
|
|
- switch(*v) {
|
|
|
|
|
- case Local_0: v = &program.vars[0]; break;
|
|
|
|
|
- case Local_1: v = &program.vars[1]; break;
|
|
|
|
|
- case Local_2: v = &program.vars[2]; break;
|
|
|
|
|
- case Local_3: v = &program.vars[3]; break;
|
|
|
|
|
- case Local_4: v = &program.vars[4]; break;
|
|
|
|
|
- case Local_5: v = &program.vars[5]; break;
|
|
|
|
|
- case Local_6: v = &program.vars[6]; break;
|
|
|
|
|
- case Local_7: v = &program.vars[7]; break;
|
|
|
|
|
- case Local_8: v = &program.vars[8]; break;
|
|
|
|
|
- case Local_9: v = &program.vars[9]; break;
|
|
|
|
|
- case Local_10: v = &program.vars[10]; break;
|
|
|
|
|
- case Local_11: v = &program.vars[11]; break;
|
|
|
|
|
- case Local_12: v = &program.vars[12]; break;
|
|
|
|
|
- case Local_13: v = &program.vars[13]; break;
|
|
|
|
|
- case Local_14: v = &program.vars[14]; break;
|
|
|
|
|
- case Local_15: v = &program.vars[15]; break;
|
|
|
|
|
- case Local_16: v = &program.vars[16]; break;
|
|
|
|
|
- case Local_17: v = &program.vars[17]; break;
|
|
|
|
|
- case Local_18: v = &program.vars[18]; break;
|
|
|
|
|
- case Local_19: v = &program.vars[19]; break;
|
|
|
|
|
- case LocalActive:
|
|
|
|
|
- v = &program.active;
|
|
|
|
|
- break;
|
|
|
|
|
- case LocalBanks:
|
|
|
|
|
- *v = program.banks.size();
|
|
|
|
|
- break;
|
|
|
|
|
- case LocalInstrSet:
|
|
|
|
|
- *v = program.instructionSet;
|
|
|
|
|
- break;
|
|
|
|
|
- case LocalMobile:
|
|
|
|
|
- *v = program.mobile;
|
|
|
|
|
- break;
|
|
|
|
|
- case LocalAge:
|
|
|
|
|
- *v = cycle - program.creationCycle;
|
|
|
|
|
- break;
|
|
|
|
|
- case LocalTasks:
|
|
|
|
|
- *v = program.tasks.size();
|
|
|
|
|
- break;
|
|
|
|
|
- case LocalGeneration:
|
|
|
|
|
- *v = program.generation;
|
|
|
|
|
- break;
|
|
|
|
|
- case LocalId:
|
|
|
|
|
- // @todo
|
|
|
|
|
- break;
|
|
|
|
|
- case RemoteActive: {
|
|
|
|
|
- auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
- auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
- if(remoteProgram) {
|
|
|
|
|
- v = &remoteProgram->active;
|
|
|
|
|
- }
|
|
|
|
|
- else {
|
|
|
|
|
- *v = 0;
|
|
|
|
|
- }
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- case RemoteBanks: {
|
|
|
|
|
- auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
- auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
- *v = remoteProgram ? remoteProgram->banks.size() : 0;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- case RemoteInstrSet: {
|
|
|
|
|
- auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
- auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
- *v = remoteProgram ? remoteProgram->instructionSet : 0;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- case RemoteMobile: {
|
|
|
|
|
- auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
- auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
- *v = remoteProgram ? remoteProgram->mobile: 0;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- case RemoteAge: {
|
|
|
|
|
- auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
- auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
- *v = remoteProgram ? (cycle - remoteProgram->creationCycle) : 0;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- case RemoteTasks: {
|
|
|
|
|
- auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
- auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
- *v = remoteProgram ? remoteProgram->tasks.size() : 0;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- case RemoteGeneration: {
|
|
|
|
|
- auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
- auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
- *v = remoteProgram ? remoteProgram->generation : 0;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- case GlobalPub:
|
|
|
|
|
- // @todo
|
|
|
|
|
- break;
|
|
|
|
|
- case GlobalTeam:
|
|
|
|
|
- // @todo
|
|
|
|
|
- break;
|
|
|
|
|
- case GlobalOwn:
|
|
|
|
|
- // @todo
|
|
|
|
|
- break;
|
|
|
|
|
- case GlobalOthers:
|
|
|
|
|
- // @todo
|
|
|
|
|
- break;
|
|
|
|
|
- case GlobalFields:
|
|
|
|
|
- *v = FIELDS_XY * FIELDS_XY;
|
|
|
|
|
- break;
|
|
|
|
|
- case GlobalTime:
|
|
|
|
|
- *v = cycle;
|
|
|
|
|
- break;
|
|
|
|
|
- case GlobalTimeout:
|
|
|
|
|
- *v = CYCLE_TIMEOUT;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- switch(inst.params) {
|
|
|
|
|
- case LLL: { task.a = inst.a; task.b = inst.b; task.c = inst.c; break; }
|
|
|
|
|
- case LLV: { task.a = inst.a; task.b = inst.b; decode(task.p_c); break; }
|
|
|
|
|
- case LVL: { task.a = inst.a; decode(task.p_b); task.c = inst.c; break; }
|
|
|
|
|
- case LVV: { task.a = inst.a; decode(task.p_b); decode(task.p_c); break; }
|
|
|
|
|
- case VLL: { decode(task.p_a); task.b = inst.b; task.c = inst.c; break; }
|
|
|
|
|
- case VLV: { decode(task.p_a); task.b = inst.b; decode(task.p_c); break; }
|
|
|
|
|
- case VVL: { decode(task.p_a); decode(task.p_b); task.c = inst.c; break; }
|
|
|
|
|
- case VVV: { decode(task.p_a); decode(task.p_b); decode(task.p_c); break; }
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- mapParameters(program, task, inst);
|
|
|
|
|
-
|
|
|
|
|
- switch(inst.command) {
|
|
|
|
|
- case CREATE: {
|
|
|
|
|
- auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
- auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
- if(!remoteProgram) {
|
|
|
|
|
- programs.push_back(Program(program.team, remotePosition, *task.p_a, *task.p_b, *task.p_c));
|
|
|
|
|
- }
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- case MOVE: {
|
|
|
|
|
- auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
- auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
- if(!remoteProgram) {
|
|
|
|
|
- program.position = remotePosition;
|
|
|
|
|
- }
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- case DIE: {
|
|
|
|
|
- program.error = DieExecuted;
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- case TRANS: {
|
|
|
|
|
- auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
- auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
- if(remoteProgram && *task.p_b < remoteProgram->banks.size() && *task.p_a < program.banks.size()) {
|
|
|
|
|
- remoteProgram->banks[*task.p_b] = program.banks[*task.p_a];
|
|
|
|
|
- }
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- case RTRANS: {
|
|
|
|
|
- auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
- auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
- if(remoteProgram && *task.p_a < remoteProgram->banks.size() && *task.p_b < program.banks.size()) {
|
|
|
|
|
- program.banks[*task.p_b] = remoteProgram->banks[*task.p_a];
|
|
|
|
|
- }
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- case TURN: {
|
|
|
|
|
- task.direction = static_cast<Direction>(qMax(0, (task.direction + ((*task.p_a >= 0) ? 1 : -1)) % 4));
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- case JUMP: {
|
|
|
|
|
- task.instIndex += *task.p_a;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- case AJUMP: {
|
|
|
|
|
- task.instIndex = *task.p_a;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- case BJUMP: {
|
|
|
|
|
- task.bankIndex = *task.p_a;
|
|
|
|
|
- task.instIndex = *task.p_b;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- case SCAN: {
|
|
|
|
|
- // Scans a field, result in #a
|
|
|
|
|
- // #a=0 ...empty.
|
|
|
|
|
- // #a=1 ...enemy
|
|
|
|
|
- // #a=2 ...friend
|
|
|
|
|
- auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
|
|
- auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
- *task.p_a = !remoteProgram ? 0 : remoteProgram->team == program.team ? 2: 1;
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- case FARSCAN: {
|
|
|
|
|
- // Scans up to c fields straight in front of the bot.
|
|
|
|
|
- // The nearest bot's type is stored in #a:
|
|
|
|
|
- // #a=0 ...empty.
|
|
|
|
|
- // #a=1 ...enemy
|
|
|
|
|
- // #a=2 ...friend
|
|
|
|
|
- // Its distance is stored in #b.
|
|
|
|
|
- *task.p_a = 0;
|
|
|
|
|
- *task.p_b = 0;
|
|
|
|
|
- for(int i = 0; i < *task.p_c; ++i) {
|
|
|
|
|
- auto remotePosition = calcPosition(program.position, task.direction, i + 1);
|
|
|
|
|
- auto remoteProgram = findProgram(remotePosition);
|
|
|
|
|
- if(remoteProgram) {
|
|
|
|
|
- *task.p_a = remoteProgram->team == program.team ? 2: 1;
|
|
|
|
|
- *task.p_b = i;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- case SET:
|
|
|
|
|
- *task.p_a = *task.p_b;
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- case ADD:
|
|
|
|
|
- *task.p_a += *task.p_b;
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- case SUB:
|
|
|
|
|
- *task.p_a -= *task.p_b;
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- case MUL:
|
|
|
|
|
- *task.p_a *= *task.p_b;
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- case DIV:
|
|
|
|
|
- *task.p_a /= *task.p_b;
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- case MOD:
|
|
|
|
|
- *task.p_a %= *task.p_b;
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- case MIN:
|
|
|
|
|
- *task.p_a = qMin(*task.p_a, *task.p_b);
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- case MAX:
|
|
|
|
|
- *task.p_a = qMax(*task.p_a, *task.p_b);
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- case RANDOM:
|
|
|
|
|
- *task.p_a = *task.p_b + (rand() % (*task.p_c - *task.p_b + 1));
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- case IF:
|
|
|
|
|
- task.instIndex += ((*task.p_a == *task.p_b) ? 1 : 2);
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- case IFN:
|
|
|
|
|
- task.instIndex += ((*task.p_a != *task.p_b) ? 1 : 2);
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- case IFG:
|
|
|
|
|
- task.instIndex += ((*task.p_a > *task.p_b) ? 1 : 2);
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- case IFL:
|
|
|
|
|
- task.instIndex += ((*task.p_a < *task.p_b) ? 1 : 2);
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- case IFGE:
|
|
|
|
|
- task.instIndex += ((*task.p_a >= *task.p_b) ? 1 : 2);
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- case IFLE:
|
|
|
|
|
- task.instIndex += ((*task.p_a <= *task.p_b) ? 1 : 2);
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- default:
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- ++cycle;
|
|
|
|
|
-}
|
|
|
|
|
-#endif
|
|
|