Пример #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;
 }
Пример #2
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;
    }