Ejemplo n.º 1
0
        public Play(IEnumerable <Move> moves)
        {
            this.moves    = new List <Move>();
            this.comparer = new MoveComparer();

            foreach (Move move in moves)
            {
                Add(move);
            }
        }
        public void MoveComparer_Compare_MeleeAttack_To_RangedAttack_Should_Return_Negative(PossibleMoves meleeAttack, PossibleMoves rangedAttack)
        {
            // Arrange
            var moveComparer = new MoveComparer();

            // Act
            var result = moveComparer.Compare(meleeAttack, rangedAttack);

            // Assert
            result.Should().BePositive();
        }
        public void MoveComparer_Compare_SelfDestructing_To_MeleeAttacking_Should_Return_Negative(PossibleMoves selfDestructing, PossibleMoves meleeAttacking)
        {
            // Arrange
            var moveComparer = new MoveComparer();

            // Act
            var result = moveComparer.Compare(selfDestructing, meleeAttacking);

            // Assert
            result.Should().BePositive();
        }
        public void MoveComparer_Compare_Walking_To_Teleporting_Should_Return_Negative(PossibleMoves walking, PossibleMoves teleporting)
        {
            // Arrange
            var moveComparer = new MoveComparer();

            // Act
            var result = moveComparer.Compare(walking, teleporting);

            // Assert
            result.Should().BePositive();
        }
        public void MoveComparer_Compare_Identical_PossibleMoves_Should_Return_Zero(PossibleMoves move)
        {
            // Arrange
            var moveComparer = new MoveComparer();

            // Act
            var result = moveComparer.Compare(move, move);

            // Assert
            result.Should().BeZero();
        }
Ejemplo n.º 6
0
 public Play()
 {
     this.moves    = new List <Move>();
     this.comparer = new MoveComparer();
 }
Ejemplo n.º 7
0
        private int NegaQuiet(int alfa, int beta, int ply, int depth)
        {
            int         alfaOriginal = alfa;
            int         valor;
            List <Move> moves = new List <Move>();
            bool        check;
            ulong       chaveLocal = tabuleiro.getChave();
            bool        moveu      = false;

            unsafe
            {
                if ((!temporizador.IsAlive) || (*bParar))
                {
                    return(0);
                }
            }

            this.nodes++;
            Tuple <bool, TranspItem> retorno = tabela.recuperar(chaveLocal, 0, age);

            //          if (chaveLocal == 12841783601964796451)
            //              tabuleiro.print();

            if (retorno.Item1)
            {
                this.hits++;
                if (retorno.Item2.tipo == tipoTranspItem.SCORE_EXATO)
                {
                    return(retorno.Item2.score);
                }
                else if (retorno.Item2.tipo == tipoTranspItem.SCORE_UPPER)
                {
                    beta = Math.Min(beta, retorno.Item2.score);
                }
                else if (retorno.Item2.tipo == tipoTranspItem.SCORE_LOWER)
                {
                    alfa = Math.Max(alfa, retorno.Item2.score);
                }
                if (alfa > beta)
                {
                    return(retorno.Item2.score);
                }
            }
            valor = -99999999;

            this.quiesNodes++;



            MoveComparer comparador = new MoveComparer();

            if (ply == 0)
            {
                return(this.avaliador.avaliar(tabuleiro));
            }
            check = tabuleiro.isChecked();

            moves = tabuleiro.gerarMovimentos(moves, !check);

            if ((moves.Count == 0) && (!check))
            {
                return(this.avaliador.avaliar(tabuleiro));
            }
            else if ((moves.Count == 0) && (check))
            {
                return(-(RESULT_CHECKMATE - depth));
            }
            //            Console.Out.WriteLine("-------------------------ANTES");
            //            foreach (Move move in moves)
            //                move.print();

            moves.Sort(comparador);
            //            Console.Out.WriteLine("-------------------------");
            //            foreach (Move move in moves)
            //               move.print();
            //tabuleiro.print();
            foreach (Move move in moves)
            {
                //   move.print();
                unsafe
                {
                    if ((!temporizador.IsAlive) || (*bParar))
                    {
                        return(0);
                    }
                }
                this.tabuleiro.makeMove(move);
                if (!tabuleiro.isValido())
                {
                    //  this.tabuleiro.print();
                    this.tabuleiro.unmakeMove(move);
#if DEBUG
                    if (chaveLocal != tabuleiro.getChave())
                    {
                        chaveLocal = 0;
                    }
#endif
                }
                else
                {
                    moveu = true;
                    valor = Math.Max(valor, -NegaQuiet(-beta, -alfa, ply - 1, depth + 1));

                    if (valor > alfa)
                    {
                        alfa = valor;
                    }
                    if (alfa > beta)
                    {
#if DEBUG
//                        if (chaveLocal != tabuleiro.getChave())
//                            chaveLocal = 0;
#endif

                        tabuleiro.unmakeMove(move);

                        break;
                    }
                    tabuleiro.unmakeMove(move);
#if DEBUG
                    if (chaveLocal != tabuleiro.getChave())
                    {
                        Console.Out.WriteLine("Errooooo");
                        move.print();
                        tabuleiro.print();
                    }
#endif
                }
            }
            if ((check) && (!moveu))
            {
                return(-(RESULT_CHECKMATE - depth));
            }
            else if (!moveu)
            {
                return(this.avaliador.avaliar(tabuleiro));
            }
            return(alfa);
        }
