Пример #1
0
        static public Ply CastlingQueenSide()
        {
            Ply newPly = new Ply();

            newPly.castlingQueenSide = true;
            return(newPly);
        }
Пример #2
0
        static public Ply PromoteBishop(Case from, Case to)
        {
            Ply newPly = Position(from, to);

            newPly.promotion = new BishopPromotion();
            return(newPly);
        }
Пример #3
0
        static public Ply PromoteKnight(Case from, Case to)
        {
            Ply newPly = Position(from, to);

            newPly.promotion = new KnightPromotion();
            return(newPly);
        }
Пример #4
0
        static public Ply PromoteQueen(Case from, Case to)
        {
            Ply newPly = Position(from, to);

            newPly.promotion = new QueenPromotion();
            return(newPly);
        }
Пример #5
0
        static public Ply EatKing(uint from, uint to)
        {
            Ply newPly = Position(from, to);

            newPly.lastPly = true;
            return(newPly);
        }
Пример #6
0
        public Ply Run()
        {
            /*Console.WriteLine("Avant : B" + board.GetMailbox().countPieceBlanche + ", N " + board.GetMailbox().countPieceNoir);
             * foreach(int elmt in board.GetMailbox().etatPieceBlanche)
             * {
             *  Console.Write(elmt + " ");
             * }*/
            // Syzygy end-game table
            Ply ply = tableReader.getBestPly();

            if (ply == null) // No results
            {
                // Iterative deepening search
                for (uint depth = 2; watch.ElapsedMilliseconds < timingMaxMs; depth++)
                {
                    Ply tempPly = NegaScout(depth, int.MinValue, int.MaxValue);
                    if (tempPly != null)
                    {
                        ply = tempPly;
                    }
                    //Console.WriteLine("Depth: " + depth + ", time: " + watch.ElapsedMilliseconds);
                }
            }

            Debug.Assert(ply != null, "ply is null");

            /*Console.WriteLine("Apres : B" + board.GetMailbox().countPieceBlanche + ", N " + board.GetMailbox().countPieceNoir);
             * foreach (int elmt in board.GetMailbox().etatPieceBlanche)
             * {
             *  Console.Write(elmt + " ");
             * }
             * Console.WriteLine("Ply : " + ply);*/
            return(ply);
        }
Пример #7
0
        static public Ply PromoteRook(Case from, Case to)
        {
            Ply newPly = Position(from, to);

            newPly.promotion = new RookPromotion();
            return(newPly);
        }
Пример #8
0
        static public Ply EnPassant(Case from, Case to, Case capturePossible, bool captureEffective)
        {
            Ply newPly = Position(from, to);

            newPly.captureEnPassant = capturePossible;
            newPly.captureEP        = captureEffective;
            return(newPly);
        }
Пример #9
0
        static public Ply Position(Case from, Case to)
        {
            Ply newPly = new Ply();

            newPly.from = from;
            newPly.to   = to;
            return(newPly);
        }
Пример #10
0
        private Ply genMovePromotion(int depart, int arrivee, Color c)
        {
            string dp   = Mailbox.tabCoord[depart];
            Case   from = Case.BuildCaseMailBox(depart, dp);
            string arr  = Mailbox.tabCoord[arrivee];
            Case   to   = Case.BuildCaseMailBox(depart, arr);

            return(Ply.PromoteQueen(from, to));
        }
Пример #11
0
        private int RecursiveNegaScout(uint depth, Ply parentPly, int alpha, int beta)
        {
            board.Push(parentPly);

            int best;
            int score2;

            WDL?wdl = tableReader.getWDL();

            if (wdl.HasValue)
            {
                best = evaluator.EvaluateWDL(wdl.Value);
            }

            else
            {
                best = int.MinValue;

                if (depth == 0)
                {
                    best = evaluator.Evaluate();
                }
                else
                {
                    foreach (Ply ply in ruler.GetPossiblePlies())
                    {
                        if (watch.ElapsedMilliseconds >= timingMaxMs)
                        {
                            break;
                        }

                        int score = RecursiveNegaScout(depth - 1, ply, -beta, -alpha);
                        score2 = score;

                        if (score > alpha && score < beta && depth > 1)
                        {
                            score2 = RecursiveNegaScout(depth - 1, ply, -beta, -score);
                        }

                        if (score >= score2)
                        {
                            best = score;
                        }
                        else
                        {
                            best = score2;
                        }
                    }
                }
            }

            board.Pop();

            return(best);
        }
Пример #12
0
        public void Push(Ply ply)
        {
            // Backup the current chessboard
            stack.Push(pos);

            //Copy of pos
            Mailbox mailbox = new Mailbox(pos);

            mailbox.ply(ply);
            switchTurn();
            pos = mailbox;
        }
