/*
 * Copyright (C) 2013-2014 Phokham Nonava
 *
 * Use of this source code is governed by the MIT license that can be
 * found in the LICENSE file.
 */
package com.fluxchess.pulse;

import java.lang.reflect.Array;

/**
 * This class stores our moves for a specific position. For the root node we
 * will populate pv for every root move.
 */
final class MoveList<T extends MoveList.MoveEntry> {

  private static final int MAX_MOVES = 256;

  final T[] entries;
  int size = 0;

  static final class MoveVariation {
    final int[] moves = new int[Depth.MAX_PLY];
    int size = 0;
  }

  static class MoveEntry {
    int move = Move.NOMOVE;
    int value = Value.NOVALUE;
  }

  static final class RootEntry extends MoveEntry {
    final MoveVariation pv = new MoveVariation();
  }

  MoveList(Class<T> clazz) {
    @SuppressWarnings("unchecked")
    final T[] entries = (T[]) Array.newInstance(clazz, MAX_MOVES);
    this.entries = entries;
    try {
      for (int i = 0; i < entries.length; ++i) {
        entries[i] = clazz.newInstance();
      }
    } catch (InstantiationException | IllegalAccessException e) {
      throw new IllegalStateException(e);
    }
  }

  /**
   * Sorts the move list using a stable insertion sort.
   */
  void sort() {
    for (int i = 1; i < size; ++i) {
      T entry = entries[i];

      int j = i;
      while ((j > 0) && (entries[j - 1].value < entry.value)) {
        entries[j] = entries[j - 1];
        --j;
      }

      entries[j] = entry;
    }
  }

  /**
   * Rates the moves in the list according to "Most Valuable Victim - Least Valuable Aggressor".
   */
  void rateFromMVVLVA() {
    for (int i = 0; i < size; ++i) {
      int move = entries[i].move;
      int value = 0;

      int piecetypeValue = PieceType.getValue(Piece.getType(Move.getOriginPiece(move)));
      value += PieceType.KING_VALUE / piecetypeValue;

      int target = Move.getTargetPiece(move);
      if (Piece.isValid(target)) {
        value += 10 * PieceType.getValue(Piece.getType(target));
      }

      assert value >= (PieceType.KING_VALUE / PieceType.KING_VALUE)
          && value <= (PieceType.KING_VALUE / PieceType.PAWN_VALUE) + 10 * PieceType.QUEEN_VALUE;

      entries[i].value = value;
    }
  }

}

@@ -208,16 +208,392 @@
 Array;%0A%0A
+import static com.fluxchess.pulse.Move.NOMOVE;%0Aimport static com.fluxchess.pulse.Move.getOriginPiece;%0Aimport static com.fluxchess.pulse.Move.getTargetPiece;%0Aimport static com.fluxchess.pulse.PieceType.KING_VALUE;%0Aimport static com.fluxchess.pulse.PieceType.PAWN_VALUE;%0Aimport static com.fluxchess.pulse.PieceType.QUEEN_VALUE;%0Aimport static com.fluxchess.pulse.Value.NOVALUE;%0A%0A
 /**%0A * T
@@ -997,21 +997,16 @@
  move = 
-Move.
 NOMOVE;%0A
@@ -1021,22 +1021,16 @@
 value = 
-Value.
 NOVALUE;
@@ -2143,21 +2143,16 @@
 getType(
-Move.
 getOrigi
@@ -2182,26 +2182,16 @@
 alue += 
-PieceType.
 KING_VAL
@@ -2231,21 +2231,16 @@
 arget = 
-Move.
 getTarge
@@ -2385,26 +2385,16 @@
 lue %3E= (
-PieceType.
 KING_VAL
@@ -2398,26 +2398,16 @@
 VALUE / 
-PieceType.
 KING_VAL
@@ -2433,26 +2433,16 @@
 lue %3C= (
-PieceType.
 KING_VAL
@@ -2446,26 +2446,16 @@
 VALUE / 
-PieceType.
 PAWN_VAL
@@ -2465,26 +2465,16 @@
  + 10 * 
-PieceType.
 QUEEN_VA

Add static import in MoveList