Exemple #1
0
        public static void GeneratePrograms(
            bool useRed, bool useGreen, bool useBlue, IList <int> funcSlotCount, Predicate <Program> shouldStopPredicate)
        {
            Debug.Assert(funcSlotCount.Count <= 5 && !funcSlotCount.Contains(0));

            List <FieldColor> availableColors = new List <FieldColor> {
                FieldColor.None
            };

            if (useRed)
            {
                availableColors.Add(FieldColor.Red);
            }
            if (useGreen)
            {
                availableColors.Add(FieldColor.Green);
            }
            if (useBlue)
            {
                availableColors.Add(FieldColor.Blue);
            }

            List <ProgramAction> availableActions =
                new List <ProgramAction> {
                ProgramAction.Forward, ProgramAction.Left, ProgramAction.Right
            };

            if (funcSlotCount.Count > 0)
            {
                availableActions.Add(ProgramAction.F1);
            }
            if (funcSlotCount.Count > 1)
            {
                availableActions.Add(ProgramAction.F2);
            }
            if (funcSlotCount.Count > 2)
            {
                availableActions.Add(ProgramAction.F3);
            }
            if (funcSlotCount.Count > 3)
            {
                availableActions.Add(ProgramAction.F4);
            }
            if (funcSlotCount.Count > 4)
            {
                availableActions.Add(ProgramAction.F5);
            }

            ProgramSlot[][] generatedCode = new ProgramSlot[funcSlotCount.Count][];
            for (int i = 0; i < funcSlotCount.Count; ++i)
            {
                generatedCode[i] = new ProgramSlot[funcSlotCount[i]];
            }

            GenerateProgramsDfs(availableColors, availableActions, 0, generatedCode, shouldStopPredicate);
        }
        public Program ChromosomeToProgram(ProgramChromosome chromosome)
        {
            ProgramSlot[][] programCode = new ProgramSlot[this.funcSlotCount.Count][];
            int index = 0;
            for (int i = 0; i < this.funcSlotCount.Count; ++i)
            {
                programCode[i] = new ProgramSlot[this.funcSlotCount[i]];
                for (int j = 0; j < this.funcSlotCount[i]; ++j)
                    programCode[i][j] = chromosome.GetSlot(index++);
            }

            return new Program(programCode);
        }
Exemple #3
0
        public override void Crossover(IChromosome pair)
        {
            ProgramChromosome pairCasted = (ProgramChromosome)pair;

            int randomPos1 = random.Next(this.slotCount);
            int randomPos2 = random.Next(this.slotCount);

            for (int i = Math.Min(randomPos1, randomPos2); i <= Math.Max(randomPos1, randomPos2); ++i)
            {
                ProgramSlot temp = pairCasted.program[i];
                pairCasted.program[i] = this.program[i];
                this.program[i]       = temp;
            }
        }
Exemple #4
0
        public Program ChromosomeToProgram(ProgramChromosome chromosome)
        {
            ProgramSlot[][] programCode = new ProgramSlot[this.funcSlotCount.Count][];
            int             index       = 0;

            for (int i = 0; i < this.funcSlotCount.Count; ++i)
            {
                programCode[i] = new ProgramSlot[this.funcSlotCount[i]];
                for (int j = 0; j < this.funcSlotCount[i]; ++j)
                {
                    programCode[i][j] = chromosome.GetSlot(index++);
                }
            }

            return(new Program(programCode));
        }
Exemple #5
0
        public static void GeneratePrograms(
            bool useRed, bool useGreen, bool useBlue, IList<int> funcSlotCount, Predicate<Program> shouldStopPredicate)
        {
            Debug.Assert(funcSlotCount.Count <= 5 && !funcSlotCount.Contains(0));

            List<FieldColor> availableColors = new List<FieldColor> { FieldColor.None };
            if (useRed) availableColors.Add(FieldColor.Red);
            if (useGreen) availableColors.Add(FieldColor.Green);
            if (useBlue) availableColors.Add(FieldColor.Blue);

            List<ProgramAction> availableActions =
                new List<ProgramAction> { ProgramAction.Forward, ProgramAction.Left, ProgramAction.Right };
            if (funcSlotCount.Count > 0) availableActions.Add(ProgramAction.F1);
            if (funcSlotCount.Count > 1) availableActions.Add(ProgramAction.F2);
            if (funcSlotCount.Count > 2) availableActions.Add(ProgramAction.F3);
            if (funcSlotCount.Count > 3) availableActions.Add(ProgramAction.F4);
            if (funcSlotCount.Count > 4) availableActions.Add(ProgramAction.F5);

            ProgramSlot[][] generatedCode = new ProgramSlot[funcSlotCount.Count][];
            for (int i = 0; i < funcSlotCount.Count; ++i)
                generatedCode[i] = new ProgramSlot[funcSlotCount[i]];

            GenerateProgramsDfs(availableColors, availableActions, 0, generatedCode, shouldStopPredicate);
        }
