Skak:Evaluation
Fra DAMNWiki
(Omdirigeret fra Skak:Pawn Evaluation)
Indledning
Her er et link til en masse skakstrategi: http://www.chesscircle.net/chess-strategies/
Optimering
FØR OPTIMERING (v1.19) *************************************************** Kører test på evalueringer *************************************************** Tid for 100.000 evalueringer 7762 Tid for 10.000 pawneval 196 Tid for 10.000 knighteval 41 Tid for 10.000 bishopeval 30 Tid for 10.000 rookeval 123 Tid for 10.000 queeneval 5 Tid for 10.000 kingeval 4 EFTER OPTIMERING (v1.31) *************************************************** Kører test på evalueringer *************************************************** Tid for 100.000 evalueringer 4152 Tid for 10.000 pawneval 75 Tid for 10.000 knighteval 39 Tid for 10.000 bishopeval 26 Tid for 10.000 rookeval 35 Tid for 10.000 queeneval 4 Tid for 10.000 kingeval 4
Pawns (Bønder)
Pawns starter på 100 points.
- Isolerede bønder får straf for hvilken file de står på.
- Bønder på samme file, der ikke er isolerede får 12 p i straf.
- Bønder der ikke er dækket bagfra (backward pawn) får 6 point i straf.
- Bønder der ikke er dækket bagfra (backward pawn), med en halv åben file til den ene eller den anden side får 4 point i straf.
- Bønder der rykker frem i midten får 4 p per rank (i starten af spillet), 8 p i slutningen. fremryk i siden giver mindre point. (Om det er slutningen af et spil, kan måske afgøred udfra fra tid/resterende tid, antal brikker, antal træk).
- Bønder på e og d files får 10 point straf hvis de befinder sig på rank to. yderligere 15 p hvis de er blocked.
- Bønder inden for 2 ryk af kongen får 10 p bonus.
- "Passed" bønder får bonus point for hver rank de rykker frem (som funktion af spillet fremskred), og om modstanderen blokker eller kan angribe et eller flere felter frem, eller om modstanderen konge er i nærheden af bonden. Denne bonus går fra 15 point til blokkeret bonde på rank 2, til 300 point til en unblocked pawn der ikke kan stoppes fra queening.
public static int evalPawn(Piece pawn, Board board) { int points = 100; byte position = pawn.getPos(); // Tjekker nummer 1, om en bonde er isoleret. Variable straf 12 - 20 int surroundings[] = new int[] { -11, -10, -9, -1, 1, 9, 10, 11 }; int penalty[] = new int[] { 12, 14, 16, 20, 20, 16, 14, 12 }; boolean isolated = true; for (int i = 0; i < surroundings.length; i++) { if (board.getBoard()[position - surroundings[i]] == pawn.getType()) { isolated = false; break; } } if (isolated) points -= penalty[pawn.getFile() - 1]; // skal lige rettes // Tjekker nummer 2, om bønder er på samme file. Ikke isolerede får // 12 point i straf. surroundings = new int[] { -10, 10 }; for (int i = 0; i < surroundings.length; i++) { if (board.getBoard()[position - surroundings[i]] == pawn.getType()) { points -= 12; break; } } // Tjekker nummer 3, om en pawn er en backward pawn. Straf 6p if (pawn.getType() == Piece.WPAWN) surroundings = new int[] { -9, -11, -1, 1 }; else if (pawn.getType() == Piece.BPAWN) surroundings = new int[] { 9, 11, -1, 1 }; boolean backwardpawn = true; for (int i = 0; i < surroundings.length; i++) { if (board.getBoard()[position - surroundings[i]] == pawn.getType()) { backwardpawn = false; break; } } if (backwardpawn) { points -= 6; // Tjekker nummer 4, om en backwardpawn har en halvåben file til den // ene eller anden side. Straf 4p. boolean leftSideIsOpen = true; boolean rightSideIsOpen = true; // 20+10+file // Nederste og øverste felt behøver vi ikke kigge på. Nederst kommer // ens bonde aldrig. Øverst bliver ens bonde promoted if (pawn.getType() == Piece.WPAWN) { for (int i = 1; i < 7; i++) { if (board.getBoard()[20 + pawn.getFile() - 1 + i * 10] == 100) { leftSideIsOpen = false; break; } if (board.getBoard()[20 + pawn.getFile() - 1 + i * 10] == pawn.getType()) { leftSideIsOpen = false; } } for (int i = 1; i < 7; i++) { if (board.getBoard()[20 + pawn.getFile() + 1 + i * 10] == 100) { rightSideIsOpen = false; break; } if (board.getBoard()[20 + pawn.getFile() + 1 + i * 10] == pawn.getType()) { rightSideIsOpen = false; } } } if (pawn.getType() == Piece.BPAWN) { for (int i = 1; i < 7; i++) { if (board.getBoard()[80 + pawn.getFile() + 1 - i * 10] == 100) { leftSideIsOpen = false; break; } if (board.getBoard()[80 + pawn.getFile() + 1 - i * 10] == pawn.getType()) { leftSideIsOpen = false; } } for (int i = 1; i < 7; i++) { if (board.getBoard()[80 + pawn.getFile() - 1 - i * 10] == 100) { rightSideIsOpen = false; break; } if (board.getBoard()[80 + pawn.getFile() - 1 - i * 10] == pawn.getType()) { rightSideIsOpen = false; } } } if (leftSideIsOpen || rightSideIsOpen) points -= 4; } // Tjekker nummer 5, bønder der rykker frem får bonus int[] filePoint = { 1, 2, 3, 4, 4, 3, 2, 1 }; // (pawn.getRank()-2), sørger for at man ikke får point når man står i // startpositionen // filePoint[pawn.getFile()] - antal point varierer ud fra den file man // står på // EvalTools.getGameProgress(board) / 10 - hvor langt er vi i spillet. // Ganges med hvor man står på boardet if (pawn.getType() == Piece.WPAWN) points += (double) ((pawn.getRank() - 2) * filePoint[pawn.getFile() - 1] + (double) ((double) EvalTools.getGameProgress(board)) / 10 * (double) ((pawn.getRank() - 2) * filePoint[pawn.getFile() - 1])); else if (pawn.getType() == Piece.BPAWN) points += (double) (7 - (pawn.getRank()) * filePoint[pawn.getFile() - 1] + (double) ((double) EvalTools.getGameProgress(board)) / 10 * (double) ((pawn.getRank() - 2) * filePoint[pawn.getFile() - 1])); // Tjekker nummer 6, bønder på e/d får 10p straf, hvis de er på rank 2. // Yderligere 15p hvis blocked if (pawn.getType() == Piece.WPAWN) { if (pawn.getRank() == 2 && (pawn.getFile() == 4 || pawn.getFile() == 5)) { points -= 10; if ((board.getBoard()[board.D3] != 0 && pawn.getFile() == 4) || (board.getBoard()[board.E3] != 0 && pawn.getFile() == 5)) points -= 15; } } else if (pawn.getType() == Piece.BPAWN) { if (pawn.getRank() == 7 && (pawn.getFile() == 4 || pawn.getFile() == 5)) { points -= 10; if ((board.getBoard()[board.D6] != 0 && pawn.getFile() == 4) || (board.getBoard()[board.E6] != 0 && pawn.getFile() == 5)) points -= 15; } } // Tjekker nummer 7, 10p bonus hvis man befinder sig inden for 2 ryk fra // kongen // pawn.getType()*6[0] returnerer spillerens egen konge. if (EvalTools.getTaxicabDistance(pawn, board.getPiecesOfType((byte) (pawn.getType() * 6)).get(0), board) <= 2) points += 10; // Tjekker nummer 8, "Passed" bønder får bonus point for hver rank de // rykker frem // (som funktion af spillet fremskred), og om modstanderen blokker eller // kan angribe // et eller flere felter frem, eller om modstanderen konge er i nærheden // af bonden. // Denne bonus går fra 15 point til blokkeret bonde på rank 2, til 300 // point til en unblocked // pawn der ikke kan stoppes fra queening. boolean isPassed = true; // kigger alle brikker igennem for (Piece p : board.getPieces()) { // hvis brikken er mine egen -> continue if ((p.getType() > 0 && pawn.getType() > 0) || (p.getType() < 0 && pawn.getType() < 0)) continue; // tjekker om nogen af modstanderens brikker kan tage felter // foran bonden byte[] moves = board.getLegalMoves(p); for (byte move : moves) { if (pawn.getType() == Piece.WPAWN && move % 10 == pawn.getFile() % 10 && move > pawn.getPos()) { System.out.println("Brik: " + p.getType() + " felt: " + move + " attackerpos: " + p.getPos()); isPassed = false; break; } else if (pawn.getType() == Piece.BPAWN && move % 10 == pawn.getFile() % 10 && move < pawn.getPos()) { isPassed = false; break; } } if (!isPassed) break; } // tjekker om vejen foran bonden er ikke ledige if (pawn.getType() == Piece.WPAWN && isPassed) { for (int i = pawn.getPos() + 10; i <= 98; i += 10) { if (board.getBoard()[i] != 0) { isPassed = false; break; } } } else if (pawn.getType() == Piece.BPAWN && isPassed) { for (int i = pawn.getPos() - 10; i >= 21; i -= 10) { if (board.getBoard()[i] != 0) { isPassed = false; break; } } } // hvis bonden er passed gives der point if (pawn.getType() == Piece.WPAWN && isPassed) { points += ((double) ((double) EvalTools.getGameProgress(board) / (double) 20) + (double) ((pawn.getRank() - 2)) / 12) * (double) 300; } if (pawn.getType() == Piece.BPAWN && isPassed) { points += ((double) ((double) EvalTools.getGameProgress(board) / (double) 20) + (double) ((7 - pawn.getRank())) / 12) * (double) 300; } return points; }
Knights (Springer)
Får tildelt 330 point.
- Knights får bonus for hvor tæt de er på midten. Varierer fra 0p i hjørner til 30p hvis de er i midten.
- Får bonus for at være indenfor 2 ryk fra fjenden. Funktion af spillets fremskred. 4p i slutningen af spillet
- Straf på 1p pr. felt for afstanden til hver konge.
- Op til 8p bonus (afhænger af spillets fremskred) for en Knight som fjendens bønder ikke kan få til at flytte sig.
Bishop (Løber)
Får tildelt 330 point.
- (done) Får bonus som brikker bliver slået ud fra pladen. 10p i slutningen af spillet (ændret til 32 point i slutningen)
- (venter) Får bonus for mobilitet og X-ray mobilitet gennem brikker (ikke pawns). Fra -4p for helt blokkeret bishop til 18p for at angribe mindst 12 felter.
- (venter) X-ray angreb på R,Q,K eller en udefineret brik giver 8p.
- (done) Får 14p i bonus hvis de er ved kanten, og op til 22p hvis de er i midten.
- (done) Får 5p for et angreb på et felt der ligger lige op til fjendens konge.
- (done) This bonus ranges from -4 points for a totally blocked bishop up to 18 points for a bishop attacking 12 or more squares.
public int evalBishop(Piece bishop, Board board) { int points = 330; double piecesLeft = board.getPieces().size(); points += 32 - piecesLeft; // Nr. x: Bonus for afstand til midten. 0 i hjørner, 30 i midten. int[][] distanceFromCenterBonus = {{14,14,14,14,14,14,14,14}, {14,17,17,17,17,17,17,14}, {14,17,20,20,20,20,17,14}, {14,17,20,22,22,20,17,14}, {14,17,20,22,22,20,17,14}, {14,17,20,20,20,20,17,14}, {14,17,17,17,17,17,17,14}, {14,14,14,14,14,14,14,14}}; // finder brikkens position udfra file og rank int[] position = {bishop.getFile(), bishop.getRank()}; points += distanceFromCenterBonus[position[0]][position[1]]; // giver 5 point for hvert felt den kan angribe, der ligger op at modstanderens konge byte kingMoves[] = {-11, -10, -9, -1, 1, 9, 10, 11}; byte kingPos; if (bishop.getType() == Piece.WBISHOP) kingPos = board.getPiecesOfType(Piece.BKING).get(0).getPos(); else kingPos = board.getPiecesOfType(Piece.WKING).get(0).getPos(); byte[] bishopMoves = board.getLegalMoves(bishop); for (int i = 0; i < kingMoves.length; i++) { for (byte b : bishopMoves) { if (kingPos - kingMoves[i] == b) points += 5; } } // giver point alt efter hvor mange felter løberen kan tage int moves = board.getLegalMoves(bishop).length; if (moves == 0) points -= 4; else if (moves == 1) points -= 2; else if (moves <= 12){ points += ((double)(moves-2) / (double)10 * 18); } else { points += 18; } return points; }
Rook (Tårn)
Får tildelt 520 point.
- (done) Som med Bishops får Rooks point for mobilitet. Fra 0p hvis blokkeret op til 20p hvis angriber 12+ felter.
- (venter) 8p bonus for X-ray angreb.
- (done) 10p bonus for at være på en file, der ikke indeholder nogle af egne bønder. Yderligere 4, hvis ingen fjendtlige bønder.
- (done) Efter åbning straffes Rooks udfra taxicab-afstanden til fjendens konge.
public int evalRook(Piece rook, Board board) { int points = 520; // giver point alt efter hvor mange felter tårnet kan tage int moves = board.getLegalMoves(rook).length; if (moves <= 12){ points += ((double)moves / (double)12 * 20); } else { points += 20; } // tjekker om der er bønder på tårnets file int file = rook.getFile(); boolean foundEnemyPawn = false; boolean foundOwnPawn = false; if (rook.getType() == Piece.BROOK) { for (int i = 20 + file; i <= 98; i += 10) { if (board.getPieceAtPos((byte) i).getType() == Piece.WPAWN) foundEnemyPawn = true; if (board.getPieceAtPos((byte) i).getType() == Piece.BPAWN) foundOwnPawn = true; } } else if (rook.getType() == Piece.WROOK) { for (int i = 20 + file; i <= 98; i += 10) { if (board.getPieceAtPos((byte) i).getType() == Piece.BPAWN) foundEnemyPawn = true; if (board.getPieceAtPos((byte) i).getType() == Piece.WPAWN) foundOwnPawn = true; } } if (!foundOwnPawn) points += 10; if (!foundEnemyPawn) points += 4; // Straffes udfra taxicabafstand til fjendens konge. 10p pr. felt byte enemyKingType = (rook.getType() == Piece.WROOK ? Piece.BKING : Piece.WKING); Piece enemyKing = board.getPiecesOfType(enemyKingType).get(0); points -= 5 * EvalTools.getTaxicabDistance(rook, enemyKing, board); return points; }
Queen (Dronning)
Får tildelt 980 point.
- Efter åbning straffes Queen udfra taxicab-afstanden til fjendens konge.
King (Konge)
Får tildelt 1000 point.
- Straffes for at være tæt på midten i starten af spillet (op til 24p)
- Belønnes for at være tæt på midten i slutningen af spillet (op til 36p) -- dog ikke hvis fjenden kun har pawns.
- Kongen straffes for at være på en åben eller halv-åben file, eller hvis den file kongen ligger opad, som er tættest på hjørnet er åben eller halv-åben. Op til 23p i starten, ned til 0p i slutningen.
- Straffes op til 8 point hvis der er ikke er nogen pawn lige ved siden af.
- Der gives straf udfra antallet af "safe" checks der er tilgængelige for modstanderen. Går fra 6p for ét check, op til 50p for 4+.
- Udfra hvor langt inde i spillet vi er, får kongen 10p for castling og helt ned til -40p for at flytte sig før castling.