added our rulesets, support for multiple bots and a roadmap

This commit is contained in:
2022-09-18 17:22:37 +02:00
parent 0f8b0ce880
commit 238fbc2f52
14 changed files with 251 additions and 107 deletions

15
pom.xml
View File

@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.tman</groupId> <groupId>com.koet</groupId>
<artifactId>MauMau</artifactId> <artifactId>MauMau</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<dependencies> <dependencies>
@@ -16,9 +16,18 @@
</dependency> </dependency>
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
</plugins>
</build>
<properties> <properties>
<maven.compiler.source>17</maven.compiler.source> <maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target> <maven.compiler.target>16</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>

View File

@@ -5,17 +5,15 @@ import mau.mau.players.Human;
import mau.mau.players.Player; import mau.mau.players.Player;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
public class Game { public class Game {
private Card currentCard; private Card currentCard;
private Deck deck = new Deck(); private final Deck deck = new Deck();
private Dealer dealer; private Dealer dealer;
private Human human; private final List<Player> players = new ArrayList<>();
private Referee referee = new Referee(); private int playerTurn = 0;
private List<Player> turnOrder = new ArrayList<>(); private Boolean reverse = false;
private Boolean skipNextPlayer = false;
public Game() { public Game() {
setupGame(); setupGame();
@@ -24,40 +22,39 @@ public class Game {
private void setupGame() { private void setupGame() {
dealer = new Dealer(deck); dealer = new Dealer(deck);
human = new Human(dealer); Human human = new Human("Peppie's Maueria", dealer);
turnOrder.add(human); players.add(human);
turnOrder.add(new Bot(dealer)); players.add(new Bot("Jordan", dealer));
dealer.dealCards(turnOrder); players.add(new Bot("MaarKoet", dealer));
dealer.dealCards(players);
currentCard = dealer.getInitialCard(); currentCard = dealer.getInitialCard();
} }
private void playGame() { private void playGame() {
while (turnOrder.size() > 1) { while (players.size() > 1) {
for (Player player : turnOrder) { Player player = players.get(playerTurn);
if (skipNextPlayer) {
skipNextPlayer = false; System.out.println("Current card: " + currentCard);
continue; Card playedCard = player.getPlay(currentCard);
if(player.getHandSize() > 0) {
if(playedCard != null){
playCard(playedCard);
} }
System.out.println("Current card is " + currentCard); System.out.println(deck.getDeck().size() + " cards left in deck");
Card card = player.getPlay(currentCard); } else {
if (card != null) { if(Referee.isValidEndCard(playedCard)) {
playCard(card); playCard(playedCard);
} System.out.println(player.getName() + " won!");
if (player.getHandSize() == 0) { } else {
if (Referee.isValidEndCard(currentCard)) { System.out.println("You can't end the game with that card!");
System.out.println(player.getClass().getSimpleName() + " won!"); for (int i = 0; i < 5; i++) {
turnOrder.remove(player); player.addCardToHand(dealer.drawCard());
break;
} else {
System.out.println("You can't end with this card!");
player.addCardToHand(card);
} }
turnOrder.remove(player);
break;
} }
break;
} }
System.out.println(deck.getDeck().size() + " cards left in deck"); players.removeIf(Player::handIsEmpty);
turnOrder.removeIf(Player::handIsEmpty); handleTurn(playedCard);
} }
System.out.println("Game has ended"); System.out.println("Game has ended");
} }
@@ -68,38 +65,74 @@ public class Game {
} }
public void handleTurn(Card card) { public void handleTurn(Card card) {
if(card == null){
incrementPlayerTurn(1);
return;
}
TYPENUM cardType = card.getType(); TYPENUM cardType = card.getType();
VALUENUM cardValue = card.getValue(); VALUENUM cardValue = card.getValue();
if (cardType == TYPENUM.JOKER) { if (cardType == TYPENUM.JOKER) {
// Draw 5 cards
// Choose color incrementPlayerTurn(1);
Player player = players.get(playerTurn);
Referee.setAllowedCards(player.getTypeChoice());
for (int i = 0; i < 5; i++) {
player.addCardToHand(dealer.drawCard());
}
incrementPlayerTurn(1);
return; return;
} }
switch (cardValue) { switch (cardValue) {
case TWO: case TWO -> {
handleTwo(); incrementPlayerTurn(1);
Player player = players.get(playerTurn);
for (int i = 0; i < 2; i++) {
player.addCardToHand(dealer.drawCard());
}
incrementPlayerTurn(1);
return; return;
case SEVEN: }
case KING: case SEVEN -> {
// Keep turn System.out.println("Sticky seven go again");
return; return;
case EIGHT: }
// Skip next player case KING -> {
System.out.println("Kinky king go again");
return; return;
case JACK: }
// Draw 5 cards case EIGHT -> {
// Change card type System.out.println("Eighty wait");
return; incrementPlayerTurn(2);
case ACE:
Collections.reverse(turnOrder);
return; return;
}
case JACK -> {
Player player = players.get(playerTurn);
Referee.setAllowedCards(player.getTypeChoice());
}
case ACE -> {
reverse = !reverse;
if (players.size() == 2) {
return;
}
}
} }
incrementPlayerTurn(1);
} }
private void handleTwo(){ private void incrementPlayerTurn(int increment) {
Player player = turnOrder.get(1); for (int i = 0; i < increment; i++) {
player.addCardToHand(dealer.drawCard()); if (reverse) {
player.addCardToHand(dealer.drawCard()); playerTurn--;
skipNextPlayer = true; } else {
playerTurn++;
}
if (playerTurn < 0) {
playerTurn = players.size() - 1;
}
if (playerTurn >= players.size()) {
playerTurn = 0;
}
}
} }
} }