Exemple #6
0
        private ProgramExecutionResult CanBeSolvedWithDfs(
            HashSet <ProgramState> stateSet, bool[,] eatenStarsMask, ref ProgramState state, ref int starsEaten, Program program)
        {
            Debug.Assert(state.Instruction == 0);

            for (int instr = 0; instr < program.GetInstructionCountInFunc(state.Func); ++instr)
            {
                state.Instruction = instr;

                // Loop check
                if (stateSet.Contains(state))
                {
                    return(ProgramExecutionResult.Fail);
                }

                FieldColor  currentColor = this.colors[state.Position.X, state.Position.Y];
                ProgramSlot slot         = program.GetProgramSlot(state.Func, state.Instruction);
                if (slot.Action == ProgramAction.None)
                {
                    continue;
                }
                if (slot.Color != FieldColor.None && slot.Color != currentColor)
                {
                    continue;
                }

                if (slot.Action == ProgramAction.Forward || slot.Action == ProgramAction.Left || slot.Action == ProgramAction.Right)
                {
                    switch (slot.Action)
                    {
                    case ProgramAction.Left:
                        state.Dir = (state.Dir - 1 + 4) % 4;
                        break;

                    case ProgramAction.Right:
                        state.Dir = (state.Dir + 1) % 4;
                        break;

                    case ProgramAction.Forward:
                        Coord newPosition = state.Position;
                        newPosition.X += shiftX[state.Dir];
                        newPosition.Y += shiftY[state.Dir];
                        state.Position = newPosition;

                        if (state.Position.X < 0 || state.Position.Y < 0 ||
                            state.Position.X >= this.width || state.Position.Y >= this.height)
                        {
                            return(ProgramExecutionResult.Fail);
                        }
                        if (colors[state.Position.X, state.Position.Y] == FieldColor.None)
                        {
                            return(ProgramExecutionResult.Fail);
                        }

                        // If star was eaten after this turn
                        if (this.stars[state.Position.X, state.Position.Y] && !eatenStarsMask[state.Position.X, state.Position.Y])
                        {
                            eatenStarsMask[state.Position.X, state.Position.Y] = true;
                            starsEaten += 1;
                            if (starsEaten == this.starsCount)
                            {
                                return(ProgramExecutionResult.StarsEaten);
                            }
                        }

                        break;
                    }
                }
                else if (slot.Action == ProgramAction.F1 || slot.Action == ProgramAction.F2 ||
                         slot.Action == ProgramAction.F3 || slot.Action == ProgramAction.F4 ||
                         slot.Action == ProgramAction.F5)
                {
                    ProgramState stateToPass = state;
                    stateToPass.Instruction = 0;

                    switch (slot.Action)
                    {
                    case ProgramAction.F1:
                        stateToPass.Func = 0;
                        break;

                    case ProgramAction.F2:
                        stateToPass.Func = 1;
                        break;

                    case ProgramAction.F3:
                        stateToPass.Func = 2;
                        break;

                    case ProgramAction.F4:
                        stateToPass.Func = 3;
                        break;

                    case ProgramAction.F5:
                        stateToPass.Func = 4;
                        break;
                    }

                    stateSet.Add(state);
                    ProgramExecutionResult result = CanBeSolvedWithDfs(stateSet, eatenStarsMask, ref stateToPass, ref starsEaten, program);
                    stateSet.Remove(state);

                    state.Position = stateToPass.Position;
                    state.Dir      = stateToPass.Dir;
                    if (result != ProgramExecutionResult.StillWorking)
                    {
                        return(result);
                    }
                }
            }

            return(ProgramExecutionResult.StillWorking);
        }
