|
|
@@ -1,5 +1,6 @@
|
|
|
#include "simulator.h"
|
|
|
|
|
|
+enum { RemoteAccessCost = 6};
|
|
|
|
|
|
Simulator::Simulator() {
|
|
|
programs.reserve(FIELDS_XY * FIELDS_XY);
|
|
|
@@ -11,6 +12,7 @@ Simulator::Simulator() {
|
|
|
|
|
|
Position Simulator::calcPosition(Position position, Direction direction, int32_t distance) {
|
|
|
switch(direction) {
|
|
|
+ default:
|
|
|
case Right: return Position{(position.x + distance) % FIELDS_XY, position.y};
|
|
|
case Down: return Position{position.x, (position.y + distance) % FIELDS_XY};
|
|
|
case Left: return Position{(position.x - distance) % FIELDS_XY, position.y};
|
|
|
@@ -18,7 +20,7 @@ Position Simulator::calcPosition(Position position, Direction direction, int32_t
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void Simulator::decode(Program& program, Task& task, int& v, int*& var_v, int param) {
|
|
|
+void Simulator::decode(Program& program, Task& task, int& v, int*& var_v, int param, int& additionalCycles) {
|
|
|
var_v = nullptr;
|
|
|
|
|
|
switch(param) {
|
|
|
@@ -68,6 +70,7 @@ void Simulator::decode(Program& program, Task& task, int& v, int*& var_v, int pa
|
|
|
v = program.team->id;
|
|
|
break;
|
|
|
case RemoteActive: {
|
|
|
+ additionalCycles += RemoteAccessCost;
|
|
|
auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
auto remoteProgram = findProgram(remotePosition);
|
|
|
if(remoteProgram) {
|
|
|
@@ -81,36 +84,42 @@ void Simulator::decode(Program& program, Task& task, int& v, int*& var_v, int pa
|
|
|
break;
|
|
|
}
|
|
|
case RemoteBanks: {
|
|
|
+ additionalCycles += RemoteAccessCost;
|
|
|
auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
auto remoteProgram = findProgram(remotePosition);
|
|
|
v = remoteProgram ? remoteProgram->banks.size() : 0;
|
|
|
break;
|
|
|
}
|
|
|
case RemoteInstrSet: {
|
|
|
+ additionalCycles += RemoteAccessCost;
|
|
|
auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
auto remoteProgram = findProgram(remotePosition);
|
|
|
v = remoteProgram ? remoteProgram->instructionSet : 0;
|
|
|
break;
|
|
|
}
|
|
|
case RemoteMobile: {
|
|
|
+ additionalCycles += RemoteAccessCost;
|
|
|
auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
auto remoteProgram = findProgram(remotePosition);
|
|
|
v = remoteProgram ? remoteProgram->mobile: 0;
|
|
|
break;
|
|
|
}
|
|
|
case RemoteAge: {
|
|
|
+ additionalCycles += RemoteAccessCost;
|
|
|
auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
auto remoteProgram = findProgram(remotePosition);
|
|
|
v = remoteProgram ? (cycle - remoteProgram->creationCycle) : 0;
|
|
|
break;
|
|
|
}
|
|
|
case RemoteTasks: {
|
|
|
+ additionalCycles += RemoteAccessCost;
|
|
|
auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
auto remoteProgram = findProgram(remotePosition);
|
|
|
v = remoteProgram ? remoteProgram->tasks.size() : 0;
|
|
|
break;
|
|
|
}
|
|
|
case RemoteGeneration: {
|
|
|
+ additionalCycles += RemoteAccessCost;
|
|
|
auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
auto remoteProgram = findProgram(remotePosition);
|
|
|
v = remoteProgram ? remoteProgram->generation : 0;
|
|
|
@@ -147,7 +156,7 @@ void Simulator::decode(Program& program, Task& task, int& v, int*& var_v, int pa
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void Simulator::decodeInstructionParameters(Program& program, Task& task, const Instruction& instruction) {
|
|
|
+void Simulator::decodeInstructionParameters(Program& program, Task& task, const Instruction& instruction, int& additionalCycles) {
|
|
|
task.a = instruction.a;
|
|
|
task.b = instruction.b;
|
|
|
task.c = instruction.c;
|
|
|
@@ -162,7 +171,7 @@ void Simulator::decodeInstructionParameters(Program& program, Task& task, const
|
|
|
task.a = instruction.a;
|
|
|
break;
|
|
|
case V:
|
|
|
- decode(program, task, task.a, task.var_a, instruction.a);
|
|
|
+ decode(program, task, task.a, task.var_a, instruction.a, additionalCycles);
|
|
|
break;
|
|
|
case LL:
|
|
|
task.a = instruction.a;
|
|
|
@@ -170,15 +179,15 @@ void Simulator::decodeInstructionParameters(Program& program, Task& task, const
|
|
|
break;
|
|
|
case LV:
|
|
|
task.a = instruction.a;
|
|
|
- decode(program, task, task.b, task.var_b, instruction.b);
|
|
|
+ decode(program, task, task.b, task.var_b, instruction.b, additionalCycles);
|
|
|
break;
|
|
|
case VL:
|
|
|
- decode(program, task, task.a, task.var_a, instruction.a);
|
|
|
+ decode(program, task, task.a, task.var_a, instruction.a, additionalCycles);
|
|
|
task.b = instruction.b;
|
|
|
break;
|
|
|
case VV:
|
|
|
- decode(program, task, task.a, task.var_a, instruction.a);
|
|
|
- decode(program, task, task.b, task.var_b, instruction.b);
|
|
|
+ decode(program, task, task.a, task.var_a, instruction.a, additionalCycles);
|
|
|
+ decode(program, task, task.b, task.var_b, instruction.b, additionalCycles);
|
|
|
break;
|
|
|
case LLL:
|
|
|
task.a = instruction.a;
|
|
|
@@ -188,37 +197,37 @@ void Simulator::decodeInstructionParameters(Program& program, Task& task, const
|
|
|
case LLV:
|
|
|
task.a = instruction.a;
|
|
|
task.b = instruction.b;
|
|
|
- decode(program, task, task.c, task.var_c, instruction.c);
|
|
|
+ decode(program, task, task.c, task.var_c, instruction.c, additionalCycles);
|
|
|
break;
|
|
|
case LVL:
|
|
|
task.a = instruction.a;
|
|
|
- decode(program, task, task.b, task.var_b, instruction.b);
|
|
|
+ decode(program, task, task.b, task.var_b, instruction.b, additionalCycles);
|
|
|
task.c = instruction.c;
|
|
|
break;
|
|
|
case LVV:
|
|
|
task.a = instruction.a;
|
|
|
- decode(program, task, task.b, task.var_b, instruction.b);
|
|
|
- decode(program, task, task.c, task.var_c, instruction.c);
|
|
|
+ decode(program, task, task.b, task.var_b, instruction.b, additionalCycles);
|
|
|
+ decode(program, task, task.c, task.var_c, instruction.c, additionalCycles);
|
|
|
break;
|
|
|
case VLL:
|
|
|
- decode(program, task, task.a, task.var_a, instruction.a);
|
|
|
+ decode(program, task, task.a, task.var_a, instruction.a, additionalCycles);
|
|
|
task.b = instruction.b;
|
|
|
task.c = instruction.c;
|
|
|
break;
|
|
|
case VLV:
|
|
|
- decode(program, task, task.a, task.var_a, instruction.a);
|
|
|
+ decode(program, task, task.a, task.var_a, instruction.a, additionalCycles);
|
|
|
task.b = instruction.b;
|
|
|
- decode(program, task, task.c, task.var_c, instruction.c);
|
|
|
+ decode(program, task, task.c, task.var_c, instruction.c, additionalCycles);
|
|
|
break;
|
|
|
case VVL:
|
|
|
- decode(program, task, task.a, task.var_a, instruction.a);
|
|
|
- decode(program, task, task.b, task.var_b, instruction.b);
|
|
|
+ decode(program, task, task.a, task.var_a, instruction.a, additionalCycles);
|
|
|
+ decode(program, task, task.b, task.var_b, instruction.b, additionalCycles);
|
|
|
task.c = instruction.c;
|
|
|
break;
|
|
|
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);
|
|
|
+ decode(program, task, task.a, task.var_a, instruction.a, additionalCycles);
|
|
|
+ decode(program, task, task.b, task.var_b, instruction.b, additionalCycles);
|
|
|
+ decode(program, task, task.c, task.var_c, instruction.c, additionalCycles);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
@@ -305,7 +314,8 @@ void Simulator::beginInstruction(Program& program, Task& task) {
|
|
|
auto& instruction = program.banks[task.bankIndex]->instructions[task.instIndex];
|
|
|
|
|
|
// decode instruction parameters
|
|
|
- decodeInstructionParameters(program, task, instruction);
|
|
|
+ int additionalCycles = 0;
|
|
|
+ decodeInstructionParameters(program, task, instruction, additionalCycles);
|
|
|
|
|
|
// calculate cycle durations and check preconditions
|
|
|
switch(instruction.command) {
|
|
|
@@ -318,7 +328,7 @@ void Simulator::beginInstruction(Program& program, Task& task) {
|
|
|
program.error = InvalidParameter;
|
|
|
break;
|
|
|
}
|
|
|
- task.remainingCycles = 100 + 50 * task.a + 25 * task.b + 120 * task.c;
|
|
|
+ task.remainingCycles = 100 + 50 * task.a + 25 * task.b + 120 * task.c + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case MOVE:
|
|
|
@@ -326,21 +336,21 @@ void Simulator::beginInstruction(Program& program, Task& task) {
|
|
|
program.error = MobilityRequired;
|
|
|
break;
|
|
|
}
|
|
|
- task.remainingCycles = 20;
|
|
|
+ task.remainingCycles = 20 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case DIE:
|
|
|
- task.remainingCycles = 1;
|
|
|
+ task.remainingCycles = 1 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case TRANS: {
|
|
|
int ar = task.a - 1;
|
|
|
- int br = task.b - 1;
|
|
|
+ //int br = task.b - 1;
|
|
|
if(program.instructionSet < 1) {
|
|
|
program.error = HigherInstructionSetRequired;
|
|
|
break;
|
|
|
}
|
|
|
- if(ar < 0 || ar >= program.banks.size()) {
|
|
|
+ if(ar < 0 || ar >= static_cast<int>(program.banks.size())) {
|
|
|
program.error = InvalidBankNumber;
|
|
|
break;
|
|
|
}
|
|
|
@@ -356,30 +366,30 @@ void Simulator::beginInstruction(Program& program, Task& task) {
|
|
|
program.error = HigherInstructionSetRequired;
|
|
|
break;
|
|
|
}
|
|
|
- if(ar < 0 || ar >= 50 || br < 0 || br >= program.banks.size()) {
|
|
|
+ if(ar < 0 || ar >= 50 || br < 0 || br >= static_cast<int>(program.banks.size())) {
|
|
|
program.error = InvalidBankNumber;
|
|
|
break;
|
|
|
}
|
|
|
auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
auto remoteProgram = findProgram(remotePosition);
|
|
|
- task.remainingCycles = 14 + remoteProgram ? (ar < remoteProgram->banks.size() ? (remoteProgram->banks[ar] ? remoteProgram->banks[ar]->instructions.size() : 0): 0): 0;
|
|
|
+ task.remainingCycles = 14 + additionalCycles + remoteProgram ? (ar < static_cast<int>(remoteProgram->banks.size()) ? (remoteProgram->banks[ar] ? remoteProgram->banks[ar]->instructions.size() : 0): 0): 0;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
case TURN:
|
|
|
- task.remainingCycles = 8;
|
|
|
+ task.remainingCycles = 8 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case JUMP:
|
|
|
- task.remainingCycles = 1;
|
|
|
+ task.remainingCycles = 1 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case AJUMP:
|
|
|
- task.remainingCycles = 1;
|
|
|
+ task.remainingCycles = 1 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case BJUMP:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case SCAN:
|
|
|
@@ -387,7 +397,7 @@ void Simulator::beginInstruction(Program& program, Task& task) {
|
|
|
program.error = HigherInstructionSetRequired;
|
|
|
break;
|
|
|
}
|
|
|
- task.remainingCycles = 8;
|
|
|
+ task.remainingCycles = 8 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case FARSCAN:
|
|
|
@@ -399,35 +409,35 @@ void Simulator::beginInstruction(Program& program, Task& task) {
|
|
|
break;
|
|
|
|
|
|
case SET:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case ADD:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case SUB:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case MUL:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case DIV:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case MOD:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case MIN:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case MAX:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case RANDOM:
|
|
|
@@ -435,47 +445,47 @@ void Simulator::beginInstruction(Program& program, Task& task) {
|
|
|
program.error = InvalidParameter;
|
|
|
break;
|
|
|
}
|
|
|
- task.remainingCycles = 1;
|
|
|
+ task.remainingCycles = 1 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case IF:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case IFN:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case IFG:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case IFL:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case IFGE:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case IFLE:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case INIT:
|
|
|
- task.remainingCycles = 2;
|
|
|
+ task.remainingCycles = 2 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case BREAK:
|
|
|
- task.remainingCycles = 1;
|
|
|
+ task.remainingCycles = 1 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case RESUME:
|
|
|
- task.remainingCycles = 1;
|
|
|
+ task.remainingCycles = 1 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case SEIZE:
|
|
|
- task.remainingCycles = 1;
|
|
|
+ task.remainingCycles = 1 + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case SLEEP:
|
|
|
@@ -483,11 +493,11 @@ void Simulator::beginInstruction(Program& program, Task& task) {
|
|
|
program.error = InvalidParameter;
|
|
|
break;
|
|
|
}
|
|
|
- task.remainingCycles = task.a;
|
|
|
+ task.remainingCycles = task.a + additionalCycles;
|
|
|
break;
|
|
|
|
|
|
case QUIT:
|
|
|
- task.remainingCycles = 1;
|
|
|
+ task.remainingCycles = 1 + additionalCycles;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
@@ -539,7 +549,7 @@ void Simulator::endInstruction(Program& program, Task& task) {
|
|
|
int br = task.b - 1;
|
|
|
auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
auto remoteProgram = findProgram(remotePosition);
|
|
|
- if(remoteProgram && br < remoteProgram->banks.size() && ar < program.banks.size()) {
|
|
|
+ if(remoteProgram && br < static_cast<int>(remoteProgram->banks.size()) && ar < static_cast<int>(program.banks.size())) {
|
|
|
remoteProgram->banks[br] = program.banks[ar];
|
|
|
}
|
|
|
task.instIndex += 1;
|
|
|
@@ -551,7 +561,7 @@ void Simulator::endInstruction(Program& program, Task& task) {
|
|
|
int br = task.b - 1;
|
|
|
auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
auto remoteProgram = findProgram(remotePosition);
|
|
|
- if(remoteProgram && ar < remoteProgram->banks.size() && br < program.banks.size()) {
|
|
|
+ if(remoteProgram && ar < static_cast<int>(remoteProgram->banks.size()) && br < static_cast<int>(program.banks.size())) {
|
|
|
program.banks[br] = remoteProgram->banks[ar];
|
|
|
}
|
|
|
task.instIndex += 1;
|