Ejemplo n.º 8
0
        private int Nega(int alfa, int beta, int ply, int depth)
        {
            int          alfaOriginal = alfa;
            int          valor;
            int          melhorValor;
            Move         melhorMov = new Move();
            List <Move>  moves     = new List <Move>();
            Queue <Move> atrasados = new Queue <Move>();
            ulong        moveHash  = 0;
            bool         check;
            bool         visitado   = false;
            ulong        chaveLocal = tabuleiro.getChave();

            unsafe
            {
                if ((!temporizador.IsAlive) || (*bParar))
                {
                    return(0);
                }
            }

            this.nodes++;
//                       if (chaveLocal == 13861742866784470756)
//                           tabuleiro.print();
            Tuple <bool, TranspItem> retorno = tabela.recuperar(chaveLocal, ply, age);

            if (retorno.Item1)
            {
                this.hits++;
                if (depth == 0)
                {
                    melhorMov = retorno.Item2.move;
                    this.move = melhorMov;
                }
                if (retorno.Item2.tipo == tipoTranspItem.SCORE_EXATO)
                {
                    return(retorno.Item2.score);
                }
                else if (retorno.Item2.tipo == tipoTranspItem.SCORE_UPPER)
                {
                    beta = Math.Min(beta, retorno.Item2.score);
                }
                else if (retorno.Item2.tipo == tipoTranspItem.SCORE_LOWER)
                {
                    alfa = Math.Max(alfa, retorno.Item2.score);
                }
                if (alfa > beta)
                {
                    return(retorno.Item2.score);
                }
                if ((retorno.Item2.move != null) && (retorno.Item2.move.tipo != tipoMovimento.MOVNENHUM))
                {
                    retorno.Item2.move.score = bbConstants.SCORE_MOVE_HASH;
                    moves.Add(retorno.Item2.move);
                    moveHash = tabela.moveHash(retorno.Item2.move);
                }
            }
            else if ((retorno.Item2 != null) && (retorno.Item2.move != null) && (retorno.Item2.move.tipo != tipoMovimento.MOVNENHUM))
            {
                retorno.Item2.move.score = bbConstants.SCORE_MOVE_HASH;
                moves.Add(retorno.Item2.move);
                moveHash = tabela.moveHash(retorno.Item2.move);
            }
            valor       = -99999999;
            melhorValor = -99999999;
            check       = tabuleiro.isChecked();
            if (check)
            {
                ply++;
            }
//            if (ply == 0)
//                return avaliador.avaliar(tabuleiro);

            MoveComparer comparador = new MoveComparer();

            moves = tabuleiro.gerarMovimentos(moves, false);
//            Console.Out.WriteLine("-------------------------ANTES");
//            foreach (Move move in moves)
//                move.print();
            moves.Sort(comparador);
//            Console.Out.WriteLine("-------------------------");
//            foreach (Move move in moves)
//               move.print();
            // if (chaveLocal == 10541650143722217845)
            // {
            //     tabuleiro.print();
            // chaveLocal = tabuleiro.getChave();
            //}
            do
            {
                if (atrasados.Count != 0)
                {
                    moves = new List <Move>();
                    while (atrasados.Count > 0)
                    {
                        moves.Add(atrasados.Dequeue());
                    }
                }
                foreach (Move move in moves)
                {
                    if ((visitado) && (moveHash == tabela.moveHash(move)))
                    {
                        continue;
                    }
                    unsafe
                    {
                        if ((!temporizador.IsAlive) || (*bParar))
                        {
                            return(0);
                        }
                    }
                    if (!tabela.verificaSeBuscado(id, chaveLocal, tabela.moveHash(move), ply))
                    {
                        atrasados.Enqueue(move);
                        continue;
                    }
                    //if (ply == this.maxPly)
                    //    tabuleiro.print();
                    // move.print();
                    //move.print(ply,10);
//                    if ((move.peca == tipoPeca.BISPO) && (chaveLocal == 15571111703642359256))
//                        Thread.Sleep(1);
                    this.tabuleiro.makeMove(move);
                    //tabuleiro.print();
                    if (!tabuleiro.isValido())
                    {
                        this.tabuleiro.unmakeMove(move);
                        tabela.retiraMov(id, ply);
                    }
                    else
                    {
                        if (ply > 1)
                        {
                            valor = -Nega(-beta, -alfa, ply - 1, depth + 1);
                        }
                        else
                        {
                            valor = -NegaQuiet(-beta, -alfa, QUIES_PLY, depth + 1);
                        }
                        if (valor > melhorValor)
                        {
                            melhorMov   = move;
                            melhorValor = valor;
                        }
                        if (valor > alfa)
                        {
                            alfa = valor;
                        }
                        if (alfa > beta)
                        {
                            tabuleiro.unmakeMove(move);
                            tabela.retiraMov(id, ply);
                            atrasados.Clear();
                            //   if (chaveLocal != tabuleiro.getChave())
                            //   {
                            //       move.print();
                            //       tabuleiro.print();
                            //   }
                            break;
                        }
                        tabuleiro.unmakeMove(move);
                        tabela.retiraMov(id, ply);
                        // if (chaveLocal != tabuleiro.getChave())
                        // {
                        //     tabuleiro.print();
                        //     move.print();
                        // }
                    }
                    visitado = visitado || tabela.moveHash(move) == moveHash;
                }
            } while (atrasados.Count != 0);


            if (melhorMov.tipo == tipoMovimento.MOVNENHUM)
            {
                if (check)
                {
                    return(-(RESULT_CHECKMATE - depth));
                }
                else
                {
                    return(RESULT_STALEMATE);
                }
            }

            if (depth == 0)
            {
                unsafe
                {
                    if ((temporizador.IsAlive) && (!*bParar))
                    {
                        this.move = melhorMov;
                    }
                }
            }
            if (check)
            {
                ply--;
            }

            TranspItem itemT = new TranspItem();

            itemT.move  = melhorMov;
            itemT.idade = age;
            itemT.score = melhorValor;
            itemT.chave = chaveLocal;
            itemT.ply   = ply;

            if (alfa <= alfaOriginal)
            {
                itemT.tipo = tipoTranspItem.SCORE_UPPER;
            }
            else if (alfa > beta)
            {
                itemT.tipo = tipoTranspItem.SCORE_LOWER;
            }
            else
            {
                itemT.tipo = tipoTranspItem.SCORE_EXATO;
            }

            tabela.armazenar(itemT);

            return(melhorValor);
        }