Ejemplo n.º 1
0
        public void advance(char dir, apple apl, snake[] snakes, bool printapl)
        {
            if (l > 2)
            {
                if (Save == 'w' && dir == 's')
                {
                    dir = Save;
                }
                if (Save == 's' && dir == 'w')
                {
                    dir = Save;
                }
                if (Save == 'a' && dir == 'd')
                {
                    dir = Save;
                }
                if (Save == 'd' && dir == 'a')
                {
                    dir = Save;
                }
            }

            ttl--;
            num++;
            if (!alive)
            {
                if (l > 0)
                {
                    l--;
                }
                else
                {
                    delete();
                    Xsnake[0] = -1;
                    Ysnake[0] = -1;
                    delete();
                }
            }
            else
            {
                runTime++;
                for (int i = l; i > 0; i--)
                {
                    Xsnake[i] = Xsnake[i - 1];
                    Ysnake[i] = Ysnake[i - 1];
                }

                if (dir == 's')
                {
                    Ysnake[0]++;
                }
                if (dir == 'w')
                {
                    Ysnake[0]--;
                }
                if (dir == 'd')
                {
                    Xsnake[0]++;
                }
                if (dir == 'a')
                {
                    Xsnake[0]--;
                }

                if ((apl.appleX() == Xsnake[0]) && (apl.appleY() == Ysnake[0]))
                {
                    l++;
                    num = 0;
                    apl.newCord(snakes, s);
                    if (printapl)
                    {
                        apl.print();
                    }
                    //ttl = ((ttl + ttlConst) * 6) / 10;
                    ttl = ttl + ttlConst;
                }
            }
            Save = dir;
        }
