//----------------------------------------------------------------------------------------------- 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 bool SetConjuntoPiezasPosicion(cPosicion pos) { whitePieceSquares.Clear(); whiteTypesSquares.Clear(); blackPieceSquares.Clear(); blackTypesSquares.Clear(); for(type pt = cPieza.PEON; pt<=cPieza.REY; ++pt) { for(int i = 0; i<pos.GetNum(cColor.BLANCO, pt); i++) { whitePieceSquares.Add(pos.GetList(cColor.BLANCO, pt)[i]); whiteTypesSquares.Add(pt); } for(int i = 0; i<pos.GetNum(cColor.NEGRO, pt); i++) { blackPieceSquares.Add(pos.GetList(cColor.NEGRO, pt)[i]); blackTypesSquares.Add(pt); } } enPassantSquare=pos.CasillaEnPaso(); whosTurn=pos.ColorMueve(); return true; }
//----------------------------------------------------------------------------------------------- public bool CheckMaterial(cPosicion posicion, color colr, val nMaterialPeones, int nPeones) { return posicion.MaterialPieza(colr) == nMaterialPeones && posicion.GetNum(colr, cPieza.PEON) == nPeones; }
//---------------------------------------------------------------------------------------------------------- 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 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 val Eval(cPosicion pos) { cEvalInfo eval = new cEvalInfo(); pnt nPuntos; pnt[] movilidad = new pnt[] { 0, 0 }; cThread thread = pos.ThreadActive(); nPuntos = pos.GetPuntosPeon() + (pos.ColorMueve() == cColor.BLANCO ? m_Tempo : -m_Tempo); eval.m_Material = cMaterial.Buscar(pos, thread.m_Material, thread.m_Finales); nPuntos += eval.m_Material.Valor(); if (eval.m_Material.FuncionEvaluacion()) return eval.m_Material.Eval(pos); eval.m_Peones = cBonusPeones.Buscar(pos, thread.m_TablaPeones); Init(pos, eval, cColor.BLANCO); Init(pos, eval, cColor.NEGRO); nPuntos += SetPesos(eval.m_Peones.GetValue(), m_Pesos[cEvalPesos.ESTRUCTURA_PEONES]); eval.m_Ataques[cColor.BLANCO][cPieza.NAN] |= eval.m_Ataques[cColor.BLANCO][cPieza.REY]; eval.m_Ataques[cColor.NEGRO][cPieza.NAN] |= eval.m_Ataques[cColor.NEGRO][cPieza.REY]; bitbrd[] areaMovilidad = new bitbrd[]{ ~(eval.m_Ataques[cColor.NEGRO][cPieza.PEON] | pos.PiezasColor(cColor.BLANCO, cPieza.PEON, cPieza.REY)), ~(eval.m_Ataques[cColor.BLANCO][cPieza.PEON] | pos.PiezasColor(cColor.NEGRO, cPieza.PEON, cPieza.REY)) }; nPuntos += EvalPiezas(pos, eval, movilidad, areaMovilidad, cPieza.CABALLO, cColor.BLANCO); nPuntos += cEval.SetPesos(movilidad[cColor.BLANCO] - movilidad[cColor.NEGRO], m_Pesos[cEvalPesos.MOVILIDAD]); nPuntos += EvalRey(pos, eval, cColor.BLANCO) - EvalRey(pos, eval, cColor.NEGRO); nPuntos += EvalAmenazas(pos, eval, cColor.BLANCO) - EvalAmenazas(pos, eval, cColor.NEGRO); nPuntos += EvalPeonesPasados(pos, eval, cColor.BLANCO) - EvalPeonesPasados(pos, eval, cColor.NEGRO); if (0 == pos.MaterialPieza(cColor.BLANCO) || 0 == pos.MaterialPieza(cColor.NEGRO)) nPuntos += EvalPeonImparable(pos, cColor.BLANCO, eval) - EvalPeonImparable(pos, cColor.NEGRO, eval); if (eval.m_Material.Peso() != 0) { int s = EvalEspacio(pos, eval, cColor.BLANCO) - EvalEspacio(pos, eval, cColor.NEGRO); nPuntos += cEval.SetPesos(s * eval.m_Material.Peso(), m_Pesos[cEvalPesos.ESPACIO]); } factor sf = cTypes.GetFinalJuego(nPuntos) > cValoresJuego.TABLAS ? eval.m_Material.FactorDeEscala(pos, cColor.BLANCO) : eval.m_Material.FactorDeEscala(pos, cColor.NEGRO); if (eval.m_Material.Fase() < cFaseJuego.MEDIO_JUEGO && pos.AlfilesOpuestos() && (sf == cFactorEscala.NORMAL || sf == cFactorEscala.PEON)) { if (pos.MaterialPieza(cColor.BLANCO) == cValoresJuego.ALFIL_MJ && pos.MaterialPieza(cColor.NEGRO) == cValoresJuego.ALFIL_MJ) { bool one_pawn = (pos.GetNum(cColor.BLANCO, cPieza.PEON) + pos.GetNum(cColor.NEGRO, cPieza.PEON) == 1); sf = one_pawn ? (8) : (32); } else sf = (50 * sf / cFactorEscala.NORMAL); } val v = cTypes.GetMedioJuego(nPuntos) * (eval.m_Material.Fase()) + cTypes.GetFinalJuego(nPuntos) * (cFaseJuego.MEDIO_JUEGO - eval.m_Material.Fase()) * sf / cFactorEscala.NORMAL; v /= (cFaseJuego.MEDIO_JUEGO); return pos.ColorMueve() == cColor.BLANCO ? v : -v; }