Untitled

mail@pastecode.io avatar
unknown
plain_text
7 months ago
8.9 kB
2
Indexable
Never
package sezione15.javaCollections.esercitazione5.pokerChallenge;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Random;

import sezione15.javaCollections.esercitazione3.cardChallenge.model.Card;
import sezione15.javaCollections.esercitazione5.pokerChallenge.model.Player;
import sezione15.javaCollections.esercitazione5.pokerChallenge.util.Console;

public class GameController {

	private String gameName;
	private List<Player> players;
	private List<Card> deck;
	private static final int MIN_NUM_PLAYER = 2;
	private static final int MAX_NUM_PLAYER = 10;
	private static final int MAX_NUM_CARDS_FOR_SET = 5;
	private static final int MAX_NUM_CARD_CAN_BE_REMOVED = 3;
	
	
	public GameController() {
		gameName = "High's score";
		this.players = new ArrayList<Player>();
		
	}
	
	public boolean addPlayers(List<Player> players) {
		int numPlayersToAdd = players.size();
		if( numPlayersToAdd + this.players.size() <= MAX_NUM_PLAYER) {
			players.forEach(p -> {		
				addPlayer(p);
			});
			return true;
		} else {
			var numPossiblePlayersToAdd = MAX_NUM_PLAYER - this.players.size();
			System.err.println("Can't add " + numPlayersToAdd + " more players. Its possible to add maximun another " + numPossiblePlayersToAdd + " players");
		}
		return false;
	}
	
	public boolean addPlayer(Player player) {
		if(this.players.size() < MAX_NUM_PLAYER) {
			if(this.players.contains(player)) {
				System.err.println(player.getName() + " is already in the game");
			} else {
				this.players.add(player);
				System.out.println(player.getName() + " is added");
				return true;
			}
		}
		return false;
	}
	
	public boolean start() {
		if(players.size() >= MIN_NUM_PLAYER) {
			deck = Card.getStandardDeck();
			shuffleDeck();
			cutDeck();
			dealsCards();
			printPlayerSets();
//			System.out.println(this);
			return true;
		}
		System.err.println("There must be at least " + MIN_NUM_PLAYER +" players");
		return false;
	}
	
	public String getName() {
		return gameName;
	}

	public List<Player> getPlayers() {
		return players;
	}

	public List<Card> getDeck() {
		return deck;
	}

	public boolean changeCards(Player player, List<Card> cards) {
		Objects.requireNonNull(player);
		Objects.requireNonNull(cards);
		
		if(!players.contains(player)) {
			System.err.println("No such player with the name " + player.getName() +" is in the game");
			return false;
		}
		
		if(player.getNumCardsRemoved() > MAX_NUM_CARD_CAN_BE_REMOVED) {
			System.err.println("The player " + player.getName() + " has already removed " + MAX_NUM_CARD_CAN_BE_REMOVED + " cards");
			return false;
		}
		
		if(cards.size() > MAX_NUM_CARD_CAN_BE_REMOVED) {
			System.err.println("Its possible to change max " + MAX_NUM_CARD_CAN_BE_REMOVED + " cards");
			return false;
		}
		
		if(cards.size() < 1) {
			System.err.println("No card to change");
			return false;
		}
		
		if(cards.size() > getNumCardsLeft()) {
			System.err.println("No card left in the deck");
			return false;
		}
		
		for(var card : cards) {
			if(player.removeCard(card)) {
				System.out.println("The player " + player.getName()+ " remove the card " + card);
				player.addCard(deck.get(0));
				deck.remove(0);
			}
		}
		setScore();
		return true;
	}
	
	public boolean changeCards(Player player, Card... cards) {
		var listOfCards = new ArrayList<Card>();
		for(var c : cards) {
			listOfCards.add(c);
		}
		return changeCards(player, listOfCards);
	}
	
	public void printFinalScoreAndWinner() {
		
		var winner = Collections.max(players, (p1, p2) -> {
			Integer score1 = p1.getScore();
			Integer score2 = p2.getScore();
			return score1.compareTo(score2);
		});
		System.out.println("Final sets: ");
		players.forEach(p -> System.out.println(p));
		System.out.println("The winner is: %s with a score of %d".formatted(winner.getName(), winner.getScore()));
	}
	
	private void setScore() {
		players.forEach(p -> {
			var set = p.getSet();
			if(!set.isEmpty()) {
				int totScore = 0;
				for(var card : set) {
					totScore += card.getRank();
				}
				p.setScore(totScore);
			}
		});
	}
	
	public void printPlayerSets() {
		players.forEach(p -> {
			System.out.println(p.getName() + " \n" + p.getSet());
		});
	}
	
