protected override void InitializeRound() { base.InitializeRound(); cycle = 0; cyclesLeft = rules.MaxCycles * rules.WarriorsCount; liveWarriors = new Queue <EngineWarrior>(); int warriorIndex = starter; while (liveWarriors.Count < rules.WarriorsCount) { EngineWarrior engineWarrior = warriors[warriorIndex]; engineWarrior.StartOrder = liveWarriors.Count; engineWarrior.Result = RoundResult.Tie; liveWarriors.Enqueue(engineWarrior); //first task engineWarrior.Tasks.Clear(); engineWarrior.Tasks.Enqueue(mod(engineWarrior.LoadAddress + engineWarrior.StartOffset)); incWarrior(ref warriorIndex); } ResetCache(); }
public EngineEvent(EngineInstruction executedInstruction, int cycles, int cyclesLeft, int ip, EngineWarrior warrior, StepResult prevStepResult) { ExecutedInstruction = executedInstruction; Cycles = cycles; CyclesLeft = cyclesLeft; Ip = ip; Warrior = warrior; PrevStepResult = prevStepResult; instructionsChanged = new Stack <EngineInstruction>(); }
protected override void InitializeMatch(IProject aProject) { project = aProject; base.InitializeMatch(project); if (project.Warriors.Count != rules.WarriorsCount) { throw new EngineException("Count of warriors differ from rules"); } random = project.EngineOptions.Random; if (random == null) { random = new Random(); } forcedAddresses = project.EngineOptions.ForcedAddresses; sourceWarriors = project.Warriors; warriors = new List <EngineWarrior>(rules.WarriorsCount); runningWarriors = new List <IRunningWarrior>(rules.WarriorsCount); iWarriors = new List <IWarrior>(rules.WarriorsCount); for (int w = 0; w < rules.WarriorsCount; w++) { IWarrior sourceWarrior = sourceWarriors[w]; if (!sourceWarrior.Rules.Equals(rules)) { throw new EngineException("Warrior was compiled under different rules"); } EngineWarrior engineWarrior = new EngineWarrior(sourceWarrior, this, w); warriors.Add(engineWarrior); runningWarriors.Add(engineWarrior); iWarriors.Add(engineWarrior); } InitPSpaces(); permutate = project.EngineOptions.Permutate; if (forcedAddresses != null && forcedAddresses.Count > 0) { seed = forcedAddresses[1] - rules.MinDistance; } else { seed = random.Next(); } }
protected void NextRound() { for (int w = 0; w < rules.WarriorsCount; w++) { EngineWarrior warrior = warriors[w]; results.results[w, round] = warrior.Result; if (warrior.Result != RoundResult.Loss) { warrior.PSpace[0] = LiveWarriorsCount; } else { warrior.PSpace[0] = 0; } } FinalizeRound(); if (!Project.EngineOptions.InitRoundBefore) { InitRound(); } }
private void Load(EngineWarrior warrior) { //copy warrior to core for (int a = 0; a < warrior.Length; a++) { IInstruction instruction = warrior[a]; if (instruction.ValueA >= coreSize || instruction.ValueA < 0 || instruction.ValueB >= coreSize || instruction.ValueB < 0) { throw new RulesException("operand value out of core size"); } if (instruction.Operation == Operation.LDP || instruction.Operation == Operation.STP) { if (!rules.EnablePSpace) { throw new RulesException("Current rules don't support p-space operations"); } } int addr = mod(warrior.LoadAddress + a); core[addr] = new EngineInstruction(instruction, addr, warrior); } }
protected virtual void PerformInstruction() { EngineWarrior warrior = liveWarriors.Dequeue(); int insructionPointer = warrior.Tasks.Dequeue(); activeWarrior = warrior; InitializeCycle(insructionPointer); PerformInstruction(insructionPointer); if (warrior.LiveTasks > 0) { liveWarriors.Enqueue(warrior); } else { warrior.Result = RoundResult.Loss; cyclesLeft = cyclesLeft - 1 - (cyclesLeft - 1) / (LiveWarriorsCount + 1); } FinalizeCycle(); cyclesLeft--; cycle++; }
private void ExecuteInstruction(EngineWarrior warrior) { bool jump = false; bool die = false; int psAddress; switch (reg.IR.Operation) { #region Simple case Operation.DAT: die = true; break; case Operation.NOP: reg.ip++; break; case Operation.SPL: if (warrior.LiveTasks + 1 < rules.MaxProcesses) { warrior.Tasks.Enqueue(mod(reg.ip + 1)); reg.ip = reg.AdrA; // as second to queue Split(reg.AdrA); } else { reg.ip++; } break; case Operation.JMP: reg.ip = reg.AdrA; break; #endregion #region JMZ case Operation.JMZ: switch (reg.IR.Modifier) { case Modifier.BA: case Modifier.A: jump = (reg.AB_Value == 0); break; case Modifier.F: case Modifier.X: case Modifier.I: jump = (reg.AB_Value == 0 && reg.IR.ValueB == 0); break; case Modifier.B: case Modifier.AB: jump = (reg.IR.ValueB == 0); break; } if (jump) { reg.ip = reg.AdrA; } else { reg.ip++; } break; #endregion #region JMN case Operation.JMN: switch (reg.IR.Modifier) { case Modifier.BA: case Modifier.A: jump = !(reg.AB_Value == 0); break; case Modifier.B: case Modifier.AB: jump = !(reg.IR.ValueB == 0); break; case Modifier.F: case Modifier.X: case Modifier.I: jump = !(reg.AB_Value == 0 && reg.IR.ValueB == 0); break; } if (jump) { reg.ip = reg.AdrA; } else { reg.ip++; } break; #endregion #region DJN case Operation.DJN: switch (reg.IR.Modifier) { case Modifier.A: case Modifier.BA: jump = (reg.AB_Value != 1); dec(reg.AdrB, Column.A); break; case Modifier.B: case Modifier.AB: jump = (reg.IR.ValueB != 1); dec(reg.AdrB, Column.B); break; case Modifier.F: case Modifier.X: case Modifier.I: jump = !(reg.AB_Value == 1 && reg.IR.ValueB == 1); dec(reg.AdrB, Column.A); dec(reg.AdrB, Column.B); break; } if (jump) { reg.ip = reg.AdrA; } else { reg.ip++; } break; #endregion #region SEQ case Operation.CMP: switch (reg.IR.Modifier) { case Modifier.A: jump = (reg.AA_Value == reg.AB_Value); break; case Modifier.B: jump = (reg.IR.ValueA == reg.IR.ValueB); break; case Modifier.AB: jump = (reg.IR.ValueB == reg.AA_Value); break; case Modifier.BA: jump = (reg.AB_Value == reg.IR.ValueA); break; case Modifier.I: BeforeRead(reg.AdrA, Column.All); BeforeRead(reg.AdrB, Column.All); jump = (core[reg.AdrA].Operation == core[reg.AdrB].Operation && core[reg.AdrA].Modifier == core[reg.AdrB].Modifier && core[reg.AdrA].ModeA == core[reg.AdrB].ModeA && core[reg.AdrA].ModeB == core[reg.AdrB].ModeB && reg.AA_Value == reg.AB_Value && reg.IR.ValueA == reg.IR.ValueB); break; case Modifier.F: jump = (reg.AA_Value == reg.AB_Value && reg.IR.ValueA == reg.IR.ValueB); break; case Modifier.X: jump = (reg.IR.ValueB == reg.AA_Value && reg.AB_Value == reg.IR.ValueA); break; } if (jump) { reg.ip += 2; } else { reg.ip++; } break; #endregion #region SNE case Operation.SNE: switch (reg.IR.Modifier) { case Modifier.A: jump = (reg.AA_Value != reg.AB_Value); break; case Modifier.B: jump = (reg.IR.ValueA != reg.IR.ValueB); break; case Modifier.AB: jump = (reg.IR.ValueB != reg.AA_Value); break; case Modifier.BA: jump = (reg.AB_Value != reg.IR.ValueA); break; case Modifier.I: BeforeRead(reg.AdrA, Column.All); BeforeRead(reg.AdrB, Column.All); jump = (core[reg.AdrA].Operation != core[reg.AdrB].Operation || core[reg.AdrA].Modifier != core[reg.AdrB].Modifier || core[reg.AdrA].ModeA != core[reg.AdrB].ModeA || core[reg.AdrA].ModeB != core[reg.AdrB].ModeB || reg.AB_Value != reg.AA_Value || reg.IR.ValueA != reg.IR.ValueB); break; case Modifier.F: jump = (reg.AA_Value != reg.AB_Value || reg.IR.ValueA != reg.IR.ValueB); break; case Modifier.X: jump = (reg.IR.ValueB != reg.AA_Value || reg.AB_Value != reg.IR.ValueA); break; } if (jump) { reg.ip += 2; } else { reg.ip++; } break; #endregion #region SLT case Operation.SLT: switch (reg.IR.Modifier) { case Modifier.A: jump = (reg.AB_Value > reg.AA_Value); break; case Modifier.B: jump = (reg.IR.ValueB > reg.IR.ValueA); break; case Modifier.AB: jump = (reg.IR.ValueB > reg.AA_Value); break; case Modifier.BA: jump = (reg.AB_Value > reg.IR.ValueA); break; case Modifier.I: case Modifier.F: jump = (reg.AB_Value > reg.AA_Value && reg.IR.ValueB > reg.IR.ValueA); break; case Modifier.X: jump = (reg.IR.ValueB > reg.AA_Value && reg.AB_Value > reg.IR.ValueA); break; } if (jump) { reg.ip += 2; } else { reg.ip++; } break; #endregion #region Binary case Operation.MOD: case Operation.DIV: die = BinOperation(); reg.ip++; break; case Operation.SUB: case Operation.ADD: case Operation.MUL: BinOperation(); reg.ip++; break; #endregion #region MOV case Operation.MOV: switch (reg.IR.Modifier) { case Modifier.A: this[reg.AdrB, Column.A] = reg.AA_Value; break; case Modifier.F: this[reg.AdrB, Column.A] = reg.AA_Value; this[reg.AdrB, Column.B] = reg.IR.ValueA; break; case Modifier.B: this[reg.AdrB, Column.B] = reg.IR.ValueA; break; case Modifier.AB: this[reg.AdrB, Column.B] = reg.AA_Value; break; case Modifier.X: this[reg.AdrB, Column.B] = reg.AA_Value; this[reg.AdrB, Column.A] = reg.IR.ValueA; break; case Modifier.BA: this[reg.AdrB, Column.A] = reg.IR.ValueA; break; case Modifier.I: BeforeRead(reg.AdrA, Column.All); BeforeWrite(reg.AdrB, Column.All); core[reg.AdrB].OriginalInstruction = core[reg.AdrA].OriginalInstruction; core[reg.AdrB].OriginalOwner = core[reg.AdrA].OriginalOwner; core[reg.AdrB].Operation = core[reg.AdrA].Operation; core[reg.AdrB].Modifier = core[reg.AdrA].Modifier; core[reg.AdrB].ModeA = core[reg.AdrA].ModeA; core[reg.AdrB].ModeB = core[reg.AdrA].ModeB; core[reg.AdrB].ValueA = reg.AA_Value; core[reg.AdrB].ValueB = reg.IR.ValueA; AfterWrite(reg.AdrB, Column.All); break; } reg.ip++; break; #endregion #region LDP case Operation.LDP: switch (reg.IR.Modifier) { case Modifier.A: psAddress = Instruction.Mod(reg.AA_Value, rules.PSpaceSize); this[reg.AdrB, Column.A] = warrior.GetPSpaceValue(psAddress); break; case Modifier.F: case Modifier.B: case Modifier.X: case Modifier.I: psAddress = Instruction.Mod(reg.IR.ValueA, rules.PSpaceSize); this[reg.AdrB, Column.B] = warrior.GetPSpaceValue(psAddress); break; case Modifier.AB: psAddress = Instruction.Mod(reg.AA_Value, rules.PSpaceSize); this[reg.AdrB, Column.B] = warrior.GetPSpaceValue(psAddress); break; case Modifier.BA: psAddress = Instruction.Mod(reg.IR.ValueA, rules.PSpaceSize); this[reg.AdrB, Column.A] = warrior.GetPSpaceValue(psAddress); break; } reg.ip++; break; #endregion #region STP case Operation.STP: switch (reg.IR.Modifier) { case Modifier.A: psAddress = Instruction.Mod(reg.AB_Value, rules.PSpaceSize); BeforeWritePSpace(psAddress); warrior.SetPSpaceValue(psAddress, reg.AA_Value); break; case Modifier.F: case Modifier.B: case Modifier.X: case Modifier.I: psAddress = Instruction.Mod(reg.IR.ValueB, rules.PSpaceSize); BeforeWritePSpace(psAddress); warrior.SetPSpaceValue(psAddress, reg.IR.ValueA); break; case Modifier.AB: psAddress = Instruction.Mod(reg.IR.ValueB, rules.PSpaceSize); BeforeWritePSpace(psAddress); warrior.SetPSpaceValue(psAddress, reg.AA_Value); break; case Modifier.BA: psAddress = Instruction.Mod(reg.AB_Value, rules.PSpaceSize); BeforeWritePSpace(psAddress); warrior.SetPSpaceValue(psAddress, reg.IR.ValueA); break; } reg.ip++; break; #endregion default: throw new InvalidOperationException("Unknown instruction"); } if (!die) { warrior.Tasks.Enqueue(mod(reg.ip)); } else { warrior.DeadTasksCount++; Died(reg.ip); } }