예제 #1
0
        public Individual[] Operate(Individual[] parents)
        {
            Individual[] offspring = new Individual[parents.Length];

            Parallel.For(0, parents.Length, i =>
            {
                MapBlueprintIndividual p = (MapBlueprintIndividual)parents[i];
                MapBlueprintIndividual o = (MapBlueprintIndividual)p.Clone();

                if (Rnd.NextDouble() < MutationProbability && o.Rooms.Count > 0)
                {
                    byte removeAt = o.RoomsOrdered.ElementAt(GetRandomNumber(0, o.RoomsOrdered.Count, 4));

                    foreach (Coords coords in o.Rooms[removeAt])
                    {
                        o.Gene.Encoding[coords.X, coords.Y][0] = 0;
                    }

                    o.RoomsOrdered.Remove(removeAt);
                    o.Rooms.Remove(removeAt);
                }

                offspring[i] = o;
            });

            return(offspring);
        }
예제 #2
0
        bool EdgeTerminator(int x, int y, int startX, int startY, Direction dir, MapBlueprintIndividual o)
        {
            if (!o.Gene.IsOnMap(x, y))
            {
                return(false);
            }

            switch (dir)
            {
            case Direction.Up:
                return(o.Gene.Encoding[x, y][0] == 0 &&
                       o.Gene.Encoding[x, y + 1][0] == o.Gene.Encoding[startX, startY][0]);

            case Direction.Right:
                return(o.Gene.Encoding[x, y][0] == 0 &&
                       o.Gene.Encoding[x - 1, y][0] == o.Gene.Encoding[startX, startY][0]);

            case Direction.Down:
                return(o.Gene.Encoding[x, y][0] == 0 &&
                       o.Gene.Encoding[x, y - 1][0] == o.Gene.Encoding[startX, startY][0]);

            case Direction.Left:
                return(o.Gene.Encoding[x, y][0] == 0 &&
                       o.Gene.Encoding[x + 1, y][0] == o.Gene.Encoding[startX, startY][0]);

            default:
                // we've considered every possible direction, so this will never happen
                throw new InvalidOperationException();
            }
        }
예제 #3
0
        public double Evaluate(Individual ind)
        {
            MapBlueprintIndividual map = (MapBlueprintIndividual)ind;
            double fitness             = 0;

            foreach (HashSet <Coords> room in map.Rooms.Values)
            {
                int maxdist = int.MinValue;

                foreach (Coords coordsA in room)
                {
                    foreach (Coords coordsB in room)
                    {
                        if (coordsA.Equals(coordsB))
                        {
                            continue;
                        }

                        int dist = distance(coordsA.X, coordsA.Y, coordsB.X, coordsB.Y);

                        if (dist > maxdist)
                        {
                            maxdist = dist;
                        }
                    }
                }

                fitness += room.Count / (double)maxdist;
            }

            return(fitness / map.Rooms.Count);
        }
예제 #4
0
 bool IsHole(int x, int y, MapBlueprintIndividual o)
 {
     return(o.Gene.Encoding[x, y][0] == 0 &&
            (!o.Gene.IsOnMap(x + 1, y) || o.Gene.Encoding[x + 1, y][0] > 0) &&
            (!o.Gene.IsOnMap(x - 1, y) || o.Gene.Encoding[x - 1, y][0] > 0) &&
            (!o.Gene.IsOnMap(x, y + 1) || o.Gene.Encoding[x, y + 1][0] > 0) &&
            (!o.Gene.IsOnMap(x, y - 1) || o.Gene.Encoding[x, y - 1][0] > 0));
 }
예제 #5
0
 void CheckAdjacency(int x, int y, Coords tile, MapBlueprintIndividual map, HashSet <byte> neighbors)
 {
     if (map.Gene.IsOnMap(x, y) &&
         map.Gene.Encoding[x, y][0] > 0 &&
         map.Gene.Encoding[x, y][0] != map.Gene.Encoding[tile.X, tile.Y][0] &&
         !neighbors.Contains(map.Gene.Encoding[x, y][0]))
     {
         neighbors.Add(map.Gene.Encoding[x, y][0]);
     }
 }
예제 #6
0
        public double Evaluate(Individual ind)
        {
            MapBlueprintIndividual map = (MapBlueprintIndividual)ind;
            double fitness             = 0;

            foreach (HashSet <Coords> room in map.Rooms.Values)
            {
                fitness += room.Count;
            }

            return(fitness);
        }
