Пример #1
0
    public void CreatePlayers()
    {
        playerList = new List <ChessAI>();
        pointsList = new List <int>();
        int numInputs  = 64 * 12 + 1;
        int numOutputs = 64 + 4 + 1;

        networkBuilder = new ChessNetworkBuilder(numInputs, numOutputs, 4, 4, 100, 5);
        for (int i = 0; i < maxPlayerNumber; i++)
        {
            ChessAIDNA aIDNA = networkBuilder.BuildGene();
            playerDNA.playerList.Add(aIDNA);
            playerList.Add(networkBuilder.BuildNetworkFromGene(aIDNA));
            pointsList.Add(0);
        }
        Debug.Log("Done making players");
    }
Пример #2
0
    private List <ChessAI> MakeChildren(List <ChessAI> playerList, List <int> pointsList, int maxPlayerNumber)
    {
        List <ChessAI> raffle = new List <ChessAI>();

        for (int i = 0; i < playerList.Count; i++)
        {
            if (pointsList[i] > 5)
            {
                raffle.Add(playerList[i]);
                raffle.Add(playerList[i]);
                raffle.Add(playerList[i]);
                raffle.Add(playerList[i]);
                raffle.Add(playerList[i]);
            }
            else if (pointsList[i] > 0)
            {
                raffle.Add(playerList[i]);
                raffle.Add(playerList[i]);
                raffle.Add(playerList[i]);
            }
            else
            {
                raffle.Add(playerList[i]);
            }
        }
        while (playerList.Count < maxPlayerNumber)
        {
            int father = Random.Range(0, raffle.Count);
            int mother = Random.Range(0, raffle.Count);
            if (father != mother)
            {
                ChessAIDNA kid = CrossOver(raffle[father], raffle[mother]);
                kid = Mutate(kid);

                ChessAI newAI = BuildNetworkFromGene(kid);
                playerList.Add(newAI);
            }
        }

        Debug.Log("Next Generation ready!");
        return(playerList);
    }
