//----------------------------------------------------------------------------------------------- public factor KNPKB(cPosicion pos) { sq sqPeon = pos.GetList(m_cFuerte, cPieza.PEON)[0]; sq alfilCasillaPeon = pos.GetList(m_cDebil, cPieza.ALFIL)[0]; sq weakerKingSq = pos.GetRey(m_cDebil); if ((cBitBoard.Atras(m_cFuerte, sqPeon) & pos.attacks_from_square_piecetype(alfilCasillaPeon, cPieza.ALFIL)) != 0) return cBitBoard.Distancia(weakerKingSq, sqPeon); return cFactorEscala.NAN; }
//----------------------------------------------------------------------------------------------- public factor KPsK(cPosicion pos) { sq ksq = pos.GetRey(m_cDebil); bitbrd pawns = pos.PiezasColor(m_cFuerte, cPieza.PEON); sq nCasillaPeon = pos.GetList(m_cFuerte, cPieza.PEON)[0]; if (0 == (pawns & ~cBitBoard.EnFrente(m_cDebil, cTypes.Fila(ksq))) && !((pawns & ~cBitBoard.A) != 0 && (pawns & ~cBitBoard.H) != 0) && cBitBoard.ColumDistancia(ksq, nCasillaPeon) <= 1) return cFactorEscala.TABLAS; return cFactorEscala.NAN; }
//---------------------------------------------------------------------------------------- public static int JugadasLegales(cPosicion pos, cMov[] mlist, int mPos) { int end, cur = mPos; bitbrd pinned = pos.pinned_pieces(pos.ColorMueve()); sq ksq = pos.GetRey(pos.ColorMueve()); end=pos.Jaques()!=0 ? Evasiones(pos, mlist, mPos) : Generar(pos, mlist, mPos, cMovType.NON_EVASIONS); while(cur!=end) if((pinned!=0||cTypes.GetFromCasilla(mlist[cur].m)==ksq||cTypes.TipoMovimiento(mlist[cur].m)==cMovType.ENPASO) &&!pos.IsLegalMov(mlist[cur].m, pinned)) mlist[cur].m=mlist[--end].m; else ++cur; return end; }
//----------------------------------------------------------------------------------------------- public factor KNPK(cPosicion pos) { sq sqPeon = Normalizar(pos, m_cFuerte, pos.GetList(m_cFuerte, cPieza.PEON)[0]); sq weakKingSq = Normalizar(pos, m_cFuerte, pos.GetRey(m_cDebil)); if (sqPeon == cCasilla.A7 && cBitBoard.Distancia(cCasilla.A8, weakKingSq) <= 1) return cFactorEscala.TABLAS; return cFactorEscala.NAN; }
//----------------------------------------------------------------------------------------------- public factor KRPKB(cPosicion pos) { if ((pos.GetNumPiezas(cPieza.PEON) & (cBitBoard.A | cBitBoard.H)) != 0) { sq ksq = pos.GetRey(m_cDebil); sq bsq = pos.GetList(m_cDebil, cPieza.ALFIL)[0]; sq nCasillaPeon = pos.GetList(m_cFuerte, cPieza.PEON)[0]; fila rk = cTypes.FilaProxima(m_cFuerte, nCasillaPeon); sq push = cTypes.AtaquePeon(m_cFuerte); if (rk == FILA.F5 && !cTypes.IsColorContrario(bsq, nCasillaPeon)) { int d = cBitBoard.Distancia(nCasillaPeon + 3 * push, ksq); if (d <= 2 && !(d == 0 && ksq == pos.GetRey(m_cFuerte) + 2 * push)) return (24); else return (48); } if (rk == FILA.F6 && cBitBoard.Distancia(nCasillaPeon + 2 * push, ksq) <= 1 && (cBitBoard.m_PseudoAtaques[cPieza.ALFIL][bsq] & cBitBoard.m_nCasillas[(nCasillaPeon + push)]) != 0 && cBitBoard.ColumDistancia(bsq, nCasillaPeon) >= 2) return (8); } return cFactorEscala.NAN; }
//----------------------------------------------------------------------------------------------- public factor KRPPKRP(cPosicion pos) { sq wnCasillaPeon1 = pos.GetList(m_cFuerte, cPieza.PEON)[0]; sq wnCasillaPeon2 = pos.GetList(m_cFuerte, cPieza.PEON)[1]; sq nCasillaReyNegro = pos.GetRey(m_cDebil); if (pos.IsPeonPasado(m_cFuerte, wnCasillaPeon1) || pos.IsPeonPasado(m_cFuerte, wnCasillaPeon2)) return cFactorEscala.NAN; fila r = Math.Max(cTypes.FilaProxima(m_cFuerte, wnCasillaPeon1), cTypes.FilaProxima(m_cFuerte, wnCasillaPeon2)); if (cBitBoard.ColumDistancia(nCasillaReyNegro, wnCasillaPeon1) <= 1 && cBitBoard.ColumDistancia(nCasillaReyNegro, wnCasillaPeon2) <= 1 && cTypes.FilaProxima(m_cFuerte, nCasillaReyNegro) > r) { switch (r) { case FILA.F2: return (10); case FILA.F3: return (10); case FILA.F4: return (15); case FILA.F5: return (20); case FILA.F6: return (40); default: break; } } return cFactorEscala.NAN; }
//---------------------------------------------------------------------------------------------------------- public static void Init(cPosicion pos, cEvalInfo evalInfo, color colr) { color colorVS = (colr == cColor.BLANCO ? cColor.NEGRO : cColor.BLANCO); sq Down = (colr == cColor.BLANCO ? cCasilla.SUR : cCasilla.NORTE); evalInfo.m_Clavadas[colr] = pos.pinned_pieces(colr); bitbrd b = evalInfo.m_Ataques[colorVS][cPieza.REY] = pos.attacks_from_square_piecetype(pos.GetRey(colorVS), cPieza.REY); evalInfo.m_Ataques[colr][cPieza.NAN] = evalInfo.m_Ataques[colr][cPieza.PEON] = evalInfo.m_Peones.GetPeonesAtaques(colr); if (pos.GetNum(colr, cPieza.DAMA) != 0 && pos.MaterialPieza(colr) > cValoresJuego.DAMA_MJ + cValoresJuego.PEON_MJ) { evalInfo.m_ReyAcorralado[colorVS] = b | cBitBoard.Desplazamiento(b, Down); b &= evalInfo.m_Ataques[colr][cPieza.PEON]; evalInfo.m_AtaquesAlRey[colr] = (b != 0) ? cBitBoard.CountMax15(b) : 0; evalInfo.m_ZonaDelRey[colr] = evalInfo.m_PesoAtaquesAlRey[colr] = 0; } else { evalInfo.m_ReyAcorralado[colorVS] = 0; evalInfo.m_AtaquesAlRey[colr] = 0; } }
//----------------------------------------------------------------------------------------------- public val KRKN(cPosicion pos) { sq nCasillaReyNegro = pos.GetRey(m_cDebil); sq nCasillaCaballo = pos.GetList(m_cDebil, cPieza.CABALLO)[0]; val result = (m_lstValorBorde[nCasillaReyNegro] + m_lstValorLejania[cBitBoard.Distancia(nCasillaReyNegro, nCasillaCaballo)]); return m_cFuerte == pos.ColorMueve() ? result : -result; }
//---------------------------------------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------------------------------------- public static pnt EvalRey(cPosicion pos, cEvalInfo ei, color colr) { color colorVS = (colr == cColor.BLANCO ? cColor.NEGRO : cColor.BLANCO); bitbrd indefenso, b, b1, b2, safe; int attackUnits; sq nCasillaRey = pos.GetRey(colr); pnt score = 0; if (ei.m_AtaquesAlRey[colorVS] != 0) { indefenso = ei.m_Ataques[colorVS][cPieza.NAN] & ei.m_Ataques[colr][cPieza.REY] & ~(ei.m_Ataques[colr][cPieza.PEON] | ei.m_Ataques[colr][cPieza.CABALLO] | ei.m_Ataques[colr][cPieza.ALFIL] | ei.m_Ataques[colr][cPieza.TORRE] | ei.m_Ataques[colr][cPieza.DAMA]); attackUnits = Math.Min(20, (ei.m_AtaquesAlRey[colorVS] * ei.m_PesoAtaquesAlRey[colorVS]) / 2) + 3 * (ei.m_ZonaDelRey[colorVS] + cBitBoard.CountMax15(indefenso)) + 2 * (ei.m_Clavadas[colr] != 0 ? 1 : 0) - cTypes.GetMedioJuego(score) / 32; b = indefenso & ei.m_Ataques[colorVS][cPieza.DAMA] & ~pos.PiezasColor(colorVS); if (b != 0) { b &= (ei.m_Ataques[colorVS][cPieza.PEON] | ei.m_Ataques[colorVS][cPieza.CABALLO] | ei.m_Ataques[colorVS][cPieza.ALFIL] | ei.m_Ataques[colorVS][cPieza.TORRE]); if (b != 0) attackUnits += QueenContactCheck * cBitBoard.CountMax15(b) * (colorVS == pos.ColorMueve() ? 2 : 1); } b = indefenso & ei.m_Ataques[colorVS][cPieza.TORRE] & ~pos.PiezasColor(colorVS); b &= cBitBoard.m_PseudoAtaques[cPieza.TORRE][nCasillaRey]; if (b != 0) { b &= (ei.m_Ataques[colorVS][cPieza.PEON] | ei.m_Ataques[colorVS][cPieza.CABALLO] | ei.m_Ataques[colorVS][cPieza.ALFIL] | ei.m_Ataques[colorVS][cPieza.DAMA]); if (b != 0) attackUnits += RookContactCheck * cBitBoard.CountMax15(b) * (colorVS == pos.ColorMueve() ? 2 : 1); } safe = ~(pos.PiezasColor(colorVS) | ei.m_Ataques[colr][cPieza.NAN]); b1 = pos.attacks_from_square_piecetype(nCasillaRey, cPieza.TORRE) & safe; b2 = pos.attacks_from_square_piecetype(nCasillaRey, cPieza.ALFIL) & safe; b = (b1 | b2) & ei.m_Ataques[colorVS][cPieza.DAMA]; if (b != 0) attackUnits += QueenCheck * cBitBoard.CountMax15(b); b = b1 & ei.m_Ataques[colorVS][cPieza.TORRE]; if (b != 0) attackUnits += RookCheck * cBitBoard.CountMax15(b); b = b2 & ei.m_Ataques[colorVS][cPieza.ALFIL]; if (b != 0) attackUnits += BishopCheck * cBitBoard.CountMax15(b); b = pos.attacks_from_square_piecetype(nCasillaRey, cPieza.CABALLO) & ei.m_Ataques[colorVS][cPieza.CABALLO] & safe; if (b != 0) attackUnits += KnightCheck * cBitBoard.CountMax15(b); attackUnits = Math.Min(99, Math.Max(0, attackUnits)); score -= m_ReyAmenazado[colr == cSearch.RootColor ? 1 : 0][attackUnits]; } return score; }
//----------------------------------------------------------------------------------------------------------------------------------- public static pnt EvalPeonesPasados(cPosicion pos, cEvalInfo ei, color colr) { color colorVS = (colr == cColor.BLANCO ? cColor.NEGRO : cColor.BLANCO); bitbrd b, squaresToQueen, defendedSquares, unsafeSquares; pnt nPuntos = 0; b = ei.m_Peones.GetPeonesPasados(colr); while (b != 0) { sq casilla = cBitBoard.GetLSB(ref b); int r = (int)(cTypes.FilaProxima(colr, casilla) - FILA.F2); int rr = r * (r - 1); val mbonus = (17 * rr), ebonus = (7 * (rr + r + 1)); if (rr != 0) { sq blockSq = casilla + cTypes.AtaquePeon(colr); ebonus += (cBitBoard.Distancia(pos.GetRey(colorVS), blockSq) * 5 * rr) - (cBitBoard.Distancia(pos.GetRey(colr), blockSq) * 2 * rr); if (cTypes.FilaProxima(colr, blockSq) != FILA.F8) ebonus -= (cBitBoard.Distancia(pos.GetRey(colr), blockSq + cTypes.AtaquePeon(colr)) * rr); if (pos.CasillaVacia(blockSq)) { squaresToQueen = cBitBoard.Atras(colr, casilla); if ((cBitBoard.Atras(colorVS, casilla) & pos.PiezasColor(colorVS, cPieza.TORRE, cPieza.DAMA)) != 0 && (cBitBoard.Atras(colorVS, casilla) & pos.PiezasColor(colorVS, cPieza.TORRE, cPieza.DAMA) & pos.attacks_from_square_piecetype(casilla, cPieza.TORRE)) != 0) unsafeSquares = squaresToQueen; else unsafeSquares = squaresToQueen & (ei.m_Ataques[colorVS][cPieza.NAN] | pos.PiezasColor(colorVS)); if ((cBitBoard.Atras(colorVS, casilla) & pos.PiezasColor(colr, cPieza.TORRE, cPieza.DAMA)) != 0 && (cBitBoard.Atras(colorVS, casilla) & pos.PiezasColor(colr, cPieza.TORRE, cPieza.DAMA) & pos.attacks_from_square_piecetype(casilla, cPieza.TORRE)) != 0) defendedSquares = squaresToQueen; else defendedSquares = squaresToQueen & ei.m_Ataques[colr][cPieza.NAN]; int k = 0 == unsafeSquares ? 15 : 0 == (unsafeSquares & cBitBoard.m_nCasillas[blockSq]) ? 9 : 0; if (defendedSquares == squaresToQueen) k += 6; else if ((defendedSquares & cBitBoard.m_nCasillas[blockSq]) != 0) k += 4; mbonus += (k * rr); ebonus += (k * rr); } } //-- rr != 0 if (pos.GetNum(colr, cPieza.PEON) < pos.GetNum(colorVS, cPieza.PEON)) ebonus += ebonus / 4; nPuntos += cTypes.Puntua(mbonus, ebonus); } return cEval.SetPesos(nPuntos, m_Pesos[cEvalPesos.PEONES_PASADOS]); }
//---------------------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------------------- 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)⌖ 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; }
//----------------------------------------------------------------------------------------------- public val KQKP(cPosicion pos) { sq nCasillaReyGanador = pos.GetRey(m_cFuerte); sq nCasillaReyPerdedor = pos.GetRey(m_cDebil); sq nCasillaPeon = pos.GetList(m_cDebil, cPieza.PEON)[0]; val result = (m_lstValorCerrado[cBitBoard.Distancia(nCasillaReyGanador, nCasillaReyPerdedor)]); if (cTypes.FilaProxima(m_cDebil, nCasillaPeon) != FILA.F7 || cBitBoard.Distancia(nCasillaReyPerdedor, nCasillaPeon) != 1 || 0 == ((cBitBoard.A | cBitBoard.C | cBitBoard.F | cBitBoard.H) & cBitBoard.m_nCasillas[nCasillaPeon])) result += cValoresJuego.DAMA_FINAL - cValoresJuego.PEON_FINAL; return m_cFuerte == pos.ColorMueve() ? result : -result; }
//----------------------------------------------------------------------------------------------- public factor KBPKB(cPosicion pos) { sq sqPeon = pos.GetList(m_cFuerte, cPieza.PEON)[0]; sq strongerBishonCasillaPeon = pos.GetList(m_cFuerte, cPieza.ALFIL)[0]; sq weakerBishonCasillaPeon = pos.GetList(m_cDebil, cPieza.ALFIL)[0]; sq weakerKingSq = pos.GetRey(m_cDebil); if (cTypes.Columna(weakerKingSq) == cTypes.Columna(sqPeon) && cTypes.FilaProxima(m_cFuerte, sqPeon) < cTypes.FilaProxima(m_cFuerte, weakerKingSq) && (cTypes.IsColorContrario(weakerKingSq, strongerBishonCasillaPeon) || cTypes.FilaProxima(m_cFuerte, weakerKingSq) <= FILA.F6)) return cFactorEscala.TABLAS; if (cTypes.IsColorContrario(strongerBishonCasillaPeon, weakerBishonCasillaPeon)) { if (cTypes.FilaProxima(m_cFuerte, sqPeon) <= FILA.F5) return cFactorEscala.TABLAS; else { bitbrd path = cBitBoard.Atras(m_cFuerte, sqPeon); if ((path & pos.PiezasColor(m_cDebil, cPieza.REY)) != 0) return cFactorEscala.TABLAS; if (((pos.attacks_from_square_piecetype(weakerBishonCasillaPeon, cPieza.ALFIL) & path) != 0) && cBitBoard.Distancia(weakerBishonCasillaPeon, sqPeon) >= 3) return cFactorEscala.TABLAS; } } return cFactorEscala.NAN; }
//----------------------------------------------------------------------------------------------- public factor KQKRPs(cPosicion pos) { sq kingSq = pos.GetRey(m_cDebil); sq nCasillaTorre = pos.GetList(m_cDebil, cPieza.TORRE)[0]; if (cTypes.FilaProxima(m_cDebil, kingSq) <= FILA.F2 && cTypes.FilaProxima(m_cDebil, pos.GetRey(m_cFuerte)) >= FILA.F4 && cTypes.FilaProxima(m_cDebil, nCasillaTorre) == FILA.F3 && (pos.PiezasColor(m_cDebil, cPieza.PEON) & pos.attacks_from_square_piecetype(kingSq, cPieza.REY) & pos.AtaquesDePeon(nCasillaTorre, m_cFuerte)) != 0) return cFactorEscala.TABLAS; return cFactorEscala.NAN; }
//----------------------------------------------------------------------------------------------- public factor KBPKN(cPosicion pos) { sq sqPeon = pos.GetList(m_cFuerte, cPieza.PEON)[0]; sq strongerBishonCasillaPeon = pos.GetList(m_cFuerte, cPieza.ALFIL)[0]; sq weakerKingSq = pos.GetRey(m_cDebil); if (cTypes.Columna(weakerKingSq) == cTypes.Columna(sqPeon) && cTypes.FilaProxima(m_cFuerte, sqPeon) < cTypes.FilaProxima(m_cFuerte, weakerKingSq) && (cTypes.IsColorContrario(weakerKingSq, strongerBishonCasillaPeon) || cTypes.FilaProxima(m_cFuerte, weakerKingSq) <= FILA.F6)) return cFactorEscala.TABLAS; return cFactorEscala.NAN; }
//----------------------------------------------------------------------------------------------- public val KRKP(cPosicion pos) { val result = 0; sq nCasillaReyBlanco = cTypes.CasillaProxima(m_cFuerte, pos.GetRey(m_cFuerte)); sq nCasillaReyNegro = cTypes.CasillaProxima(m_cFuerte, pos.GetRey(m_cDebil)); sq nCasillaTorre = cTypes.CasillaProxima(m_cFuerte, pos.GetList(m_cFuerte, cPieza.TORRE)[0]); sq nCasillaPeon = cTypes.CasillaProxima(m_cFuerte, pos.GetList(m_cDebil, cPieza.PEON)[0]); sq nCasillaCoronacion = cTypes.CreaCasilla(cTypes.Columna(nCasillaPeon), FILA.F1); if (nCasillaReyBlanco < nCasillaPeon && cTypes.Columna(nCasillaReyBlanco) == cTypes.Columna(nCasillaPeon)) result = cValoresJuego.TORRE_FINAL - (cBitBoard.Distancia(nCasillaReyBlanco, nCasillaPeon)); else if (cBitBoard.Distancia(nCasillaReyNegro, nCasillaPeon) >= 3 + ((pos.ColorMueve() == m_cDebil) ? 1 : 0) && cBitBoard.Distancia(nCasillaReyNegro, nCasillaTorre) >= 3) result = cValoresJuego.TORRE_FINAL - (cBitBoard.Distancia(nCasillaReyBlanco, nCasillaPeon)); else if (cTypes.Fila(nCasillaReyNegro) <= FILA.F3 && cBitBoard.Distancia(nCasillaReyNegro, nCasillaPeon) == 1 && cTypes.Fila(nCasillaReyBlanco) >= FILA.F4 && cBitBoard.Distancia(nCasillaReyBlanco, nCasillaPeon) > 2 + ((pos.ColorMueve() == m_cFuerte) ? 1 : 0)) result = 80 - 8 * cBitBoard.Distancia(nCasillaReyBlanco, nCasillaPeon); else result = (val)(200) - 8 * (cBitBoard.Distancia(nCasillaReyBlanco, nCasillaPeon + cCasilla.SUR) - cBitBoard.Distancia(nCasillaReyNegro, nCasillaPeon + cCasilla.SUR) - cBitBoard.Distancia(nCasillaPeon, nCasillaCoronacion)); return m_cFuerte == pos.ColorMueve() ? result : -result; }
//----------------------------------------------------------------------------------------------- public factor KBPPKB(cPosicion pos) { sq wbsq = pos.GetList(m_cFuerte, cPieza.ALFIL)[0]; sq bbsq = pos.GetList(m_cDebil, cPieza.ALFIL)[0]; if (!cTypes.IsColorContrario(wbsq, bbsq)) return cFactorEscala.NAN; sq ksq = pos.GetRey(m_cDebil); sq nCasillaPeon1 = pos.GetList(m_cFuerte, cPieza.PEON)[0]; sq nCasillaPeon2 = pos.GetList(m_cFuerte, cPieza.PEON)[1]; fila r1 = cTypes.Fila(nCasillaPeon1); fila r2 = cTypes.Fila(nCasillaPeon2); sq blockSq1, blockSq2; if (cTypes.FilaProxima(m_cFuerte, nCasillaPeon1) > cTypes.FilaProxima(m_cFuerte, nCasillaPeon2)) { blockSq1 = nCasillaPeon1 + cTypes.AtaquePeon(m_cFuerte); blockSq2 = cTypes.CreaCasilla(cTypes.Columna(nCasillaPeon2), cTypes.Fila(nCasillaPeon1)); } else { blockSq1 = nCasillaPeon2 + cTypes.AtaquePeon(m_cFuerte); blockSq2 = cTypes.CreaCasilla(cTypes.Columna(nCasillaPeon1), cTypes.Fila(nCasillaPeon2)); } switch (cBitBoard.ColumDistancia(nCasillaPeon1, nCasillaPeon2)) { case 0: if (cTypes.Columna(ksq) == cTypes.Columna(blockSq1) && cTypes.FilaProxima(m_cFuerte, ksq) >= cTypes.FilaProxima(m_cFuerte, blockSq1) && cTypes.IsColorContrario(ksq, wbsq)) return cFactorEscala.TABLAS; else return cFactorEscala.NAN; case 1: if (ksq == blockSq1 && cTypes.IsColorContrario(ksq, wbsq) && (bbsq == blockSq2 || (pos.attacks_from_square_piecetype(blockSq2, cPieza.ALFIL) & pos.PiezasColor(m_cDebil, cPieza.ALFIL)) != 0 || Math.Abs(r1 - r2) >= 2)) return cFactorEscala.TABLAS; else if (ksq == blockSq2 && cTypes.IsColorContrario(ksq, wbsq) && (bbsq == blockSq1 || (pos.attacks_from_square_piecetype(blockSq1, cPieza.ALFIL) & pos.PiezasColor(m_cDebil, cPieza.ALFIL)) != 0)) return cFactorEscala.TABLAS; else return cFactorEscala.NAN; default: return cFactorEscala.NAN; } }
//----------------------------------------------------------------------------------------------- public factor KRPKR(cPosicion pos) { sq nCasillaReyBlanco = Normalizar(pos, m_cFuerte, pos.GetRey(m_cFuerte)); sq nCasillaReyNegro = Normalizar(pos, m_cFuerte, pos.GetRey(m_cDebil)); sq wnCasillaTorre = Normalizar(pos, m_cFuerte, pos.GetList(m_cFuerte, cPieza.TORRE)[0]); sq wnCasillaPeon = Normalizar(pos, m_cFuerte, pos.GetList(m_cFuerte, cPieza.PEON)[0]); sq bnCasillaTorre = Normalizar(pos, m_cFuerte, pos.GetList(m_cDebil, cPieza.TORRE)[0]); colum f = cTypes.Columna(wnCasillaPeon); fila r = cTypes.Fila(wnCasillaPeon); sq queeningSq = cTypes.CreaCasilla(f, FILA.F8); int tempo = (pos.ColorMueve() == m_cFuerte ? 1 : 0); if (r <= FILA.F5 && cBitBoard.Distancia(nCasillaReyNegro, queeningSq) <= 1 && nCasillaReyBlanco <= cCasilla.H5 && (cTypes.Fila(bnCasillaTorre) == FILA.F6 || (r <= FILA.F3 && cTypes.Fila(wnCasillaTorre) != FILA.F6))) return cFactorEscala.TABLAS; if (r == FILA.F6 && cBitBoard.Distancia(nCasillaReyNegro, queeningSq) <= 1 && cTypes.Fila(nCasillaReyBlanco) + tempo <= FILA.F6 && (cTypes.Fila(bnCasillaTorre) == FILA.F1 || (0 == tempo && Math.Abs(cTypes.Columna(bnCasillaTorre) - f) >= 3))) return cFactorEscala.TABLAS; if (r >= FILA.F6 && nCasillaReyNegro == queeningSq && cTypes.Fila(bnCasillaTorre) == FILA.F1 && (0 == tempo || cBitBoard.Distancia(nCasillaReyBlanco, wnCasillaPeon) >= 2)) return cFactorEscala.TABLAS; if (wnCasillaPeon == cCasilla.A7 && wnCasillaTorre == cCasilla.A8 && (nCasillaReyNegro == cCasilla.H7 || nCasillaReyNegro == cCasilla.G7) && cTypes.Columna(bnCasillaTorre) == COLUMNA.A && (cTypes.Fila(bnCasillaTorre) <= FILA.F3 || cTypes.Columna(nCasillaReyBlanco) >= COLUMNA.D || cTypes.Fila(nCasillaReyBlanco) <= FILA.F5)) return cFactorEscala.TABLAS; if (r <= FILA.F5 && nCasillaReyNegro == wnCasillaPeon + cCasilla.NORTE && cBitBoard.Distancia(nCasillaReyBlanco, wnCasillaPeon) - tempo >= 2 && cBitBoard.Distancia(nCasillaReyBlanco, bnCasillaTorre) - tempo >= 2) return cFactorEscala.TABLAS; if (r == FILA.F7 && f != COLUMNA.A && cTypes.Columna(wnCasillaTorre) == f && wnCasillaTorre != queeningSq && (cBitBoard.Distancia(nCasillaReyBlanco, queeningSq) < cBitBoard.Distancia(nCasillaReyNegro, queeningSq) - 2 + tempo) && (cBitBoard.Distancia(nCasillaReyBlanco, queeningSq) < cBitBoard.Distancia(nCasillaReyNegro, wnCasillaTorre) + tempo)) return (factor)(cFactorEscala.MAXIMO - 2 * cBitBoard.Distancia(nCasillaReyBlanco, queeningSq)); if (f != COLUMNA.A && cTypes.Columna(wnCasillaTorre) == f && wnCasillaTorre < wnCasillaPeon && (cBitBoard.Distancia(nCasillaReyBlanco, queeningSq) < cBitBoard.Distancia(nCasillaReyNegro, queeningSq) - 2 + tempo) && (cBitBoard.Distancia(nCasillaReyBlanco, wnCasillaPeon + cCasilla.NORTE) < cBitBoard.Distancia(nCasillaReyNegro, wnCasillaPeon + cCasilla.NORTE) - 2 + tempo) && (cBitBoard.Distancia(nCasillaReyNegro, wnCasillaTorre) + tempo >= 3 || (cBitBoard.Distancia(nCasillaReyBlanco, queeningSq) < cBitBoard.Distancia(nCasillaReyNegro, wnCasillaTorre) + tempo && (cBitBoard.Distancia(nCasillaReyBlanco, wnCasillaPeon + cCasilla.NORTE) < cBitBoard.Distancia(nCasillaReyNegro, wnCasillaTorre) + tempo)))) return (factor)(cFactorEscala.MAXIMO - 8 * cBitBoard.Distancia(wnCasillaPeon, queeningSq) - 2 * cBitBoard.Distancia(nCasillaReyBlanco, queeningSq)); if (r <= FILA.F4 && nCasillaReyNegro > wnCasillaPeon) { if (cTypes.Columna(nCasillaReyNegro) == cTypes.Columna(wnCasillaPeon)) return 10; if (Math.Abs(cTypes.Columna(nCasillaReyNegro) - cTypes.Columna(wnCasillaPeon)) == 1 && cBitBoard.Distancia(nCasillaReyBlanco, nCasillaReyNegro) > 2) return (24 - 2 * cBitBoard.Distancia(nCasillaReyBlanco, nCasillaReyNegro)); } return cFactorEscala.NAN; }
//----------------------------------------------------------------------------------------------- public factor KBPsK(cPosicion pos) { bitbrd pawns = pos.PiezasColor(m_cFuerte, cPieza.PEON); colum pawnFile = cTypes.Columna(pos.GetList(m_cFuerte, cPieza.PEON)[0]); if ((pawnFile == COLUMNA.A || pawnFile == COLUMNA.H) && 0 == (pawns & ~cBitBoard.GetColumna(pawnFile))) { sq bishonCasillaPeon = pos.GetList(m_cFuerte, cPieza.ALFIL)[0]; sq queeningSq = cTypes.CasillaProxima(m_cFuerte, cTypes.CreaCasilla(pawnFile, FILA.F8)); sq kingSq = pos.GetRey(m_cDebil); if (cTypes.IsColorContrario(queeningSq, bishonCasillaPeon) && cBitBoard.Distancia(queeningSq, kingSq) <= 1) return cFactorEscala.TABLAS; } if ((pawnFile == COLUMNA.B || pawnFile == COLUMNA.G) && 0 == (pos.GetNumPiezas(cPieza.PEON) & ~cBitBoard.GetColumna(pawnFile)) && pos.MaterialPieza(m_cDebil) == 0 && pos.GetNum(m_cDebil, cPieza.PEON) >= 1) { sq weaksqPeon = cBitBoard.backmost_sq(m_cDebil, pos.PiezasColor(m_cDebil, cPieza.PEON)); sq strongKingSq = pos.GetRey(m_cFuerte); sq weakKingSq = pos.GetRey(m_cDebil); sq bishonCasillaPeon = pos.GetList(m_cFuerte, cPieza.ALFIL)[0]; if (cTypes.FilaProxima(m_cFuerte, weaksqPeon) == FILA.F7 && (pos.PiezasColor(m_cFuerte, cPieza.PEON) & cBitBoard.m_nCasillas[(weaksqPeon + cTypes.AtaquePeon(m_cDebil))]) != 0 && (cTypes.IsColorContrario(bishonCasillaPeon, weaksqPeon) || pos.GetNum(m_cFuerte, cPieza.PEON) == 1)) { int strongKingDist = cBitBoard.Distancia(weaksqPeon, strongKingSq); int weakKingDist = cBitBoard.Distancia(weaksqPeon, weakKingSq); if (cTypes.FilaProxima(m_cFuerte, weakKingSq) >= FILA.F7 && weakKingDist <= 2 && weakKingDist <= strongKingDist) return cFactorEscala.TABLAS; } } return cFactorEscala.NAN; }
//----------------------------------------------------------------------------------------------- public val KXK(cPosicion pos) { if (pos.ColorMueve() == m_cDebil && 0 == (new cReglas(pos, cMovType.LEGAL)).Size()) return cValoresJuego.TABLAS; sq posReyGanador = pos.GetRey(m_cFuerte); sq posReyPerdedor = pos.GetRey(m_cDebil); val result = pos.MaterialPieza(m_cFuerte) + pos.GetNum(m_cFuerte, cPieza.PEON) * cValoresJuego.PEON_FINAL + m_lstValorBorde[posReyPerdedor] + m_lstValorCerrado[cBitBoard.Distancia(posReyGanador, posReyPerdedor)]; if (pos.GetNum(m_cFuerte, cPieza.DAMA) != 0 || pos.GetNum(m_cFuerte, cPieza.TORRE) != 0 || (pos.GetNum(m_cFuerte, cPieza.ALFIL) != 0 && pos.GetNum(m_cFuerte, cPieza.CABALLO) != 0) || pos.IsAlfilPar(m_cFuerte)) { result += cValoresJuego.GANA; } return m_cFuerte == pos.ColorMueve() ? result : -result; }
//---------------------------------------------------------------------------------------- public static int Evasiones(cPosicion pos, cMov[] mlist, int mPos) { color us = pos.ColorMueve(); sq ksq = pos.GetRey(us); bitbrd sliderAttacks = 0; bitbrd sliders = pos.Jaques()&~pos.GetNumPiezas(cPieza.CABALLO, cPieza.PEON); while(sliders!=0) { sq checksq = cBitBoard.GetLSB(ref sliders); sliderAttacks|=cBitBoard.m_EnLinea[checksq][ksq]^cBitBoard.m_nCasillas[checksq]; } bitbrd b = pos.attacks_from_square_piecetype(ksq, cPieza.REY)&~pos.PiezasColor(us)&~sliderAttacks; while(b!=0) mlist[mPos++].m=cTypes.CreaMov(ksq, cBitBoard.GetLSB(ref b)); if(cBitBoard.MayorQue(pos.Jaques())) return mPos; sq checksq2 = cBitBoard.LSB(pos.Jaques()); bitbrd target = cBitBoard.Entre(checksq2, ksq)|cBitBoard.m_nCasillas[checksq2]; return us==cColor.BLANCO ? ToDO(pos, mlist, mPos, target, cColor.BLANCO, cMovType.EVASIONS, null) : ToDO(pos, mlist, mPos, target, cColor.NEGRO, cMovType.EVASIONS, null); }