Skip to content
Snippets Groups Projects
Commit 27c43774 authored by FrederickPi1969's avatar FrederickPi1969
Browse files

wildDraw4 test passed

parent 959a678e
No related branches found
No related tags found
No related merge requests found
Showing
with 307 additions and 23 deletions
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
File added
File added
...@@ -3,10 +3,45 @@ ...@@ -3,10 +3,45 @@
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/Test" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/Test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/UNO" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/UNO" isTestSource="false" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library" exported="">
<library>
<CLASSES>
<root url="jar://$USER_HOME$/.jdks/external/junit-4.13.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" exported="">
<library>
<CLASSES>
<root url="file://$USER_HOME$/.jdks/external" />
</CLASSES>
<JAVADOC />
<SOURCES />
<jarDirectory url="file://$USER_HOME$/.jdks/external" recursive="false" />
</library>
</orderEntry>
<orderEntry type="module-library" scope="TEST">
<library name="JUnit5.4">
<CLASSES>
<root url="jar://$USER_HOME$/.jdks/external/junit-jupiter-5.4.2.jar!/" />
<root url="jar://$USER_HOME$/.jdks/external/junit-jupiter-api-5.4.2.jar!/" />
<root url="jar://$USER_HOME$/.jdks/external/apiguardian-api-1.0.0.jar!/" />
<root url="jar://$USER_HOME$/.jdks/external/opentest4j-1.1.1.jar!/" />
<root url="jar://$USER_HOME$/.jdks/external/junit-platform-commons-1.4.2.jar!/" />
<root url="jar://$USER_HOME$/.jdks/external/junit-jupiter-params-5.4.2.jar!/" />
<root url="jar://$USER_HOME$/.jdks/external/junit-jupiter-engine-5.4.2.jar!/" />
<root url="jar://$USER_HOME$/.jdks/external/junit-platform-engine-1.4.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component> </component>
</module> </module>
\ No newline at end of file
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CardParserTest {
@Test
void parseCardID() {
}
@Test
void parseCardDescription() {
}
@Test
void isWildCard() {
}
}
\ No newline at end of file
import com.sun.source.tree.UsesTree;
import org.junit.Rule;
import org.junit.jupiter.api.Test;
import javax.print.attribute.standard.Finishings;
import java.lang.invoke.VarHandle;
import java.util.ArrayList;
import java.util.Random;
// Test for judging whether a play is legal
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
void test_Player_Red_N_WildDraw4_Y_UseWildDraw4() throws Exception {
Player player = player_Red_N_WildDraw4_Y();
RuleController ruler = new RuleController();
ruler.setNextPlayerSkiplevel(0);
ruler.setAllowedColor("red");
ruler.setAllowedSymbol("skip");
assert(ruler.isValidPlay(player, 105, false));
ruler.setAllowedColor("red");
ruler.setAllowedSymbol("reverse");
assert(ruler.isValidPlay(player, 105, false));
ruler.setAllowedColor("blue");
ruler.setAllowedSymbol("skip");
assert(!ruler.isValidPlay(player, 105, false));
ruler.setAllowedColor("blue");
ruler.setAllowedSymbol("reverse");
assert(!ruler.isValidPlay(player, 105, false));
ruler.setAllowedColor("green");
ruler.setAllowedSymbol("skip");
assert(!ruler.isValidPlay(player, 105, false));
ruler.setAllowedColor("green");
ruler.setAllowedSymbol("reverse");
assert(!ruler.isValidPlay(player, 105, false));
ruler.setAllowedColor("yellow");
assert(!ruler.isValidPlay(player, 105, false));
}
@Test // 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();
assert(!ruler.isValidPlay(player, 105, false));
ruler.setNextPlayerSkiplevel(0);
ruler.setAllowedColor("red");
ruler.setAllowedSymbol("skip");
assert(!ruler.isValidPlay(player, 105, false));
ruler.setAllowedColor("red");
ruler.setAllowedSymbol("reverse");
assert(!ruler.isValidPlay(player, 105, false));
ruler.setAllowedColor("blue");
ruler.setAllowedSymbol("skip");
assert(!ruler.isValidPlay(player, 105, false));
ruler.setAllowedColor("blue");
ruler.setAllowedSymbol("reverse");
assert(!ruler.isValidPlay(player, 105, false));
ruler.setAllowedColor("green");
ruler.setAllowedSymbol("skip");
assert(!ruler.isValidPlay(player, 105, false));
ruler.setAllowedColor("green");
ruler.setAllowedSymbol("reverse");
assert(!ruler.isValidPlay(player, 105, false));
ruler.setAllowedColor("yellow");
assert(!ruler.isValidPlay(player, 105, false));
}
// @Test // Last round a red 8 played
// void testRed8() throws Exception {
// RuleController ruler = new RuleController();
//
// }
/**
*
*/
void testInitializer() {}
/**
* extract all the cards that the ruler think as legal
*/
private ArrayList<Integer> getAllLegalCardsByRuler(RuleController ruler, ArrayList<Integer> cards) {
ArrayList<Integer> validList = new ArrayList<>();
for (int cardID : cards) {
if (ruler.isValidPlay(null, cardID, false)) {
validList.add(cardID);
}
}
return validList;
}
/**
* 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) {
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"));
} else if (ruler.getNextPlayerSkiplevel() == 1) {
// both draw 2 and wild draw 4 are allowed
} else {
// cards with any one of color, number or symbol matched are playable
}
}
// if (ruler.getSkip)
return null;
}
/**
* construct a player who has no red cards, but a wildDraw4 card
* This player should be able to play wildDraw4 card if current allowed color is red
* @return
*/
private Player player_Red_N_WildDraw4_Y() {
Player player = new Player(0, null);
player.addOneCard(26); // green 1
player.addOneCard(51); // blue 1
player.addOneCard(76); // yellow 1
player.addOneCard(101); // wild
player.addOneCard(105); // wildDraw 4
return player;
}
/**
* Construct a player who owns all colors, and also a wildDraw4 card
* This player should not be able to play wildDraw4 card.
* @return
*/
private Player player_AllColor_Y_WildDraw4_Y() {
Player player = new Player(0, null);
player.addOneCard(1); // red 1
player.addOneCard(26); // green 1
player.addOneCard(51); // blue 1
player.addOneCard(76); // yellow 1
player.addOneCard(101); // wild
player.addOneCard(105); // wildDraw 4
return player;
}
/**
* Construct a magic player who own ALL CARDS
* This player should not be able to play wildDraw4 card
*/
private Player playerAllCards() {
Player player = new Player(0, null);
for (int i = 1; i <= 108; i++) {
player.addOneCard(i);
}
return player;
}
}
\ No newline at end of file
...@@ -83,5 +83,10 @@ public class CardManager { ...@@ -83,5 +83,10 @@ public class CardManager {
*/ */
public int numLeftDiscardPile() { return discardPile.size(); } public int numLeftDiscardPile() { return discardPile.size(); }
/**
* get all the cards currently in card pile as a Array list
*/
public ArrayList<Integer> getCardPile() { return cardPile; }
} }
...@@ -8,9 +8,10 @@ public class CmdUI { ...@@ -8,9 +8,10 @@ public class CmdUI {
public CmdUI(Player p) { public CmdUI(Player p) {
player = p; player = p;
parser = player.parser;
gameController = player.gameController; gameController = player.gameController;
ruler = gameController.ruler; parser = (gameController != null) ? player.parser : null;
ruler = (gameController != null) ? gameController.ruler : null;
} }
......
...@@ -43,7 +43,7 @@ public class Game { ...@@ -43,7 +43,7 @@ public class Game {
*/ */
private void decideFirstPlayerID(int playerNum) { private void decideFirstPlayerID(int playerNum) {
Random rand = new Random(); Random rand = new Random();
currentPlayerID = rand.nextInt(playerNum); // -1 to convert to index currentPlayerID = rand.nextInt(playerNum);
} }
......
...@@ -15,8 +15,8 @@ public class Player { ...@@ -15,8 +15,8 @@ public class Player {
playerID = ID; playerID = ID;
cards = new ArrayList<Integer>(); cards = new ArrayList<Integer>();
gameController = game; gameController = game;
ruler = game.ruler; ruler = (game != null) ? game.ruler : null; // for testing purpose
parser = RuleController.parser; parser = (game != null) ? RuleController.parser : null;
prompterCmd = new CmdUI(this); prompterCmd = new CmdUI(this);
prompterGUI = null; prompterGUI = null;
} }
...@@ -137,6 +137,11 @@ public class Player { ...@@ -137,6 +137,11 @@ public class Player {
} }
/**
* For Test only. Add one card with Given card ID to the player's cards
*/
public void addOneCard(int cardID) {
cards.add(cardID);
}
} }
\ No newline at end of file
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random;
public class RuleController { public class RuleController {
public static CardParser parser = new CardParser(); public static CardParser parser = new CardParser();
...@@ -6,13 +7,32 @@ public class RuleController { ...@@ -6,13 +7,32 @@ public class RuleController {
/** IMPORTANT /** IMPORTANT
* As long as one of the following three is matchable, the play will be considered as legal * As long as one of the following three is matchable, the play will be considered as legal
*/ */
private String currentMatchableColor = "all"; private String currentMatchableColor;
private String currentMatchableNumber = "all"; private String currentMatchableNumber;
private String currentMatchableSymbol = "all"; private String currentMatchableSymbol = "all"; // all symbols can be played in the first round
private int nextPlayerSkipLevel = 0; private int nextPlayerSkipLevel = 0;
private int cumulativePenaltyDraw = 0; private int cumulativePenaltyDraw = 0;
private boolean isClockWise = true; // if clockwise, next player will be the element in player list private boolean isClockWise = true; // if clockwise, next player will be the element in player list
public RuleController() {
// initialize first matched color and number
boolean chosen = false;
while (!chosen) {
Random rand = new Random();
int cardID = rand.nextInt(100) + 1; // generate a number from 1 - 100. these are colored cards
String desc = parser.parseCardID(cardID);
String[] result = parser.parseCardDescription(desc);
String color = result[0];
String type = result[1];
String content = result[2];
if (type.equals("num")) {
currentMatchableColor = color;
currentMatchableNumber = content;
chosen = true;
}
}
}
/** /**
* judge whether a pending player should be skipped * judge whether a pending player should be skipped
...@@ -49,7 +69,7 @@ public class RuleController { ...@@ -49,7 +69,7 @@ public class RuleController {
* @return whether the play is valid * @return whether the play is valid
*/ */
public boolean isValidPlay(Player player, int cardID, boolean updateIfValid) { public boolean isValidPlay(Player player, int cardID, boolean updateIfValid) {
assert(player != null);
String cardDescription = parser.parseCardID(cardID); String cardDescription = parser.parseCardID(cardID);
String[] result = parser.parseCardDescription(cardDescription); String[] result = parser.parseCardDescription(cardDescription);
String color = result[0]; String color = result[0];
...@@ -57,31 +77,37 @@ public class RuleController { ...@@ -57,31 +77,37 @@ public class RuleController {
String content = result[2]; String content = result[2];
// pending skip // pending skip
if (nextPlayerSkipLevel == 4) { if (nextPlayerSkipLevel == 3) {
return false; return false;
} else if (nextPlayerSkipLevel == 3) {
return content.equals("wildDraw4"); // not sure - check draw 4 legal?
} else if (nextPlayerSkipLevel == 2) { } else if (nextPlayerSkipLevel == 2) {
return content.equals("wildDraw4") || content.equals("draw2"); if (content.equals("wildDraw4")) {
return checkDraw4IsLegal(player);
}
} else if (nextPlayerSkipLevel == 1) {
if (content.equals("wildDraw4")) {
return checkDraw4IsLegal(player);
}
return content.equals("draw2"); // draw 2 is always allowed in this case
} }
boolean valid = false; boolean valid = false;
// if not skipped, first consider wild // if not skipped, first consider wild card
if (content.equals("wild")) { if (content.equals("wild")) {
valid = true; // can be used unconditionally valid = true; // can be used unconditionally
} }
// then consider wildDraw4
if (content.equals("wildDraw4")) {
valid = checkDraw4IsLegal(player);
}
// then other colored cards // then other colored cards
if (checkAttrMatch(currentMatchableColor, color)) if (checkAttrMatch(currentMatchableColor, color))
valid = true; valid = true;
if (checkAttrMatch(currentMatchableNumber, content) || checkAttrMatch(currentMatchableSymbol, content)) if (checkAttrMatch(currentMatchableNumber, content) || checkAttrMatch(currentMatchableSymbol, content))
valid = true; valid = true;
// check wildDraw4 at last
if (content.equals("wildDraw4")) {
valid = checkDraw4IsLegal(player);
}
if (valid && updateIfValid) { if (valid && updateIfValid) {
updateRule(color, type, content); updateRule(color, type, content);
} }
...@@ -143,12 +169,17 @@ public class RuleController { ...@@ -143,12 +169,17 @@ public class RuleController {
* Check whether a player have currently matchable **color** when attempting to play wild draw 4 * Check whether a player have currently matchable **color** when attempting to play wild draw 4
*/ */
private boolean checkDraw4IsLegal(Player player) { private boolean checkDraw4IsLegal(Player player) {
ArrayList<Integer> cards = player.getCards(); ArrayList<Integer> cards = player.getCards();
for (int i = 0; i < cards.size(); i++) { for (int i = 0; i < cards.size(); i++) {
int cardID = cards.get(i); int cardID = cards.get(i);
String cardDescription = parser.parseCardID(cardID); String cardDescription = parser.parseCardID(cardID);
String color = parser.parseCardDescription(cardDescription)[0]; // color of wild cards are NA String color = parser.parseCardDescription(cardDescription)[0]; // color of wild cards are NA
if (color.equals(currentMatchableNumber)) return false; System.out.println(color);
if (color.equals(currentMatchableColor)) {
return false;
}
} }
return true; return true;
} }
...@@ -246,7 +277,6 @@ public class RuleController { ...@@ -246,7 +277,6 @@ public class RuleController {
System.out.println("There are " + gameController.gameCardManager.numCardLeft() + " cards in the card pile."); System.out.println("There are " + gameController.gameCardManager.numCardLeft() + " cards in the card pile.");
System.out.println("There are " + gameController.gameCardManager.numLeftDiscardPile() + " cards in the discard pile."); System.out.println("There are " + gameController.gameCardManager.numLeftDiscardPile() + " cards in the discard pile.");
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment