|
@@ -8,650 +8,29 @@
|
|
|
#include <stdint.h>
|
|
#include <stdint.h>
|
|
|
using namespace std;
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
+#include "program.h"
|
|
|
|
|
+
|
|
|
enum {
|
|
enum {
|
|
|
CYCLE_TIMEOUT = 100000,
|
|
CYCLE_TIMEOUT = 100000,
|
|
|
FIELDS_XY = 20,
|
|
FIELDS_XY = 20,
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-struct Position {
|
|
|
|
|
- size_t x = 0;
|
|
|
|
|
- size_t y = 0;
|
|
|
|
|
-
|
|
|
|
|
- Position()
|
|
|
|
|
- : x(0)
|
|
|
|
|
- , y(0)
|
|
|
|
|
- {}
|
|
|
|
|
- Position(size_t _x, size_t _y)
|
|
|
|
|
- : x(_x)
|
|
|
|
|
- , y(_y)
|
|
|
|
|
- {}
|
|
|
|
|
- Position(const Position& _pos)
|
|
|
|
|
- : x(_pos.x)
|
|
|
|
|
- , y(_pos.y)
|
|
|
|
|
- {}
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-enum Direction {
|
|
|
|
|
- Right,
|
|
|
|
|
- Down,
|
|
|
|
|
- Left,
|
|
|
|
|
- Up,
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-enum Command : uint16_t {
|
|
|
|
|
- NOP,
|
|
|
|
|
-
|
|
|
|
|
- CREATE,
|
|
|
|
|
- MOVE,
|
|
|
|
|
- DIE,
|
|
|
|
|
- TRANS,
|
|
|
|
|
- RTRANS,
|
|
|
|
|
- TURN,
|
|
|
|
|
-
|
|
|
|
|
- JUMP,
|
|
|
|
|
- AJUMP,
|
|
|
|
|
- BJUMP,
|
|
|
|
|
-
|
|
|
|
|
- SCAN,
|
|
|
|
|
- FARSCAN,
|
|
|
|
|
-
|
|
|
|
|
- SET,
|
|
|
|
|
- ADD,
|
|
|
|
|
- SUB,
|
|
|
|
|
- MUL,
|
|
|
|
|
- DIV,
|
|
|
|
|
- MOD,
|
|
|
|
|
- MIN,
|
|
|
|
|
- MAX,
|
|
|
|
|
- RANDOM,
|
|
|
|
|
-
|
|
|
|
|
- IF,
|
|
|
|
|
- IFN,
|
|
|
|
|
- IFG,
|
|
|
|
|
- IFL,
|
|
|
|
|
- IFGE,
|
|
|
|
|
- IFLE,
|
|
|
|
|
-
|
|
|
|
|
- // INIT,
|
|
|
|
|
- // BREAK,
|
|
|
|
|
- // RESUME,
|
|
|
|
|
- // SEIZE,
|
|
|
|
|
- // SLEEP,
|
|
|
|
|
- // QUIT,
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-enum Params : uint16_t {
|
|
|
|
|
- LLL,
|
|
|
|
|
- LLV,
|
|
|
|
|
- LVL,
|
|
|
|
|
- LVV,
|
|
|
|
|
- VLL,
|
|
|
|
|
- VLV,
|
|
|
|
|
- VVL,
|
|
|
|
|
- VVV,
|
|
|
|
|
-
|
|
|
|
|
- N = LLL,
|
|
|
|
|
- L = LLL,
|
|
|
|
|
- V = VLL,
|
|
|
|
|
-
|
|
|
|
|
- LL = LLL,
|
|
|
|
|
- LV = LVL,
|
|
|
|
|
- VL = VLL,
|
|
|
|
|
- VV = VVV,
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-enum Variables {
|
|
|
|
|
- Local_0,
|
|
|
|
|
- Local_1,
|
|
|
|
|
- Local_2,
|
|
|
|
|
- Local_3,
|
|
|
|
|
- Local_4,
|
|
|
|
|
- Local_5,
|
|
|
|
|
- Local_6,
|
|
|
|
|
- Local_7,
|
|
|
|
|
- Local_8,
|
|
|
|
|
- Local_9,
|
|
|
|
|
- Local_10,
|
|
|
|
|
- Local_11,
|
|
|
|
|
- Local_12,
|
|
|
|
|
- Local_13,
|
|
|
|
|
- Local_14,
|
|
|
|
|
- Local_15,
|
|
|
|
|
- Local_16,
|
|
|
|
|
- Local_17,
|
|
|
|
|
- Local_18,
|
|
|
|
|
- Local_19,
|
|
|
|
|
- LocalActive,
|
|
|
|
|
- LocalBanks,
|
|
|
|
|
- LocalInstrSet,
|
|
|
|
|
- LocalMobile,
|
|
|
|
|
- LocalAge,
|
|
|
|
|
- LocalTasks,
|
|
|
|
|
- LocalGeneration,
|
|
|
|
|
- LocalId,
|
|
|
|
|
-
|
|
|
|
|
- RemoteActive,
|
|
|
|
|
- RemoteBanks,
|
|
|
|
|
- RemoteInstrSet,
|
|
|
|
|
- RemoteMobile,
|
|
|
|
|
- RemoteAge,
|
|
|
|
|
- RemoteTasks,
|
|
|
|
|
- RemoteGeneration,
|
|
|
|
|
-
|
|
|
|
|
- GlobalPub,
|
|
|
|
|
- GlobalTeam,
|
|
|
|
|
- GlobalOwn,
|
|
|
|
|
- GlobalOthers,
|
|
|
|
|
- GlobalFields,
|
|
|
|
|
- GlobalTime,
|
|
|
|
|
- GlobalTimeout,
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-enum Error {
|
|
|
|
|
- NoError, // No error
|
|
|
|
|
- EliminationTrigger, // Elimination Trigger released
|
|
|
|
|
- DataHunger, // Data Hunger (Bank 1 empty and executed)
|
|
|
|
|
- DivisionByZero, // Division by zero
|
|
|
|
|
- InvalidBankNumber, // Invalid bank number (e.g. in TRANS or BJUMP)
|
|
|
|
|
- HigherInstructionSetRequired, // Higher Instruction Set required
|
|
|
|
|
- MobilityRequired, // Mobility required
|
|
|
|
|
- DieExecuted, // DIE executed
|
|
|
|
|
- InvalidParameter , // Invalid parameter (e.g. CREATE x, -1, x)
|
|
|
|
|
- Unemployment, // No more tasks left in a robot (Unemployment)
|
|
|
|
|
- InstructionDurationTooHigh, // Instruction duration too high (i.e. > MaxInstrDur)
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-using Parameter = int32_t;
|
|
|
|
|
-
|
|
|
|
|
-struct Instruction {
|
|
|
|
|
- Command command = NOP;
|
|
|
|
|
- Params params = N;
|
|
|
|
|
- Parameter a = 0;
|
|
|
|
|
- Parameter b = 0;
|
|
|
|
|
- Parameter c = 0;
|
|
|
|
|
-
|
|
|
|
|
- Instruction(Command _command, Params _params = N, Parameter _a = 0, Parameter _b = 0, Parameter _c = 0)
|
|
|
|
|
- : command(_command)
|
|
|
|
|
- , params(_params)
|
|
|
|
|
- , a(_a)
|
|
|
|
|
- , b(_b)
|
|
|
|
|
- , c(_c)
|
|
|
|
|
- {
|
|
|
|
|
- }
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-struct Team {
|
|
|
|
|
- QColor color = Qt::red;
|
|
|
|
|
|
|
|
|
|
- Team(QColor color)
|
|
|
|
|
- : color(color)
|
|
|
|
|
- {
|
|
|
|
|
- }
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-struct Bank {
|
|
|
|
|
- shared_ptr<Team> team;
|
|
|
|
|
- vector<Instruction> instructions;
|
|
|
|
|
-
|
|
|
|
|
- Bank(shared_ptr<Team> team, const vector<Instruction>& instructions)
|
|
|
|
|
- : team(team)
|
|
|
|
|
- , instructions(instructions)
|
|
|
|
|
- {
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- Bank(const Bank& bank)
|
|
|
|
|
- : team(bank.team)
|
|
|
|
|
- , instructions(bank.instructions)
|
|
|
|
|
- {
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-using BankIndex = size_t;
|
|
|
|
|
-using InstIndex = size_t;
|
|
|
|
|
-using TaskIndex = size_t;
|
|
|
|
|
-
|
|
|
|
|
-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 {
|
|
|
|
|
- int active = 0;
|
|
|
|
|
- int instructionSet = 0;
|
|
|
|
|
- int mobile = 0;
|
|
|
|
|
- int creationCycle = 0;
|
|
|
|
|
- int generation = 0;
|
|
|
|
|
- Error error = NoError;
|
|
|
|
|
- shared_ptr<Team> team;
|
|
|
|
|
- Position position;
|
|
|
|
|
- vector<Task> tasks;
|
|
|
|
|
- TaskIndex taskIndex = 0;
|
|
|
|
|
- vector<shared_ptr<Bank>> banks;
|
|
|
|
|
- array<int32_t, 20> vars{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
|
|
|
|
|
-
|
|
|
|
|
- Program(shared_ptr<Team> _team, Position _position, int32_t instructionSet, int32_t slotCount, int32_t mobile) {
|
|
|
|
|
- team = _team;
|
|
|
|
|
- position = _position;
|
|
|
|
|
- banks.resize(slotCount);
|
|
|
|
|
- tasks.resize(1);
|
|
|
|
|
- }
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-struct Field {
|
|
|
|
|
- Program* program = nullptr;
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
struct Simulator {
|
|
struct Simulator {
|
|
|
size_t cycle = 0;
|
|
size_t cycle = 0;
|
|
|
vector<Program> programs;
|
|
vector<Program> programs;
|
|
|
|
|
|
|
|
- Simulator() {
|
|
|
|
|
- programs.reserve(FIELDS_XY * FIELDS_XY);
|
|
|
|
|
-
|
|
|
|
|
-// std::srand(std::time(0));
|
|
|
|
|
- std::srand(0);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- Position calcPosition(Position position, Direction direction, int32_t distance) {
|
|
|
|
|
- switch(direction) {
|
|
|
|
|
- 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};
|
|
|
|
|
- case Up: return Position{position.x, (position.y - distance) % FIELDS_XY};
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- void loadProgram(QColor color, size_t x, size_t y) {
|
|
|
|
|
- shared_ptr<Team> team = make_shared<Team>(color);
|
|
|
|
|
-
|
|
|
|
|
- programs.push_back(Program(team, Position{x, y}, 2, 50, 1));
|
|
|
|
|
-
|
|
|
|
|
- programs.back().banks[0] = make_shared<Bank>(team, vector<Instruction>{
|
|
|
|
|
- Instruction(BJUMP, LL, 1, 0)
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- 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)
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- Program* findProgram(Position position) {
|
|
|
|
|
- for(auto& program : programs) {
|
|
|
|
|
- if(program.position.x == position.x && program.position.y == position.y && program.error == NoError) {
|
|
|
|
|
- return &program;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return nullptr;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- void simulate() {
|
|
|
|
|
- for (auto& program : programs) {
|
|
|
|
|
- auto& taskIndex = program.taskIndex;
|
|
|
|
|
-
|
|
|
|
|
- if(program.error != NoError) {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(program.tasks.empty()) {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- taskIndex = (taskIndex + 1) % program.tasks.size();
|
|
|
|
|
-
|
|
|
|
|
- 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;
|
|
|
|
|
|
|
+ Simulator();
|
|
|
|
|
|
|
|
- case IFGE:
|
|
|
|
|
- task.instIndex += ((*task.p_a >= *task.p_b) ? 1 : 2);
|
|
|
|
|
- break;
|
|
|
|
|
|
|
+ Position calcPosition(Position position, Direction direction, int32_t distance);
|
|
|
|
|
|
|
|
- case IFLE:
|
|
|
|
|
- task.instIndex += ((*task.p_a <= *task.p_b) ? 1 : 2);
|
|
|
|
|
- break;
|
|
|
|
|
|
|
+ void loadProgram(QColor color, size_t x, size_t y);
|
|
|
|
|
|
|
|
|
|
+ Program* findProgram(Position position);
|
|
|
|
|
|
|
|
- default:
|
|
|
|
|
- task.instIndex += 1;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- ++cycle;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ void simulate();
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|