package com.srs.tetris.bob;

import com.srs.tetris.bob.evaluator.BoardEvaluator;
import com.srs.tetris.bob.evaluator.SapientEvaluator;
import com.srs.tetris.game.Board;
import com.srs.tetris.game.Game;
import com.srs.tetris.game.Piece;
import java.util.ArrayList;
import java.util.List;

public class MoveSelector {
	private Board board;
	private Piece piece;

	//private Piece nextPiece, swapPiece;

	public MoveSelector(Game game) {
		this.board = game.getBoard();
		this.piece = game.getPiece();
		//this.nextPiece = game.getNextPiece();
		//this.swapPiece = game.getSwapPiece();
	}

	public Move getMove() {
		BoardEvaluator evaluator = new SapientEvaluator();

		Board board = this.board.clone();

		// Enumerate all the current moves.
		List<Move> moves = findPossibleMoves(board);

		Move best = null;
		for (Move move : moves) {
			// Draw the piece on the board so we can see what it would look like after.
			Piece piece = this.piece.moveTo(move.getX(), move.getY(), move.getOrientation());
			board.place(piece);

			// Evaluate the position.
			move.setScore(evaluator.evaluate(board));

			// Now remove the piece from the board.
			board.remove(piece);

			// If this move is the best so far, remember it.
			if (best == null || move.getScore().getScore() > best.getScore().getScore()) {
				best = move;
			}
		}

		return best;
	}

	private ArrayList<Move> findPossibleMoves(Board board) {
		ArrayList<Move> moves = new ArrayList<>(board.getWidth() * 4);

		// For each possible orientation.
		for (int orientation = 0; orientation < 4; orientation++) {
			Piece piece = this.piece.moveTo(0, 0, orientation);

			// For each possible horizontal position.
			for (int x = -piece.getBoard().getWidth(); x < board.getWidth(); x++) {
				piece = piece.moveTo(x, 0);
				if (!board.canPlace(piece)) continue;

				// Drop the piece until it lands.
				while (board.canPlace(piece.moveDown())) {
					piece = piece.moveDown();
				}

				moves.add(new Move(piece));
			}
		}

		return moves;
	}
}

@@ -663,25 +663,33 @@
 );%0A%0A%09%09Board 
-b
+originalB
 oard = this.
@@ -702,16 +702,47 @@
 clone();
+%0A%09%09Board board = originalBoard;
 %0A%0A%09%09// E
@@ -873,87 +873,8 @@
 ) %7B%0A
-%09%09%09// Draw the piece on the board so we can see what it would look like after.%0A
 %09%09%09P
@@ -958,23 +958,113 @@
 ));%0A
+%0A
 %09%09%09
-board.place(
+// Draw the piece on the board so we can see what it would look like after.%0A%09%09%09board = doMove(board, 
 piec
@@ -1157,40 +1157,48 @@
 Now 
-remove the piece from the b
+undo the move.%0A%09%09%09board = originalB
 oard
-.
+;
 %0A%09%09%09
@@ -1399,16 +1399,651 @@
 st;%0A%09%7D%0A%0A
+%09private Board doMove(Board board, Piece piece) %7B%0A%09%09// First, place the piece on the board.%0A%09%09board.place(piece);%0A%0A%09%09// Now, remove completed lines, checking only the lines that were impacted by the piece.%0A%09%09Board result = board;%0A%0A%09%09int top = Math.max(0, piece.getY());%0A%09%09int bottom = Math.min(board.getHeight(), top + piece.getBoard().getHeight());%0A%09%09for (int y = top; y %3C bottom; y++) %7B%0A%09%09%09if (result.isLineComplete(y)) %7B%0A%09%09%09%09// This line was complete.  Clone the board if it hasn't been cloned yet and remove it.%0A%09%09%09%09if (result == board) %7B%0A%09%09%09%09%09result = board.clone();%0A%09%09%09%09%7D%0A%09%09%09%09result.removeLine(y);%0A%09%09%09%7D%0A%09%09%7D%0A%0A%09%09return result;%0A%09%7D%0A%0A
 %09private

Remove the completed lines from a position before evaluating it