Ejemplo n.º 1
0
        //
        //fonction de base du minimax qui va s'occuper de la profondeur itérative.
        //
        override public Move GetNextMove(Grille grille, int profondeur)
        {
            double valeurOptimal = Double.MinValue;
            Move   moveOptimal   = null;

            stopwatch = new Stopwatch();
            stopwatch.Start();
            HashSet <Move> possibleMoves = grille.ListPossibleMoves();

            while (true)
            {
                foreach (var possibleMove in possibleMoves)
                {
                    Grille moveGrille = new Grille(grille);
                    moveGrille.UpdateGrille(possibleMove);
                    moveGrille.ReverseBoard();
                    double valeurTest = Execute(moveGrille, profondeur - 1, valeurOptimal, Double.MaxValue);
                    if (valeurTest > valeurOptimal)
                    {
                        valeurOptimal = valeurTest;
                        moveOptimal   = possibleMove;
                    }

                    if (stopwatch.Elapsed.TotalMilliseconds > Settings.TIME_TO_MOVE)
                    {
                        stopwatch.Stop();
                        return(moveOptimal);
                    }
                }
                profondeur++;
            }
        }
Ejemplo n.º 2
0
        public override double Calculer(Grille grille)
        {
            double valeurHeuristique = 0;
            double coefficient       = 1.0;

            // parcours toute le board
            for (int i = 0; i < 24; i++)
            {
                if (grille.board[i] == 1) // si on a un pion non protegé
                {
                    valeurHeuristique -= 1 * coefficient;
                }
                else if (grille.board[i] >= 2) // si on a un pion protegé
                {
                    valeurHeuristique += 1 * coefficient * grille.board[i];
                }
                coefficient -= 0.01;
            }

            valeurHeuristique += grille.oppBar * 1.3;

            // On check pour quel joueur on est.
            if (grille.player)
            {
                return(valeurHeuristique);
            }
            return(-valeurHeuristique);
        }
Ejemplo n.º 3
0
        //
        //  Cette fonction retourne la liste de tous les moves possible pour la grille.
        //
        private void GetPossibleMoves(Grille grille, List <Tuple <int, int> > listeMoves)
        {
            bool foundPossibleMove = false;

            for (int i = 0; i < grille.dice.Count; i++)
            {
                var possibleMovesForDie = GetPossibleMovesForDie(grille, grille.dice[i]);
                if (possibleMovesForDie.Count != 0)
                {
                    foundPossibleMove = true;
                    foreach (var move in possibleMovesForDie)
                    {
                        Grille moveGrille = new Grille(grille);
                        moveGrille.UpdateGrille(move);
                        List <Tuple <int, int> > moveListe = new List <Tuple <int, int> >(listeMoves);
                        moveListe.Add(move);
                        GetPossibleMoves(moveGrille, moveListe);
                    }
                }
            }

            if (!foundPossibleMove && listeMoves.Count > 0)// on est dans une feuille, on ajoute le move a la liste.
            {
                Move move = new Move(listeMoves);
                if (maxDice <= move.DiceUsed && maxStep <= move.Step)
                {
                    listPossibleMoves.Add(move);
                    maxStep = move.Step;
                    maxDice = move.DiceUsed;
                }
            }
        }
Ejemplo n.º 4
0
 //
 // constructeur par copie
 //
 public Grille(Grille grille)
 {
     grille.board.CopyTo(board, 0);
     dice   = new List <int>(grille.dice);
     bar    = grille.bar;
     oppBar = grille.oppBar;
     player = grille.player;
 }
Ejemplo n.º 5
0
        //
        // Retourne la liste des moves possibles pour un dé
        //
        private List <Tuple <int, int> > GetPossibleMovesForDie(Grille grille, int die)
        {
            var moves = new List <Tuple <int, int> >();

            //si l'on doit vider le bar.
            if (grille.bar != 0)
            {
                if (grille.board[25 - die - 1] >= -1)
                {
                    moves.Add(new Tuple <int, int>(25, 25 - die));
                }
            }
            else if (grille.IsFinalStage())  // si on est rendu a vider la planche.
            {
                int pionLePlusEloigne = 0;
                for (int i = 0; i < 6; i++)
                {
                    if (grille.board[i] > 0)
                    {
                        pionLePlusEloigne = i + 1;
                    }
                }
                for (int i = 0; i < 6; i++)
                {
                    if (grille.board[i] > 0)
                    {
                        if (i + 1 - die == 0)
                        {
                            moves.Add(new Tuple <int, int>(i + 1, i + 1 - die));
                        }
                        else if (i + 1 - die < 0 && die >= pionLePlusEloigne)
                        {
                            moves.Add(new Tuple <int, int>(i + 1, i + 1 - die));
                        }
                        else if (i - die >= 0 && grille.board[i - die] >= -1)
                        {
                            moves.Add(new Tuple <int, int>(i + 1, i + 1 - die));
                        }
                    }
                }
            }
            else // on peut jouer n'importequoi
            {
                for (int i = 0; i < 24; i++)
                {
                    if (grille.board[i] > 0 && i - die >= 0 && grille.board[i - die] >= -1) //on peut jouer sur cette case.
                    {
                        moves.Add(new Tuple <int, int>(i + 1, i + 1 - die));
                    }
                }
            }
            return(moves);
        }
