diff --git a/out/production/sp21-cs242-assignment1/CmdUI.class b/out/production/sp21-cs242-assignment1/CmdUI.class index ed707a5d848bfe36341a91d099a66097d3c0b42e..9e4a053d8df256d5f7e95477d0e4e5fc5397a49c 100644 Binary files a/out/production/sp21-cs242-assignment1/CmdUI.class and b/out/production/sp21-cs242-assignment1/CmdUI.class differ diff --git a/out/production/sp21-cs242-assignment1/RuleController.class b/out/production/sp21-cs242-assignment1/RuleController.class index cfcfdeff757385315eabfaa03c3974a8e2ef7467..3cbec0e8bc6d73ca34e345d23260d98e2851eae0 100644 Binary files a/out/production/sp21-cs242-assignment1/RuleController.class and b/out/production/sp21-cs242-assignment1/RuleController.class differ diff --git a/out/test/sp21-cs242-assignment1/RuleControllerTest.class b/out/test/sp21-cs242-assignment1/RuleControllerTest.class index da9badcd08ce0b4609ba10d8fa911d6f7329d88c..193d470dab21a84f25e59a09e3affae987875f93 100644 Binary files a/out/test/sp21-cs242-assignment1/RuleControllerTest.class and b/out/test/sp21-cs242-assignment1/RuleControllerTest.class differ diff --git a/src/Test/RuleControllerTest.java b/src/Test/RuleControllerTest.java index 9c2820484a4f1ac4a184011f438db40821811f5e..dfc804013e5cb5c6228ad2df61b2276b02c2b167 100644 --- a/src/Test/RuleControllerTest.java +++ b/src/Test/RuleControllerTest.java @@ -13,102 +13,372 @@ import java.util.Random; class RuleControllerTest { private static CardParser parser = new CardParser(); - @Test // if current allowed color is red, player with no red cards can use wild Draw 4 + @Test + /** + * 0. A magic player owning all cards cannot play wildDraw4 anyway + * Test lots of combinations of color (r,g,b,y) & symbol (skip, reverse) + */ + void test_Player_AllCards_CannotWildDraw4() throws Exception { + Player player = playerAllCards(); + System.out.println(player.getCards()); + RuleController ruler = new RuleController(); + + ruler.setMatchableColor("red"); + ruler.setMatchableSymbol("skip"); + ruler.setNextPlayerSkiplevel(3); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setMatchableColor("red"); + ruler.setMatchableSymbol("reverse"); + ruler.setNextPlayerSkiplevel(0); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setMatchableColor("red"); + ruler.setMatchableSymbol("none"); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setMatchableColor("blue"); + ruler.setMatchableSymbol("skip"); + ruler.setNextPlayerSkiplevel(3); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setMatchableColor("blue"); + ruler.setMatchableSymbol("reverse"); + ruler.setNextPlayerSkiplevel(0); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setMatchableColor("blue"); + ruler.setMatchableSymbol("none"); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setMatchableColor("green"); + ruler.setMatchableSymbol("skip"); + ruler.setNextPlayerSkiplevel(3); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setMatchableColor("green"); + ruler.setMatchableSymbol("reverse"); + ruler.setNextPlayerSkiplevel(0); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setMatchableColor("green"); + ruler.setMatchableSymbol("none"); + assert(!ruler.isValidPlay(player, 105, false)); + + + ruler.setMatchableColor("yellow"); + ruler.setMatchableSymbol("skip"); + ruler.setNextPlayerSkiplevel(3); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setMatchableColor("yellow"); + ruler.setMatchableSymbol("reverse"); + ruler.setNextPlayerSkiplevel(0); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setMatchableColor("yellow"); + ruler.setMatchableSymbol("none"); + assert(!ruler.isValidPlay(player, 105, false)); + } + + + @Test + /** + * 1. if current allowed color is red, player with no red cards can use wild Draw 4 + */ void test_Player_Red_N_WildDraw4_Y_UseWildDraw4() throws Exception { Player player = player_Red_N_WildDraw4_Y(); RuleController ruler = new RuleController(); + ruler.setMatchableColor("red"); + ruler.setMatchableSymbol("skip"); + ruler.setNextPlayerSkiplevel(3); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setMatchableColor("red"); + ruler.setMatchableSymbol("reverse"); ruler.setNextPlayerSkiplevel(0); - ruler.setAllowedColor("red"); - ruler.setAllowedSymbol("skip"); - assert(ruler.isValidPlay(player, 105, false)); + assert(ruler.isValidPlay(player, 105, false)); // playable! - ruler.setAllowedColor("red"); - ruler.setAllowedSymbol("reverse"); - assert(ruler.isValidPlay(player, 105, false)); + ruler.setMatchableColor("red"); + ruler.setMatchableSymbol("none"); + assert(ruler.isValidPlay(player, 105, false)); // playable! - ruler.setAllowedColor("blue"); - ruler.setAllowedSymbol("skip"); + ruler.setMatchableColor("blue"); + ruler.setMatchableSymbol("skip"); + ruler.setNextPlayerSkiplevel(3); assert(!ruler.isValidPlay(player, 105, false)); - ruler.setAllowedColor("blue"); - ruler.setAllowedSymbol("reverse"); + ruler.setMatchableColor("blue"); + ruler.setMatchableSymbol("reverse"); + ruler.setNextPlayerSkiplevel(0); assert(!ruler.isValidPlay(player, 105, false)); - ruler.setAllowedColor("green"); - ruler.setAllowedSymbol("skip"); + ruler.setMatchableColor("blue"); + ruler.setMatchableSymbol("none"); assert(!ruler.isValidPlay(player, 105, false)); - ruler.setAllowedColor("green"); - ruler.setAllowedSymbol("reverse"); + ruler.setMatchableColor("green"); + ruler.setMatchableSymbol("skip"); + ruler.setNextPlayerSkiplevel(3); assert(!ruler.isValidPlay(player, 105, false)); - ruler.setAllowedColor("yellow"); + ruler.setMatchableColor("green"); + ruler.setMatchableSymbol("reverse"); + ruler.setNextPlayerSkiplevel(0); assert(!ruler.isValidPlay(player, 105, false)); + ruler.setMatchableColor("green"); + ruler.setMatchableSymbol("none"); + assert(!ruler.isValidPlay(player, 105, false)); + + + ruler.setMatchableColor("yellow"); + ruler.setMatchableSymbol("skip"); + ruler.setNextPlayerSkiplevel(3); + assert(!ruler.isValidPlay(player, 105, false)); + ruler.setMatchableColor("yellow"); + ruler.setMatchableSymbol("reverse"); + ruler.setNextPlayerSkiplevel(0); + assert(!ruler.isValidPlay(player, 105, false)); + ruler.setMatchableColor("yellow"); + ruler.setMatchableSymbol("none"); + assert(!ruler.isValidPlay(player, 105, false)); } - @Test // test player with all colors cannot use wildDraw4 anyway + @Test + /** + * 2. test player with all colors cannot use wildDraw4 anyway + */ + void test_Player_AllColors_CannotUseWildDraw4() throws Exception { Player player = player_AllColor_Y_WildDraw4_Y(); RuleController ruler = new RuleController(); + ruler.setMatchableColor("red"); + ruler.setMatchableSymbol("skip"); + ruler.setNextPlayerSkiplevel(3); assert(!ruler.isValidPlay(player, 105, false)); + ruler.setMatchableColor("red"); + ruler.setMatchableSymbol("reverse"); ruler.setNextPlayerSkiplevel(0); - ruler.setAllowedColor("red"); - ruler.setAllowedSymbol("skip"); assert(!ruler.isValidPlay(player, 105, false)); - ruler.setAllowedColor("red"); - ruler.setAllowedSymbol("reverse"); + ruler.setMatchableColor("red"); + ruler.setMatchableSymbol("none"); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setMatchableColor("blue"); + ruler.setMatchableSymbol("skip"); + ruler.setNextPlayerSkiplevel(3); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setMatchableColor("blue"); + ruler.setMatchableSymbol("reverse"); + ruler.setNextPlayerSkiplevel(0); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setMatchableColor("blue"); + ruler.setMatchableSymbol("none"); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setMatchableColor("green"); + ruler.setMatchableSymbol("skip"); + ruler.setNextPlayerSkiplevel(3); assert(!ruler.isValidPlay(player, 105, false)); - ruler.setAllowedColor("blue"); - ruler.setAllowedSymbol("skip"); + ruler.setMatchableColor("green"); + ruler.setMatchableSymbol("reverse"); + ruler.setNextPlayerSkiplevel(0); assert(!ruler.isValidPlay(player, 105, false)); - ruler.setAllowedColor("blue"); - ruler.setAllowedSymbol("reverse"); + ruler.setMatchableColor("green"); + ruler.setMatchableSymbol("none"); assert(!ruler.isValidPlay(player, 105, false)); - ruler.setAllowedColor("green"); - ruler.setAllowedSymbol("skip"); + + ruler.setMatchableColor("yellow"); + ruler.setMatchableSymbol("skip"); + ruler.setNextPlayerSkiplevel(3); assert(!ruler.isValidPlay(player, 105, false)); - ruler.setAllowedColor("green"); - ruler.setAllowedSymbol("reverse"); + ruler.setMatchableColor("yellow"); + ruler.setMatchableSymbol("reverse"); + ruler.setNextPlayerSkiplevel(0); assert(!ruler.isValidPlay(player, 105, false)); - ruler.setAllowedColor("yellow"); + ruler.setMatchableColor("yellow"); + ruler.setMatchableSymbol("none"); assert(!ruler.isValidPlay(player, 105, false)); + } + + + + @Test + /** + * 3. test previous card: red 8 + */ + void testSituation_Red8() throws Exception { + RuleController ruler = new RuleController(); + Player player = playerAllCards(); // a player who owns all cards + + ruler.setMatchableColor("red"); + ruler.setMatchableSymbol("none"); + ruler.setMatchableNumber("8"); + + ArrayList<Integer> validByRuler = getAllLegalCardsByRuler(ruler, player); + ArrayList<Integer> groundTruth = groundTruthGenerator(ruler, player, + ruler.getMatchableColor(), ruler.getMatchableNumber(), ruler.getMatchableSymbol()); + + System.out.println(validByRuler); + System.out.println(groundTruth); + assert(validByRuler.equals(groundTruth)); + } + + + @Test + /** + * 4. test previous card: yellow 0 + */ + void testSituation_Yellow0() throws Exception { + RuleController ruler = new RuleController(); + Player player = playerAllCards(); // a player who owns all cards + ruler.setMatchableColor("yellow"); + ruler.setMatchableSymbol("none"); + ruler.setMatchableNumber("0"); + ArrayList<Integer> validByRuler = getAllLegalCardsByRuler(ruler, player); + ArrayList<Integer> groundTruth = groundTruthGenerator(ruler, player, + ruler.getMatchableColor(), ruler.getMatchableNumber(), ruler.getMatchableSymbol()); + + System.out.println(validByRuler); + System.out.println(groundTruth); + assert(validByRuler.equals(groundTruth)); + } + + @Test + /** + * 5. test previous card: blue skip + */ + void testSituation_blueSkip() throws Exception { + RuleController ruler = new RuleController(); + Player player = playerAllCards(); // a player who owns all cards + ruler.setMatchableColor("blue"); + ruler.setMatchableSymbol("skip"); + ruler.setMatchableNumber("none"); + ruler.setNextPlayerSkiplevel(3); + ArrayList<Integer> validByRuler = getAllLegalCardsByRuler(ruler, player); + ArrayList<Integer> groundTruth = groundTruthGenerator(ruler, player, + ruler.getMatchableColor(), ruler.getMatchableNumber(), ruler.getMatchableSymbol()); + + System.out.println(validByRuler); + System.out.println(groundTruth); + assert(validByRuler.equals(groundTruth)); + } + + @Test + /** + * 6. test previous card: green reverse + */ + void testSituation_greenReverse() throws Exception { + RuleController ruler = new RuleController(); + Player player = playerAllCards(); // a player who owns all cards + ruler.setMatchableColor("green"); + ruler.setMatchableSymbol("reverse"); + ruler.setMatchableNumber("none"); + ruler.setNextPlayerSkiplevel(0); + ArrayList<Integer> validByRuler = getAllLegalCardsByRuler(ruler, player); + ArrayList<Integer> groundTruth = groundTruthGenerator(ruler, player, + ruler.getMatchableColor(), ruler.getMatchableNumber(), ruler.getMatchableSymbol()); + System.out.println(validByRuler); + System.out.println(groundTruth); + assert(validByRuler.equals(groundTruth)); + } + @Test + /** + * 7. test previous card: red draw2 + */ + void testSituation_RedDraw2() throws Exception { + RuleController ruler = new RuleController(); + Player player = playerAllCards(); // a player who owns all cards + ruler.setMatchableColor("red"); + ruler.setMatchableSymbol("draw2"); + ruler.setMatchableNumber("none"); + ruler.setNextPlayerSkiplevel(1); + ArrayList<Integer> validByRuler = getAllLegalCardsByRuler(ruler, player); + ArrayList<Integer> groundTruth = groundTruthGenerator(ruler, player, + ruler.getMatchableColor(), ruler.getMatchableNumber(), ruler.getMatchableSymbol()); + + System.out.println(validByRuler); + System.out.println(groundTruth); + assert(validByRuler.equals(groundTruth)); } -// @Test // Last round a red 8 played -// void testRed8() throws Exception { -// RuleController ruler = new RuleController(); -// -// } + @Test + /** + * 8. test previous card: wild with red as declared color + */ + void testSituation_wildDeclaredRed() throws Exception { + RuleController ruler = new RuleController(); + Player player = playerAllCards(); // a player who owns all cards + ruler.setMatchableColor("red"); // only color should be matchable in this case + ruler.setMatchableSymbol("none"); + ruler.setMatchableNumber("none"); + ruler.setNextPlayerSkiplevel(0); + ArrayList<Integer> validByRuler = getAllLegalCardsByRuler(ruler, player); + ArrayList<Integer> groundTruth = groundTruthGenerator(ruler, player, + ruler.getMatchableColor(), ruler.getMatchableNumber(), ruler.getMatchableSymbol()); + System.out.println(validByRuler); + System.out.println(groundTruth); + assert(validByRuler.equals(groundTruth)); + } + + + @Test /** - * + * 9. test previous card: wildDraw4 with red as declared color */ - void testInitializer() {} + void testSituation_wildDraw4DeclaredRed() throws Exception { + RuleController ruler = new RuleController(); + Player player = playerAllCards(); // a player who owns all cards + ruler.setMatchableColor("red"); // only color should be matchable in this case + ruler.setMatchableSymbol("none"); + ruler.setMatchableNumber("none"); + ruler.setNextPlayerSkiplevel(2); + ArrayList<Integer> validByRuler = getAllLegalCardsByRuler(ruler, player); + ArrayList<Integer> groundTruth = groundTruthGenerator(ruler, player, + ruler.getMatchableColor(), ruler.getMatchableNumber(), ruler.getMatchableSymbol()); + + System.out.println(validByRuler); + System.out.println(groundTruth); + assert(validByRuler.equals(groundTruth)); + } + + + + + + + + + + /** * extract all the cards that the ruler think as legal */ - private ArrayList<Integer> getAllLegalCardsByRuler(RuleController ruler, ArrayList<Integer> cards) { + private ArrayList<Integer> getAllLegalCardsByRuler(RuleController ruler, Player player) { ArrayList<Integer> validList = new ArrayList<>(); - for (int cardID : cards) { - if (ruler.isValidPlay(null, cardID, false)) { + for (int cardID : player.getCards()) { + if (ruler.isValidPlay(player, cardID, false)) { validList.add(cardID); } } @@ -119,30 +389,54 @@ class RuleControllerTest { * extract all the cards that are indeed legal (ground true generator) */ private ArrayList<Integer> groundTruthGenerator(RuleController ruler, - ArrayList<Integer> cards, - String color, String number, - String symbol) { - for (int cardID : cards) { + Player player, + String colorTruth, + String numberTruth, + String symbolTruth) { + ArrayList<Integer> validList = new ArrayList<>(); + for (int cardID : player.getCards()) { String cardDescription = parser.parseCardID(cardID); String[] result = parser.parseCardDescription(cardDescription); String cardCol = result[0]; - String cardType = result[1]; String cardContent = result[2]; if (ruler.getNextPlayerSkiplevel() == 3) { continue; // skip card played. any card will be illegal + } else if (ruler.getNextPlayerSkiplevel() == 2) { - // only wildDraw4 if allowed - if (cardContent.equals("wildDraw4") || cardContent.equals("wildDraw2")); + // only wildDraw4 is allowed + if (cardContent.equals("wildDraw4") && ruler.isValidPlay(player, cardID, false)) { + // this call is valid because wildDraw4 behavior has passed the test. + validList.add(cardID); + } + } else if (ruler.getNextPlayerSkiplevel() == 1) { - // both draw 2 and wild draw 4 are allowed + // both draw 2 and wild draw 4 are allowed + if (cardContent.equals("wildDraw4") && ruler.isValidPlay(player, cardID, false)) { + validList.add(cardID); + } else if (cardContent.equals("draw2")) { + validList.add(cardID); + } + } else { // cards with any one of color, number or symbol matched are playable - + if (cardContent.equals("wild")) { + validList.add(cardID); + } else if (cardContent.equals("wildDraw4") && ruler.isValidPlay(player, cardID, false)) { + validList.add(cardID); + } else { + if (cardCol.equals(colorTruth)) { + validList.add(cardID); + } else if (cardContent.equals(numberTruth)) { + validList.add(cardID); + } else if (cardContent.equals(symbolTruth)) { + validList.add(cardID); + } + } } } -// if (ruler.getSkip) - return null; + + return validList; } /** diff --git a/src/UNO/CmdUI.java b/src/UNO/CmdUI.java index 75d95c81f7a1498cf9dad8ce565c7fddfb66bade..9da970239c7a9feddedc7a73aca19dbfc3815629 100644 --- a/src/UNO/CmdUI.java +++ b/src/UNO/CmdUI.java @@ -77,7 +77,7 @@ public class CmdUI { promptChooseColor(); colorChosen = getInputColor(); } - ruler.setAllowedColor(parser.colorDict.get(colorChosen)); + ruler.setMatchableColor(parser.colorDict.get(colorChosen)); } return cardID; } @@ -97,7 +97,7 @@ public class CmdUI { promptChooseColor(); colorChosen = getInputColor(); } - gameController.ruler.setAllowedColor(parser.colorDict.get(colorChosen)); + gameController.ruler.setMatchableColor(parser.colorDict.get(colorChosen)); } return cardID; diff --git a/src/UNO/RuleController.java b/src/UNO/RuleController.java index 2c2a08e1b2ff61a101949a48cafbf9ae02bb274b..67639ad3f7e78b0f0bd9857cd25e93f29faf5670 100644 --- a/src/UNO/RuleController.java +++ b/src/UNO/RuleController.java @@ -83,6 +83,7 @@ public class RuleController { if (content.equals("wildDraw4")) { return checkDraw4IsLegal(player); } + return false; // any cards other than wildDraw4 are not playable } else if (nextPlayerSkipLevel == 1) { if (content.equals("wildDraw4")) { return checkDraw4IsLegal(player); @@ -116,7 +117,7 @@ public class RuleController { } private void updateRule(String color, String type, String content) { - setAllowedColor(color); // wildcard "NA" - this will be updated later by player declaring the color + setMatchableColor(color); // wildcard "NA" - this will be updated later by player declaring the color if (type.equals("sym")) { if (content.equals("skip")) { @@ -175,8 +176,6 @@ public class RuleController { int cardID = cards.get(i); String cardDescription = parser.parseCardID(cardID); String color = parser.parseCardDescription(cardDescription)[0]; // color of wild cards are NA - System.out.println(color); - if (color.equals(currentMatchableColor)) { return false; } @@ -192,19 +191,19 @@ public class RuleController { return currentMatchableNumber; } - public void getAllowedNumber(String number) { - currentMatchableColor = number; + public void setMatchableNumber(String number) { + currentMatchableNumber = number; } /** * Getter and Setter for Allowed Symbol */ - public String getCurrentMatchableSymbol() { + public String getMatchableSymbol() { return currentMatchableSymbol; } - public void setAllowedSymbol(String symbol) { + public void setMatchableSymbol(String symbol) { currentMatchableSymbol = symbol; } @@ -217,7 +216,7 @@ public class RuleController { return currentMatchableColor; } - public void setAllowedColor(String color) { + public void setMatchableColor(String color) { currentMatchableColor = color; } @@ -270,7 +269,7 @@ public class RuleController { System.out.println("============================= Game State Report ========================================"); System.out.println("Current matchable color : " + getMatchableColor()); System.out.println("Current matchable number : " + getMatchableNumber()); - System.out.println("Current matchable symbol : " + getCurrentMatchableSymbol()); + System.out.println("Current matchable symbol : " + getMatchableSymbol()); System.out.println("Game order : " + (getIsClockwise() ? "clockwise" : "counterclockwise")); System.out.println("Player skip level is " + descSkipLevel()); System.out.println("Player will be forced to draw " + cumulativePenaltyDraw + " cards");