示例#1
0
        //----------------------------------------------------------------------------------------
        public static int Enroques(cPosicion pos, cMov[] mlist, int mPos, color us, cInfoJaque ci, enroque Cr, bool Checks, bool Chess960)
        {
            bool KingSide = (Cr==cEnroque.OO_BLANCAS||Cr==cEnroque.OO_NEGRAS);

              if(pos.CanNotEnroque(Cr)||0==pos.PosibleEnrocar(Cr))
            return mPos;

              sq kfrom = pos.GetRey(us);
              sq rfrom = pos.CasillaTorreEnroque(Cr);
              sq kto = cTypes.CasillaProxima(us, KingSide ? cCasilla.G1 : cCasilla.C1);
              bitbrd enemies = pos.PiezasColor(cTypes.Contrario(us));

              sq K = Chess960 ? kto>kfrom ? cCasilla.OESTE : cCasilla.ESTE : KingSide ? cCasilla.OESTE : cCasilla.ESTE;

              for(sq s = kto; s!=kfrom; s+=K)
            if((pos.AtaquesA(s)&enemies)!=0)
              return mPos;

              if(Chess960&&(cBitBoard.AtaquesPieza(kto, pos.Piezas()^cBitBoard.m_nCasillas[rfrom], cPieza.TORRE)&pos.PiezasColor(cTypes.Contrario(us), cPieza.TORRE, cPieza.DAMA))!=0)
            return mPos;

              mov m = cTypes.CreaMov(kfrom, rfrom, cMovType.ENROQUE, cPieza.CABALLO);

              if(Checks&&!pos.IsJaque(m, ci))
            return mPos;

              mlist[mPos++].m=m;

              return mPos;
        }
