|
|
@@ -192,6 +192,12 @@ struct Task {
|
|
|
Direction direction = Right;
|
|
|
BankIndex bankIndex = 0;
|
|
|
InstIndex instIndex = 0;
|
|
|
+ int32_t a = 0;
|
|
|
+ int32_t b = 0;
|
|
|
+ int32_t c = 0;
|
|
|
+ int32_t* p_a = nullptr;
|
|
|
+ int32_t* p_b = nullptr;
|
|
|
+ int32_t* p_c = nullptr;
|
|
|
};
|
|
|
|
|
|
struct Program {
|
|
|
@@ -255,8 +261,8 @@ struct Simulator {
|
|
|
bank->push_back(Instruction(CREATE, LLL, 2, 50, 1));
|
|
|
bank->push_back(Instruction(TRANS, LL, 0, 0));
|
|
|
bank->push_back(Instruction(TRANS, LL, 1, 1));
|
|
|
- bank->push_back(Instruction(RANDOM, VLL, 5, -5, 5));
|
|
|
- bank->push_back(Instruction(TURN, V, 5));
|
|
|
+// bank->push_back(Instruction(RANDOM, VLL, 5, -5, 5));
|
|
|
+ bank->push_back(Instruction(TURN, L, 0));
|
|
|
bank->push_back(Instruction(ADD, VL, 6, 1));
|
|
|
// bank->push_back(Instruction(IFG, VL, 6, 5));
|
|
|
// bank->push_back(Instruction(DIE));
|
|
|
@@ -305,150 +311,151 @@ struct Simulator {
|
|
|
const auto& inst = bank[task.instIndex];
|
|
|
|
|
|
//prevent overrideing of instuctions...
|
|
|
- int32_t a_safe = inst.a;
|
|
|
- int32_t b_safe = inst.b;
|
|
|
- int32_t c_safe = inst.c;
|
|
|
-
|
|
|
- int32_t* a = &a_safe;
|
|
|
- int32_t* b = &b_safe;
|
|
|
- int32_t* c = &c_safe;
|
|
|
-
|
|
|
- auto decode = [&](int*& 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;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ 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;
|
|
|
}
|
|
|
- else {
|
|
|
- *v = 0;
|
|
|
+ case RemoteBanks: {
|
|
|
+ auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
+ auto remoteProgram = findProgram(remotePosition);
|
|
|
+ *v = remoteProgram ? remoteProgram->banks.size() : 0;
|
|
|
+ break;
|
|
|
}
|
|
|
- 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 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;
|
|
|
}
|
|
|
- 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; }
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- switch(inst.params) {
|
|
|
- case LLL: { break; }
|
|
|
- case LLV: { decode(c); break; }
|
|
|
- case LVL: { decode(b); break; }
|
|
|
- case LVV: { decode(b); decode(c); break; }
|
|
|
- case VLL: { decode(a); break; }
|
|
|
- case VLV: { decode(a); decode(c); break; }
|
|
|
- case VVL: { decode(a); decode(b); break; }
|
|
|
- case VVV: { decode(a); decode(b); decode(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.color, remotePosition, *a, *b, *c));
|
|
|
+ programs.push_back(Program(program.color, remotePosition, *task.p_a, *task.p_b, *task.p_c));
|
|
|
}
|
|
|
task.instIndex += 1;
|
|
|
break;
|
|
|
@@ -473,8 +480,8 @@ struct Simulator {
|
|
|
case TRANS: {
|
|
|
auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
auto remoteProgram = findProgram(remotePosition);
|
|
|
- if(remoteProgram && *b < remoteProgram->banks.size() && *a < program.banks.size()) {
|
|
|
- remoteProgram->banks[*b] = program.banks[*a];
|
|
|
+ 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;
|
|
|
@@ -483,32 +490,32 @@ struct Simulator {
|
|
|
case RTRANS: {
|
|
|
auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
auto remoteProgram = findProgram(remotePosition);
|
|
|
- if(remoteProgram && *a < remoteProgram->banks.size() && *b < program.banks.size()) {
|
|
|
- program.banks[*b] = remoteProgram->banks[*a];
|
|
|
+ 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 + ((*a >= 0) ? 1 : -1)) % 4));
|
|
|
+ task.direction = static_cast<Direction>(qMax(0, (task.direction + ((*task.p_a >= 0) ? 1 : -1)) % 4));
|
|
|
task.instIndex += 1;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
case JUMP: {
|
|
|
- task.instIndex += *a;
|
|
|
+ task.instIndex += *task.p_a;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
case AJUMP: {
|
|
|
- task.instIndex = *a;
|
|
|
+ task.instIndex = *task.p_a;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
case BJUMP: {
|
|
|
- task.bankIndex = *a;
|
|
|
- task.instIndex = *b;
|
|
|
+ task.bankIndex = *task.p_a;
|
|
|
+ task.instIndex = *task.p_b;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
@@ -519,7 +526,7 @@ struct Simulator {
|
|
|
// #a=2 ...friend
|
|
|
auto remotePosition = calcPosition(program.position, task.direction, 1);
|
|
|
auto remoteProgram = findProgram(remotePosition);
|
|
|
- *a = !remoteProgram ? 0 : remoteProgram->color == program.color ? 2: 1;
|
|
|
+ *task.p_a = !remoteProgram ? 0 : remoteProgram->color == program.color ? 2: 1;
|
|
|
task.instIndex += 1;
|
|
|
break;
|
|
|
}
|
|
|
@@ -531,14 +538,14 @@ struct Simulator {
|
|
|
// #a=1 ...enemy
|
|
|
// #a=2 ...friend
|
|
|
// Its distance is stored in #b.
|
|
|
- *a = 0;
|
|
|
- *b = 0;
|
|
|
- for(int i = 0; i < *c; ++i) {
|
|
|
+ *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) {
|
|
|
- *a = remoteProgram->color == program.color ? 2: 1;
|
|
|
- *b = i;
|
|
|
+ *task.p_a = remoteProgram->color == program.color ? 2: 1;
|
|
|
+ *task.p_b = i;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
@@ -548,72 +555,72 @@ struct Simulator {
|
|
|
|
|
|
|
|
|
case SET:
|
|
|
- *a = *b;
|
|
|
+ *task.p_a = *task.p_b;
|
|
|
task.instIndex += 1;
|
|
|
break;
|
|
|
|
|
|
case ADD:
|
|
|
- *a += *b;
|
|
|
+ *task.p_a += *task.p_b;
|
|
|
task.instIndex += 1;
|
|
|
break;
|
|
|
|
|
|
case SUB:
|
|
|
- *a -= *b;
|
|
|
+ *task.p_a -= *task.p_b;
|
|
|
task.instIndex += 1;
|
|
|
break;
|
|
|
|
|
|
case MUL:
|
|
|
- *a *= *b;
|
|
|
+ *task.p_a *= *task.p_b;
|
|
|
task.instIndex += 1;
|
|
|
break;
|
|
|
|
|
|
case DIV:
|
|
|
- *a /= *b;
|
|
|
+ *task.p_a /= *task.p_b;
|
|
|
task.instIndex += 1;
|
|
|
break;
|
|
|
|
|
|
case MOD:
|
|
|
- *a %= *b;
|
|
|
+ *task.p_a %= *task.p_b;
|
|
|
task.instIndex += 1;
|
|
|
break;
|
|
|
|
|
|
case MIN:
|
|
|
- *a = qMin(*a, *b);
|
|
|
+ *task.p_a = qMin(*task.p_a, *task.p_b);
|
|
|
task.instIndex += 1;
|
|
|
break;
|
|
|
|
|
|
case MAX:
|
|
|
- *a = qMax(*a, *b);
|
|
|
+ *task.p_a = qMax(*task.p_a, *task.p_b);
|
|
|
task.instIndex += 1;
|
|
|
break;
|
|
|
|
|
|
case RANDOM:
|
|
|
- *a = *b + (rand() % (*c - *b + 1));
|
|
|
+ *task.p_a = *task.p_b + (rand() % (*task.p_c - *task.p_b + 1));
|
|
|
task.instIndex += 1;
|
|
|
break;
|
|
|
|
|
|
case IF:
|
|
|
- task.instIndex += ((*a == *b) ? 1 : 2);
|
|
|
+ task.instIndex += ((*task.p_a == *task.p_b) ? 1 : 2);
|
|
|
break;
|
|
|
|
|
|
case IFN:
|
|
|
- task.instIndex += ((*a != *b) ? 1 : 2);
|
|
|
+ task.instIndex += ((*task.p_a != *task.p_b) ? 1 : 2);
|
|
|
break;
|
|
|
|
|
|
case IFG:
|
|
|
- task.instIndex += ((*a > *b) ? 1 : 2);
|
|
|
+ task.instIndex += ((*task.p_a > *task.p_b) ? 1 : 2);
|
|
|
break;
|
|
|
|
|
|
case IFL:
|
|
|
- task.instIndex += ((*a < *b) ? 1 : 2);
|
|
|
+ task.instIndex += ((*task.p_a < *task.p_b) ? 1 : 2);
|
|
|
break;
|
|
|
|
|
|
case IFGE:
|
|
|
- task.instIndex += ((*a >= *b) ? 1 : 2);
|
|
|
+ task.instIndex += ((*task.p_a >= *task.p_b) ? 1 : 2);
|
|
|
break;
|
|
|
|
|
|
case IFLE:
|
|
|
- task.instIndex += ((*a <= *b) ? 1 : 2);
|
|
|
+ task.instIndex += ((*task.p_a <= *task.p_b) ? 1 : 2);
|
|
|
break;
|
|
|
|
|
|
|