Пример #13
0
 public void testPly(Ply p)
 {
     Array.Copy(piece, savePiece, 64);
     Array.Copy(color, saveColor, 64);
     Array.Copy(etatPieceBlanche, saveEtatPieceBlanche, 6);
     Array.Copy(etatPieceNoir, saveEtatPieceNoir, 6);
     saveCountW = countPieceBlanche;
     saveCountB = countPieceNoir;
     if (ep.HasValue)
     {
         saveEp = ep.Value;
     }
     else
     {
         saveEp = null;
     }
     this.ply(p);
 }
Пример #14
0
        private int RecursiveNegaMax(uint depth, Ply parentPly)
        {
            board.Push(parentPly);

            int best;

            WDL?wdl = tableReader.getWDL();

            if (wdl.HasValue)
            {
                best = evaluator.EvaluateWDL(wdl.Value);
            }

            else // We need to explore only if the end game is unknown
            {
                best = int.MinValue;

                if (depth == 0)
                {
                    best = evaluator.Evaluate();
                }
                else
                {
                    foreach (Ply ply in ruler.GetPossiblePlies())
                    {
                        if (watch.ElapsedMilliseconds >= timingMaxMs)
                        {
                            break;
                        }

                        int score = -RecursiveNegaMax(depth - 1, ply);
                        if (score > best)
                        {
                            best = score;
                        }
                    }
                }
            }

            board.Pop();

            return(best);
        }
Пример #15
0
        private Ply genMove(int depart, int arrivee, int v, int enPassant)
        {
            string dp  = Mailbox.tabCoord[depart];
            string arr = Mailbox.tabCoord[arrivee];

            Ply p = null;

            //Generation d'une case EN_PASSANT car double saut
            if (enPassant != -1)
            {
                if (v == 0)
                {
                    string ep = Mailbox.tabCoord[enPassant];
                    p = Ply.EnPassant(Case.BuildCaseMailBox(depart, dp), Case.BuildCaseMailBox(arrivee, arr), Case.BuildCaseMailBox(enPassant, ep), false);
                    return(p);
                }
                //On mange un pion via la case en Passant
                else if (v == 1 && board.GetMailbox().getColor()[arrivee] == (int)Color.PAWN_EN_PASSANT)
                {
                    string ep = Mailbox.tabCoord[enPassant];
                    p = Ply.EnPassant(Case.BuildCaseMailBox(depart, dp), Case.BuildCaseMailBox(arrivee, arr), Case.BuildCaseMailBox(enPassant, ep), true);
                    return(p);
                }
            }
            //Generation d'un mouvement normal

            p = Ply.Position(Case.BuildCaseMailBox(depart, dp), Case.BuildCaseMailBox(arrivee, arr));


            return(p);


            //return Ply.Position(Case.BuildCaseMailBox(depart, dp), Case.BuildCaseMailBox(arrivee, arr));
            //int valeur = evaluateBoard(LIGHT);

            //Console.WriteLine("Mouvement possible {2} : {0}, {1}", dp, arr, piece[i]);
        }
Пример #16
0
        private Ply NegaMax(uint depth)
        {
            Debug.Assert(depth >= 2);

            Ply bestPly   = null;
            int bestScore = int.MinValue;

            foreach (Ply ply in ruler.GetPossiblePlies())
            {
                if (watch.ElapsedMilliseconds >= timingMaxMs)
                {
                    break;
                }

                int score = -RecursiveNegaMax(depth - 1, ply);
                if (score > bestScore)
                {
                    bestPly   = ply;
                    bestScore = score;
                }
            }

            return(bestPly);
        }
Пример #17
0
 static public Ply PromoteRook(Ply ply)
 {
     ply.promotion = new RookPromotion();
     return(ply);
 }