Exemple #7
0
        private static bool CheckIfCompleteCodeIsGood(ProgramSlot[][] programCode)
        {
            // Check if program contains any forward instructions
            bool forwardInstructionFound = false;
            foreach (ProgramSlot[] funcCode in programCode)
                foreach (ProgramSlot programSlot in funcCode)
                {
                    if (programSlot.Action == ProgramAction.Forward)
                    {
                        forwardInstructionFound = true;
                        break;
                    }
                }

            // Program with no forward instructions is bad
            if (!forwardInstructionFound)
                return false;

            return true;
        }
Exemple #8
0
        private static bool SkipDueToOptimizations(ProgramSlot[] code, int funcIndex, int depth, ProgramAction action, FieldColor color)
        {
            // Rotation code optimization
            if ((action == ProgramAction.Left || action == ProgramAction.Right) && depth > 0)
            {
                // Do not use consequent opposite rotations with the same color
                if (code[depth - 1].Color == color &&
                    ((code[depth - 1].Action == ProgramAction.Left && action == ProgramAction.Right) ||
                     (code[depth - 1].Action == ProgramAction.Right && action == ProgramAction.Left)))
                {
                    return true;
                }

                // Consequent rotation count optimization
                int i = depth - 1;
                int sameCount = 1;
                while (i >= 0 && code[i].Color == color && code[i].Action == action)
                {
                    sameCount += 1;
                    i -= 1;
                }

                // Max 2 rotations right and 1 rotation left
                if ((sameCount > 2 && action == ProgramAction.Right) || (sameCount > 1 && action == ProgramAction.Left))
                    return true;
            }

            // Recursion optimization - do not call function from itself in the first instruction
            if (depth == 0 && funcIndex == 0 && action == ProgramAction.F1 ||
                depth == 0 && funcIndex == 1 && action == ProgramAction.F2 ||
                depth == 0 && funcIndex == 2 && action == ProgramAction.F3 ||
                depth == 0 && funcIndex == 3 && action == ProgramAction.F4 ||
                depth == 0 && funcIndex == 4 && action == ProgramAction.F5)
            {
                return true;
            }

            return false;
        }
Exemple #9
0
 public Program(ProgramSlot[][] programCode)
 {
     this.programCode = new ProgramSlot[programCode.Length][];
     for (int i = 0; i < programCode.Length; ++i)
         this.programCode[i] = (ProgramSlot[])programCode[i].Clone();
 }
Exemple #10
0
        private static bool GenerateProgramsDfs(
            IEnumerable<FieldColor> colors,
            IEnumerable<ProgramAction> actions,
            int func,
            ProgramSlot[][] generatedCode,
            Predicate<Program> shouldStopPredicate)
        {
            if (func >= generatedCode.Length)
            {
                if (!CheckIfCompleteCodeIsGood(generatedCode))
                    return false;

                return shouldStopPredicate(new Program(generatedCode));
            }

            Predicate<ProgramSlot[]> funcCodePredicate = (
                code =>
                {
                    generatedCode[func] = (ProgramSlot[])code.Clone();
                    return GenerateProgramsDfs(colors, actions, func + 1, generatedCode, shouldStopPredicate);
                });

            return GenerateFuncCodeDfs(func, colors, actions, 0, new ProgramSlot[generatedCode[func].Length], funcCodePredicate);
        }
Exemple #11
0
        private static bool GenerateFuncCodeDfs(
            int funcIndex,
            IEnumerable<FieldColor> colors,
            IEnumerable<ProgramAction> actions,
            int depth,
            ProgramSlot[] funcCode,
            Predicate<ProgramSlot[]> funcCodePredicate)
        {
            foreach (ProgramAction action in actions)
                foreach (FieldColor color in colors)
                {
                    if (SkipDueToOptimizations(funcCode, funcIndex, depth, action, color))
                        continue;

                    funcCode[depth].Action = action;
                    funcCode[depth].Color = color;

                    if (funcCodePredicate(funcCode))
                        return true;

                    if (action != ProgramAction.None && depth < funcCode.Length - 1)
                    {
                        if (GenerateFuncCodeDfs(funcIndex, colors, actions, depth + 1, funcCode, funcCodePredicate))
                            return true;
                    }

                    funcCode[depth].Action = ProgramAction.None;
                    funcCode[depth].Color = FieldColor.None;
                }

            return false;
        }