	public void printDeck(String name) {
	    System.out.println(name);
	    int row = 4;
	    int elementsPerRow = deck.size() / row;
	    for (int i = 0; i < deck.size(); i++) {
	        System.out.print(deck.get(i) + " ");
	        if ((i + 1) % elementsPerRow == 0) {
	            System.out.println(); // Break after a {elementsPerRow} elements are printed
	        }
	    }
	    System.out.println();
	}
	
	@Override
	public String toString() {
		return "%s has %d players: \n %s \n The deck is = %s".formatted(gameName, players.size(), players, deck); 
	}

	private void shuffleDeck() {
	    Collections.shuffle(deck);
	    printDeck("The shuffle deck: ");
		
	}
	
	private void cutDeck() {
		int randomCut = new Random().nextInt(1,deck.size());
		System.out.println("The random cut is: " + randomCut + "\n");
		Collections.rotate(deck, randomCut);
		printDeck("The deck after cut: ");
	}
	
	private boolean dealsCards() {
		if(checkEnoughCards()) {
			int numCards = MAX_NUM_CARDS_FOR_SET * players.size(); 
			
			for(int i = 0; i < numCards ; i++) {
				var card = deck.get(0);
				getNextPlayer().addCard(card);
				deck.remove(0);
			}
			System.out.println("All the cards were dealt to the players");
			setScore();
			return true;
		}
		System.err.println("There are not enough cards in the deck");
		return false;
	}
	
	private int getNumCardsLeft() {
		int numCards = MAX_NUM_CARDS_FOR_SET * players.size();
		return deck.size() - numCards;
	}
	
	
	private boolean checkEnoughCards() {
		int needNumCards = MAX_NUM_CARDS_FOR_SET * players.size();
		return (deck.size() - needNumCards) > -1;
	}
	
	private int indexPlayer = -1;
	private Player getNextPlayer() {
		indexPlayer++;
		if(indexPlayer >= players.size()) {
			indexPlayer = 0;
		} 
		
		return players.get(indexPlayer);
	}
	

	public static void main(String[] args) {
		
		// Open console
		var console = new Console();
		
		// Initialize the game
		GameController game = new GameController();
		System.out.println("/* WELCOME TO \"" + game.getName().toUpperCase() + "\" */ \n");
		
		// Get the number of players
		int numPlayers = console.getInt("- How many players will play? (Minimum 2, Maximum 10):",
				"Invalid input, enter a number from 2 to 10",
				GameController.MIN_NUM_PLAYER,  GameController.MAX_NUM_PLAYER);
		console.printBreak();	
		System.out.println("Number of players: " + numPlayers);
		
		// Add players
		int numPlayersToAdd = 1;
		while(game.players.size() < numPlayers) {
			String playerName = console.getString("- Enter the name of the player number (%d)".formatted((numPlayersToAdd)), "Invalid input, the string can't be empty").toUpperCase();
			if( game.addPlayer(new Player(playerName)) ) {
				numPlayersToAdd++;
			}
		}
		console.printBreak();
		
		// Start the game
		game.start();
		console.printBreak();
		
		// Ask to each player if he want to change the cards
		var players = game.getPlayers();
		players.forEach(p -> {
			boolean isLoop = true;
			while(isLoop) {
				String namePlayer = p.getName();
				boolean changeCards = console.getBoolean("- %s wants to change the cards? Write 'Yes' or 'No'".formatted(namePlayer));
				if(changeCards) {
					var numCardsToChange = console.getInt("- How many cards you want to change? Minimum 1 maximun 3. Enter 0 to go back.".formatted(namePlayer),
							"Invalid input",
							0, 3);
					if(numCardsToChange > 0 && numCardsToChange < 4) {
						
						// Select the cards
						var set = new ArrayList<Card>(p.getSet());
						var cardsToChange = new ArrayList<Card>();
						for(int i = 1; i <= numCardsToChange; i++) {
							var card = console.getElementFromMenu(set,
									"- %s chooses the %s card to change from this list: ".formatted(namePlayer,
											switch(i) {
											case 1 -> "first";
											case 2 -> "second";
											default -> "third";
											}
								));
							System.out.println("Chosen card: " + card + "\n");
							
							set.remove(card);
							cardsToChange.add(card);
						}
						
						// Change the cards
						System.out.println(cardsToChange + " will be repleaced");
						game.changeCards(p, cardsToChange);
						console.printBreak();
						
						isLoop = false;
					}
				} else {
					isLoop = false;
				}
			}
			
		});
		
		// Print the winner
		game.printFinalScoreAndWinner();
		
		// Close console
		console.close();
	    
	}
	
}