Parcourir la source

implemented cycle duration calculation and precondition checking

Zoadian il y a 10 ans
Parent
commit
cc8448bb49
5 fichiers modifiés avec 277 ajouts et 22 suppressions
  1. 3 3
      README.md
  2. 9 9
      instruction.h
  3. 2 0
      program.cpp
  4. 262 10
      simulator.cpp
  5. 1 0
      simulator.h

+ 3 - 3
README.md

@@ -7,8 +7,8 @@ A programming game based on RoboCom.
 | CREATE a, b, c     | 100+50*a+25*b+120*c | 2       | 0      | Create a new pogram with:<br> instSet a; b banks; c mobile                                                   | IS, IP   |
 | MOVE               | 20                  | 0       | 1      | Move the program one field                                                                                   |          |
 | DIE                | 1                   | 0       | 0      | Destroy the program                                                                                          | DI       |
-| TRANS a, b         | 14+1*numOfInst      | 1       | 0      | Transfers bank a to bank b in the program in front                                                           | IS, IB   |
-| RTRANS a, b        | 14+1*numOfInst      | 1       | 0      | Transfers bank afrom program in front to bank b                                                              | IS, IB   |
+| TRANS a, b         | 14+numOfInst        | 1       | 0      | Transfers bank a to bank b in the program in front                                                           | IS, IB   |
+| RTRANS a, b        | 14+numOfInst        | 1       | 0      | Transfers bank afrom program in front to bank b                                                              | IS, IB   |
 | TURN a             | 8                   | 0       | 0      | Turn by 90°;<br> Turn right if a >= 0 else left                                                              |          |
 | JUMP a             | 1                   | 0       | 0      | Realtive jump for a instructions                                                                             |          |
 | AJUMP a            | 1                   | 0       | 0      | Jump to instruction a in current bank                                                                        |          |
@@ -34,7 +34,7 @@ A programming game based on RoboCom.
 | BREAK              | 1                   | 0       | 0      | Stops other tasks, gives current task 100%                                                                   |          |
 | RESUME             | 1                   | 0       | 0      | Resume all other tasks suspended by SEIZE                                                                    |          |
 | SEIZE              | 1                   | 0       | 0      | Stops other tasks, gives current task 100% until RESUME                                                      |          |
-| SLEEP a            | 1                   | 0       | 0      | Suspend current task a cycles                                                                                |          |
+| SLEEP a            | a                   | 0       | 0      | Suspend current task a cycles                                                                                |          |
 | QUIT               | 1                   | 0       | 0      | Stops current task                                                                                           | UE       |
 
 

+ 9 - 9
instruction.h