Ejemplo n.º 6
0
        override public Move GetNextMove(Grille grille, int profondeur)
        {
            double valeurOptimal = Double.MinValue;
            Move   moveOptimal   = null;

            HashSet <Move> possibleMoves = grille.ListPossibleMoves();

            foreach (var possibleMove in possibleMoves)
            {
                Grille moveGrille = new Grille(grille);
                moveGrille.UpdateGrille(possibleMove);
                moveGrille.ReverseBoard();
                double valeurTest = Execute(moveGrille, profondeur - 1);
                if (valeurTest > valeurOptimal)
                {
                    valeurOptimal = valeurTest;
                    moveOptimal   = possibleMove;
                }
            }
            return(moveOptimal);
        }
        override public double Calculer(Grille grille)
        {
            double valeurHeuristique = 0;

            // Aucune menace: http://i.imgur.com/ktuiqfY.jpg
            // Menace ennemie: http://i.imgur.com/oBM4sIj.jpg
            bool menaceEnnemie = false;

            // TODO: à vérifier pour l'ennemi (dans l'autre direction?)
            for (int i = 0; i < grille.board.Length; i++)
            {
                int nbPionsJoueur = 0;
                if (grille.board[i] < 0)
                {
                    menaceEnnemie = true;
                    break;
                }
                if (grille.board[i] > 0)
                {
                    nbPionsJoueur += grille.board[i];
                    if (nbPionsJoueur == 15)
                    {
                        break;
                    }
                }
            }

            // S'il n'y a aucune menace ennemie, c'est free-for-all
            if (menaceEnnemie)
            {
                int    nbPairsColles            = 0;
                double multiplicateurRecompense = 0;
                int    nbGroupesPairs           = 0;
                for (int i = 0; i < grille.board.Length; i++)
                {
                    // On pénalise tous les checkers non protégés
                    if (grille.board[i] == 1)
                    {
                        bool ennemiEnAvant = grille.EnnemiEnAvantDuPoint(i);

                        if (ennemiEnAvant)
                        {
                            // Plus pénalisant si on est proche de la fin
                            valeurHeuristique -= 2000 / (double)(i + 1);
                        }
                        // Moins grave s'il y a aucun checker ennemi en avant, mais quand même risqué
                        else
                        {
                            valeurHeuristique -= 200 / (double)(i + 1);
                        }
                    }

                    // On récompense les pairs (bloquent le point)
                    if (grille.board[i] >= 2)
                    {
                        if (i >= 1 && grille.board[i - 1] < 2)
                        {
                            nbPairsColles = 0;
                            nbGroupesPairs++;
                        }

                        bool ennemiEnAvant = grille.EnnemiEnAvantDuPoint(i);
                        nbPairsColles++;
                        if (ennemiEnAvant)
                        {
                            multiplicateurRecompense += 2 + (0.1 * i);
                        }
                        // Se trouve dans les 6 derniers points
                        if (i <= 5)
                        {
                            multiplicateurRecompense += 2 + (0.1 * i);
                        }
                    }
                }
                double valeurHeuristiquePairs = 0;
                switch (nbPairsColles)
                {
                case 0:
                    break;

                case 1:
                    valeurHeuristiquePairs += (5 * multiplicateurRecompense);
                    break;

                case 2:
                    valeurHeuristiquePairs += (15 * multiplicateurRecompense);
                    break;

                case 3:
                    valeurHeuristiquePairs += (40 * multiplicateurRecompense);
                    break;

                case 4:
                    valeurHeuristiquePairs += (70 * multiplicateurRecompense);
                    break;

                case 5:
                    valeurHeuristiquePairs += (110 * multiplicateurRecompense);
                    break;

                case 6:
                    valeurHeuristiquePairs += (200 * multiplicateurRecompense);
                    break;

                default:
                    valeurHeuristiquePairs += (200 * multiplicateurRecompense);
                    break;
                }
                valeurHeuristiquePairs *= nbGroupesPairs;
                valeurHeuristique      += valeurHeuristiquePairs;
            }

            // Plus on peut manger de checkers, mieux c'est
            valeurHeuristique += 1000 * grille.oppBar;

            // Plus on peut bear-off (rentrer) de checkers, mieux c'est
            valeurHeuristique += grille.GetNbPionsJoueurRentres() * 10000;

            if (grille.player)
            {
                return(valeurHeuristique);
            }
            return(-valeurHeuristique);
        }