示例#2
0
        public static val search(cPosicion pos, cStackMov[] ss, int ssPos, val alpha, val beta, ply depth, bool cutNode, NodeType NT, bool SpNode)
        {
            bool RootNode = (NT == cTipoNodo.RAIZ);
              bool PvNode = (NT == cTipoNodo.PV || NT == cTipoNodo.RAIZ);
              mov[] quietsSearched = new mov[64];
              cPosInfo st = new cPosInfo();
              cTablaHashStruct tte;
              cSplitPoint splitPoint = null;
              hash posKey = 0;
              mov ttMove, move, excludedMove, bestMove;
              ply ext, newDepth, predictedDepth;
              val bestValue, value, ttValue, eval, nullValue, futilityValue;
              bool inCheck, givesCheck, pvMove, singularExtensionNode, improving;
              bool captureOrPromotion, dangerous, doFullDepthSearch;
              int moveCount = 0, quietCount = 0;

              cThread thisThread = pos.ThreadActive();
              inCheck = pos.Jaques() != 0;
              if (SpNode)
              {
            splitPoint = ss[ssPos].splitPoint;
            bestMove = splitPoint.bestMove;
            bestValue = splitPoint.bestValue;
            tte = null;
            ttMove = excludedMove = cMovType.MOV_NAN;
            ttValue = cValoresJuego.NAN;
            goto moves_loop;
              }
              moveCount = quietCount = 0;
              bestValue = -cValoresJuego.INFINITO;
              ss[ssPos].currentMove = ss[ssPos].ttMove = ss[ssPos + 1].excludedMove = bestMove = cMovType.MOV_NAN;
              ss[ssPos].ply = ss[ssPos - 1].ply + 1;
              ss[ssPos + 1].skipNullMove = 0;
              ss[ssPos + 1].reduction = cPly.DEPTH_ZERO;
              ss[ssPos + 2].killers0 = ss[ssPos + 2].killers1 = cMovType.MOV_NAN;

              if (PvNode && thisThread.m_nMaxPly < ss[ssPos].ply)
            thisThread.m_nMaxPly = ss[ssPos].ply;
              if (!RootNode)
              {

            if (Signals.STOP || pos.IsTablas() || ss[ssPos].ply > cSearch.MAX_PLY)
              return ss[ssPos].ply > cSearch.MAX_PLY && !inCheck ? cEval.Eval(pos) : DrawValue[pos.ColorMueve()];

            alpha = Math.Max(cTypes.MateEnVs(ss[ssPos].ply), alpha);
            beta = Math.Min(cTypes.MateEn(ss[ssPos].ply + 1), beta);
            if (alpha >= beta)
              return alpha;
              }

              excludedMove = ss[ssPos].excludedMove;
              posKey = excludedMove != 0 ? pos.GetClaveHashExclusion() : pos.ClaveHash();
              tte = cMotor.m_TablaHash.Buscar(posKey);
              ss[ssPos].ttMove = ttMove = RootNode ? RootMoves[PVIdx].m_PV[0] : tte != null ? tte.GetMove() : cMovType.MOV_NAN;
              ttValue = (tte != null) ? value_from_tt(tte.GetValue(), ss[ssPos].ply) : cValoresJuego.NAN;

              if (!RootNode
              && tte != null
              && tte.GetDepth() >= depth
              && ttValue != cValoresJuego.NAN
              && (PvNode ? tte.GetBound() == cBordes.BOUND_EXACT
              : ttValue >= beta ? (tte.GetBound() & cBordes.BOUND_LOWER) != 0
                                : (tte.GetBound() & cBordes.BOUND_UPPER) != 0))
              {
            ss[ssPos].currentMove = ttMove;

            if (ttValue >= beta && ttMove != 0 && !pos.IsCapturaOrPromocion(ttMove) && !inCheck)
              update_stats(pos, ss, ssPos, ttMove, depth, null, 0);
            return ttValue;
              }

              if (inCheck)
              {
            ss[ssPos].staticEval = eval = cValoresJuego.NAN;
            goto moves_loop;
              }
              else if (tte != null)
              {

            if ((ss[ssPos].staticEval = eval = tte.GetValueEval()) == cValoresJuego.NAN)
              eval = ss[ssPos].staticEval = cEval.Eval(pos);

            if (ttValue != cValoresJuego.NAN)
              if ((tte.GetBound() & (ttValue > eval ? cBordes.BOUND_LOWER : cBordes.BOUND_UPPER)) != 0)
            eval = ttValue;
              }
              else
              {
            eval = ss[ssPos].staticEval = cEval.Eval(pos);
            cMotor.m_TablaHash.Save(posKey, cValoresJuego.NAN, cBordes.BOUND_NONE, cPly.DEPTH_NONE, cMovType.MOV_NAN, ss[ssPos].staticEval);
              }
              if (0 == pos.GetTipoPiezaCapturada()
              && ss[ssPos].staticEval != cValoresJuego.NAN
              && ss[ssPos - 1].staticEval != cValoresJuego.NAN
              && (move = ss[ssPos - 1].currentMove) != cMovType.MOV_NULO
              && cTypes.TipoMovimiento(move) == cMovType.NORMAL)
              {
            sq to = cTypes.GetToCasilla(move);
            Gains.Fill(pos.GetPieza(to), to, -ss[ssPos - 1].staticEval - ss[ssPos].staticEval);
              }

              if (!PvNode
              && depth < 4 * cPly.ONE_PLY
              && eval + razor_margin(depth) <= beta
              && ttMove == cMovType.MOV_NAN
              && Math.Abs(beta) < cValoresJuego.MATE_MAXIMO
              && !pos.IsPeonOn7(pos.ColorMueve())
              )
              {
            if (depth <= cPly.ONE_PLY
            && eval + razor_margin(3 * cPly.ONE_PLY) <= alpha)
              return qsearch(pos, ss, ssPos, alpha, beta, cPly.DEPTH_ZERO, cTipoNodo.NO_PV, false);
            val ralpha = alpha - razor_margin(depth);
            val v = qsearch(pos, ss, ssPos, ralpha, ralpha + 1, cPly.DEPTH_ZERO, cTipoNodo.NO_PV, false);
            if (v <= ralpha)
              return v;
              }

              if (!PvNode
              && 0 == ss[ssPos].skipNullMove
              && depth < 7 * cPly.ONE_PLY
              && eval - futility_margin(depth) >= beta
              && Math.Abs(beta) < cValoresJuego.MATE_MAXIMO
              && Math.Abs(eval) < cValoresJuego.GANA
              && pos.MaterialPieza(pos.ColorMueve()) != 0)
            return eval - futility_margin(depth);

              if (!PvNode
              && 0 == ss[ssPos].skipNullMove
              && depth >= 2 * cPly.ONE_PLY
              && eval >= beta
              && Math.Abs(beta) < cValoresJuego.MATE_MAXIMO
              && pos.MaterialPieza(pos.ColorMueve()) != 0)
              {
            ss[ssPos].currentMove = cMovType.MOV_NULO;

            ply R = 3 * cPly.ONE_PLY
             + depth / 4
             + (eval - beta) / cValoresJuego.PEON_MJ * cPly.ONE_PLY;
            pos.DoNullMov(st);
            ss[ssPos + 1].skipNullMove = 1;
            nullValue = depth - R < cPly.ONE_PLY ? -qsearch(pos, ss, ssPos + 1, -beta, -beta + 1, cPly.DEPTH_ZERO, cTipoNodo.NO_PV, false)
                              : -search(pos, ss, ssPos + 1, -beta, -beta + 1, depth - R, !cutNode, cTipoNodo.NO_PV, false);
            ss[ssPos + 1].skipNullMove = 0;
            pos.undo_null_move();
            if (nullValue >= beta)
            {

              if (nullValue >= cValoresJuego.MATE_MAXIMO)
            nullValue = beta;
              if (depth < 12 * cPly.ONE_PLY)
            return nullValue;

              ss[ssPos].skipNullMove = 1;
              val v = depth - R < cPly.ONE_PLY ? qsearch(pos, ss, ssPos, beta - 1, beta, cPly.DEPTH_ZERO, cTipoNodo.NO_PV, false)
                              : search(pos, ss, ssPos, beta - 1, beta, depth - R, false, cTipoNodo.NO_PV, false);
              ss[ssPos].skipNullMove = 0;
              if (v >= beta)
            return nullValue;
            }
              }

              if (!PvNode
              && depth >= 5 * cPly.ONE_PLY
              && 0 == ss[ssPos].skipNullMove
              && Math.Abs(beta) < cValoresJuego.MATE_MAXIMO)
              {
            val rbeta = Math.Min(beta + 200, cValoresJuego.INFINITO);
            ply rdepth = depth - 4 * cPly.ONE_PLY;
            cMovOrder mp2 = new cMovOrder(pos, ttMove, History, pos.GetTipoPiezaCapturada());
            cInfoJaque ci2 = new cInfoJaque(pos);
            while ((move = mp2.SiguienteMovimientoEnFalso()) != cMovType.MOV_NAN)
              if (pos.IsLegalMov(move, ci2.m_Clavadas))
              {
            ss[ssPos].currentMove = move;
            pos.DoMov(move, st, ci2, pos.IsJaque(move, ci2));
            value = -search(pos, ss, ssPos + 1, -rbeta, -rbeta + 1, rdepth, !cutNode, cTipoNodo.NO_PV, false);
            pos.DesMov(move);
            if (value >= rbeta)
              return value;
              }
              }

              if (depth >= (PvNode ? 5 * cPly.ONE_PLY : 8 * cPly.ONE_PLY)
              && 0 == ttMove
              && (PvNode || (ss[ssPos].staticEval + 256 >= beta)))
              {
            ply d = depth - 2 * cPly.ONE_PLY - (PvNode ? cPly.DEPTH_ZERO : depth / 4);
            ss[ssPos].skipNullMove = 1;
            search(pos, ss, ssPos, alpha, beta, d, true, PvNode ? cTipoNodo.PV : cTipoNodo.NO_PV, false);
            ss[ssPos].skipNullMove = 0;
            tte = cMotor.m_TablaHash.Buscar(posKey);
            ttMove = (tte != null) ? tte.GetMove() : cMovType.MOV_NAN;
              }
            moves_loop:
              sq prevMoveSq = cTypes.GetToCasilla(ss[ssPos - 1].currentMove);
              mov[] countermoves = { Countermoves[pos.GetPieza(prevMoveSq)][prevMoveSq].m_Key1,
                                    Countermoves[pos.GetPieza(prevMoveSq)][prevMoveSq].m_Key2 };
              sq prevOwnMoveSq = cTypes.GetToCasilla(ss[ssPos - 2].currentMove);
              mov[] followupmoves = {Followupmoves[pos.GetPieza(prevOwnMoveSq)][prevOwnMoveSq].m_Key1,
                                    Followupmoves[pos.GetPieza(prevOwnMoveSq)][prevOwnMoveSq].m_Key2 };
              cMovOrder mp = new cMovOrder(pos, ttMove, depth, History, countermoves, followupmoves, ss[ssPos]);
              cInfoJaque ci = new cInfoJaque(pos);
              value = bestValue;
              improving = ss[ssPos].staticEval >= ss[ssPos - 2].staticEval
             || ss[ssPos].staticEval == cValoresJuego.NAN
             || ss[ssPos - 2].staticEval == cValoresJuego.NAN;
              singularExtensionNode = !RootNode
                             && !SpNode
                             && depth >= 8 * cPly.ONE_PLY
                             && ttMove != cMovType.MOV_NAN
                             && 0 == excludedMove
                             && (tte.GetBound() & cBordes.BOUND_LOWER) != 0
                             && tte.GetDepth() >= depth - 3 * cPly.ONE_PLY;

              while ((move = (SpNode ? mp.SiguienteMovimiento() : mp.SiguienteMovimientoEnFalso())) != cMovType.MOV_NAN)
              {
            if (move == excludedMove)
              continue;

            if (RootNode && (Buscar(RootMoves, PVIdx, RootMoves.Count, move) == -1))
              continue;
            if (SpNode)
            {

              if (!pos.IsLegalMov(move, ci.m_Clavadas))
            continue;
              moveCount = ++splitPoint.moveCount;
              splitPoint.mutex.Liberar();
            }
            else
              ++moveCount;
            if (RootNode)
            {
              Signals.FIRST_MOVE = (moveCount == 1);

            }
            ext = cPly.DEPTH_ZERO;
            captureOrPromotion = pos.IsCapturaOrPromocion(move);
            givesCheck = cTypes.TipoMovimiento(move) == cMovType.NORMAL && 0 == ci.m_Candidatas
              ? (ci.m_Jaque[cTypes.TipoPieza(pos.GetPieza(cTypes.GetFromCasilla(move)))] & cBitBoard.m_nCasillas[cTypes.GetToCasilla(move)]) != 0
              : pos.IsJaque(move, ci);
            dangerous = givesCheck
             || cTypes.TipoMovimiento(move) != cMovType.NORMAL
             || pos.IsPeonAvanzado(move);

            if (givesCheck && pos.SEEReducido(move) >= cValoresJuego.CERO)
              ext = cPly.ONE_PLY;

            if (singularExtensionNode
            && move == ttMove
            && 0 == ext
            && pos.IsLegalMov(move, ci.m_Clavadas)
            && Math.Abs(ttValue) < cValoresJuego.GANA)
            {
              val rBeta = ttValue - depth;
              ss[ssPos].excludedMove = move;
              ss[ssPos].skipNullMove = 1;
              value = search(pos, ss, ssPos, rBeta - 1, rBeta, depth / 2, cutNode, cTipoNodo.NO_PV, false);
              ss[ssPos].skipNullMove = 0;
              ss[ssPos].excludedMove = cMovType.MOV_NAN;
              if (value < rBeta)
            ext = cPly.ONE_PLY;
            }

            newDepth = depth - cPly.ONE_PLY + ext;

            if (!PvNode
            && !captureOrPromotion
            && !inCheck
            && !dangerous
            && bestValue > cValoresJuego.MATE_MAXIMO_VS)
            {

              if (depth < 16 * cPly.ONE_PLY && moveCount >= FutilityMoveCounts[improving ? 1 : 0][depth])
              {
            if (SpNode)
              splitPoint.mutex.Bloquear();
            continue;
              }
              predictedDepth = newDepth - reduction(improving ? 1 : 0, depth, moveCount, PvNode ? 1 : 0);

              if (predictedDepth < 7 * cPly.ONE_PLY)
              {
            futilityValue = ss[ssPos].staticEval + futility_margin(predictedDepth)
                        + 128 + Gains[pos.GetPiezaMovida(move)][cTypes.GetToCasilla(move)];
            if (futilityValue <= alpha)
            {
              bestValue = Math.Max(bestValue, futilityValue);
              if (SpNode)
              {
                splitPoint.mutex.Bloquear();
                if (bestValue > splitPoint.bestValue)
                  splitPoint.bestValue = bestValue;
              }
              continue;
            }
              }

              if (predictedDepth < 4 * cPly.ONE_PLY && pos.SEEReducido(move) < cValoresJuego.CERO)
              {
            if (SpNode)
              splitPoint.mutex.Bloquear();
            continue;
              }
            }

            if (!RootNode && !SpNode && !pos.IsLegalMov(move, ci.m_Clavadas))
            {
              moveCount--;
              continue;
            }
            pvMove = PvNode && moveCount == 1;
            ss[ssPos].currentMove = move;
            if (!SpNode && !captureOrPromotion && quietCount < 64)
              quietsSearched[quietCount++] = move;

            pos.DoMov(move, st, ci, givesCheck);

            if (depth >= 3 * cPly.ONE_PLY
            && !pvMove
            && !captureOrPromotion
            && move != ttMove
            && move != ss[ssPos].killers0
            && move != ss[ssPos].killers1)
            {
              ss[ssPos].reduction = reduction(improving ? 1 : 0, depth, moveCount, PvNode ? 1 : 0);
              if (!PvNode && cutNode)
            ss[ssPos].reduction += cPly.ONE_PLY;
              else if (History[pos.GetPieza(cTypes.GetToCasilla(move))][cTypes.GetToCasilla(move)] < 0)
            ss[ssPos].reduction += cPly.ONE_PLY / 2;
              if (move == countermoves[0] || move == countermoves[1])
            ss[ssPos].reduction = Math.Max(cPly.DEPTH_ZERO, ss[ssPos].reduction - cPly.ONE_PLY);
              ply d = Math.Max(newDepth - ss[ssPos].reduction, cPly.ONE_PLY);
              if (SpNode)
            alpha = splitPoint.alpha;
              value = -search(pos, ss, ssPos + 1, -(alpha + 1), -alpha, d, true, cTipoNodo.NO_PV, false);

              if (value > alpha && ss[ssPos].reduction >= 4 * cPly.ONE_PLY)
              {
            ply d2 = Math.Max(newDepth - 2 * cPly.ONE_PLY, cPly.ONE_PLY);
            value = -search(pos, ss, ssPos + 1, -(alpha + 1), -alpha, d2, true, cTipoNodo.NO_PV, false);
              }
              doFullDepthSearch = (value > alpha && ss[ssPos].reduction != cPly.DEPTH_ZERO);
              ss[ssPos].reduction = cPly.DEPTH_ZERO;
            }
            else
              doFullDepthSearch = !pvMove;

            if (doFullDepthSearch)
            {
              if (SpNode)
            alpha = splitPoint.alpha;
              value = newDepth < cPly.ONE_PLY ?
                givesCheck ? -qsearch(pos, ss, ssPos + 1, -(alpha + 1), -alpha, cPly.DEPTH_ZERO, cTipoNodo.NO_PV, true)
                           : -qsearch(pos, ss, ssPos + 1, -(alpha + 1), -alpha, cPly.DEPTH_ZERO, cTipoNodo.NO_PV, false)
                           : -search(pos, ss, ssPos + 1, -(alpha + 1), -alpha, newDepth, !cutNode, cTipoNodo.NO_PV, false);
            }

            if (PvNode && (pvMove || (value > alpha && (RootNode || value < beta))))
              value = newDepth < cPly.ONE_PLY ?
                        givesCheck ? -qsearch(pos, ss, ssPos + 1, -beta, -alpha, cPly.DEPTH_ZERO, cTipoNodo.PV, true)
                           : -qsearch(pos, ss, ssPos + 1, -beta, -alpha, cPly.DEPTH_ZERO, cTipoNodo.PV, false)
                           : -search(pos, ss, ssPos + 1, -beta, -alpha, newDepth, false, cTipoNodo.PV, false);

            pos.DesMov(move);

            if (SpNode)
            {
              splitPoint.mutex.Bloquear();
              bestValue = splitPoint.bestValue;
              alpha = splitPoint.alpha;
            }

            if (Signals.STOP || thisThread.IsCorte())
              return cValoresJuego.CERO;
            if (RootNode)
            {
              int rmPos = Buscar(RootMoves, 0, RootMoves.Count, move);
              cRaizMov rm = RootMoves[rmPos];

              if (pvMove || value > alpha)
              {
            rm.m_nVal = value;
            rm.extract_pv_from_tt(pos);

            if (!pvMove)
              ++BestMoveChanges;
              }
              else

            rm.m_nVal = -cValoresJuego.INFINITO;
            }
            if (value > bestValue)
            {
              bestValue = SpNode ? splitPoint.bestValue = value : value;
              if (value > alpha)
              {
            bestMove = SpNode ? splitPoint.bestMove = move : move;
            if (PvNode && value < beta)
              alpha = SpNode ? splitPoint.alpha = value : value;
            else
            {
              if (SpNode)
                splitPoint.m_bCorte = true;
              break;
            }
              }
            }

            if (!SpNode
            && cMotor.m_Threads.Count >= 2
            && depth >= cMotor.m_Threads.minimumSplitDepth
            && (null == thisThread.m_SplitPointActivo
            || !thisThread.m_SplitPointActivo.allSlavesSearching)
            && thisThread.m_nSplitPointSize < cThreadBase.MAX_SPLITPOINTS_PER_THREAD)
            {
              thisThread.Split(pos, ss, ssPos, alpha, beta, ref bestValue, ref bestMove,
                                       depth, moveCount, mp, NT, cutNode);
              if (Signals.STOP || thisThread.IsCorte())
            return cValoresJuego.CERO;
              if (bestValue >= beta)
            break;
            }
              }
              if (SpNode)
            return bestValue;

              if (0 == moveCount)
            bestValue = excludedMove != 0 ? alpha
               : inCheck ? cTypes.MateEnVs(ss[ssPos].ply) : DrawValue[pos.ColorMueve()];

              else if (bestValue >= beta && !pos.IsCapturaOrPromocion(bestMove) && !inCheck)
            update_stats(pos, ss, ssPos, bestMove, depth, quietsSearched, quietCount - 1);
              cMotor.m_TablaHash.Save(posKey, value_to_tt(bestValue, ss[ssPos].ply),
               bestValue >= beta ? cBordes.BOUND_LOWER :
               PvNode && bestMove != 0 ? cBordes.BOUND_EXACT : cBordes.BOUND_UPPER,
               depth, bestMove, ss[ssPos].staticEval);
              return bestValue;
        }
