Beispiel #1
0
        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>();
 }
Beispiel #3
0
        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();
     }
 }
Beispiel #5
0
 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);
            }
        }