Ejemplo n.º 8
0
        override public double Execute(Grille grille, int profondeur)
        {
            if (profondeur == 0) // on est au bout.
            {
                Grille grillePourEnnemi = new Grille(grille);
                grillePourEnnemi.ReverseBoard();
                double test = this.heuristique.Calculer(grille) - this.heuristique.Calculer(grillePourEnnemi);
                if (grille.player)
                {
                    return(test);
                }
                else
                {
                    return(-test);
                }
            }

            if (grille.dice.Count > 0) // un joueur peut jouer.
            {
                if (grille.player)     // on joue
                {
                    HashSet <Move> possibleMoves = grille.ListPossibleMoves();
                    double         value         = double.MinValue;
                    foreach (var possibleMove in possibleMoves)
                    {
                        Grille moveGrille = new Grille(grille);
                        moveGrille.UpdateGrille(possibleMove);
                        moveGrille.ReverseBoard();
                        value = Math.Max(value, Execute(moveGrille, profondeur - 1));
                    }
                    return(value);
                }
                else //l'adversaire joue.
                {
                    HashSet <Move> possibleMoves = grille.ListPossibleMoves();
                    double         value         = double.MaxValue;
                    foreach (var possibleMove in possibleMoves)
                    {
                        Grille moveGrille = new Grille(grille);
                        moveGrille.UpdateGrille(possibleMove);
                        moveGrille.ReverseBoard();
                        value = Math.Max(value, Execute(moveGrille, profondeur - 1));
                    }
                    return(value);
                }
            }
            else // on est dans notre cas random.
            {
                double   value   = 0;
                double[] values  = new double[Player.possibleDiceRoll.Count + 1];
                Thread[] threads = new Thread[Player.possibleDiceRoll.Count + 1];
                int      i       = 0;

                for (i = 0; i < Player.possibleDiceRoll.Count; i++)
                {
                    Grille diceGrille = new Grille(grille);
                    diceGrille.dice = Player.possibleDiceRoll[i].Item2;
                    int num = i;
                    threads[i] = new Thread(delegate()
                    {
                        values[num] = Player.possibleDiceRoll[num].Item1 * Execute(diceGrille, profondeur);
                    });
                    threads[i].Start();
                }

                for (int j = 0; j < Player.possibleDiceRoll.Count; j++)
                {
                    threads[j].Join();
                    value += values[j];
                }
                return(value);
            }
        }
Ejemplo n.º 9
0
 abstract public Move GetNextMove(Grille pos, int depth);
Ejemplo n.º 10
0
 abstract public double Execute(Grille grille, int profondeur);
Ejemplo n.º 11
0
        public double Execute(Grille grille, int profondeur, double alpha, double beta)
        {
            if (profondeur == 0) // on est au bout.
            {
                Grille grillePourEnnemi = new Grille(grille);
                grillePourEnnemi.ReverseBoard();
                double test = this.heuristique.Calculer(grille) - this.heuristique.Calculer(grillePourEnnemi);
                if (grille.player)
                {
                    return(test);
                }
                else
                {
                    return(-test);
                }
            }

            if (grille.dice.Count > 0) // un joueur peut jouer.
            {
                if (grille.player)     // on joue
                {
                    HashSet <Move> possibleMoves = grille.ListPossibleMoves();
                    foreach (var possibleMove in possibleMoves)
                    {
                        Grille moveGrille = new Grille(grille);
                        moveGrille.UpdateGrille(possibleMove);
                        moveGrille.ReverseBoard();
                        alpha = Math.Max(alpha, Execute(moveGrille, profondeur - 1, alpha, beta));
                        if (beta <= alpha)
                        {
                            break;
                        }

                        if (stopwatch.Elapsed.TotalMilliseconds > Settings.TIME_TO_MOVE)
                        {
                            stopwatch.Stop();
                            return(alpha);
                        }
                    }
                    return(alpha);
                }
                else //l'adversaire joue.
                {
                    HashSet <Move> possibleMoves = grille.ListPossibleMoves();
                    foreach (var possibleMove in possibleMoves)
                    {
                        Grille moveGrille = new Grille(grille);
                        moveGrille.UpdateGrille(possibleMove);
                        moveGrille.ReverseBoard();
                        beta = Math.Min(beta, Execute(moveGrille, profondeur - 1, alpha, beta));
                        if (beta <= alpha)
                        {
                            break;
                        }

                        if (stopwatch.Elapsed.TotalMilliseconds > Settings.TIME_TO_MOVE)
                        {
                            stopwatch.Stop();
                            return(beta);
                        }
                    }
                    return(beta);
                }
            }
            else // on est dans notre cas random.
            {
                double   value   = 0;
                double[] values  = new double[Player.possibleDiceRoll.Count + 1];
                Thread[] threads = new Thread[Player.possibleDiceRoll.Count + 1];
                int      i       = 0;

                for (i = 0; i < Player.possibleDiceRoll.Count; i++)
                {
                    if (stopwatch.Elapsed.TotalMilliseconds > Settings.TIME_TO_MOVE)
                    {
                        stopwatch.Stop();
                        return(value);
                    }

                    Grille diceGrille = new Grille(grille);
                    diceGrille.dice = Player.possibleDiceRoll[i].Item2;
                    int num = i;
                    threads[i] = new Thread(delegate()
                    {
                        values[num] = Player.possibleDiceRoll[num].Item1 * Execute(diceGrille, profondeur, alpha, beta);
                    });
                    threads[i].Start();
                }

                for (int j = 0; j < Player.possibleDiceRoll.Count; j++)
                {
                    threads[j].Join();
                    value += values[j];
                }

                return(value);
            }
        }