Пример #3
0
    private ChessAIDNA Mutate(ChessAIDNA toMutate)
    {
        for (int i = 0; i < maxMutations; i++)
        {
            // Possible mutations:
            int mutationType = Random.Range(0, 14);
            // Switch two DNA strands
            if (mutationType == 0)
            {
                int      toSwitch1 = Random.Range(0, toMutate.DNA.Count);
                int      toSwitch2 = Random.Range(0, toMutate.DNA.Count);
                ChessDNA tempDNA   = CopyDNA(toMutate.DNA[toSwitch1].chessGenes);
                toMutate.DNA[toSwitch1] = CopyDNA(toMutate.DNA[toSwitch2].chessGenes);
                toMutate.DNA[toSwitch2] = tempDNA;
            }
            // Add a neuron in the DNA
            if (mutationType == 1)
            {
                int randomDNA  = Random.Range(0, toMutate.DNA.Count);
                int insertSpot = Random.Range(1, toMutate.DNA[randomDNA].chessGenes.Count);
                highestTransmitterNumber = toMutate.highestTransmitterNumber;
                ChessGene newGene = MakeGene(1);
                toMutate.DNA[randomDNA].chessGenes.Insert(insertSpot, newGene);
            }
            // Remove a neuron from the DNA
            if (mutationType == 2)
            {
                int randomDNA = Random.Range(0, toMutate.DNA.Count);
                // Can't remove if there's no internediate neurons
                if (toMutate.DNA[randomDNA].chessGenes.Count > 2)
                {
                    int removeSpot = Random.Range(1, toMutate.DNA[randomDNA].chessGenes.Count - 1);
                    toMutate.DNA[randomDNA].chessGenes.RemoveAt(removeSpot);
                }
            }
            // Change a Threshold
            if (mutationType == 3)
            {
                int randomDNA    = Random.Range(0, toMutate.DNA.Count);
                int randomNeuron = Random.Range(0, toMutate.DNA[randomDNA].chessGenes.Count);
                toMutate.DNA[randomDNA].chessGenes[randomNeuron].threshold = Random.Range(0, 101);
            }
            // Add input
            if (mutationType == 4)
            {
                int randomDNA    = Random.Range(0, toMutate.DNA.Count);
                int randomNeuron = Random.Range(0, toMutate.DNA[randomDNA].chessGenes.Count);
                if (toMutate.DNA[randomDNA].chessGenes[randomNeuron].neuronType != 0)
                {
                    int numIn = toMutate.DNA[randomDNA].chessGenes[randomNeuron].possibleConnectionsIn.Count;
                    if (numIn < maxInput)
                    {
                        int tempTrans = Random.Range(0, highestTransmitterNumber + 2);
                        toMutate.DNA[randomDNA].chessGenes[randomNeuron].possibleConnectionsIn.Add(tempTrans);
                        if (tempTrans > highestTransmitterNumber)
                        {
                            highestTransmitterNumber = tempTrans;
                        }
                    }
                }
            }
            // Remove input
            if (mutationType == 5)
            {
                int randomDNA    = Random.Range(0, toMutate.DNA.Count);
                int randomNeuron = Random.Range(0, toMutate.DNA[randomDNA].chessGenes.Count);
                if (toMutate.DNA[randomDNA].chessGenes[randomNeuron].neuronType != 0)
                {
                    int numIn = toMutate.DNA[randomDNA].chessGenes[randomNeuron].possibleConnectionsIn.Count;
                    if (numIn > 1)
                    {
                        int toRemove = Random.Range(0, numIn);
                        toMutate.DNA[randomDNA].chessGenes[randomNeuron].possibleConnectionsIn.RemoveAt(toRemove);
                    }
                }
            }
            // Add output
            if (mutationType == 6)
            {
                int randomDNA    = Random.Range(0, toMutate.DNA.Count);
                int randomNeuron = Random.Range(0, toMutate.DNA[randomDNA].chessGenes.Count);
                if (toMutate.DNA[randomDNA].chessGenes[randomNeuron].neuronType != 2)
                {
                    int numOut = toMutate.DNA[randomDNA].chessGenes[randomNeuron].possibleConnectionsOut.Count;
                    if (numOut < maxOutput)
                    {
                        int tempTrans = Random.Range(0, highestTransmitterNumber + 2);
                        toMutate.DNA[randomDNA].chessGenes[randomNeuron].possibleConnectionsOut.Add(tempTrans);
                        if (tempTrans > highestTransmitterNumber)
                        {
                            highestTransmitterNumber = tempTrans;
                        }
                    }
                }
            }
            // Remove output
            if (mutationType == 7)
            {
                int randomDNA    = Random.Range(0, toMutate.DNA.Count);
                int randomNeuron = Random.Range(0, toMutate.DNA[randomDNA].chessGenes.Count);
                if (toMutate.DNA[randomDNA].chessGenes[randomNeuron].neuronType != 2)
                {
                    int numOut = toMutate.DNA[randomDNA].chessGenes[randomNeuron].possibleConnectionsOut.Count;
                    if (numOut > 1)
                    {
                        int toRemove = Random.Range(0, numOut);
                        toMutate.DNA[randomDNA].chessGenes[randomNeuron].possibleConnectionsOut.RemoveAt(toRemove);
                    }
                }
            }
            // Change output strength
            if (mutationType == 8)
            {
                int randomDNA    = Random.Range(0, toMutate.DNA.Count);
                int randomNeuron = Random.Range(0, toMutate.DNA[randomDNA].chessGenes.Count);
                toMutate.DNA[randomDNA].chessGenes[randomNeuron].outputStrength = Random.Range(0, 101);
            }
            // Change a transmitter value in Inputs
            if (mutationType == 9)
            {
                int randomDNA    = Random.Range(0, toMutate.DNA.Count);
                int randomNeuron = Random.Range(0, toMutate.DNA[randomDNA].chessGenes.Count);
                if (toMutate.DNA[randomDNA].chessGenes[randomNeuron].neuronType != 0)
                {
                    int randomInput    = Random.Range(0, toMutate.DNA[randomDNA].chessGenes[randomNeuron].possibleConnectionsIn.Count);
                    int transmitterNum = Random.Range(0, highestTransmitterNumber + 2);
                    toMutate.DNA[randomDNA].chessGenes[randomNeuron].possibleConnectionsIn[randomInput] = transmitterNum;
                    if (transmitterNum > highestTransmitterNumber)
                    {
                        highestTransmitterNumber = transmitterNum;
                    }
                }
            }
            // Change a transmitter value in Outputs
            if (mutationType == 10)
            {
                int randomDNA    = Random.Range(0, toMutate.DNA.Count);
                int randomNeuron = Random.Range(0, toMutate.DNA[randomDNA].chessGenes.Count);
                if (toMutate.DNA[randomDNA].chessGenes[randomNeuron].neuronType != 2)
                {
                    int randomOutput   = Random.Range(0, toMutate.DNA[randomDNA].chessGenes[randomNeuron].possibleConnectionsOut.Count);
                    int transmitterNum = Random.Range(0, highestTransmitterNumber + 2);
                    toMutate.DNA[randomDNA].chessGenes[randomNeuron].possibleConnectionsOut[randomOutput] = transmitterNum;
                    if (transmitterNum > highestTransmitterNumber)
                    {
                        highestTransmitterNumber = transmitterNum;
                    }
                }
            }
            // Add output of pre-output neuron
            if (mutationType == 11)
            {
                int randomDNA         = Random.Range(0, toMutate.DNA.Count);
                int preOutputLocation = toMutate.DNA[randomDNA].chessGenes.Count - 1;
                if (toMutate.DNA[randomDNA].chessGenes[preOutputLocation].neuronType != 2)
                {
                    Debug.Log("I f****d up captain");
                }
                int numOutputs = toMutate.DNA[randomDNA].chessGenes[preOutputLocation].possibleConnectionsOut.Count;
                if (numOutputs < 5)
                {
                    int randomOut = Random.Range(0, outputNumber);
                    toMutate.DNA[randomDNA].chessGenes[preOutputLocation].possibleConnectionsOut.Add(randomOut);
                }
            }
            // Remove output of pre-output neuron
            if (mutationType == 12)
            {
                int randomDNA         = Random.Range(0, toMutate.DNA.Count);
                int preOutputLocation = toMutate.DNA[randomDNA].chessGenes.Count - 1;
                if (toMutate.DNA[randomDNA].chessGenes[preOutputLocation].neuronType != 2)
                {
                    Debug.Log("I f****d up captain");
                }
                int numOutputs = toMutate.DNA[randomDNA].chessGenes[preOutputLocation].possibleConnectionsOut.Count;
                if (numOutputs > 1)
                {
                    int randomOut = Random.Range(0, numOutputs);
                    toMutate.DNA[randomDNA].chessGenes[preOutputLocation].possibleConnectionsOut.RemoveAt(randomOut);
                }
            }
            // Change value of pre-output output
            if (mutationType == 13)
            {
                int randomDNA         = Random.Range(0, toMutate.DNA.Count);
                int preOutputLocation = toMutate.DNA[randomDNA].chessGenes.Count - 1;
                if (toMutate.DNA[randomDNA].chessGenes[preOutputLocation].neuronType != 2)
                {
                    Debug.Log("I f****d up captain");
                }
                int randomOut = Random.Range(0, outputNumber);
                int toRandom  = Random.Range(0, toMutate.DNA[randomDNA].chessGenes[preOutputLocation].possibleConnectionsOut.Count);
                toMutate.DNA[randomDNA].chessGenes[preOutputLocation].possibleConnectionsOut[toRandom] = randomOut;
            }
        }

        return(toMutate);
    }
