Exemple #1
0
 public IMemberContainer CopyGenotype() {
     List<TileNode> newGraph = new List<TileNode>();
     Dictionary<TileNode, TileNode> oldToNewMapping = new Dictionary<TileNode, TileNode>();
     foreach (TileNode o in graph.nodes) {
         TileNode n = TileNode.Copy(o);
         oldToNewMapping.Add(o, n);
         newGraph.Add(n);
     }
     foreach (TileNode o in graph.nodes) {
         foreach (TileNode c in o.connectedNodes) {
             oldToNewMapping[o].AddConnectedNode(oldToNewMapping[c]);
         }
     }
     MemberTilePCG ret = new MemberTilePCG();
     ret.graph = new TileGraph(newGraph);
     return ret;
 }
Exemple #2
0
 private static void ConnectCandidates(MemberTilePCG firstParent, List<TileNode> firstCandidates, MemberTilePCG secondParent, List<TileNode> secondCandidates, Dictionary<TileNode, TileNode> oldToNewMapping) {
     foreach (TileNode fc in firstCandidates) {
         float minDistance = -1;
         TileNode candidate = null;
         foreach (TileNode sc in secondCandidates) {
             if (oldToNewMapping[sc].connectedNodes.Count < oldToNewMapping[sc].type.doorLocs.Length) {
                 float dist = (secondParent.renderedTiles[sc].location - firstParent.renderedTiles[fc].location).magnitude;
                 if (minDistance == -1 || dist < minDistance) {
                     minDistance = dist;
                     candidate = oldToNewMapping[sc];
                 }
             }
         }
         if (candidate != null)
             oldToNewMapping[fc].AddConnectedNode(candidate);
     }
 }
Exemple #3
0
 private static List<TileNode>[] CreateHalvesAndCandidates(Vector3 lineCheck, MemberTilePCG m) {
     List<TileNode> firstHalf = new List<TileNode>();
     List<TileNode> secondHalf = new List<TileNode>();
     foreach (KeyValuePair<TileNode, RenderedTileInfo> renderedTile in m.renderedTiles) {
         if (Vector3.Cross(lineCheck, renderedTile.Value.location).y < 0) {
             firstHalf.Add(renderedTile.Key);
         } else {
             secondHalf.Add(renderedTile.Key);
         }
     }
     // find candidate doors
     List<TileNode> firstHalfCandidates = new List<TileNode>();
     List<TileNode> secondHalfCandidates = new List<TileNode>();
     foreach (TileNode t in firstHalf) {
         foreach (TileNode c in t.connectedNodes) {
             if (secondHalf.Contains(c)) {
                 firstHalfCandidates.Add(t);
                 if (!secondHalfCandidates.Contains(c))
                     secondHalfCandidates.Add(c);
             }
         }
     }
     return new List<TileNode>[]{ firstHalf, secondHalf, firstHalfCandidates, secondHalfCandidates };
 }
Exemple #4
0
    public IMemberContainer[] Crossover(IMemberContainer otherParent) {
        // This is difficult.
        // First (and bad) attempt:
        // 1. draw the same line through the origin in both graphs, splitting them.
        // 2. for each child, pick two nodes in the two halves as close to the origin as possible that have doors that used to be connected.
        // 3. connect the nodes on each half via the single door.
        // NOTE: THIS IS PRONE TO FAIL CATASTROPHICALLY. If the one new connection cannot be made, the entire crossover will fail.
        float angle = Random.Range(0, 180);
        // turn angle into vector
        Vector3 lineCheck = Quaternion.AngleAxis(angle, Vector3.up) * Vector3.forward;
        List<TileNode>[] mySplit = CreateHalvesAndCandidates(lineCheck, this);
        List<TileNode>[] otherSplit = CreateHalvesAndCandidates(lineCheck, (MemberTilePCG)otherParent);

        // Child 1
        List<TileNode> firstChild = new List<TileNode>();
        Dictionary<TileNode, TileNode> firstOldToNewMapping = new Dictionary<TileNode, TileNode>();
        // First Half Copy
        foreach (TileNode t in mySplit[0]) {
            TileNode newTile = TileNode.Copy(t);
            firstOldToNewMapping[t] = newTile;
            firstChild.Add(newTile);
            foreach (TileNode c in t.connectedNodes) {
                if (firstOldToNewMapping.ContainsKey(c)) {
                    newTile.AddConnectedNode(firstOldToNewMapping[c]);
                    firstOldToNewMapping[c].AddConnectedNode(newTile);
                }
            }
        }
        // Second Half Copy
        foreach (TileNode t in otherSplit[1]) {
            TileNode newTile = TileNode.Copy(t);
            firstOldToNewMapping[t] = newTile;
            firstChild.Add(newTile);
            foreach (TileNode c in t.connectedNodes) {
                if (firstOldToNewMapping.ContainsKey(c)) {
                    newTile.AddConnectedNode(firstOldToNewMapping[c]);
                    firstOldToNewMapping[c].AddConnectedNode(newTile);
                }
            }
        }

        // Child 2
        List<TileNode> secondChild = new List<TileNode>();
        Dictionary<TileNode, TileNode> secondOldToNewMapping = new Dictionary<TileNode, TileNode>();
        // First Half Copy
        foreach (TileNode t in mySplit[1]) {
            TileNode newTile = TileNode.Copy(t);
            secondOldToNewMapping[t] = newTile;
            secondChild.Add(newTile);
            foreach (TileNode c in t.connectedNodes) {
                if (secondOldToNewMapping.ContainsKey(c)) {
                    newTile.AddConnectedNode(secondOldToNewMapping[c]);
                    secondOldToNewMapping[c].AddConnectedNode(newTile);
                }
            }
        }
        // Second Half Copy
        foreach (TileNode t in otherSplit[0]) {
            TileNode newTile = TileNode.Copy(t);
            secondOldToNewMapping[t] = newTile;
            secondChild.Add(newTile);
            foreach (TileNode c in t.connectedNodes) {
                if (secondOldToNewMapping.ContainsKey(c)) {
                    newTile.AddConnectedNode(secondOldToNewMapping[c]);
                    secondOldToNewMapping[c].AddConnectedNode(newTile);
                }
            }
        }
        ConnectCandidates(this, mySplit[2], (MemberTilePCG)otherParent, otherSplit[3], firstOldToNewMapping);
        ConnectCandidates(this, mySplit[3], (MemberTilePCG)otherParent, otherSplit[2], secondOldToNewMapping);
        MemberTilePCG[] containers = new MemberTilePCG[2];
        containers[0] = new MemberTilePCG();
        containers[0].graph = new TileGraph(firstChild);
        containers[1] = new MemberTilePCG();
        containers[1].graph = new TileGraph(secondChild);
        return containers;
    }