// Arup Guha
// 3/3/2017
// Solution to Junior Knights OOP Problem War (War class)

import java.util.*;

public class War {

	final public static int MAXROUNDS = 1000;

	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);
		System.out.println("How many players are playing (2,4 or 13)?");
		int numPlayers = stdin.nextInt();

		// Make a new deck and fill it.
		CollectionOfCards deck = new CollectionOfCards();
		deck.fillDeck();
		deck.shuffle();

		// Create empty hands for each player.
		CollectionOfCards[] players = new CollectionOfCards[numPlayers];
		for (int i=0; i<players.length; i++)
			players[i] = new CollectionOfCards();

		// Deal the cards.
		deal(deck, players);

		// Play the game for 1000 rounds.
		playGame(players, MAXROUNDS);

		// Print out the end outcomes.
		printOutcome(players);
	}

	public static void playGame(CollectionOfCards[] players, int max) {

		// Keep track of who has exited.
		int numPlayers = players.length;
		boolean[] exited = new boolean[numPlayers];

		int rounds = 0;

		// Just get everyone who has cards.
		ArrayList<Integer> playList = getPlayList(players);

		// Keep on playing until one player has ALL of the cards!
		while (playList.size() > 1 && rounds < max) {

			// Store all discarded cards here.
			ArrayList<Card> discard = new ArrayList<Card>();

			// Get first player's discarded card.
			Card bestCard = players[playList.get(0)].removeFromTop();
			int bestPlayer = playList.get(0);
			discard.add(bestCard);

			// Print this play.
			System.out.println("Player "+bestPlayer+" plays "+bestCard);

			// Now, let the rest play.
			for (int i=1; i<playList.size(); i++) {

				// Next player discards.
				Card tmp = players[playList.get(i)].removeFromTop();
				discard.add(tmp);

				// Show what this player plays.
				System.out.println("Player "+playList.get(i)+" plays "+tmp);

				// This is better!
				if (tmp.compareTo(bestCard) > 0) {
					bestPlayer = playList.get(i);
					bestCard = tmp;
				}
			}

			// Print the outcome of the round.
			System.out.println("Player "+bestPlayer+" wins the round with card "+bestCard);

			// Give the winner all of the cards from the discard pile.
			for (Card c : discard)
				players[bestPlayer].addCard(c);
			players[bestPlayer].wonRound();

			// Separate out round output from exiting output.
			System.out.println();

			// Go through all players to see who has exited.
			for (int i=0; i<numPlayers; i++) {
				if (players[i].size() == 0 && !exited[i]) {
					System.out.println("Player "+i+" has exited the game with "+players[i].numWins()+" rounds won.");
					exited[i] = true;
				}
			}

			// For the next round.
			playList = getPlayList(players);
			rounds++;

			// Just to nicely separate output for each round.
			System.out.println();
			System.out.println("--------------------------------------------------------");
			System.out.println();
		}
	}

	public static void printOutcome(CollectionOfCards[] players) {

		// Just get everyone who has cards.
		ArrayList<Integer> playList = getPlayList(players);

		// Got a unique winner.
		if (playList.size() == 1) {

			// Print out the winner.
			System.out.println("The winner is player "+playList.get(0)+" with "+players[playList.get(0)].numWins()+" rounds won.");
		}

		// More than 1 team still alive
		else {

			// Print out losers.
			for (int i=0; i<players.length; i++) {
				if (!playList.contains(i))
					System.out.println("Sorry, player "+i+" you lost all of our cards in the game.");
			}
			System.out.println();

			// Now, print players still alive.
			System.out.println("There was no one winner, but here are the tallies for each player still in the game.");
			System.out.println("Player\tWins\tNum Cards Left");
			for (int i : playList)
				System.out.println(i+"\t"+players[i].numWins()+"\t"+players[i].size());
		}
	}

	public static ArrayList<Integer> getPlayList(CollectionOfCards[] players) {

		// Store answers here.
		ArrayList<Integer> res = new ArrayList<Integer>();

		// Just add everyone who can play.
		for (int i=0; i<players.length; i++)
			if (players[i].canPlay())
				res.add(i);
		return res;
	}

	public static void deal(CollectionOfCards thisDeck, CollectionOfCards[] players) {

		int i = 0;

		// Go till the deck is done.
		while (thisDeck.size() > 0) {

			// Deal this card.
			players[i].addCard(thisDeck.removeFromTop());

			// Go to the next player.
			i = (i + 1)%players.length;
		}
	}
}