示例#3
0
        public static val qsearch(cPosicion pos, cStackMov[] ss, int ssPos, val alpha, val beta, ply depth, NodeType NT, bool InCheck)
        {
            bool PvNode = (NT == cTipoNodo.PV);
              cPosInfo st = null;
              cTablaHashStruct tte;
              hash posKey;
              mov ttMove, move, bestMove;
              val bestValue, value, ttValue, futilityValue, futilityBase, oldAlpha = 0;
              bool givesCheck, evasionPrunable;
              ply ttDepth;

              if (PvNode)
            oldAlpha = alpha;
              ss[ssPos].currentMove = bestMove = cMovType.MOV_NAN;
              ss[ssPos].ply = ss[ssPos - 1].ply + 1;

              if (pos.IsTablas() || ss[ssPos].ply > cSearch.MAX_PLY)
            return ss[ssPos].ply > cSearch.MAX_PLY && !InCheck ? cEval.Eval(pos) : DrawValue[pos.ColorMueve()];

              ttDepth = ((InCheck || depth >= cPly.DEPTH_QS_CHECKS) ? cPly.DEPTH_QS_CHECKS
                                                              : cPly.DEPTH_QS_NO_CHECKS);

              posKey = pos.ClaveHash();
              tte = cMotor.m_TablaHash.Buscar(posKey);
              ttMove = (tte != null ? tte.GetMove() : cMovType.MOV_NAN);
              ttValue = tte != null ? value_from_tt(tte.GetValue(), ss[ssPos].ply) : cValoresJuego.NAN;
              if (tte != null
              && tte.GetDepth() >= ttDepth
              && ttValue != cValoresJuego.NAN
              && (PvNode ? tte.GetBound() == cBordes.BOUND_EXACT
              : (ttValue >= beta) ? (tte.GetBound() & cBordes.BOUND_LOWER) != 0
                                : (tte.GetBound() & cBordes.BOUND_UPPER) != 0))
              {
            ss[ssPos].currentMove = ttMove;
            return ttValue;
              }

              if (InCheck)
              {
            ss[ssPos].staticEval = cValoresJuego.NAN;
            bestValue = futilityBase = -cValoresJuego.INFINITO;
              }
              else
              {
            if (tte != null)
            {

              if ((ss[ssPos].staticEval = bestValue = tte.GetValueEval()) == cValoresJuego.NAN)
            ss[ssPos].staticEval = bestValue = cEval.Eval(pos);

              if (ttValue != cValoresJuego.NAN)
            if ((tte.GetBound() & (ttValue > bestValue ? cBordes.BOUND_LOWER : cBordes.BOUND_UPPER)) != 0)
              bestValue = ttValue;
            }
            else
              ss[ssPos].staticEval = bestValue = cEval.Eval(pos);

            if (bestValue >= beta)
            {
              if (tte == null)
            cMotor.m_TablaHash.Save(pos.ClaveHash(), value_to_tt(bestValue, ss[ssPos].ply), cBordes.BOUND_LOWER,
                cPly.DEPTH_NONE, cMovType.MOV_NAN, ss[ssPos].staticEval);
              return bestValue;
            }
            if (PvNode && bestValue > alpha)
              alpha = bestValue;
            futilityBase = bestValue + 128;
              }

              cMovOrder mp = new cMovOrder(pos, ttMove, depth, History, cTypes.GetToCasilla(ss[ssPos - 1].currentMove));
              cInfoJaque ci = new cInfoJaque(pos);
              st = new cPosInfo();

              while ((move = mp.SiguienteMovimientoEnFalso()) != cMovType.MOV_NAN)
              {
            givesCheck = cTypes.TipoMovimiento(move) == cMovType.NORMAL && 0 == ci.m_Candidatas
              ? (ci.m_Jaque[cTypes.TipoPieza(pos.GetPieza(cTypes.GetFromCasilla(move)))] & cBitBoard.m_nCasillas[cTypes.GetToCasilla(move)]) != 0
              : pos.IsJaque(move, ci);

            if (!PvNode
              && !InCheck
              && !givesCheck
              && move != ttMove
              && futilityBase > -cValoresJuego.GANA
              && !pos.IsPeonAvanzado(move))
            {
              futilityValue = futilityBase + cPosicion.m_nValPieza[cFaseJuego.FASE_FINAL][pos.GetPieza(cTypes.GetToCasilla(move))];
              if (futilityValue < beta)
              {
            bestValue = Math.Max(bestValue, futilityValue);
            continue;
              }
              if (futilityBase < beta && pos.SEE(move) <= cValoresJuego.CERO)
              {
            bestValue = Math.Max(bestValue, futilityBase);
            continue;
              }
            }

            evasionPrunable = InCheck
                       && bestValue > cValoresJuego.MATE_MAXIMO_VS
                       && !pos.IsCaptura(move)
                       && 0 == pos.CanEnroque(pos.ColorMueve());

            if (!PvNode
              && (!InCheck || evasionPrunable)
              && move != ttMove
              && cTypes.TipoMovimiento(move) != cMovType.PROMOCION
              && pos.SEEReducido(move) < cValoresJuego.CERO)
              continue;

            if (!pos.IsLegalMov(move, ci.m_Clavadas))
              continue;
            ss[ssPos].currentMove = move;

            pos.DoMov(move, st, ci, givesCheck);
            value = givesCheck ? -qsearch(pos, ss, ssPos + 1, -beta, -alpha, depth - cPly.ONE_PLY, NT, true)
                            : -qsearch(pos, ss, ssPos + 1, -beta, -alpha, depth - cPly.ONE_PLY, NT, false);
            pos.DesMov(move);

            if (value > bestValue)
            {
              bestValue = value;
              if (value > alpha)
              {
            if (PvNode && value < beta)
            {
              alpha = value;
              bestMove = move;
            }
            else
            {
              cMotor.m_TablaHash.Save(posKey, value_to_tt(value, ss[ssPos].ply), cBordes.BOUND_LOWER,
                       ttDepth, move, ss[ssPos].staticEval);
              return value;
            }
              }
            }
              }

              if (InCheck && bestValue == -cValoresJuego.INFINITO)
            return cTypes.MateEnVs(ss[ssPos].ply);
              cMotor.m_TablaHash.Save(posKey, value_to_tt(bestValue, ss[ssPos].ply),
              PvNode && bestValue > oldAlpha ? cBordes.BOUND_EXACT : cBordes.BOUND_UPPER,
              ttDepth, bestMove, ss[ssPos].staticEval);
              return bestValue;
        }