Пример #18
0
        // Castling is not supported
        public Ply getBestPly()
        {
            if (impl is null)
            {
                return(null);
            }
            if (board.CountMen > impl.Largest)
            {
                return(null);
            }

            Bitboard bitboard = board.ToBitboard();

            uint res = impl.ProbeRoot(
                bitboard.white,
                bitboard.black,
                bitboard.kings,
                bitboard.queens,
                bitboard.rooks,
                bitboard.bishops,
                bitboard.knights,
                bitboard.pawns,
                0,           // 50-move clock
                bitboard.castling,
                bitboard.ep, // "En passant"
                bitboard.turn,
                UIntPtr.Zero // No more results
                );

            if (res == Fathom.TB_RESULT_FAILED)
            {
                return(null);
            }

            uint from    = Fathom.GetFrom(res);
            uint to      = Fathom.GetTo(res);
            uint promote = Fathom.GetPromotes(res);
            uint ep      = Fathom.GetEP(res);

            Ply ply;

            switch (promote)
            {
            case Fathom.TB_PROMOTES_ROOK:
                ply = Ply.PromoteRook(from, to);
                break;

            case Fathom.TB_PROMOTES_KNIGHT:
                ply = Ply.PromoteKnight(from, to);
                break;

            case Fathom.TB_PROMOTES_BISHOP:
                ply = Ply.PromoteBishop(from, to);
                break;

            case Fathom.TB_PROMOTES_QUEEN:
                ply = Ply.PromoteQueen(from, to);
                break;

            default:
                if (ep == 0)
                {
                    ply = Ply.Position(from, to);
                }
                else
                {
                    ply = Ply.EnPassant(from, to, ep, false);    //TODO <----- Qu'est ce qu'il se passe la ? Si capture effective mettre true, si generation d'une case EP mettre false
                }
                break;
            }


            // From here, it is just printf debugging
            {
                String status;

                if (res == Fathom.TB_RESULT_CHECKMATE)
                {
                    status = "Checkmate";
                }

                else if (res == Fathom.TB_RESULT_STALEMATE)
                {
                    status = "Stalemate";
                }

                else if (res == Fathom.TB_RESULT_FAILED)
                {
                    status = "Failed";
                }

                else
                {
                    status = "Normal";
                }

                uint   wdl = Fathom.GetWDL(res);
                String wdlStr;

                switch (wdl)
                {
                case Fathom.TB_WIN:
                    wdlStr = "WIN";
                    break;

                case Fathom.TB_CURSED_WIN:
                    wdlStr = "CURSED WIN";
                    break;

                case Fathom.TB_DRAW:
                    wdlStr = "DRAW";
                    break;

                case Fathom.TB_BLESSED_LOSS:
                    wdlStr = "BLESSED LOSS";
                    break;

                case Fathom.TB_LOSS:
                    wdlStr = "LOSS";
                    break;

                default:
                    wdlStr = "N/A";
                    break;
                }

                uint dtz = Fathom.GetDTZ(res);

                Console.Out.WriteLine(
                    "Status: " + status + "\n" +
                    "WDL: " + wdlStr + ", DTZ: " + dtz + "\n" +
                    "ply: " + ply.ToString() + "\n" +
                    "ep: " + ep + "\n"
                    );
            }

            return(ply);
        }
Пример #19
0
 static public Ply PromoteKnight(Ply ply)
 {
     ply.promotion = new KnightPromotion();
     return(ply);
 }
Пример #20
0
 static public Ply PromoteQueen(Ply ply)
 {
     ply.promotion = new QueenPromotion();
     return(ply);
 }
Пример #21
0
 static public Ply PromoteBishop(Ply ply)
 {
     ply.promotion = new BishopPromotion();
     return(ply);
 }
Пример #22
0
        static void Main(string[] args)
        {
#if DEBUG
            Debugger.Launch();
#endif

            if (args.Length != 1)
            {
                Console.WriteLine("Incorrect count of arguments.");
                Console.WriteLine("1 required and you have specified " + args.Length);
                Console.WriteLine("Did you forgot to specify 'white' or 'black' in the arguments?");
                Console.WriteLine("Press enter to exit");
                Console.ReadKey();
                return;
            }

            Color  agentColor;
            String fileSuffix;

            if (args[0] == "white")
            {
                fileSuffix = "AI1";
                agentColor = Color.WHITE;
            }
            else if (args[0] == "black")
            {
                fileSuffix = "AI2";
                agentColor = Color.BLACK;
            }
            else
            {
                Console.WriteLine("\'" + args[0] + "\' argument is unknown.");
                Console.WriteLine("Please choose between 'white' or 'black'");
                Console.WriteLine("Press enter to exit");
                Console.ReadKey();
                return;
            }

            try
            {
                Init();

                bool   stop   = false;
                int[]  tabVal = new int[64];
                String value;

                while (!stop)
                {
                    using (var mmf = MemoryMappedFile.OpenExisting("plateau"))
                    {
                        using (var mmf2 = MemoryMappedFile.OpenExisting("rep" + fileSuffix))
                        {
                            Mutex mutexStartAI = Mutex.OpenExisting("mutexStart" + fileSuffix);
                            Mutex mutexAI      = Mutex.OpenExisting("mutex" + fileSuffix);
                            mutexAI.WaitOne();
                            mutexStartAI.WaitOne();

                            watch.Restart();

                            using (var accessor = mmf.CreateViewAccessor())
                            {
                                ushort Size   = accessor.ReadUInt16(0);
                                byte[] Buffer = new byte[Size];
                                accessor.ReadArray(0 + 2, Buffer, 0, Buffer.Length);

                                value = ASCIIEncoding.ASCII.GetString(Buffer);
                                if (value == "stop")
                                {
                                    stop = true;
                                }
                                else
                                {
                                    //Console.WriteLine(value);
                                    String[] substrings = value.Split(',');
                                    for (int i = 0; i < substrings.Length; i++)
                                    {
                                        tabVal[i] = Convert.ToInt32(substrings[i]);
                                    }
                                }
                            }
                            if (!stop)
                            {
                                /******************************************************************************************************/
                                /***************************************** ECRIRE LE CODE DE L'IA *************************************/
                                /******************************************************************************************************/

                                board.ResetFromPlatformRepresentation(tabVal, agentColor);
                                Ply ply = strategist.Run();
                                value = ply.ToString();

                                /********************************************************************************************************/
                                /********************************************************************************************************/
                                /********************************************************************************************************/

                                using (var accessor = mmf2.CreateViewAccessor())
                                {
                                    byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(value);
                                    accessor.Write(0, (ushort)Buffer.Length);
                                    accessor.WriteArray(0 + 2, Buffer, 0, Buffer.Length);
                                };
                            }
                            mutexAI.ReleaseMutex();
                            mutexStartAI.ReleaseMutex();

                            watch.Stop();
                            Debug.Assert(
                                watch.ElapsedMilliseconds < 250,
                                "IA took " + watch.ElapsedMilliseconds.ToString() + " which is more than 250ms to decide"
                                );
                        }
                    }
                }
            }
            catch (FileNotFoundException)
            {
                Console.WriteLine("Memory-mapped file does not exist. Run Process A first.");
                Console.ReadLine();
            }

#if DEBUG
            Console.ReadLine();
#endif
        }