@@ -44,6 +44,15 @@ enum Command : uint16_t {
 };
 
 enum Params : uint16_t {
+    N,
+    L,
+    V,
+
+    LL,
+    LV,
+    VL,
+    VV,
+
     LLL,
     LLV,
     LVL,
@@ -52,15 +61,6 @@ enum Params : uint16_t {
     VLV,
     VVL,
     VVV,
-
-    N = LLL,
-    L = LLL,
-    V = VLL,
-
-    LL = LLL,
-    LV = LVL,
-    VL = VLL,
-    VV = VVV,
 };
 
 enum Variables {

+ 2 - 0
program.cpp

@@ -3,6 +3,8 @@
 
 Program::Program(shared_ptr<Team> team, Direction direction, Position position, int32_t instructionSet, int32_t slotCount, int32_t mobile)
     : team(team)
+    , instructionSet(instructionSet)
+    , mobile(mobile)
     , position(position)
 {
     banks.resize(slotCount);

+ 262 - 10
simulator.cpp

@@ -18,6 +18,87 @@ Position Simulator::calcPosition(Position position, Direction direction, int32_t
     }
 }
 
+void Simulator::decodeInstructionParameters(Task& task, const Instruction& instruction) {
+    task.a = instruction.a;
+    task.b = instruction.b;
+    task.c = instruction.c;
+    task.var_a = nullptr;
+    task.var_b = nullptr;
+    task.var_c = nullptr;
+
+    switch(instruction.params) {
+        case N:
+            break;
+        case L:
+            task.a = instruction.a;
+            break;
+        case V:
+
+            break;
+        case LL:
+            task.a = instruction.a;
+            task.b = instruction.b;
+            break;
+        case LV:
+            task.a = instruction.a;
+
+            break;
+        case VL:
+
+            task.b = instruction.b;
+            break;
+        case VV:
+
+
+            break;
+        case LLL:
+            task.a = instruction.a;
+            task.b = instruction.b;
+            task.c = instruction.c;
+            break;
+        case LLV:
+            task.a = instruction.a;
+            task.b = instruction.b;
+
+            break;
+        case LVL:
+            task.a = instruction.a;
+
+            task.c = instruction.c;
+            break;
+        case LVV:
+            task.a = instruction.a;
+
+
+            break;
+        case VLL:
+
+            task.b = instruction.b;
+            task.c = instruction.c;
+            break;
+        case VLV:
+
+            task.b = instruction.b;
+
+            break;
+        case VVL:
+
+
+            task.c = instruction.c;
+            break;
+        case VVV:
+
+
+
+            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) {
     shared_ptr<Team> team = make_shared<Team>(color);
@@ -106,22 +187,193 @@ void Simulator::beginInstruction(Program& program, Task& task) {
 
     task.execBank = program.banks[task.bankIndex];
 
-    task.remainingCycles = 10;
+    auto& instruction = program.banks[task.bankIndex]->instructions[task.instIndex];
 
-    auto& inst = program.banks[task.bankIndex]->instructions[task.instIndex];
-    task.a = inst.a;
-    task.b = inst.b;
-    task.c = inst.c;
+    decodeInstructionParameters(task, instruction);
 
-    //@todo: remove dummy!
-    task.var_a = &task.a;
-    task.var_b = &task.b;
-    task.var_c = &task.c;
+    switch(instruction.command) {
+        case CREATE:
+            if(program.instructionSet < 2) {
+                program.error = HigherInstructionSetRequired;
+                break;
+            }
+            if(task.a < 0 || task.a > 2 || task.b < 1 || task.b > 50 || task.c < 0 || task.c > 1) {
+                program.error = InvalidParameter;
+                break;
+            }
+            task.remainingCycles = 100 + 50 * task.a + 25 * task.b + 120 * task.c;
+            break;
+
+        case MOVE:
+            if(program.mobile < 1) {
+                program.error = MobilityRequired;
+                break;
+            }
+            task.remainingCycles = 20;
+            break;
+
+        case DIE:
+            task.remainingCycles = 1;
+            break;
+
+        case TRANS: {
+            if(program.instructionSet < 1) {
+                program.error = HigherInstructionSetRequired;
+                break;
+            }
+            if(task.a < 0 || task.a >= program.banks.size()) {
+                program.error = InvalidBankNumber;
+                break;
+            }
+            const auto& bank = program.banks[task.a];
+            task.remainingCycles = 14 + (bank ? bank->instructions.size() : 0);
+            break;
+        }
+
+        case RTRANS: {
+            if(program.instructionSet < 1) {
+                program.error = HigherInstructionSetRequired;
+                break;
+            }
+            if(task.a < 0 || task.a >= 50 || task.b < 0 || task.b >= program.banks.size()) {
+                program.error = InvalidBankNumber;
+                break;
+            }
+            auto remotePosition = calcPosition(program.position, task.direction, 1);
+            auto remoteProgram = findProgram(remotePosition);
+            task.remainingCycles = 14 + remoteProgram ? (task.a < remoteProgram->banks.size() ? (remoteProgram->banks[task.a] ? remoteProgram->banks[task.a]->instructions.size() : 0): 0): 0;
+            break;
+        }
+
+        case TURN:
+            task.remainingCycles = 8;
+            break;
+
+        case JUMP:
+            task.remainingCycles = 1;
+            break;
+
+        case AJUMP:
+            task.remainingCycles = 1;
+            break;
+
+        case BJUMP:
+            task.remainingCycles = 2;
+            break;
+
+        case SCAN:
+            if(program.instructionSet < 1) {
+                program.error = HigherInstructionSetRequired;
+                break;
+            }
+            task.remainingCycles = 8;
+            break;
+
+        case FARSCAN:
+            if(program.instructionSet < 1) {
+                program.error = HigherInstructionSetRequired;
+                break;
+            }
+            task.remainingCycles = 10 + 3 * task.c;
+            break;
+
+        case SET:
+            task.remainingCycles = 2;
+            break;
+
+        case ADD:
+            task.remainingCycles = 2;
+            break;
+
+        case SUB:
+            task.remainingCycles = 2;
+            break;
+
+        case MUL:
+            task.remainingCycles = 2;
+            break;
+
+        case DIV:
+            task.remainingCycles = 2;
+            break;
+
+        case MOD:
+            task.remainingCycles = 2;
+            break;
+
+        case MIN:
+            task.remainingCycles = 2;
+            break;
+
+        case MAX:
+            task.remainingCycles = 2;
+            break;
+
+        case RANDOM:
+            if(task.b > task.c) {
+                program.error = InvalidParameter;
+                break;
+            }
+            task.remainingCycles = 1;
+            break;
+
+        case IF:
+            task.remainingCycles = 2;
+            break;
+
+        case IFN:
+            task.remainingCycles = 2;
+            break;
+
+        case IFG:
+            task.remainingCycles = 2;
+            break;
+
+        case IFL:
+            task.remainingCycles = 2;
+            break;
+
+        case IFGE:
+            task.remainingCycles = 2;
+            break;
+
+        case IFLE:
+            task.remainingCycles = 2;
+            break;
+
+        case INIT:
+            task.remainingCycles = 2;
+            break;
+
+        case BREAK:
+            task.remainingCycles = 1;
+            break;
+
+        case RESUME:
+            task.remainingCycles = 1;
+            break;
+
+        case SEIZE:
+            task.remainingCycles = 1;
+            break;
+
+        case SLEEP:
+            if(task.a > 2000) {
+                program.error = InvalidParameter;
+                break;
+            }
+            task.remainingCycles = task.a;
+            break;
+
+        case QUIT:
+            task.remainingCycles = 1;
+            break;
+    }
 }
 
 void Simulator::endInstruction(Program& program, Task& task) {
     // we are not executing yet
-    if(!task.execBank) {
+    if(!task.execBank || program.error != NoError) {
         return;
     }
 

+ 1 - 0
simulator.h

@@ -25,6 +25,7 @@ struct Simulator {
     Simulator();
 
     Position calcPosition(Position position, Direction direction, int32_t distance);
+    void decodeInstructionParameters(Task& task, const Instruction& instruction);
 
     void loadProgram(QColor color, size_t x, size_t y);