示例#4
0
        //----------------------------------------------------------------------------------------
        public static int ToDO(cPosicion pos, cMov[] mlist, int mPos, bitbrd target, color us, type Type, cInfoJaque ci)
        {
            bool Checks = Type==cMovType.QUIET_CHECKS;

              mPos=Peones(pos, mlist, mPos, target, ci, us, Type);
              mPos=Piezas(pos, mlist, mPos, us, target, ci, cPieza.CABALLO, Checks);
              mPos=Piezas(pos, mlist, mPos, us, target, ci, cPieza.ALFIL, Checks);
              mPos=Piezas(pos, mlist, mPos, us, target, ci, cPieza.TORRE, Checks);
              mPos=Piezas(pos, mlist, mPos, us, target, ci, cPieza.DAMA, Checks);

              if(Type!=cMovType.QUIET_CHECKS&&Type!=cMovType.EVASIONS)
              {
            sq ksq = pos.GetRey(us);
            bitbrd b = pos.attacks_from_square_piecetype(ksq, cPieza.REY)&target;
            while(b!=0)
              mlist[mPos++].m=cTypes.CreaMov(ksq, cBitBoard.GetLSB(ref b));
              }

              if(Type!=cMovType.CAPTURES&&Type!=cMovType.EVASIONS&&pos.CanEnroque(us)!=0)
              {
            if (pos.IsChess960() != false)
            {
              mPos=Enroques(pos, mlist, mPos, us, ci, (new cEnroque(us, cEnroque.LADO_REY)).m_Tipo, Checks, true);
              mPos=Enroques(pos, mlist, mPos, us, ci, (new cEnroque(us, cEnroque.LADO_DAMA)).m_Tipo, Checks, true);
            }
            else
            {
              mPos=Enroques(pos, mlist, mPos, us, ci, (new cEnroque(us, cEnroque.LADO_REY)).m_Tipo, Checks, false);
              mPos=Enroques(pos, mlist, mPos, us, ci, (new cEnroque(us, cEnroque.LADO_DAMA)).m_Tipo, Checks, false);
            }
              }

              return mPos;
        }
