package org.lichess.compression.game;

import java.util.Comparator;

public class MoveComparator implements Comparator<Move> {

    private final Board board;

    public MoveComparator(Board board) {
        this.board = board;
    }

    @Override
    public int compare(Move a, Move b) {
        if (a.promotion != b.promotion) {
            if (a.promotion == null) return 1;
            else if (b.promotion == null) return -1;
            else return Integer.compare(b.promotion.index, a.promotion.index);
        }

        if (a.capture != b.capture) {
            if (a.capture) return -1;
            else return 1;
        }

        if (a.to != b.to) return Integer.compare(a.to, b.to);

        return Integer.compare(a.from, b.from);
    }

    private static int PQST[][] = {
        {   0,  0,  0,  0,  0,  0,  0,  0,
           50, 50, 50, 50, 50, 50, 50, 50,
           10, 10, 20, 30, 30, 20, 10, 10,
            5,  5, 10, 25, 25, 10,  5,  5,
            0,  0,  0, 20, 20,  0,  0,  0,
            5, -5,-10,  0,  0,-10, -5,  5,
            5, 10, 10,-20,-20, 10, 10,  5,
            0,  0,  0,  0,  0,  0,  0,  0 },

        { -50,-40,-30,-30,-30,-30,-40,-50,
          -40,-20,  0,  0,  0,  0,-20,-40,
          -30,  0, 10, 15, 15, 10,  0,-30,
          -30,  5, 15, 20, 20, 15,  5,-30,
          -30,  0, 15, 20, 20, 15,  0,-30,
          -30,  5, 10, 15, 15, 10,  5,-30,
          -40,-20,  0,  5,  5,  0,-20,-40,
          -50,-40,-30,-30,-30,-30,-40,-50 },

        { -20,-10,-10,-10,-10,-10,-10,-20,
          -10,  0,  0,  0,  0,  0,  0,-10,
          -10,  0,  5, 10, 10,  5,  0,-10,
          -10,  5,  5, 10, 10,  5,  5,-10,
          -10,  0, 10, 10, 10, 10,  0,-10,
          -10, 10, 10, 10, 10, 10, 10,-10,
          -10,  5,  0,  0,  0,  0,  5,-10,
          -20,-10,-10,-10,-10,-10,-10,-20 },

        {   0,  0,  0,  0,  0,  0,  0,  0,
            5, 10, 10, 10, 10, 10, 10,  5,
           -5,  0,  0,  0,  0,  0,  0, -5,
           -5,  0,  0,  0,  0,  0,  0, -5,
           -5,  0,  0,  0,  0,  0,  0, -5,
           -5,  0,  0,  0,  0,  0,  0, -5,
           -5,  0,  0,  0,  0,  0,  0, -5,
            0,  0,  0,  5,  5,  0,  0,  0 },

        { -20,-10,-10, -5, -5,-10,-10,-20,
          -10,  0,  0,  0,  0,  0,  0,-10,
          -10,  0,  5,  5,  5,  5,  0,-10,
           -5,  0,  5,  5,  5,  5,  0, -5,
            0,  0,  5,  5,  5,  5,  0, -5,
          -10,  5,  5,  5,  5,  5,  0,-10,
          -10,  0,  5,  0,  0,  0,  0,-10,
          -20,-10,-10, -5, -5,-10,-10,-20 },

        { -30,-40,-40,-50,-50,-40,-40,-30,
          -30,-40,-40,-50,-50,-40,-40,-30,
          -30,-40,-40,-50,-50,-40,-40,-30,
          -30,-40,-40,-50,-50,-40,-40,-30,
          -20,-30,-30,-40,-40,-30,-30,-20,
          -10,-20,-20,-20,-20,-20,-20,-10,
           20, 20,  0,  0,  0,  0, 20, 20,
           20, 30, 10,  0,  0, 10, 30, 20 }
    };
}

@@ -643,108 +643,516 @@
    i
-f (a.to != b.to) return Integer.compare(a.to, b.to);%0A%0A        return Integer.compare(a.from, b.from)
+nt cmpMoveValue = Integer.compare(moveValue(b), moveValue(a));%0A        if (cmpMoveValue != 0) return cmpMoveValue;%0A%0A        if (a.to != b.to) return Integer.compare(a.to, b.to);%0A%0A        return Integer.compare(a.from, b.from);%0A    %7D%0A%0A    private int moveValue(Move move) %7B%0A        return pieceValue(move.role, move.to) - pieceValue(move.role, move.from);%0A    %7D%0A%0A    private int pieceValue(Role role, int square) %7B%0A        if (this.board.turn) square %5E= 0x38; // mirror%0A        return PQST%5Brole.index%5D%5Bsquare%5D
 ;%0A  

use move value heuristic