Пример #4
0
    public ChessAI BuildNetworkFromGene(ChessAIDNA gene)
    {
        // Keep a list of all neurons that are available to make new connections (initialize at input neurons)
        // If the neuron is set to wait, let it wait, otherwise, find a neuron that can be connected
        // If there is no neuron available with the correct transmitter, make a new neuron with the settings from the gene

        ChessAI aI = new ChessAI(gene);

        aI.inputNeurons = new List <ChessNeuron>();

        List <ChessNeuron> availableOutNeurons = new List <ChessNeuron>();
        List <ChessNeuron> availableInNeurons  = new List <ChessNeuron>();
        List <ChessNeuron> outputNeurons       = new List <ChessNeuron>();
        List <ChessNeuron> allNeurons          = new List <ChessNeuron>();

        // First, make the list of output neurons.
        outputNeurons = MakeOutputNeurons();

        foreach (ChessDNA chessDNA in gene.DNA)
        {
            ChessNeuron tempNeuron = new ChessNeuron(chessDNA.chessGenes);
            tempNeuron.MakeInputNeuron();
            aI.inputNeurons.Add(tempNeuron);
            availableOutNeurons.Add(tempNeuron);
            allNeurons.Add(tempNeuron);
        }
        while (availableOutNeurons.Count > 0)
        {
            // Build the network
            List <ChessNeuron> nextAvailableList = new List <ChessNeuron>();
            foreach (ChessNeuron neuron in availableOutNeurons)
            {
                if (neuron.CheckIfAvailable())
                {
                    List <int> possibleOut = neuron.CheckPossibleOut();
                    foreach (int i in possibleOut)
                    {
                        ChessNeuron possibleConnection = CheckPossibleIns(i, availableInNeurons);
                        if (possibleConnection != null)
                        {
                            neuron.ConnectToNeuron(possibleConnection, i);
                            if (possibleConnection.CheckIfInConnectionsFull())
                            {
                                availableInNeurons.Remove(possibleConnection);
                            }
                        }
                        else
                        {
                            ChessNeuron tempNeuron = neuron.MakeNewNeuron(i);
                            allNeurons.Add(tempNeuron);

                            if (tempNeuron.GetNeuronType() == 1)
                            {
                                neuron.ForceConnect(tempNeuron);
                                if (!tempNeuron.CheckIfInConnectionsFull())
                                {
                                    availableInNeurons.Add(tempNeuron);
                                }
                                nextAvailableList.Add(tempNeuron);
                            }
                            else if (tempNeuron.GetNeuronType() == 2)
                            {
                                tempNeuron.MakePreOutputNeuron(outputNeurons);
                                if (!tempNeuron.CheckIfInConnectionsFull())
                                {
                                    availableInNeurons.Add(tempNeuron);
                                }
                            }
                            else
                            {
                                Debug.Log("Error: unexpected Neuron type?");
                            }
                        }
                    }
                }
                else
                {
                    // put the neuron in the nextavailableList with a position equal to its wait time
                    if (nextAvailableList.Count >= neuron.waitForConnection)
                    {
                        nextAvailableList.Insert(neuron.waitForConnection, neuron);
                        neuron.waitForConnection = 0;
                    }
                    else
                    {
                        nextAvailableList.Add(neuron);
                        neuron.waitForConnection -= nextAvailableList.Count;
                    }
                }
            }
            availableOutNeurons = nextAvailableList;
        }
        aI.outputNeurons = outputNeurons;
        aI.allNeurons    = allNeurons;

        return(aI);
    }
Пример #5
0
 public ChessAI(ChessAIDNA DNA)
 {
     aIDNA    = DNA;
     gameList = new List <ChessGame>();
 }