示例#5
0
        //----------------------------------------------------------------------------------------
        public static int Promocion(cMov[] mlist, int mPos, bitbrd pawnsOn7, bitbrd target, cInfoJaque ci, type Type, sq Delta)
        {
            bitbrd b = cBitBoard.Desplazamiento(pawnsOn7, Delta)&target;

              while(b!=0)
              {
            sq to = cBitBoard.GetLSB(ref b);

            if(Type==cMovType.CAPTURES||Type==cMovType.EVASIONS||Type==cMovType.NON_EVASIONS)
              mlist[mPos++].m=cTypes.CreaMov(to-Delta, to, cMovType.PROMOCION, cPieza.DAMA);

            if(Type==cMovType.QUIETS||Type==cMovType.EVASIONS||Type==cMovType.NON_EVASIONS)
            {
              mlist[mPos++].m=cTypes.CreaMov(to-Delta, to, cMovType.PROMOCION, cPieza.TORRE);
              mlist[mPos++].m=cTypes.CreaMov(to-Delta, to, cMovType.PROMOCION, cPieza.ALFIL);
              mlist[mPos++].m=cTypes.CreaMov(to-Delta, to, cMovType.PROMOCION, cPieza.CABALLO);
            }

            if(Type==cMovType.QUIET_CHECKS&&(cBitBoard.m_Ataques[cPieza.CABALLO_BLANCO][to]&cBitBoard.m_nCasillas[ci.m_SqRey])!=0)
              mlist[mPos++].m=cTypes.CreaMov(to-Delta, to, cMovType.PROMOCION, cPieza.CABALLO);
              }

              return mPos;
        }
