package edu.dartmouth.cs.kalah;

/**
 *  Kalah.java
 * @author Scot Drysdale on 5/26/96, converted to Java on 5/28/00
 * Updated to use Scanner on 5/23/08.  
 * modified 7/2011 to use Model-View-Controller pattern

 * Loosely based on an earlier Pascal program, which in turn was inspired
 * by an SBASIC program by Steve Garland.

 * Kalah is an ancient African game played on a board containing 14 pits, 
 * 7 belonging to each player: 

 *                       Computer's pits                  ______________________________________                   
 *              |       13   12   11   10   9   8      |    
 *  User's      |  0                                7  |   Computer's 
 *  Kalah       |        1    2    3    4   5   6      |   Kalah
 *               ______________________________________
 *                          User's pits         

 * Initially, each of the side pits contains the same number of stones 
 * (traditionally 6).  The kalahs are empty.  A play consists of picking up all 
 * of the stones in one of the 6 pits on the mover's side of the board and 
 * depositing them one at a time in each of the pits around the board in a 
 * clockwise direction, skipping the opponent's kalah.  Play normally alternates.

 * Two rules make the game challenging.  If the last stone dropped ends up in the 
 * player's own kalah the player moves again.  If the last stone dropped ends up 
 * in an empty pit on the player's side opposite a non-empty pit on the opponent's 
 * side, all stones in both pits are moved to the player's kalah. 

 * The game ends when the player whose move it is has no stones left in any of 
 * his or her pits.  All stones on the opponent's side are moved to the opponent's
 * kalah.  The winner is the player with the most stones in the kalah at the end 
 * of the game. 

 * This program uses game tree search to look ahead a fixed number of turns 
 * (changes of move) to pick a good move for the computer.
 * 
 *  This class is the "controller" part of the model-view-controller pattern.
 */

public class Kalah
{

  public static void main(String args[]) 
  {
    int finalScore;                   // Hold final score in game
    
    // Hold the view methods.  Also whether the update should be 
    // incremental (display changes as they occur) or all at once.
    KalahView view = new KalahViewGraphical();
    boolean updateIncrementally = true;   
    
    KalahPlayer [] players = new KalahPlayer[2];                // Array to hold the players
    
    // Initialize the game 

    players[0] = makePlayer(view, "first");
    players[1] = makePlayer(view, "second");
    
    // Hold current game state
    KalahGame state = new KalahGame(0, players, view);  

    view.display(state);

    while (!state.gameIsOver()) 
    {
    	int move = state.getPlayerToMove().getMove(state, view);
    	if(updateIncrementally)
    	  state.makeMoveIncrementally(move);
    	else
    		state.makeMove(move);
    	view.display(state);
    }
    
    finalScore = state.score();       // Get the score from current player's view 

    if (finalScore > 0)
      view.reportToUser(players[state.getPlayerNum()].getName() + " wins by " + finalScore);
    else if (finalScore < 0)
      view.reportToUser(players[1 - state.getPlayerNum()].getName() + " wins by " + -finalScore);
    else
      view.reportToUser("It is a draw");
  }
  
  /** 
   * Constructs a Kalah player.  If the name contains "Computer" it
   * constructs a computer player; else a human player
   * @param view the view to use to communicate to the world
   * @param playerMsg the player to ask for 
   * @return
   */
  public static KalahPlayer makePlayer(KalahView view, String playerMsg) {
    String playerName = view.getAnswer("Enter the name of the " + playerMsg + 
    		" player." + "\n(Include 'Computer' in the name of a computer player) ");
    if(playerName.contains("Computer")) {
    	int depth = view.getIntAnswer("How far should I look ahead? ");
      return new ComputerKalahPlayerAB(playerName, depth);
    }
    else
      return new HumanKalahPlayer(playerName);
  }
}
