Skak:Evaluation

Fra DAMNWiki
Spring til navigationSpring til søgning

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.