package player.gamer.statemachine.sadna;


/**
 * Player used to Connect Four training
 */
public class TrainingPlayer {

	private final static int REWARD = 1;
	
	private Board board = new Board();
	private WeightUpdater updater;
	private ActionChooser actionChooser;
	
	public TrainingPlayer(double[] startingWeights, int treeDepth) {
		updater = new TDWeightUpdater(startingWeights);
		actionChooser = new MinMaxTreeActionChooser(new ScoreCalculator(updater), true, treeDepth);
	}
	
	public TrainingPlayer(double[] startingWeights) {
		updater = new TDWeightUpdater(startingWeights);
		actionChooser = new MinMaxTreeActionChooser(new ScoreCalculator(updater), true);
	}

	/**
	 * Play one move in Connect Four game
	 * @param opponentMove The last move the opponent made
	 * @return the move the player made (the column it drop the coin in)
	 */
	public int playMove(int opponentMove) {
		
		// update board with opponent move
		if (opponentMove != -1) {
			board.setCoin(opponentMove, Coin.OPPONENT);
		}
		
		// play
		int action = actionChooser.getAction(board);
		
		// update weights vector - besides when winning, always update after opponent move
		if (board.didWin()) {
			board.setCoin(action, Coin.PLAYER);
			updater.updateWeights(board, REWARD); 
		} else {
			updater.updateWeights(board, 0);
			board.setCoin(action, Coin.PLAYER); // only update coin in board after updating weights vector
		}
		
		return action;
	}
	
	public boolean didWin() {
		return board.didWin();
	}
	
	public double[] getWeights() {
		return updater.getWeights();
	}
	
	/**
	 * Opponent won the game
	 * @param opponentMove The last move the opponent made
	 */
	public void opponentWon(int opponentMove) {
		board.setCoin(opponentMove, Coin.OPPONENT);
		updater.updateWeights(board, -REWARD);
	}
}
