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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tman</groupId>
<groupId>com.koet</groupId>
<artifactId>MauMau</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
@@ -16,9 +16,18 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

View File

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

View File

@@ -1,8 +1,13 @@
package mau.mau;
import java.util.ArrayList;
public class Referee {
public static ArrayList<TYPENUM> allowedTypes = new ArrayList<>();
public static boolean isValidMove(Card currentCard, Card playedCard) {
TYPENUM currentCardType = currentCard.getType();
VALUENUM currentCardValue = currentCard.getValue();
TYPENUM playedCardType = playedCard.getType();
@@ -29,4 +34,9 @@ public class Referee {
public static boolean isValidEndCard(Card 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;
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),
TEN (10), JACK (11),
QUEEN (12), KING (13),
ACE (13);
ACE (14);
private final int VALUE;

View File

@@ -2,40 +2,85 @@ package mau.mau.players;
import mau.mau.*;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;
public class Bot extends Player {
public Bot(Dealer dealer) {
super(dealer);
public Bot(String name, Dealer dealer) {
super(name, dealer);
}
@Override
public Card getPlay(Card currentCard) {
new Scanner(System.in).nextLine();
List<Card> hand = super.getHand();
List<Card> hand = getHand();
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) {
hand.add(drawCard());
System.out.println("Bot drew a card");
System.out.println("Bot now has " + hand.size() + " cards");
System.out.println(getName() + " drew a card");
System.out.println(getName() + " now has " + hand.size() + " cards");
new Scanner(System.in).nextLine();
return null;
}
for (Card card : hand) {
if(Referee.allowedTypes.isEmpty()) {
if (Referee.isValidMove(card, currentCard)) {
System.out.println("Bot played " + card);
System.out.println(getName() + " played " + card);
hand.remove(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 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());
System.out.println("Bot drew a card");
System.out.println("Bot now has " + hand.size() + " cards");
System.out.println(getName() + " drew a card");
System.out.println(getName() + " now has " + hand.size() + " cards");
new Scanner(System.in).nextLine();
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;
import mau.mau.Card;
import mau.mau.Dealer;
import mau.mau.Referee;
import mau.mau.Utils;
import mau.mau.*;
import java.util.List;
import java.util.Scanner;
public class Human extends Player {
public Human(Dealer dealer) {
super(dealer);
public Human(String name, Dealer dealer) {
super(name, dealer);
}
@Override
@@ -20,14 +17,14 @@ public class Human extends Player {
Scanner scanner = new Scanner(System.in);
List<Card> hand = super.getHand();
List<Card> hand = getHand();
while (true) {
String input = scanner.nextLine();
if (input.equals("quit")) {
System.out.println("You quit the game!");
System.exit(69);
}
if (input.equals("draw")) {
if (input.equals("draw") || input.equals("d")) {
Card card = drawCard();
System.out.println("You drew a " + card);
hand.add(card);
@@ -40,10 +37,16 @@ public class Human extends Player {
continue;
}
Card card = hand.get(cardIndex);
if (Referee.allowedTypes.isEmpty()) {
if (!Referee.isValidMove(card, currentCard)) {
System.out.println("Invalid move");
continue;
}
} else {
if (Referee.allowedTypes.contains(card.getType())) {
Referee.allowedTypes.clear();
}
}
hand.remove(cardIndex);
return card;
}
@@ -51,8 +54,34 @@ public class Human extends Player {
}
}
@Override
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 = super.getHand();
List<Card> hand = getHand();
for (int i = 0; i < hand.size(); i++) {
Card card = hand.get(i);
System.out.println("(" + i + ") " + card);

View File

@@ -2,15 +2,18 @@ package mau.mau.players;
import mau.mau.Card;
import mau.mau.Dealer;
import mau.mau.TYPENUM;
import java.util.List;
public abstract class Player {
private String name;
private List<Card> hand;
private Dealer dealer;
public Player(Dealer dealer) {
public Player(String name, Dealer dealer) {
this.name = name;
this.dealer = dealer;
}
@@ -45,4 +48,10 @@ public abstract class Player {
}
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;
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(){
//Assign
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
boolean result = Referee.isValidMove(testCardOne, testCardTwo);