diff --git a/Partie_2/src/main/java/ch/hepia/App.java b/Partie_2/src/main/java/ch/hepia/App.java index 8516d850a9ea04ae55c3ea5675582e9ee490211f..f3de79a859d846f8de27e13acdc22e908dc454ed 100644 --- a/Partie_2/src/main/java/ch/hepia/App.java +++ b/Partie_2/src/main/java/ch/hepia/App.java @@ -67,9 +67,20 @@ public class App { GameManager BlackJack = new GameManager(numPlayers, startMoney); - BlackJack.StartTurn(); + boolean GameOver = false; - BlackJack.DisplayTurn(); + while (!GameOver) { + BlackJack.StartTurn(); + BlackJack.PlayTurn(); + GameOver = BlackJack.ResolveTurn(); + } + + System.out.print("\033[H\033[2J"); + System.out.flush(); + + System.out.println("*~-~* " + App.ANSI_RED + "BlackJack" + App.ANSI_RESET + " *~-~*\n"); + + System.out.println(App.ANSI_PURPLE + "Game Over !" + App.ANSI_RESET); App.in.close(); } diff --git a/Partie_2/src/main/java/ch/hepia/GameManager.java b/Partie_2/src/main/java/ch/hepia/GameManager.java index ada0f80ab24bcf6ea836ab158641fa319dc17c30..4bbb816a3fcf70bf3d9086cdc882668e1caf204b 100644 --- a/Partie_2/src/main/java/ch/hepia/GameManager.java +++ b/Partie_2/src/main/java/ch/hepia/GameManager.java @@ -8,6 +8,7 @@ public class GameManager { private JeudeCarte Deck; private ArrayList<Joueur> Players; private JoueurCroupier Dealer; + private int Step; public GameManager(int nbPlayer, int startMoney) { @@ -26,25 +27,162 @@ public class GameManager { this.Dealer = new JoueurCroupier(Deck); } - public void DisplayTurn() { + public boolean ResolveTurn() { - System.out.print("\033[H\033[2J"); - System.out.flush(); + this.Dealer.DrawCard(0, this.Deck); - System.out.println("*~-~* " + App.ANSI_RED + "BlackJack" + App.ANSI_RESET + " *~-~*\n"); + // If the player has less than the minimum bid amount allowed + if (this.Players.get(0).GetMoney() <= 10) { + return true; + } + + this.Dealer.Reset(this.Deck); + for (Joueur Player : this.Players) { + Player.Reset(this.Deck); + } + + return false; + } + + public void PlayTurn() { + + boolean EndTurn = false; + + while (!EndTurn) { + + boolean CanSplit = false, CanInsure = false, CanDouble = false, CanDraw = false; + + System.out.print("\033[H\033[2J"); + System.out.flush(); - System.out.println("Dealer Score : " + App.ANSI_PURPLE + this.Dealer.GetForce(0) + App.ANSI_RESET); - this.Dealer.ShowHands(); + System.out.println("*~-~* " + App.ANSI_RED + "BlackJack" + App.ANSI_RESET + " *~-~*\n"); - System.out.println("\nMoney : " + App.ANSI_BLUE + this.Players.get(0).GetMoney() + App.ANSI_RESET + " // Bet : " - + App.ANSI_BLUE + this.Players.get(0).GetBet(0) + App.ANSI_RESET); - System.out.println("Player Score : " + App.ANSI_PURPLE + this.Players.get(0).GetForce(0) + App.ANSI_RESET); - this.Players.get(0).ShowHands(); + System.out.println("Cards in Deck : " + App.ANSI_GREEN + this.Deck.GetNbCards() + App.ANSI_RESET + "\n"); + System.out.print("Dealer Score : " + App.ANSI_PURPLE); + if (this.Dealer.GetForce(0) == 99) { + System.out.println("BlackJack" + App.ANSI_RESET); + } else { + System.out.println(this.Dealer.GetForce(0) + App.ANSI_RESET); + } + this.Dealer.ShowHands(); + + System.out.println("\nMoney : " + App.ANSI_BLUE + this.Players.get(0).GetMoney() + App.ANSI_RESET); + + if (this.Players.get(0).HasInsured()) { + System.out.println("Insured : " + App.ANSI_BLUE + this.Players.get(0).GetInsured() + App.ANSI_RESET); + } + + char choice = 'x'; + + for (int HandNb = 0; HandNb < this.Players.get(0).NbHands(); HandNb++) { + + System.out + .println("Bet on Hand " + App.ANSI_GREEN + (HandNb + 1) + App.ANSI_RESET + " : " + App.ANSI_BLUE + + this.Players.get(0).GetBet(HandNb) + App.ANSI_RESET); + + System.out + .print("Score of Hand " + App.ANSI_GREEN + (HandNb + 1) + App.ANSI_RESET + " : " + + App.ANSI_PURPLE); + if (this.Players.get(0).GetForce(HandNb) == 99) { + System.out.println("BlackJack" + App.ANSI_RESET); + } else { + System.out.println(this.Players.get(0).GetForce(HandNb) + App.ANSI_RESET); + } + this.Players.get(0).ShowHands(); + + // Choices for player + System.out.println("\n--- " + App.ANSI_GREEN + "Choices" + App.ANSI_RESET + " ---\n"); + + // Insurance + // Can only insure if it's the first thing that the players does + // AND + // That he hasn't already insured during this round + if (this.Step == 0 && this.Dealer.OnlyAs() + && !this.Players.get(0).HasInsured()) { + CanInsure = true; + System.out.println(App.ANSI_BLUE + "[i]" + App.ANSI_RESET + " Insurance against Dealer"); + } + + // Split + // Can only split if this hand can be split (if it wasn't already split AND if + // the 2 cards have the same strength) + // AND + // if we have less that 3 hands already (Max 2 splits) + if (this.Players.get(0).CanSplit(HandNb) + && this.Players.get(0).NbHands() < 3) { + CanSplit = true; + System.out.println(App.ANSI_BLUE + "[s]" + App.ANSI_RESET + " Split your Hand"); + } + + // Double + // Can only double if this hand wasn't already doubled + // AND + // if the hand has only 2 cards + // AND + // if the hand is not a BlackJack + if (!this.Players.get(0).HasDoubled(HandNb) + && this.Players.get(0).NbCards(HandNb) == 2 + && this.Players.get(0).GetForce(HandNb) != 99) { + CanDouble = true; + System.out.println(App.ANSI_BLUE + "[d]" + App.ANSI_RESET + " Double your Hand"); + } + + // Draw a Card (Hit) + // Can NOT draw if this hand was doubled AND has already 3 cards + // AND + // if the hand has been splitted with a pair of Asses + // AND + // if the player has a BlackJack + if (!(this.Players.get(0).HasDoubled(HandNb) && this.Players.get(0).NbCards(HandNb) == 3) + && !(this.Players.get(0).CanSplit(HandNb) && this.Players.get(0).GetCardForce(HandNb, 0) == 1) + && this.Players.get(0).GetForce(HandNb) != 99) { + CanDraw = true; + System.out.println(App.ANSI_BLUE + "[h]" + App.ANSI_RESET + " Hit"); + } + + // Stand + System.out.println(App.ANSI_BLUE + "[s]" + App.ANSI_RESET + " Stand"); + + if (CanInsure || CanSplit || CanDouble || CanDraw || this.Players.get(0).GetForce(HandNb) == 99) { + + while (true) { + System.out.print("> "); + + choice = App.in.next().charAt(0); + + if ((choice == 'i' && CanInsure) || (choice == 's' && CanSplit) || (choice == 'd' && CanDouble) + || (choice == 'h' && CanDraw) + || choice == 's') { + break; + } else { + System.out.println(App.ANSI_YELLOW + "Please enter a valid choice." + App.ANSI_RESET); + } + } + } + + if (choice == 'h') { + this.Players.get(0).DrawCard(HandNb, this.Deck); + } + + Step++; + } + + if (choice == 'i') { + this.Players.get(0).Insure(); + EndTurn = false; + } else if (choice == 'h') { + EndTurn = false; + } else { + EndTurn = true; + } + } } public void StartTurn() { + this.Step = 0; + System.out.print("\033[H\033[2J"); System.out.flush(); @@ -56,7 +194,7 @@ public class GameManager { while (true) { - System.out.print("How much do you want to bet ? "); + System.out.print("How much do you want to bet (Min. 10) ? "); while (!App.in.hasNextDouble()) { System.out.println(App.ANSI_YELLOW + "Please enter a valid number to bet." + App.ANSI_RESET); @@ -67,7 +205,12 @@ public class GameManager { bet = App.in.nextDouble(); if (bet <= this.Players.get(0).GetMoney()) { - break; + if (bet < 10) { + System.out.println(App.ANSI_YELLOW + "Minimum bid amount is 10." + App.ANSI_RESET); + } else { + break; + } + } else { System.out.println(App.ANSI_YELLOW + "You don't have enough money." + App.ANSI_RESET); } diff --git a/Partie_2/src/main/java/ch/hepia/Hand.java b/Partie_2/src/main/java/ch/hepia/Hand.java index 8d9c55a1a9590b4b872c99cf5cd677ba48e6c16c..449df4bd87f7294d66c600ef027bb615c16795dc 100644 --- a/Partie_2/src/main/java/ch/hepia/Hand.java +++ b/Partie_2/src/main/java/ch/hepia/Hand.java @@ -8,23 +8,51 @@ public class Hand implements Comparable<Hand> { private ArrayList<Carte> Hand; private double Bet; + private boolean Splitted; + private boolean Doubled; public Hand(Carte... cartes) { - Hand = new ArrayList<>(); + this.Hand = new ArrayList<>(); for (Carte carte : cartes) { Hand.add(carte); } + + this.Splitted = false; + this.Doubled = false; } public Hand(JeudeCarte game, int nb) { - Hand = new ArrayList<>(); + this.Hand = new ArrayList<>(); this.DrawCardFromGame(game, nb); + + this.Splitted = false; + this.Doubled = false; + } + + public boolean HasDoubled() { + return this.Doubled; + } + + public void Double() { + this.Doubled = true; + } + + public boolean HasSplit() { + return this.Splitted; + } + + public void Splitted() { + this.Splitted = true; + } + + public int NbCard() { + return this.Hand.size(); } public void SetBet(double amount) { @@ -122,6 +150,33 @@ public class Hand implements Comparable<Hand> { } } + // Edge Case = BlackJack + if (force == 21) { + + boolean isAs = false; + boolean is10 = false; + boolean isOther = false; + + for (Carte carte : Hand) { + + switch (carte.getForce()) { + case 1: + isAs = true; + break; + case 10: + is10 = true; + break; + default: + isOther = true; + break; + } + } + + if (isAs && is10 && !isOther) { + return 99; + } + } + return force; } @@ -141,16 +196,8 @@ public class Hand implements Comparable<Hand> { @Override public int compareTo(Hand otherHand) { - int Hand_1_Power = 0; - int Hand_2_Power = 0; - - for (Carte carte : Hand) { - Hand_1_Power += carte.getRang(); - } - - for (Carte carte : otherHand.Hand) { - Hand_2_Power += carte.getRang(); - } + int Hand_1_Power = this.GetForce(); + int Hand_2_Power = otherHand.GetForce(); if (Hand_1_Power > Hand_2_Power) { return 1; diff --git a/Partie_2/src/main/java/ch/hepia/JeudeCarte.java b/Partie_2/src/main/java/ch/hepia/JeudeCarte.java index 66d165a56c2cfaa45cc1e855d1b1526fd9795404..e6bd3c6c42211a33e64b76c4d0fb0f31767038cf 100644 --- a/Partie_2/src/main/java/ch/hepia/JeudeCarte.java +++ b/Partie_2/src/main/java/ch/hepia/JeudeCarte.java @@ -70,7 +70,7 @@ public class JeudeCarte { } public List<Carte> getCartes() { - return jeuDeCartes; + return this.jeuDeCartes; } public Carte GetTopCarteOfGame() { @@ -103,6 +103,10 @@ public class JeudeCarte { } + public int GetNbCards() { + return this.jeuDeCartes.size(); + } + public void ShowPaquet() { System.out.println("------- Paquet -------"); diff --git a/Partie_2/src/main/java/ch/hepia/Joueur.java b/Partie_2/src/main/java/ch/hepia/Joueur.java index 6ae23fc28814964028276527f4b6e8572e35a93e..d80144970b997e7368a1ff85157eaebc29344c82 100644 --- a/Partie_2/src/main/java/ch/hepia/Joueur.java +++ b/Partie_2/src/main/java/ch/hepia/Joueur.java @@ -25,12 +25,34 @@ interface Joueur { public void Split(int handNb); public int GetForce(int handNb); + + public boolean CanSplit(int handNb); + + public void Reset(JeudeCarte Jeu); + + public boolean HasInsured(); + + public void Insure(); + + public double GetInsured(); + + public boolean HasDoubled(int handNb); + + public void Double(int handNb); + + public int NbHands(); + + public int NbCards(int handNb); + + public int GetCardForce(int handNb, int cardNb); } class JoueurHumain implements Joueur { private ArrayList<Hand> Hands; private double Money; + private double Insurance; + private boolean Insured; public JoueurHumain(JeudeCarte Jeu, int Money) { this.Hands = new ArrayList<>(); @@ -40,6 +62,49 @@ class JoueurHumain implements Joueur { this.Hands.get(0).SetBet(0); this.Money = Money; + this.Insurance = 0; + this.Insured = false; + } + + public void Reset(JeudeCarte Jeu) { + + this.Insured = false; + + this.Hands = new ArrayList<>(); + + this.Hands.add(new Hand(Jeu, 2)); + + this.Hands.get(0).SetBet(0); + } + + public boolean HasDoubled(int handNb) { + return this.Hands.get(handNb).HasDoubled(); + } + + public void Double(int handNb) { + this.Hands.get(handNb).Double(); + } + + public boolean CanSplit(int handNb) { + if (!this.Hands.get(handNb).HasSplit() + && this.Hands.get(handNb).GetCarte(0).getForce() == this.Hands.get(handNb).GetCarte(1).getForce()) { + return true; + } + + return false; + } + + public boolean HasInsured() { + return this.Insured; + } + + public void Insure() { + this.Insured = true; + this.Insurance = this.Hands.get(0).GetBet() / 2; + } + + public double GetInsured() { + return this.Insurance; } public void DefineStrategy() { @@ -125,22 +190,40 @@ class JoueurHumain implements Joueur { public void Split(int handNb) { - if (Hands.size() == 3) { + if (this.Hands.size() == 3) { throw new RuntimeException("Max number of slipts."); + } else if (this.Hands.get(handNb).HasSplit()) { + throw new RuntimeException("Can't split Hand twice."); } Carte card = this.Hands.get(handNb).GetCarte(handNb); this.Hands.get(handNb).RemoveCardFromHand(card); + this.Hands.get(handNb).Splitted(); + this.Hands.add(new Hand(card)); } + + public int NbHands() { + return this.Hands.size(); + } + + public int NbCards(int handNb) { + return this.Hands.get(handNb).NbCard(); + } + + public int GetCardForce(int handNb, int cardNb) { + return this.Hands.get(handNb).GetCarte(cardNb).getForce(); + } } class JoueurOrdinateur implements Joueur { private ArrayList<Hand> Hands; private double Money; + private double Insurance; + private boolean Insured; public JoueurOrdinateur(JeudeCarte Jeu, int Money) { this.Hands = new ArrayList<>(); @@ -150,6 +233,8 @@ class JoueurOrdinateur implements Joueur { Hands.get(0).SetBet(0); this.Money = Money; + this.Insurance = 0; + this.Insured = false; } public void DefineStrategy() { @@ -157,6 +242,48 @@ class JoueurOrdinateur implements Joueur { } + public boolean HasDoubled(int handNb) { + return this.Hands.get(handNb).HasDoubled(); + } + + public void Double(int handNb) { + this.Hands.get(handNb).Double(); + } + + public boolean CanSplit(int handNb) { + + if (this.Hands.get(handNb).HasSplit() + || this.Hands.get(handNb).GetCarte(0).getForce() != this.Hands.get(handNb).GetCarte(1).getForce()) { + return false; + } + + return true; + } + + public boolean HasInsured() { + return this.Insured; + } + + public double GetInsured() { + return this.Insurance; + } + + public void Insure() { + this.Insured = true; + this.Insurance = this.Hands.get(0).GetBet() / 2; + } + + public void Reset(JeudeCarte Jeu) { + + this.Insured = false; + + this.Hands = new ArrayList<>(); + + this.Hands.add(new Hand(Jeu, 2)); + + this.Hands.get(0).SetBet(0); + } + public void AddMoney(double amount) { if (amount <= 0) { throw new RuntimeException("Can't add negative amount of Money."); @@ -237,14 +364,30 @@ class JoueurOrdinateur implements Joueur { if (Hands.size() == 3) { throw new RuntimeException("Max number of slipts."); + } else if (this.Hands.get(handNb).HasSplit()) { + throw new RuntimeException("Can't split Hand twice."); } Carte card = this.Hands.get(handNb).GetCarte(handNb); this.Hands.get(handNb).RemoveCardFromHand(card); + this.Hands.get(handNb).Splitted(); + this.Hands.add(new Hand(card)); } + + public int NbHands() { + return this.Hands.size(); + } + + public int NbCards(int handNb) { + return this.Hands.get(handNb).NbCard(); + } + + public int GetCardForce(int handNb, int cardNb) { + return this.Hands.get(handNb).GetCarte(cardNb).getForce(); + } } class JoueurCroupier implements Joueur { @@ -252,7 +395,21 @@ class JoueurCroupier implements Joueur { private Hand Hand; public JoueurCroupier(JeudeCarte Jeu) { - this.Hand = new Hand(Jeu, 2); + this.Hand = new Hand(Jeu, 1); + } + + public boolean OnlyAs() { + + if (this.Hand.GetCarte(0).getNomRang() == "As" && this.Hand.NbCard() == 1) { + return true; + } + + return false; + } + + public void Reset(JeudeCarte Jeu) { + + this.Hand = new Hand(Jeu, 1); } public void DefineStrategy() { @@ -260,6 +417,37 @@ class JoueurCroupier implements Joueur { } + public boolean HasDoubled(int handNb) { + // La Banque ne peut pas doubler + throw new RuntimeException("Bank cant Double."); + } + + public void Double(int handNb) { + // La Banque ne peut pas doubler + throw new RuntimeException("Bank cant Double."); + } + + public boolean CanSplit(int handNb) { + + // La Banque ne peut pas split + throw new RuntimeException("Bank cant Split."); + } + + public boolean HasInsured() { + // La Banque ne s'assure pas contre elle même + throw new RuntimeException("Bank cant get Insurance."); + } + + public void Insure() { + // La Banque ne s'assure pas contre elle même + throw new RuntimeException("Bank cant get Insurance."); + } + + public double GetInsured() { + // La Banque ne s'assure pas contre elle même + throw new RuntimeException("Bank has no Insurance."); + } + public void AddMoney(double amount) { // La Banque n'a pas d'argent throw new RuntimeException("Bank has no Money."); @@ -320,4 +508,16 @@ class JoueurCroupier implements Joueur { // La Banque ne peut pas slip throw new RuntimeException("Bank can't Split."); } + + public int NbHands() { + return 1; + } + + public int NbCards(int handNb) { + return this.Hand.NbCard(); + } + + public int GetCardForce(int handNb, int cardNb) { + return this.Hand.GetCarte(cardNb).getForce(); + } } diff --git a/Partie_2/target/classes/ch/hepia/App.class b/Partie_2/target/classes/ch/hepia/App.class index 998649ba6f5768b7ff59fd742b6d46eadcb6f43b..1e730631e4c898c9083ecffaf77a899ec69da689 100644 Binary files a/Partie_2/target/classes/ch/hepia/App.class and b/Partie_2/target/classes/ch/hepia/App.class differ diff --git a/Partie_2/target/classes/ch/hepia/GameManager.class b/Partie_2/target/classes/ch/hepia/GameManager.class index 7226155cb75926f7fc3c4f4862943474c91eab01..0c1af52db05f54c74267841b06de56799bd9df50 100644 Binary files a/Partie_2/target/classes/ch/hepia/GameManager.class and b/Partie_2/target/classes/ch/hepia/GameManager.class differ diff --git a/Partie_2/target/classes/ch/hepia/Hand$1.class b/Partie_2/target/classes/ch/hepia/Hand$1.class index a8bc740546856cee4b41e4cfb3e1d26a464d6de7..7f75d8fe38a1822b70b602d9d7536438562761f5 100644 Binary files a/Partie_2/target/classes/ch/hepia/Hand$1.class and b/Partie_2/target/classes/ch/hepia/Hand$1.class differ diff --git a/Partie_2/target/classes/ch/hepia/Hand.class b/Partie_2/target/classes/ch/hepia/Hand.class index ad363bf8d905b7cfbc4a9c8e5bad819297676ea1..22668a718d2fcdc679e7db293da325b101f7c2b1 100644 Binary files a/Partie_2/target/classes/ch/hepia/Hand.class and b/Partie_2/target/classes/ch/hepia/Hand.class differ diff --git a/Partie_2/target/classes/ch/hepia/JeudeCarte.class b/Partie_2/target/classes/ch/hepia/JeudeCarte.class index d4ddff183e9cf28c6ac28b70552d4d214022baff..7c84a24a016f03fff7d97c2fd8eab208948f7fbf 100644 Binary files a/Partie_2/target/classes/ch/hepia/JeudeCarte.class and b/Partie_2/target/classes/ch/hepia/JeudeCarte.class differ diff --git a/Partie_2/target/classes/ch/hepia/Joueur.class b/Partie_2/target/classes/ch/hepia/Joueur.class index 455ae8e3d5d3b73cf7c6b9a46b235bea191911ed..bcf855977f1b52f5f93a278ebe3557311fabd2ba 100644 Binary files a/Partie_2/target/classes/ch/hepia/Joueur.class and b/Partie_2/target/classes/ch/hepia/Joueur.class differ diff --git a/Partie_2/target/classes/ch/hepia/JoueurCroupier.class b/Partie_2/target/classes/ch/hepia/JoueurCroupier.class index a4e1c259ee886a8733884a95595ef85a14b310b8..e3fabea53944ae65b74e0e594f8ff39da4b162f3 100644 Binary files a/Partie_2/target/classes/ch/hepia/JoueurCroupier.class and b/Partie_2/target/classes/ch/hepia/JoueurCroupier.class differ diff --git a/Partie_2/target/classes/ch/hepia/JoueurHumain.class b/Partie_2/target/classes/ch/hepia/JoueurHumain.class index b8f42854962650befa0899a29206b537071ffb3f..8d288dc186f39d3a4733813bb2aa020e68d3b710 100644 Binary files a/Partie_2/target/classes/ch/hepia/JoueurHumain.class and b/Partie_2/target/classes/ch/hepia/JoueurHumain.class differ diff --git a/Partie_2/target/classes/ch/hepia/JoueurOrdinateur.class b/Partie_2/target/classes/ch/hepia/JoueurOrdinateur.class index d366926e71ddda91c377e09f4585de936f9bb295..2f71a0b80ecd3ac59ee101b5ef06748b16c8ec66 100644 Binary files a/Partie_2/target/classes/ch/hepia/JoueurOrdinateur.class and b/Partie_2/target/classes/ch/hepia/JoueurOrdinateur.class differ