View File

@@ -1,8 +1,13 @@
package mau.mau; package mau.mau;
import java.util.ArrayList;
public class Referee { public class Referee {
public static ArrayList<TYPENUM> allowedTypes = new ArrayList<>();
public static boolean isValidMove(Card currentCard, Card playedCard) { public static boolean isValidMove(Card currentCard, Card playedCard) {
TYPENUM currentCardType = currentCard.getType(); TYPENUM currentCardType = currentCard.getType();
VALUENUM currentCardValue = currentCard.getValue(); VALUENUM currentCardValue = currentCard.getValue();
TYPENUM playedCardType = playedCard.getType(); TYPENUM playedCardType = playedCard.getType();
@@ -29,4 +34,9 @@ public class Referee {
public static boolean isValidEndCard(Card card) { public static boolean isValidEndCard(Card card) {
return !isMauCard(card); return !isMauCard(card);
} }
public static void setAllowedCards(TYPENUM type) {
allowedTypes.add(type);
allowedTypes.add(TYPENUM.JOKER);
}
} }

View File

@@ -1,5 +1,5 @@
package mau.mau; package mau.mau;
public enum TYPENUM { public enum TYPENUM {
SPADES, HEARTS, DIAMOND, CLUBS, JOKER; SPADES, HEARTS, DIAMONDS, CLUBS, JOKER;
} }

View File

@@ -7,7 +7,7 @@ public enum VALUENUM {
EIGHT (8), NINE (9), EIGHT (8), NINE (9),
TEN (10), JACK (11), TEN (10), JACK (11),
QUEEN (12), KING (13), QUEEN (12), KING (13),
ACE (13); ACE (14);
private final int VALUE; private final int VALUE;

View File

@@ -2,40 +2,85 @@ package mau.mau.players;
import mau.mau.*; import mau.mau.*;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Scanner; import java.util.Scanner;
public class Bot extends Player { public class Bot extends Player {
public Bot(Dealer dealer) { public Bot(String name, Dealer dealer) {
super(dealer); super(name, dealer);
} }
@Override @Override
public Card getPlay(Card currentCard) { public Card getPlay(Card currentCard) {
new Scanner(System.in).nextLine(); List<Card> hand = getHand();
List<Card> hand = super.getHand();
if (hand.size() == 1 && Referee.isValidEndCard(hand.get(0))) { if (hand.size() == 1 && Referee.isValidEndCard(hand.get(0))) {
return hand.get(0); Card card = hand.get(0);
System.out.println(getName() + " played " + card);
hand.remove(0);
System.out.println(getName() + " now has " + hand.size() + " cards");
new Scanner(System.in).nextLine();
return card;
} else if (hand.size() == 1) { } else if (hand.size() == 1) {
hand.add(drawCard()); hand.add(drawCard());
System.out.println("Bot drew a card"); System.out.println(getName() + " drew a card");
System.out.println("Bot now has " + hand.size() + " cards"); System.out.println(getName() + " now has " + hand.size() + " cards");
new Scanner(System.in).nextLine();
return null; return null;
} }
for(Card card : hand) { for (Card card : hand) {
if(Referee.isValidMove(card, currentCard)) { if(Referee.allowedTypes.isEmpty()) {
System.out.println("Bot played " + card); if (Referee.isValidMove(card, currentCard)) {
hand.remove(card); System.out.println(getName() + " played " + card);
System.out.println("Bot now has " + hand.size() + " cards"); hand.remove(card);
return card; System.out.println(getName() + " now has " + hand.size() + " cards");
new Scanner(System.in).nextLine();
return card;
}
} else {
if (Referee.allowedTypes.contains(card.getType())) {
Referee.allowedTypes.clear();
System.out.println(getName() + " played " + card);
hand.remove(card);
System.out.println(getName() + " now has " + hand.size() + " cards");
new Scanner(System.in).nextLine();
return card;
}
} }
} }
hand.add(drawCard()); hand.add(drawCard());
System.out.println("Bot drew a card"); System.out.println(getName() + " drew a card");
System.out.println("Bot now has " + hand.size() + " cards"); System.out.println(getName() + " now has " + hand.size() + " cards");
new Scanner(System.in).nextLine();
return null; return null;
} }
@Override
public TYPENUM getTypeChoice() {
HashMap<TYPENUM, Integer> typeCount = new HashMap<>();
for (Card card : getHand()) {
TYPENUM type = card.getType();
if (typeCount.containsKey(type)) {
typeCount.put(type, typeCount.get(type) + 1);
} else {
typeCount.put(type, 1);
}
}
TYPENUM typeChoice = null;
int maxCount = 0;
for (TYPENUM type : typeCount.keySet()) {
if (typeCount.get(type) > maxCount) {
typeChoice = type;
maxCount = typeCount.get(type);
}
}
if (typeChoice == null || typeChoice == TYPENUM.JOKER) {
typeChoice = TYPENUM.values()[(int) (Math.random() * 4)];
}
System.out.println(getName() + " chose " + typeChoice);
return typeChoice;
}
} }

View File

@@ -1,17 +1,14 @@
package mau.mau.players; package mau.mau.players;
import mau.mau.Card; import mau.mau.*;
import mau.mau.Dealer;
import mau.mau.Referee;
import mau.mau.Utils;
import java.util.List; import java.util.List;
import java.util.Scanner; import java.util.Scanner;
public class Human extends Player { public class Human extends Player {
public Human(Dealer dealer) { public Human(String name, Dealer dealer) {
super(dealer); super(name, dealer);
} }
@Override @Override
@@ -20,14 +17,14 @@ public class Human extends Player {
Scanner scanner = new Scanner(System.in); Scanner scanner = new Scanner(System.in);
List<Card> hand = super.getHand(); List<Card> hand = getHand();
while (true){ while (true) {
String input = scanner.nextLine(); String input = scanner.nextLine();
if(input.equals("quit")){ if (input.equals("quit")) {
System.out.println("You quit the game!"); System.out.println("You quit the game!");
System.exit(69); System.exit(69);
} }
if (input.equals("draw")) { if (input.equals("draw") || input.equals("d")) {
Card card = drawCard(); Card card = drawCard();
System.out.println("You drew a " + card); System.out.println("You drew a " + card);
hand.add(card); hand.add(card);
@@ -35,14 +32,20 @@ public class Human extends Player {
} }
if (Utils.isNumeric(input)) { if (Utils.isNumeric(input)) {
int cardIndex = Integer.parseInt(input); int cardIndex = Integer.parseInt(input);
if (cardIndex < 0 || cardIndex > hand.size()){ if (cardIndex < 0 || cardIndex > hand.size()) {
System.out.println("Invalid card"); System.out.println("Invalid card");
continue; continue;
} }
Card card = hand.get(cardIndex); Card card = hand.get(cardIndex);
if (!Referee.isValidMove(card, currentCard)) { if (Referee.allowedTypes.isEmpty()) {
System.out.println("Invalid move"); if (!Referee.isValidMove(card, currentCard)) {
continue; System.out.println("Invalid move");
continue;
}
} else {
if (Referee.allowedTypes.contains(card.getType())) {
Referee.allowedTypes.clear();
}
} }
hand.remove(cardIndex); hand.remove(cardIndex);
return card; return card;
@@ -51,8 +54,34 @@ public class Human extends Player {
} }
} }
private void printHand(){ @Override
List<Card> hand = super.getHand(); public TYPENUM getTypeChoice() {
System.out.println("Choose a new type:");
System.out.println("(1) Spades");
System.out.println("(2) Hearts");
System.out.println("(3) Diamonds");
System.out.println("(4) Clubs");
Scanner scanner = new Scanner(System.in);
while (true) {
int input = scanner.nextInt();
switch (input) {
case 1:
return TYPENUM.SPADES;
case 2:
return TYPENUM.HEARTS;
case 3:
return TYPENUM.DIAMONDS;
case 4:
return TYPENUM.CLUBS;
default:
System.out.println("Invalid input");
}
}
}
private void printHand() {
List<Card> hand = getHand();
for (int i = 0; i < hand.size(); i++) { for (int i = 0; i < hand.size(); i++) {
Card card = hand.get(i); Card card = hand.get(i);
System.out.println("(" + i + ") " + card); System.out.println("(" + i + ") " + card);

View File

@@ -2,15 +2,18 @@ package mau.mau.players;
import mau.mau.Card; import mau.mau.Card;
import mau.mau.Dealer; import mau.mau.Dealer;
import mau.mau.TYPENUM;
import java.util.List; import java.util.List;
public abstract class Player { public abstract class Player {
private String name;
private List<Card> hand; private List<Card> hand;
private Dealer dealer; private Dealer dealer;
public Player(Dealer dealer) { public Player(String name, Dealer dealer) {
this.name = name;
this.dealer = dealer; this.dealer = dealer;
} }
@@ -22,11 +25,11 @@ public abstract class Player {
return this.hand = hand; return this.hand = hand;
} }
public Boolean handIsEmpty(){ public Boolean handIsEmpty() {
return hand.isEmpty(); return hand.isEmpty();
} }
public void addCardToHand(Card card){ public void addCardToHand(Card card) {
hand.add(card); hand.add(card);
} }
@@ -34,15 +37,21 @@ public abstract class Player {
return dealer.drawCard(); return dealer.drawCard();
} }
public Card playCard(int cardIndex){ public Card playCard(int cardIndex) {
Card playCard = hand.get(cardIndex); Card playCard = hand.get(cardIndex);
hand.remove(cardIndex); hand.remove(cardIndex);
return playCard; return playCard;
} }
public int getHandSize(){ public int getHandSize() {
return hand.size(); return hand.size();
} }
public abstract Card getPlay(Card currentCard); public abstract Card getPlay(Card currentCard);
public abstract TYPENUM getTypeChoice();
public String getName() {
return name;
}
} }

View File

@@ -0,0 +1,22 @@
# TODO
1. Refactoring
2. Huisregels toevoegen
* Kwartet = win
* 69 mag tegelijk opgelegd worden
* ~~Als er 2 spelers zijn, mag je 2x na een Ace~~
3. Spelers kunnen een naam kiezen
4. ~~Als je laatste kaart een pestkaart is moet je 5 kaarten pakken als je hem probeert op te leggen~~
5. 100% test coverage
6. Redesign terminal interface
## Known Bugs
1. Teveel kaarten in deck na het opnieuw schudden
### In een land hier ver, ver vandaan
1. UI
* Kattenkaarten (Mau Mau)
* Jokers = Koet
* Verslepen van kaarten voor de volgorde
2. Multiplayer
3. Game settings
4. Betere bot

View File

@@ -5,17 +5,4 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
public class DealerTest { public class DealerTest {
@Test
public void isDealerAGoodShufflerTest() {
//Assign
Deck deck = new Deck();
Dealer sut = new Dealer(deck);
//Act
// sut.shuffleDeck();
//Assert
assertTrue(false);
}
} }

View File

@@ -24,7 +24,7 @@ public class RefereeTest {
public void isSameCardValueValidMoveTest(){ public void isSameCardValueValidMoveTest(){
//Assign //Assign
Card testCardOne = new Card(TYPENUM.HEARTS, VALUENUM.ACE); Card testCardOne = new Card(TYPENUM.HEARTS, VALUENUM.ACE);
Card testCardTwo = new Card(TYPENUM.DIAMOND, VALUENUM.ACE); Card testCardTwo = new Card(TYPENUM.DIAMONDS, VALUENUM.ACE);
//Act //Act
boolean result = Referee.isValidMove(testCardOne, testCardTwo); boolean result = Referee.isValidMove(testCardOne, testCardTwo);