예제 #7
0
        public Individual[] Operate(Individual[] parents)
        {
            Individual[] offspring = new Individual[parents.Length];

            Parallel.For(0, parents.Length, i =>
            {
                MapBlueprintIndividual p = (MapBlueprintIndividual)parents[i];
                MapBlueprintIndividual o = (MapBlueprintIndividual)p.Clone();

                if (Rnd.NextDouble() < MutationProbability && o.Rooms.Count > 0)
                {
                    int x         = Rnd.Next(0, o.Width);
                    int y         = Rnd.Next(0, o.Height);
                    Array values  = Enum.GetValues(typeof(Direction));
                    Direction dir = (Direction)values.GetValue(Rnd.Next(values.Length));

                    do
                    {
                        if (!IsHole(x, y, o))
                        {
                            switch (dir)
                            {
                            case Direction.Up: y--; break;

                            case Direction.Right: x++; break;

                            case Direction.Down: y++; break;

                            case Direction.Left: x--; break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }while (o.Gene.IsOnMap(x, y));

                    if (o.Gene.IsOnMap(x, y))
                    {
                        byte foam = GetFoam(x, y, o);

                        o.Gene.Encoding[x, y][0] = foam;
                        o.AddTileToRoom(foam, new Coords(x, y));
                    }
                }

                offspring[i] = o;
            });

            return(offspring);
        }
예제 #8
0
        static Dictionary <byte, GraphNode> ExtractRoomAdjacencyGraph(byte start, MapBlueprintIndividual map)
        {
            // bfs
            Queue <byte>   open   = new Queue <byte>();
            HashSet <byte> closed = new HashSet <byte>();

            Dictionary <byte, GraphNode> adjacencyGraph = new Dictionary <byte, GraphNode>();

            adjacencyGraph.Add(start, new GraphNode(start));
            open.Enqueue(start);

            while (open.Count > 0)
            {
                byte next = open.Dequeue();
                IEnumerable <byte> connections = FindNeighboringRooms(map.Gene, map.Rooms[next].First());

                foreach (byte neighbor in connections)
                {
                    if (closed.Contains(neighbor))
                    {
                        continue;
                    }

                    if (open.Contains(neighbor))
                    {
                        adjacencyGraph[neighbor].Neighbors.Add(adjacencyGraph[next]);
                        adjacencyGraph[next].Neighbors.Add(adjacencyGraph[neighbor]);
                    }
                    else
                    {
                        GraphNode newNode = new GraphNode(neighbor);
                        newNode.Neighbors.Add(adjacencyGraph[next]);
                        adjacencyGraph[next].Neighbors.Add(newNode);
                        adjacencyGraph.Add(neighbor, newNode);

                        open.Enqueue(neighbor);
                    }
                }

                closed.Add(next);
            }

            return(adjacencyGraph);
        }
예제 #9
0
        static void Phase2()
        {
            EvolutionaryAlgorithm  eva   = new EvolutionaryAlgorithm();
            MapBlueprintIndividual input = (MapBlueprintIndividual)Individual.FromFile(@"C:\Users\Jan\Source\Repos\RoguelikeEva\Results\door test\_RESULT 9.bin");
            var graph = ExtractRoomAdjacencyGraph(input.Rooms.First().Key, input);

            eva.Operators.Add(new ExtendBranchMutation(1));

            /*eva.Operators.Add(new CompressBranchMutation(1));
             * eva.Operators.Add(new ReplaceBranchMutation(1));
             * eva.Operators.Add(new ReverseBranchMutation(1));
             * eva.Operators.Add(new ShiftStartingRoomMutation(1));*/

            eva.MultiObjective.Add(new BranchRatioFitness(3.0 / 2));
            eva.MultiObjective.Add(new BranchEntryPointsFitness());

            eva.SampleIndividual = new AdjacencyGraphIndividual(new List <byte>(input.Rooms.Keys), 3, 3);
            eva.HvIndicator      = new BiobjectiveHvIndicator();

            using (StreamWriter file = new StreamWriter(@"C:\Users\Jan\Source\Repos\RoguelikeEva\Results\_out.txt"))
            {
                file.WriteLine("Gen\tHv");
                int solutionNo = 0;

                IEnumerable <Individual> result = eva.Run(e => e.Population.No == 10, 100, file, (writer, gen, hv) =>
                {
                    writer.WriteLine("{0}\t{1}", gen.No, hv);

                    Console.Clear();
                    Console.WriteLine("Current generation: " + gen.No);
                });

                foreach (Individual ind in result)
                {
                    AdjacencyGraphIndividual map = (AdjacencyGraphIndividual)ind;

                    // TODO:
                    // transform "map" to correct MapBlueprint

                    // "correct MapBlueprint".SaveImageToFile(@"C:\Users\Jan\Source\Repos\RoguelikeEva\Results\_RESULT " + solutionNo + ".png", 1536, 1024);
                    map.SaveToFile(@"C:\Users\Jan\Source\Repos\RoguelikeEva\Results\_RESULT " + (solutionNo++) + ".bin");
                }
            }
        }
예제 #10
0
        static void Phase1()
        {
            EvolutionaryAlgorithm eva = new EvolutionaryAlgorithm();

            eva.Operators.Add(new FloorTypeMutation(0.5));
            eva.Operators.Add(new JoinRoomsMutation(0.8));
            eva.Operators.Add(new RemoveRoomMutation(0.8));
            eva.Operators.Add(new FillHoleMutation(1));
            eva.Operators.Add(new ExtendEdgeMutation(1));

            eva.MultiObjective.Add(new AdjacencyFitness());
            eva.MultiObjective.Add(new RoomFitness(20));
            eva.MultiObjective.Add(new SpaceFitness());

            eva.SampleIndividual = new MapBlueprintIndividual(30, 20, 0.5);
            eva.HvIndicator      = new HvSweep3D();
            //eva.MatingSelector = new RouletteWheelSelector();

            using (StreamWriter file = new StreamWriter(@"C:\Users\Jan\Source\Repos\RoguelikeEva\Results\_out.txt"))
            {
                file.WriteLine("Gen\tHv");
                int solutionNo = 0;

                IEnumerable <Individual> result = eva.Run(e => e.Population.No == 10, 100, file, (writer, gen, hv) =>
                {
                    writer.WriteLine("{0}\t{1}", gen.No, hv);

                    Console.Clear();
                    Console.WriteLine("Current generation: " + gen.No);
                });

                foreach (Individual ind in result)
                {
                    MapBlueprintIndividual map = (MapBlueprintIndividual)ind;

                    AddDoors(map.Gene);
                    // TODO: skip map which are not correct (discontinuous)

                    map.Gene.SaveImageToFile(@"C:\Users\Jan\Source\Repos\RoguelikeEva\Results\_RESULT " + solutionNo + ".png", 1536, 1024);
                    map.SaveToFile(@"C:\Users\Jan\Source\Repos\RoguelikeEva\Results\_RESULT " + (solutionNo++) + ".bin");
                }
            }
        }
예제 #11
0
        public double Evaluate(Individual ind)
        {
            MapBlueprintIndividual map = (MapBlueprintIndividual)ind;
            double fitness             = 0;

            foreach (HashSet <Coords> room in map.Rooms.Values)
            {
                HashSet <byte> neighbors = new HashSet <byte>();

                foreach (Coords tile in room)
                {
                    CheckAdjacency(tile.X - 1, tile.Y, tile, map, neighbors);
                    CheckAdjacency(tile.X + 1, tile.Y, tile, map, neighbors);
                    CheckAdjacency(tile.X, tile.Y - 1, tile, map, neighbors);
                    CheckAdjacency(tile.X, tile.Y + 1, tile, map, neighbors);
                }

                fitness += neighbors.Count;
            }

            return(fitness / map.Rooms.Count);
        }
예제 #12
0
        byte GetFoam(int x, int y, MapBlueprintIndividual o)
        {
            byte foam = 0;

            if (o.Gene.IsOnMap(x + 1, y))
            {
                foam = o.Gene.Encoding[x + 1, y][0];
            }
            else if (o.Gene.IsOnMap(x - 1, y))
            {
                foam = o.Gene.Encoding[x - 1, y][0];
            }
            else if (o.Gene.IsOnMap(x, y + 1))
            {
                foam = o.Gene.Encoding[x, y + 1][0];
            }
            else if (o.Gene.IsOnMap(x, y - 1))
            {
                foam = o.Gene.Encoding[x, y - 1][0];
            }

            return(foam);
        }
예제 #13
0
        public Individual[] Operate(Individual[] parents)
        {
            Individual[] offspring = new Individual[parents.Length];

            Parallel.For(0, parents.Length, i =>
            {
                MapBlueprintIndividual p = (MapBlueprintIndividual)parents[i];
                MapBlueprintIndividual o = (MapBlueprintIndividual)p.Clone();

                if (Rnd.NextDouble() < MutationProbability)
                {
                    int x = Rnd.Next(0, o.Width);
                    int y = Rnd.Next(0, o.Height);

                    if (o.Gene.Encoding[x, y][0] > 0)
                    {
                        if (!o.Rooms[o.Gene.Encoding[x, y][0]].Contains(new Coords(x, y)))
                        {
                            int sgf = 5;
                        }

                        //bool rem = o.Rooms[o.Gene.Encoding[x, y][0]].Remove(new Coords(x, y));
                        o.RemoveTileFromRoom(o.Gene.Encoding[x, y][0], new Coords(x, y));

                        /*if (rem == false)
                         * {
                         *  int dkfjdf = 2;
                         * }*/

                        // did we get empty room? -> o.Rooms.Remove(o.Gene.Encoding[x, y][0]);
                        if (o.Rooms[o.Gene.Encoding[x, y][0]].Count == 0)
                        {
                            o.RoomsOrdered.Remove(o.Gene.Encoding[x, y][0]);
                            o.Rooms.Remove(o.Gene.Encoding[x, y][0]);
                        }

                        o.Gene.Encoding[x, y][0] = 0;
                        // FIXME: maybe I caused a room to be split !
                    }
                    else
                    {
                        if (o.Gene.IsOnMap(x - 1, y) && o.Gene.Encoding[x - 1, y][0] > 0)
                        {
                            o.Gene.Encoding[x, y][0] = o.Gene.Encoding[x - 1, y][0];
                            o.AddTileToRoom(o.Gene.Encoding[x, y][0], new Coords(x, y));
                            //o.Rooms[o.Gene.Encoding[x - 1, y][0]].Add(new Coords(x, y));
                        }

                        else if (o.Gene.IsOnMap(x + 1, y) && o.Gene.Encoding[x + 1, y][0] > 0)
                        {
                            o.Gene.Encoding[x, y][0] = o.Gene.Encoding[x + 1, y][0];
                            o.AddTileToRoom(o.Gene.Encoding[x, y][0], new Coords(x, y));
                        }

                        else if (o.Gene.IsOnMap(x, y - 1) && o.Gene.Encoding[x, y - 1][0] > 0)
                        {
                            o.Gene.Encoding[x, y][0] = o.Gene.Encoding[x, y - 1][0];
                            o.AddTileToRoom(o.Gene.Encoding[x, y][0], new Coords(x, y));
                        }

                        else if (o.Gene.IsOnMap(x, y + 1) && o.Gene.Encoding[x, y + 1][0] > 0)
                        {
                            o.Gene.Encoding[x, y][0] = o.Gene.Encoding[x, y + 1][0];
                            o.AddTileToRoom(o.Gene.Encoding[x, y][0], new Coords(x, y));
                        }

                        else
                        {
                            // FIXME: nepouziva o.AddTileToRoom(o.Gene.Encoding[x, y][0], new Coords(x, y));

                            /*byte newRoomId = 0;
                             *
                             * do
                             *  // FIXME: potential infinite loop!
                             *  newRoomId = (byte)Rnd.Next(0, byte.MaxValue);
                             * while (o.Rooms.ContainsKey(newRoomId));
                             *
                             * o.Rooms.Add(newRoomId, new HashSet<int[]>());
                             * o.Rooms[newRoomId].Add(new int[2] { x, y });*/
                        }
                    }
                }

                offspring[i] = o;
            });

            return(offspring);
        }
예제 #14
0
        public double Evaluate(Individual ind)
        {
            MapBlueprintIndividual map = (MapBlueprintIndividual)ind;

            return(100 - Math.Abs(Max - map.Rooms.Count));
        }
예제 #15
0
        public Individual[] Operate(Individual[] parents)
        {
            Individual[] offspring = new Individual[parents.Length];

            Parallel.For(0, parents.Length, i =>
            {
                MapBlueprintIndividual p = (MapBlueprintIndividual)parents[i];
                MapBlueprintIndividual o = (MapBlueprintIndividual)p.Clone();

                if (Rnd.NextDouble() < MutationProbability && o.Rooms.Count > 0)
                {
                    byte key      = o.RoomsOrdered.ElementAt(GetRandomNumber(0, o.RoomsOrdered.Count, 2));
                    Coords start  = o.Rooms[key].ElementAt(Rnd.Next(0, o.Rooms[key].Count));
                    Array values  = Enum.GetValues(typeof(Direction));
                    Direction dir = (Direction)values.GetValue(Rnd.Next(values.Length));

                    int x = start.X;
                    int y = start.Y;

                    do
                    {
                        switch (dir)
                        {
                        case Direction.Up: y--; break;

                        case Direction.Right: x++; break;

                        case Direction.Down: y++; break;

                        case Direction.Left: x--; break;
                        }
                    }while (o.Gene.IsOnMap(x, y) && o.Gene.Encoding[x, y][0] == o.Gene.Encoding[start.X, start.Y][0]);

                    if (o.Gene.IsOnMap(x, y) && o.Gene.Encoding[x, y][0] == 0)
                    {
                        List <Coords> edge = new List <Coords>();

                        if (dir == Direction.Up || dir == Direction.Down)
                        {
                            for (int ix = x; EdgeTerminator(ix, y, start.X, start.Y, dir, o); ix++)
                            {
                                edge.Add(new Coords(ix, y));
                            }

                            for (int ix = x - 1; EdgeTerminator(ix, y, start.X, start.Y, dir, o); ix--)
                            {
                                edge.Add(new Coords(ix, y));
                            }
                        }

                        else
                        {
                            for (int iy = y; EdgeTerminator(x, iy, start.X, start.Y, dir, o); iy++)
                            {
                                edge.Add(new Coords(x, iy));
                            }

                            for (int iy = y - 1; EdgeTerminator(x, iy, start.X, start.Y, dir, o); iy--)
                            {
                                edge.Add(new Coords(x, iy));
                            }
                        }

                        o.RoomsOrdered.Remove(key);

                        foreach (Coords coords in edge)
                        {
                            if (o.Gene.Encoding[coords.X, coords.Y][0] > 0)
                            {
                                int fdgf = 5;
                            }

                            o.Gene.Encoding[coords.X, coords.Y][0] = o.Gene.Encoding[start.X, start.Y][0];
                            o.Rooms[key].Add(coords);
                        }

                        o.RoomsOrdered.Add(key);
                    }
                }

                offspring[i] = o;
            });

            return(offspring);
        }
예제 #16
0
        public Individual[] Operate(Individual[] parents)
        {
            Individual[] offspring = new Individual[parents.Length];

            Parallel.For(0, parents.Length, i =>
            {
                MapBlueprintIndividual p = (MapBlueprintIndividual)parents[i];
                MapBlueprintIndividual o = (MapBlueprintIndividual)p.Clone();

                if (Rnd.NextDouble() < MutationProbability && o.Rooms.Count > 1)
                {
                    /*Dictionary<byte, int> histogram = new Dictionary<byte, int>();
                     *
                     * for (int k = 0; k < 1000000; k++)
                     * {
                     *  byte n = o.RoomsOrdered.ElementAt(GetRandomNumber(0, o.RoomsOrdered.Count, 4));
                     *
                     *  if (histogram.ContainsKey(n))
                     *      histogram[n]++;
                     *  else
                     *      histogram.Add(n, 1);
                     * }
                     *
                     * foreach (byte k in histogram.Keys)
                     * {
                     *  Console.WriteLine(k + ": " + histogram[k] + ", tiles: " + o.Rooms[k].Count);
                     * }
                     *
                     * throw new Exception();*/

                    int rooms   = o.Rooms.Count;
                    int ordered = o.RoomsOrdered.Count;

                    if (rooms != ordered)
                    {
                        int sgsg = 5;
                    }

                    byte key      = o.RoomsOrdered.ElementAt(GetRandomNumber(0, o.RoomsOrdered.Count, 2));
                    Coords start  = o.Rooms[key].ElementAt(Rnd.Next(0, o.Rooms[key].Count));
                    Array values  = Enum.GetValues(typeof(Direction));
                    Direction dir = (Direction)values.GetValue(Rnd.Next(values.Length));

                    int x = start.X;
                    int y = start.Y;

                    if (o.Gene.Encoding[start.X, start.Y][0] != key)
                    {
                        int fdfdfd = 0;
                    }

                    do
                    {
                        switch (dir)
                        {
                        case Direction.Up: y--; break;

                        case Direction.Right: x++; break;

                        case Direction.Down: y++; break;

                        case Direction.Left: x--; break;
                        }
                    }while (o.Gene.IsOnMap(x, y) && o.Gene.Encoding[x, y][0] == o.Gene.Encoding[start.X, start.Y][0]);

                    if (o.Gene.IsOnMap(x, y) && o.Gene.Encoding[x, y][0] > 0)
                    {
                        byte removeAt = o.Gene.Encoding[x, y][0];
                        o.RoomsOrdered.Remove(removeAt);
                        o.RoomsOrdered.Remove(key);

                        foreach (Coords coords in o.Rooms[removeAt])
                        {
                            o.Gene.Encoding[coords.X, coords.Y][0] = o.Gene.Encoding[start.X, start.Y][0];
                            o.Rooms[key].Add(coords);
                        }

                        o.RoomsOrdered.Add(key);
                        o.Rooms.Remove(removeAt);
                    }
                }

                offspring[i] = o;
            });

            return(offspring);
        }