/*
 * jeu de dé
 * par Martin Robinson
 * Créez ensuite une classe JeuDes avec un main qui exécutera un programme de jeu de dés.
 * */

package lab2;

import librairyMR.Affichable;

/**
 * dice game
 * @author martin
Créez ensuite une classe JeuDes avec un main qui exécutera un programme de jeu de dés.
 */
public class diceGame implements Affichable{
	/*properties*/
	final Player [] _players;
	final int _turn;
	final De _de6 = De.fromNface(6);

	/*constructor*/
	/**
	 * private constructor
	 * use static factory
	 * @param players
	 * @param turn
	 */
	private diceGame(final Player [] players, int turn){
		//no defensive copy here, static factory do it for us
		_players = players;
		_turn = turn;
	}

	/*static factory*/
	/**
	 * build two player game
	 * @param player1 as String name
	 * @param player2 as String name
	 * @return new two player game
	 */
	public static diceGame fromTwoPlayer(final String player1, final String player2){
		Player[] tmp = {Player.fromNewName(player1), Player.fromNewName(player2)};
		return new diceGame(tmp, 0);
	}

	/**
	 * create new game from Player array
	 * @param players[] as Player array
	 * @return new game
	 */
	public static diceGame fromPlayerArray(final Player[] players){
		return fromPlayerArrayAndTurn(players, 0);
	}

	/**
	 * create new game from Player array at given turn
	 * @param players as Player array
	 * @param turn as int turn number
	 * @return new game
	 */
	public static diceGame fromPlayerArrayAndTurn(final Player[] players, int turn){
		//defensive copy
		Player [] tmp = new Player[players.length];
		for (int i=0;i<players.length;i++){
			tmp[i] = players[i];
		}
		return new diceGame(tmp, turn);
	}

	/*getter*/
	/**
	 * @return turn
	 */
	public int getTurn(){
		return _turn;
	}

	/**
	 * @param i as player index
	 * @return Player
	 */
	public Player getPlayer(int i){
		if (i < _players.length)
			return _players[i];
		throw new ArrayIndexOutOfBoundsException();
	}

	/**
	 * @return winner as Player
	 */
	public Player getWinner(){
		Player winner = _players[0];
		for (int i=1;i<_players.length;i++)
			if (winner.getScore() < _players[i].getScore())
				winner = _players[i];
		return winner;
	}

	/*immutator*/
	/**
	 * @return new game with turn + 1
	 */
	public diceGame rollTurn(){
		Player [] tmp = new Player[_players.length];
		for (int i=0;i<_players.length;i++)
			tmp[i] = _players[i].addScore(_de6.roll());
		return diceGame.fromPlayerArrayAndTurn(tmp, getTurn()+1);
	}

	//Affichable interface
	/* (non-Javadoc)
	 * @see librairyMR.Affichable#affiche()
	 */
	public void affiche() {
		System.out.println("turn : " + getTurn());
		for (int i=0;i<_players.length;i++){
			System.out.print("    " + _players[i].getName() + " : ");
			System.out.println(_players[i].getScore());
		}
	}

	/*main*/
	public static void main(String [ ] args){
		/*
		Lise et Henri jouent aux dés. A chaque tour de jeu chacun lance un dé et marque le nombre de points
		marqués par le dé. Celui qui gagne est celui qui atteint 21 points en premier ou le plus de points en
		dix tours de jeu. Affichez les dés de chaque tour et les totaux de chaque joueur après chaque tour et
		à la fin du jeu, affichez le nom du gagnant.
		 * */

		diceGame jeux = diceGame.fromTwoPlayer("Lise", "Henri");
		while(jeux.getTurn()<20){
			jeux = jeux.rollTurn();
			jeux.affiche();
		}

		System.out.print(jeux.getWinner().getName());
		System.out.println(" win");
	}
}