示例#6
0
        //----------------------------------------------------------------------------------------
        public static int Piezas(cPosicion pos, cMov[] mlist, int mPos, color us, bitbrd target, cInfoJaque ci, type Pt, bool Checks)
        {
            sq[] pieceList = pos.GetList(us, Pt);
              int pl = 0;

              for(sq from = pieceList[pl]; from!=cCasilla.NONE; from=pieceList[++pl])
              {
            if(Checks)
            {
              if((Pt==cPieza.ALFIL||Pt==cPieza.TORRE||Pt==cPieza.DAMA)
              &&0==(cBitBoard.m_PseudoAtaques[Pt][from]&target&ci.m_Jaque[Pt]))
            continue;

              if(ci.m_Candidatas!=0&&(ci.m_Candidatas&cBitBoard.m_nCasillas[from])!=0)
            continue;
            }

            bitbrd b = pos.attacks_from_square_piecetype(from, Pt)&target;

            if(Checks)
              b&=ci.m_Jaque[Pt];

            while(b!=0)
              mlist[mPos++].m=cTypes.CreaMov(from, cBitBoard.GetLSB(ref b));
              }

              return mPos;
        }
示例#7
0
        //----------------------------------------------------------------------------------------
        public static int Peones(cPosicion pos, cMov[] mlist, int mPos, bitbrd target, cInfoJaque ci, color colr, type Type)
        {
            color colorVS = (colr==cColor.BLANCO ? cColor.NEGRO : cColor.BLANCO);
              bitbrd TRank8BB = (colr==cColor.BLANCO ? cBitBoard.F8 : cBitBoard.F1);
              bitbrd TRank7BB = (colr==cColor.BLANCO ? cBitBoard.F7 : cBitBoard.F2);
              bitbrd TRank3BB = (colr==cColor.BLANCO ? cBitBoard.F3 : cBitBoard.F6);
              sq Up = (colr==cColor.BLANCO ? cCasilla.NORTE : cCasilla.SUR);
              sq Right = (colr==cColor.BLANCO ? cCasilla.NORTE_ESTE : cCasilla.SUR_OESTE);
              sq Left = (colr==cColor.BLANCO ? cCasilla.NORTE_OESTE : cCasilla.SUR_ESTE);

              bitbrd b1, b2, dc1, dc2, emptySquares = 0;

              bitbrd pawnsOn7 = pos.PiezasColor(colr, cPieza.PEON)&TRank7BB;
              bitbrd pawnsNotOn7 = pos.PiezasColor(colr, cPieza.PEON)&~TRank7BB;

              bitbrd enemies = (Type==cMovType.EVASIONS ? pos.PiezasColor(colorVS)&target :
                          Type==cMovType.CAPTURES ? target : pos.PiezasColor(colorVS));

              if(Type!=cMovType.CAPTURES)
              {
            emptySquares=(Type==cMovType.QUIETS||Type==cMovType.QUIET_CHECKS ? target : ~pos.Piezas());

            b1=cBitBoard.Desplazamiento(pawnsNotOn7, Up)&emptySquares;
            b2=cBitBoard.Desplazamiento(b1&TRank3BB, Up)&emptySquares;

            if(Type==cMovType.EVASIONS)
            {
              b1&=target;
              b2&=target;
            }

            if(Type==cMovType.QUIET_CHECKS)
            {
              b1&=pos.AtaquesDePeon(ci.m_SqRey, colorVS);
              b2&=pos.AtaquesDePeon(ci.m_SqRey, colorVS);

              if((pawnsNotOn7&ci.m_Candidatas)!=0)
              {
            dc1=cBitBoard.Desplazamiento(pawnsNotOn7&ci.m_Candidatas, Up)&emptySquares&~cBitBoard.GetColumnaSq(ci.m_SqRey);
            dc2=cBitBoard.Desplazamiento(dc1&TRank3BB, Up)&emptySquares;

            b1|=dc1;
            b2|=dc2;
              }
            }

            while(b1!=0)
            {
              sq to = cBitBoard.GetLSB(ref b1);
              mlist[mPos++].m=cTypes.CreaMov(to-Up, to);
            }

            while(b2!=0)
            {
              sq to = cBitBoard.GetLSB(ref b2);
              mlist[mPos++].m=cTypes.CreaMov(to-Up-Up, to);
            }
              }

              if(pawnsOn7!=0&&(Type!=cMovType.EVASIONS||(target&TRank8BB)!=0))
              {
            if(Type==cMovType.CAPTURES)
              emptySquares=~pos.Piezas();

            if(Type==cMovType.EVASIONS)
              emptySquares&=target;

            mPos=Promocion(mlist, mPos, pawnsOn7, enemies, ci, Type, Right);
            mPos=Promocion(mlist, mPos, pawnsOn7, enemies, ci, Type, Left);
            mPos=Promocion(mlist, mPos, pawnsOn7, emptySquares, ci, Type, Up);
              }

              if(Type==cMovType.CAPTURES||Type==cMovType.EVASIONS||Type==cMovType.NON_EVASIONS)
              {
            b1=cBitBoard.Desplazamiento(pawnsNotOn7, Right)&enemies;
            b2=cBitBoard.Desplazamiento(pawnsNotOn7, Left)&enemies;

            while(b1!=0)
            {
              sq to = cBitBoard.GetLSB(ref b1);
              mlist[mPos++].m=cTypes.CreaMov(to-Right, to);
            }

            while(b2!=0)
            {
              sq to = cBitBoard.GetLSB(ref b2);
              mlist[mPos++].m=cTypes.CreaMov(to-Left, to);
            }

            if(pos.CasillaEnPaso()!=cCasilla.NONE)
            {
              if(Type==cMovType.EVASIONS&&(target&cBitBoard.m_nCasillas[(pos.CasillaEnPaso()-Up)])==0)
            return mPos;

              b1=pawnsNotOn7&pos.AtaquesDePeon(pos.CasillaEnPaso(), colorVS);

              while(b1!=0)
            mlist[mPos++].m=cTypes.CreaMov(cBitBoard.GetLSB(ref b1), pos.CasillaEnPaso(), cMovType.ENPASO, cPieza.CABALLO);
            }
              }

              return mPos;
        }
示例#8
0
        //----------------------------------------------------------------------------------------
        public static int Jaques(cPosicion pos, cMov[] mlist, int mPos)
        {
            color us = pos.ColorMueve();
              cInfoJaque ci = new cInfoJaque(pos);
              bitbrd dc = ci.m_Candidatas;

              while(dc!=0)
              {
            sq from = cBitBoard.GetLSB(ref dc);
            type pt = cTypes.TipoPieza(pos.GetPieza(from));

            if(pt==cPieza.PEON)
              continue;

            bitbrd b = pos.AtaquesDePieza((pieza)pt, from)&~pos.Piezas();

            if(pt==cPieza.REY)
              b&=~cBitBoard.m_PseudoAtaques[cPieza.DAMA][ci.m_SqRey];

            while(b!=0)
              mlist[mPos++].m=cTypes.CreaMov(from, cBitBoard.GetLSB(ref b));
              }

              return us==cColor.BLANCO ? ToDO(pos, mlist, mPos, ~pos.Piezas(), cColor.BLANCO, cMovType.QUIET_CHECKS, ci) :
                                  ToDO(pos, mlist, mPos, ~pos.Piezas(), cColor.NEGRO, cMovType.QUIET_CHECKS, ci);
        }