Ejemplo n.º 12
0
 // Stub method because we use header with alpha and beta vars
 override public double Execute(Grille grille, int profondeur)
 {
     return(0.0);
 }
Ejemplo n.º 13
0
 abstract public double Calculer(Grille grille);
Ejemplo n.º 14
0
        static void Main(string[] args)
        {
            ProcessStartInfo startInfo;
            String           EXPORT_PATH;

            //check if linux
            int p = (int)Environment.OSVersion.Platform;

            if ((p == 4) || (p == 6) || (p == 128))
            {
                //is linux
                startInfo   = new ProcessStartInfo("gnubg", "-t");
                EXPORT_PATH = Directory.GetCurrentDirectory() + "/";
            }
            else
            {
                //is windows
                //startInfo = new ProcessStartInfo("D:\\Games\\gnubg\\gnubg-cli.exe", "-t");
                startInfo   = new ProcessStartInfo(args[0], "-t");
                EXPORT_PATH = Directory.GetCurrentDirectory() + "\\";
            }

            startInfo.RedirectStandardOutput = true;
            startInfo.RedirectStandardError  = true;
            startInfo.RedirectStandardInput  = true;
            startInfo.UseShellExecute        = false;

            Process process = Process.Start(startInfo);

            process.BeginOutputReadLine();
            process.BeginErrorReadLine();
            //process.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
            process.OutputDataReceived += (s, e) => checkForEndGame(e.Data);
            process.OutputDataReceived += (s, e) => checkForBoard(e.Data);
            process.OutputDataReceived += (s, e) => checkForRolledDice(e.Data);
            process.OutputDataReceived += (s, e) => checkForResignation(e.Data, process);
            process.ErrorDataReceived  += (s, e) => Console.WriteLine(e.Data);
            process.ErrorDataReceived  += (s, e) => checkForError(e.Data);

            process.StandardInput.WriteLine("set matchlength 1001");
            process.StandardInput.WriteLine("set cube use off");
            process.StandardInput.WriteLine("set output rawboard on");

            // start a new game
            process.StandardInput.WriteLine("new game");

            Player player = new Player();
            int    test   = Properties.Settings.Default.totalGames;

            TimeSpan tempsTotal = new TimeSpan();
            double   nbCoups    = 0.0;

            while (CountGame < Settings.TOTAL_GAMES)// boucle pour chaque coup qu'on doit jouer.
            {
                // on se prépare à jouer le prochain coup.
                Ready = false;
                process.StandardInput.WriteLine("roll"); // on roll les dés.

                int counterTime = 0;
                while (!Ready)
                {
                    Thread.Sleep(5);
                    counterTime++;
                    if (counterTime > 100)
                    {
                        process.StandardInput.WriteLine("roll"); // on roll les dés.
                        counterTime = 0;
                    }
                }

                Grille grille = new Grille(Rawboard);

                Stopwatch stopWatch = new Stopwatch();
                if (Settings.MESURE_MOVE_TIME)
                {
                    stopWatch.Start();
                }

                Move nextMove = player.minimax.GetNextMove(grille, Settings.DEPTH);// we ask for the next move to make.
                nbCoups++;
                if (Settings.MESURE_MOVE_TIME)
                {
                    stopWatch.Stop();
                    tempsTotal = tempsTotal.Add(stopWatch.Elapsed);
                }

                process.StandardInput.WriteLine(nextMove.GetCmd());
            }
            process.StandardInput.WriteLine("save match " + EXPORT_PATH + "tester.sgf");

            Console.WriteLine("********** finished : " + CountWin + " games won ******************");
            if (Settings.MESURE_MOVE_TIME)
            {
                Console.WriteLine("Temps de CPU moyen par coup: " + tempsTotal.TotalMilliseconds / nbCoups + "ms.");
            }
            Console.ReadLine();
        }