Пример #1
0
        //----------------------------------------------------------------------------------------------------------
        public static pnt EvalPiezas(cPosicion pos, cEvalInfo ei, pnt[] mobility, bitbrd[] mobilityArea, type Pt, color colr)
        {
            if (colr == cColor.BLANCO && Pt == cPieza.REY)
              {
            return 0;
              }

              bitbrd b;
              sq s;
              pnt nPuntos = 0;

              type NextPt = (colr == cColor.BLANCO ? Pt : (Pt + 1));
              color colorVS = (colr == cColor.BLANCO ? cColor.NEGRO : cColor.BLANCO);
              sq[] pl = pos.GetList(colr, Pt);
              int plPos = 0;

              ei.m_Ataques[colr][Pt] = 0;

              while ((s = pl[plPos++]) != cCasilla.NONE)
              {
            b = Pt == cPieza.ALFIL ? cBitBoard.AtaquesPieza(s, pos.Piezas() ^ pos.PiezasColor(colr, cPieza.DAMA), cPieza.ALFIL)
              : Pt == cPieza.TORRE ? cBitBoard.AtaquesPieza(s, pos.Piezas() ^ pos.PiezasColor(colr, cPieza.TORRE, cPieza.DAMA), cPieza.TORRE)
                            : pos.attacks_from_square_piecetype(s, Pt);

            if ((ei.m_Clavadas[colr] & cBitBoard.m_nCasillas[s]) != 0)
              b &= cBitBoard.m_EnLinea[pos.GetRey(colr)][s];

            ei.m_Ataques[colr][cPieza.NAN] |= ei.m_Ataques[colr][Pt] |= b;

            if ((b & ei.m_ReyAcorralado[colorVS]) != 0)
            {
              ei.m_AtaquesAlRey[colr]++;
              ei.m_PesoAtaquesAlRey[colr] += KingAttackWeights[Pt];
              bitbrd bb = (b & ei.m_Ataques[colorVS][cPieza.REY]);
              if (bb != 0)
            ei.m_ZonaDelRey[colr] += cBitBoard.CountMax15(bb);
            }

            if (Pt == cPieza.DAMA)
              b &= ~(ei.m_Ataques[colorVS][cPieza.CABALLO]
                 | ei.m_Ataques[colorVS][cPieza.ALFIL]
                 | ei.m_Ataques[colorVS][cPieza.TORRE]);

            int mob = (Pt != cPieza.DAMA ? cBitBoard.CountMax15(b & mobilityArea[colr])
                                          : cBitBoard.Count(b & mobilityArea[colr]));

            mobility[colr] += m_Movilidad[Pt][mob];

            if ((ei.m_Ataques[colorVS][cPieza.PEON] & cBitBoard.m_nCasillas[s]) != 0)
              nPuntos -= ThreatenedByPawn[Pt];

            if (Pt == cPieza.ALFIL || Pt == cPieza.CABALLO)
            {
              if (Pt == cPieza.ALFIL)
            nPuntos -= m_AlfilEnPeon * ei.m_Peones.PeonesMismoColor(colr, s);
              if (0 == (pos.PiezasColor(colorVS, cPieza.PEON) & cBitBoard.AtaquePeon(colr, s)))
            nPuntos += evaluate_outposts(pos, ei, s, Pt, colr);

              if (cTypes.FilaProxima(colr, s) < FILA.F5 && (pos.GetNumPiezas(cPieza.PEON) & cBitBoard.m_nCasillas[(s + cTypes.AtaquePeon(colr))]) != 0)
            nPuntos += m_CercaDePeon;
            }

            if (Pt == cPieza.TORRE)
            {
              if (cTypes.FilaProxima(colr, s) >= FILA.F5)
              {
            bitbrd pawns = pos.PiezasColor(colorVS, cPieza.PEON) & cBitBoard.m_PseudoAtaques[cPieza.TORRE][s];
            if (pawns != 0)
              nPuntos += cBitBoard.CountMax15(pawns) * m_TorreEnPeon;
              }

              if (ei.m_Peones.SemiAbierta(colr, cTypes.Columna(s)) != 0)
            nPuntos += ei.m_Peones.SemiAbierta(colorVS, cTypes.Columna(s)) != 0 ? m_TorreColAbierta : m_TorreColumnaSemiAbierta;

              if (mob > 3 || ei.m_Peones.SemiAbierta(colr, cTypes.Columna(s)) != 0)
            continue;

              sq ksq = pos.GetRey(colr);

              if (((cTypes.Columna(ksq) < COLUMNA.E) == (cTypes.Columna(s) < cTypes.Columna(ksq)))
              && (cTypes.Fila(ksq) == cTypes.Fila(s) || cTypes.FilaProxima(colr, ksq) == FILA.F1)
              && 0 == ei.m_Peones.SemiAbierta(colr, cTypes.Columna(ksq), cTypes.Columna(s) < cTypes.Columna(ksq)))
            nPuntos -= (m_TorreAtrapada - cTypes.Puntua(mob * 8, 0)) * (1 + (pos.CanEnroque(colr) == 0 ? 1 : 0));
            }

            if (Pt == cPieza.ALFIL
            && pos.IsChess960() != false
            && (s == cTypes.CasillaProxima(colr, cCasilla.A1) || s == cTypes.CasillaProxima(colr, cCasilla.H1)))
            {
              sq d = cTypes.AtaquePeon(colr) + (cTypes.Columna(s) == COLUMNA.A ? cCasilla.ESTE : cCasilla.OESTE);
              if (pos.GetPieza(s + d) == cTypes.CreaPieza(colr, cPieza.PEON))
            nPuntos -= !pos.CasillaVacia(s + d + cTypes.AtaquePeon(colr)) ? m_AlfilAtrapado * 4
                : pos.GetPieza(s + d + d) == cTypes.CreaPieza(colr, cPieza.PEON) ? m_AlfilAtrapado * 2
                                                                : m_AlfilAtrapado;
            }
              }

              return nPuntos - EvalPiezas(pos, ei, mobility, mobilityArea, NextPt, colorVS);
        }
Пример #2
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;
        }
Пример #3
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;
        }