Пример #23
0
        public void ply(Ply p)
        {
            if (p.lastPly)
            {
                endGame = true;
            }

            int?testdep = p.from.getPosMailBox();
            int?testarr = p.to.getPosMailBox();

            int dep = 0;
            int arr = 0;

            if (testdep.HasValue && testarr.HasValue)
            {
                dep = p.from.getPosMailBox();
                arr = p.to.getPosMailBox();
            }
            else
            {
                for (int i = 0; i < tabCoord.Length; i++)
                {
                    if (p.from.ToString().Equals(tabCoord[i]))
                    {
                        dep = i;
                    }
                    if (p.to.ToString().Equals(tabCoord[i]))
                    {
                        arr = i;
                    }
                }
            }

            if (piece[arr] != (int)Piece.PAWN)
            {
                if (color[arr] == (int)Color.WHITE)
                {
                    countPieceBlanche--;
                    etatPieceBlanche[piece[arr]]--;
                }
                else if (color[arr] == (int)Color.BLACK)
                {
                    countPieceNoir--;
                    etatPieceNoir[piece[arr]]--;
                }
            }

            color[arr] = color[dep];
            color[dep] = (int)Color.NONE;

            piece[arr] = piece[dep];
            piece[dep] = (int)Color.NONE;

            //TODO
            //C'est un double saut qui genere une case en passant
            if (p.captureEnPassant != null && !p.captureEP)
            {
                //Si EP est deja set, c'est celui du tour d'avant donc on peut l'ecraser
                int caseEnPassant = p.captureEnPassant.getPosMailBox();
                color[caseEnPassant] = (int)Color.PAWN_EN_PASSANT;
                ep = arr;
            }
            else if (p.captureEnPassant != null && p.captureEP)
            {
                Debug.Assert(ep.HasValue, "On mange un pion via EP mais aucuns pions associe à la piece");
                //On mange un pion via la case en passant
                color[ep.Value] = (int)Color.NONE;
                piece[ep.Value] = (int)Color.NONE;
                ep = null;
            }

            if (p.captureEnPassant == null && this.ep.HasValue)
            {
                //Si on fait un mouvement et qu'il y a un EP alors on reset le EP (il est valable qu'un tour)
                int?caseEnPassant = null;
                //Il faut trouver le pion associé
                if (tabPos[ep.Value] >= 51 && tabPos[ep.Value] <= 58)
                {
                    //Noir
                    caseEnPassant = Mailbox.tab120[Mailbox.tabPos[ep.Value] + Mailbox.offset[0, 0]];
                }
                else if (tabPos[ep.Value] >= 61 && tabPos[ep.Value] <= 68)
                {
                    //blanc
                    caseEnPassant = Mailbox.tab120[Mailbox.tabPos[ep.Value] - Mailbox.offset[0, 0]];
                }

                Debug.Assert(caseEnPassant.HasValue, "Il y a une case en passant qui n'est pas au bon endroit " + tabCoord[ep.Value]);

                color[caseEnPassant.Value] = (int)Color.NONE;

                ep = null;
            }


            //Je sais pas trop l'impacte ici
            if (p.promotion != null)
            {
                piece[arr] = p.promotion.piece;
            }

            if (p.castlingKingSide)
            {
                //TODO -- qqch à faire la ? Vu qu'on a depart et arrivé ?
            }
            if (p.castlingQueenSide)
            {
                //TODO -- qqch à faire la ? Vu qu'on a depart et arrivé ?
            }
        }