Ejemplo n.º 2
0
        // the evolution function for the machine learning.
        // gets the number of snakes that plays simultaneously (Competing with each other).
        static snake Evolution(int snknum)
        {
            snake[] snakes = new snake[snknum];
            for (int i = 0; i < snakes.Length; i++)
            {
                snakes[i] = new snake(i, s);
            }

            for (int i = 0; i < snakes.Length; i++)
            {
                snakes[i].newCord(snakes, s);
            }

            bool erase      = false;
            char dir        = ' '; //snake diraction by the neural network results.
            bool life       = true;
            bool othersLife = true;

            snakes1 = new snake[60]; // the number of snakes in every generation
            int numOfGeneration = 100000000;

            int evr = 1;  // the num of iterations each snake do in one generation
            int a   = 40; // snakes1.length - a = the num of new random snakes.
            int b   = 5;  // the num of parents snakes
            int c   = 10; // the num of snakes that survives to the next generation (includes b)
            // a - (b + c) = the number of childrens.

            char pressedKey = ' '; // changes to the key pressed by the user


            for (int i = 0; i < snakes1.Length; i++)
            {
                snakes1[i] = new snake(0, s);
                snakes1[i].AIPrep(snakes);
            }

            Console.WriteLine("if you already have a saved version and want to keep training it, please write the version num. Otherwise write anything else.");
            int ErlySnk = int.Parse(Console.ReadLine());

            Console.Beep(261, 50);

            Console.Clear();
            PrintBoard();
            //loading the save version to all the snakes. Also adding mutations.
            snakes1[0].Load(ErlySnk);
            snakes1[0].snksScore = 10000;
            for (int i = 1; i < snakes1.Length; i++)
            {
                snakes1[i].Load(ErlySnk);
                snakes1[i].Change(10);
            }

            for (int t = 0; t < numOfGeneration; t++)
            {
                Console.SetCursorPosition(0, s);
                Console.WriteLine("Press '*' to stop the learning and save the neural network to file.");
                Console.WriteLine("Press 'w' to watch the current snake.");
                Console.WriteLine((t / (numOfGeneration + 0.0)) * 100 + "% (epoch " + t + " )                      ");


                for (int x = 0; x < snakes1.Length; x++)
                {
                    if ((x / (snakes1.Length + 0.0)) * 100 % 10 == 0)
                    {
                        Console.SetCursorPosition(0, s + 3);
                        Console.WriteLine((x / (snakes1.Length + 0.0)) * 100 + "%                        ");
                    }

                    //initialization of variables before the game begins
                    for (int i = 0; i < snakes.Length; i++)
                    {
                        snakes[i] = new snake(i, s);
                        snakes[i].newCord(snakes, s);
                        snakes[i].l = 1;
                    }
                    life = true;
                    apple apl = new apple(snakes, s);
                    snakes[0] = snakes1[x];
                    snakes[0].newCord(snakes, s);
                    double score = 0;


                    for (int m = 0; m < evr; m++)
                    {
                        apl.newCord(snakes, s);

                        // print the current game state to the screan
                        if ((Console.KeyAvailable || pressedKey == 'w') && x > snakes1.Length - a)
                        {
                            if (Console.KeyAvailable)
                            {
                                pressedKey = Console.ReadKey().KeyChar;
                            }
                            Console.Clear();
                            PrintBoard();
                            Console.Write(x + " / " + snakes1.Length);
                            apl.print();
                        }

                        while (Console.KeyAvailable)
                        {
                            pressedKey = Console.ReadKey().KeyChar;
                        }

                        snakes[0].l = 1; //initial snake length

                        //one game
                        while (life)
                        {
                            if (erase && (pressedKey != 'w'))
                            {
                                Console.Clear();
                                PrintBoard();
                                erase = false;
                            }
                            for (int i = 0; i < snakes.Length; i++)
                            {
                                if (i == 0)
                                {
                                    //  one move of the tested snake, according to the neural network.
                                    dir = snakes[0].AIsnkalg(snakes, apl);
                                    snakes[i].advance(dir, apl, snakes, (Console.KeyAvailable || pressedKey == 'w') && x > snakes1.Length - a);
                                    life           = snakes[0].isAlive(snakes);
                                    snakes[0].Save = dir;
                                }
                                else
                                {
                                    //one move of snakes[i], according to the fixed algorithm
                                    dir            = snakes[i].snkalg(snakes, apl);
                                    snakes[i].Save = dir;
                                    snakes[i].advance(dir, apl, snakes, (Console.KeyAvailable || pressedKey == 'w') && x > snakes1.Length - a);
                                    othersLife = snakes[i].isAlive(snakes);
                                    if (!othersLife)
                                    {
                                        snakes[i] = new snake(i, s);
                                        snakes[i].newCord(snakes, s);
                                    }
                                }

                                // print the current game state to the screan
                                if ((Console.KeyAvailable || pressedKey == 'w') && x > snakes1.Length - a)
                                {
                                    erase = true;
                                    if (Console.KeyAvailable)
                                    {
                                        pressedKey = Console.ReadKey().KeyChar;
                                    }
                                    snakes[i].delete();
                                    Console.SetCursorPosition(0, 0);
                                    snakes[i].write(arrows);
                                    Console.SetCursorPosition(2 * s + 1, 0);
                                    Console.ForegroundColor = ConsoleColor.White;
                                    Console.WriteLine("score: " + snakes1[x].score());
                                    if (i == 0)
                                    {
                                        Thread.Sleep(50);
                                    }
                                    apl.print();
                                }
                            }
                        }

                        snakes[0].ttl     = snakes[0].ttlConst;
                        life              = true;
                        snakes[0].alive   = true;
                        snakes[0].runTime = 0;
                        snakes[0].l       = 1;
                        snakes[0].bonus   = 0;
                        snakes[0].newCord(snakes, s);
                        score += snakes[0].snksScore;
                        snakes[0].snksScore = 0;
                    }

                    score = score / (evr * 1.0);

                    double temp = -0.5;
                    if (snakes1[x].Right)
                    {
                        temp += 0.5;
                    }
                    if (snakes1[x].Left)
                    {
                        temp += 0.5;
                    }
                    if (snakes1[x].Straight)
                    {
                        temp += 0.5;
                    }

                    score *= temp;

                    snakes1[x].Right     = false;
                    snakes1[x].Left      = false;
                    snakes1[x].Straight  = false;
                    snakes1[x]           = snakes[0];
                    snakes1[x].snksScore = score;
                }

                Console.WriteLine("last epoch's first place score in this epoch:  " + snakes1[snakes1.Length - 1].snksScore + "       ");
                Sort(0, snakes1.Length - 1); // sort snakes1 by score

                if (pressedKey == '*')
                {
                    return(snakes1[snakes1.Length - 1]);  // returning the snake with the best score
                }

                Console.SetCursorPosition(0, s + 5);
                Console.ForegroundColor = ConsoleColor.White;
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine((i + 1) + ": " + snakes1[snakes1.Length - i - 1].snksScore + "                                       ");
                }
                Console.SetCursorPosition(0, s + 3);



                for (int x = 0; x < snakes1.Length; x++)
                {
                    if (x < snakes1.Length - a)// create new random snakes
                    {
                        snakes1[x] = new snake(0, s);
                        snakes1[x].AIPrep(snakes);
                    }

                    else if (x < (snakes1.Length) - c) // create snakes childs
                    {
                        snakes1[x] = new snake(0, s);
                        snakes1[x].AIPrep(snakes);
                        snakes1[x].Load(snakes1[snakes1.Length - x % b - 1].nn); // duplicating a snake into this snake
                        snakes1[x].Change(rnd.NextDouble() * 8 + 4);             // add mutations
                    }

                    snakes1[x].l       = 1;
                    snakes1[x].alive   = true;
                    snakes1[x].runTime = 0;
                    snakes1[0].newCord(snakes, s);
                    snakes1[x].snksScore = 0;
                }
            }
            return(snakes1[snakes1.Length - 1]);  // returning the snake with the best score
        }