AIUtil now needs game settings, both hand and player do not anymore

git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@342 72836036-5685-4462-b002-a69064685172
This commit is contained in:
Bennet Gerlach 2011-05-31 03:45:32 +02:00
parent 278edc37a9
commit d276b03c39
10 changed files with 140 additions and 137 deletions

View file

@ -78,12 +78,12 @@ public class MockHand implements IHand {
} }
@Override @Override
public int getStonePoints() { public int getStonePoints(GameSettings settings) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
return 0; return 0;
} }
public boolean isInitialMeldPossible() { public boolean isInitialMeldPossible(GameSettings settings) {
return false; return false;
} }

View file

@ -13,12 +13,12 @@ public class MockPlayer implements IPlayer {
/** /**
* @param playerSettings * @param playerSettings
* the player settings * the player settings
* @param gameSettings * @param gameSettings
* the game settings * the game settings
*/ */
public MockPlayer(PlayerSettings playerSettings, GameSettings gameSettings) { public MockPlayer(PlayerSettings playerSettings, GameSettings gameSettings) {
hand = new Hand(gameSettings); hand = new Hand();
this.playerSettings = playerSettings; this.playerSettings = playerSettings;
laidOut = false; laidOut = false;
} }

View file

@ -7,18 +7,33 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.TreeMap; import java.util.TreeMap;
import jrummikub.model.GameSettings;
import jrummikub.model.Stone; import jrummikub.model.Stone;
import jrummikub.model.StoneColor; import jrummikub.model.StoneColor;
import jrummikub.model.StoneSet; import jrummikub.model.StoneSet;
import jrummikub.util.Pair; import jrummikub.util.Pair;
/** /**
* A collection of several AI utility methods * A collection of several AI utility methods with given game settings
* *
*/ */
public class AIUtil { public class AIUtil {
private AIUtil() { GameSettings settings;
List<StoneColor> stoneColors;
/**
* The utility class's methods calculate their results based on the game
* settings
*
* @param settings
* the underlying game settings
*/
public AIUtil(GameSettings settings) {
this.settings = settings;
stoneColors = new ArrayList<StoneColor>(Arrays.asList(StoneColor.values()));
stoneColors.retainAll(settings.getStoneColors());
} }
private static class SearchState { private static class SearchState {
@ -47,7 +62,7 @@ public class AIUtil {
* @return the sets that have the desired point total or the highest found * @return the sets that have the desired point total or the highest found
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static Pair<List<StoneSet>, Integer> findSetsWithTotalPoints( public Pair<List<StoneSet>, Integer> findSetsWithTotalPoints(
int pointsMissing, int pointsMissing,
TreeMap<Pair<Integer, StoneColor>, Integer> stoneCounts, int jokerCount) { TreeMap<Pair<Integer, StoneColor>, Integer> stoneCounts, int jokerCount) {
@ -63,14 +78,13 @@ public class AIUtil {
bestResult = new Pair<List<StoneSet>, Integer>( bestResult = new Pair<List<StoneSet>, Integer>(
Collections.<StoneSet> emptyList(), 0); Collections.<StoneSet> emptyList(), 0);
for (int value = 13; value >= 1; value--) { for (int value = settings.getHighestValue(); value >= 1; value--) {
for (StoneColor color : StoneColor.values()) { for (StoneColor color : stoneColors) {
Pair<Integer, StoneColor> stone = new Pair<Integer, StoneColor>(value, Pair<Integer, StoneColor> stone = new Pair<Integer, StoneColor>(value,
color); color);
if (stoneCounts.containsKey(stone)) { if (stoneCounts.containsKey(stone)) {
decrementStoneCount(stoneCounts, stone); decrementStoneCount(stoneCounts, stone);
result = findRunsWithTotalPoints(new SearchState(pointsMissing result = findRunsWithTotalPoints(new SearchState(pointsMissing
- value, stoneCounts, jokerCount), stone, 1); - value, stoneCounts, jokerCount), stone, 1);
if (result.getSecond() >= pointsMissing) if (result.getSecond() >= pointsMissing)
@ -109,7 +123,7 @@ public class AIUtil {
return bestResult; return bestResult;
} }
private static Pair<List<StoneSet>, Integer> findGroupsWithTotalPoints( private Pair<List<StoneSet>, Integer> findGroupsWithTotalPoints(
SearchState searchState, int value, List<StoneColor> chosenColors, SearchState searchState, int value, List<StoneColor> chosenColors,
StoneColor testedColor) { StoneColor testedColor) {
@ -175,7 +189,7 @@ public class AIUtil {
return bestResult; return bestResult;
} }
private static Pair<List<StoneSet>, Integer> findRunsWithTotalPoints( private Pair<List<StoneSet>, Integer> findRunsWithTotalPoints(
SearchState searchState, Pair<Integer, StoneColor> testedStone, SearchState searchState, Pair<Integer, StoneColor> testedStone,
int runLength) { int runLength) {
@ -262,12 +276,12 @@ public class AIUtil {
} }
} }
static StoneColor getNextColor(StoneColor color) { StoneColor getNextColor(StoneColor color) {
int index = Arrays.binarySearch(StoneColor.values(), color) + 1; int index = stoneColors.indexOf(color) + 1;
if (index >= StoneColor.values().length) { if (index >= stoneColors.size()) {
return null; return null;
} }
return StoneColor.values()[index]; return stoneColors.get(index);
} }
private final static Comparator<Pair<Integer, StoneColor>> comparator = new Comparator<Pair<Integer, StoneColor>>() { private final static Comparator<Pair<Integer, StoneColor>> comparator = new Comparator<Pair<Integer, StoneColor>>() {

View file

@ -43,9 +43,9 @@ public class RoundControl {
* Create a new RoundControl using the given gameState and view * Create a new RoundControl using the given gameState and view
* *
* @param roundState * @param roundState
* initial round state * initial round state
* @param view * @param view
* view used for user interaction * view used for user interaction
*/ */
public RoundControl(IRoundState roundState, IView view) { public RoundControl(IRoundState roundState, IView view) {
this.roundState = roundState; this.roundState = roundState;
@ -89,10 +89,10 @@ public class RoundControl {
} }
view.getTablePanel().setStoneSets(clonedTable); view.getTablePanel().setStoneSets(clonedTable);
view.setCurrentPlayerName(roundState.getActivePlayer() view.setCurrentPlayerName(roundState.getActivePlayer().getPlayerSettings()
.getPlayerSettings().getName()); .getName());
view.setCurrentPlayerColor(roundState.getActivePlayer() view.setCurrentPlayerColor(roundState.getActivePlayer().getPlayerSettings()
.getPlayerSettings().getColor()); .getColor());
view.setHasLaidOut(roundState.getActivePlayer().getLaidOut()); view.setHasLaidOut(roundState.getActivePlayer().getLaidOut());
if (!isHuman) if (!isHuman)
@ -106,15 +106,14 @@ public class RoundControl {
.getTurnControlType() == HUMAN; .getTurnControlType() == HUMAN;
boolean inspectOnly = roundState.getTurnNumber() < 1; boolean inspectOnly = roundState.getTurnNumber() < 1;
boolean mayRedeal = inspectOnly boolean mayRedeal = inspectOnly
&& roundState.getActivePlayer().getHand() && roundState.getActivePlayer().getHand().getIdenticalStoneCount() >= 3;
.getIdenticalStoneCount() >= 3;
if (isHuman) { if (isHuman) {
view.getPlayerPanel().setEndTurnMode(inspectOnly, mayRedeal); view.getPlayerPanel().setEndTurnMode(inspectOnly, mayRedeal);
} }
turnControl = TurnControlFactory.getFactory( turnControl = TurnControlFactory.getFactory(
roundState.getActivePlayer().getPlayerSettings() roundState.getActivePlayer().getPlayerSettings().getTurnControlType())
.getTurnControlType()).create(); .create();
turnControl.setup(roundState.getActivePlayer(), clonedTable, view, turnControl.setup(roundState.getActivePlayer(), clonedTable, view,
inspectOnly, mayRedeal); inspectOnly, mayRedeal);
turnControl.getEndOfTurnEvent().add(new IListener() { turnControl.getEndOfTurnEvent().add(new IListener() {
@ -136,10 +135,8 @@ public class RoundControl {
void deal() { void deal() {
for (int i = 0; i < roundState.getPlayerCount(); i++) { for (int i = 0; i < roundState.getPlayerCount(); i++) {
IHand hand = roundState.getNthNextPlayer(i).getHand(); IHand hand = roundState.getNthNextPlayer(i).getHand();
for (int j = 0; j < roundState.getGameSettings() for (int j = 0; j < roundState.getGameSettings().getNumberOfStonesDealt(); j++) {
.getNumberOfStonesDealt(); j++) { hand.drop(roundState.getGameHeap().drawStone(), new Position(0, 0));
hand.drop(roundState.getGameHeap().drawStone(), new Position(0,
0));
} }
} }
} }
@ -150,13 +147,11 @@ public class RoundControl {
int totalValue = 0; int totalValue = 0;
for (StoneSet set : newSets) { for (StoneSet set : newSets) {
totalValue += set.classify(roundState.getGameSettings()) totalValue += set.classify(roundState.getGameSettings()).getSecond();
.getSecond();
} }
return totalValue == 0 return totalValue == 0
|| totalValue >= roundState.getGameSettings() || totalValue >= roundState.getGameSettings().getInitialMeldThreshold();
.getInitialMeldThreshold();
} }
private void endOfTurn() { private void endOfTurn() {
@ -195,8 +190,7 @@ public class RoundControl {
} }
if (!roundState.getActivePlayer().getLaidOut()) { if (!roundState.getActivePlayer().getLaidOut()) {
// Player touched forbidden stones // Player touched forbidden stones
if (!tableSetDifference(clonedTable, roundState.getTable()) if (!tableSetDifference(clonedTable, roundState.getTable()).isEmpty()) {
.isEmpty()) {
rejectMove(); rejectMove();
return; return;
} }
@ -205,8 +199,7 @@ public class RoundControl {
return; return;
} }
} }
Set<Stone> tableDiff = tableDifference(roundState.getTable(), Set<Stone> tableDiff = tableDifference(roundState.getTable(), clonedTable);
clonedTable);
roundState.setTable(clonedTable); roundState.setTable(clonedTable);
@ -222,8 +215,7 @@ public class RoundControl {
} }
private void rejectMove() { private void rejectMove() {
Set<Stone> tableDiff = tableDifference(roundState.getTable(), Set<Stone> tableDiff = tableDifference(roundState.getTable(), clonedTable);
clonedTable);
// deal penalty, reset // deal penalty, reset
roundState.getGameHeap().putBack(tableDiff); roundState.getGameHeap().putBack(tableDiff);
dealPenalty(tableDiff.size()); dealPenalty(tableDiff.size());
@ -310,13 +302,13 @@ public class RoundControl {
int stonePoints = 0; int stonePoints = 0;
if (!player.getLaidOut()) { if (!player.getLaidOut()) {
stonePoints = playerHand.isInitialMeldPossible() ? 200 : 100; stonePoints = playerHand.isInitialMeldPossible(roundState
.getGameSettings()) ? 200 : 100;
} else { } else {
stonePoints = playerHand.getStonePoints(); stonePoints = playerHand.getStonePoints(roundState.getGameSettings());
} }
bestScore = updateBestScore(bestScore, -stonePoints, bestScore = updateBestScore(bestScore, -stonePoints, playerHand.getSize());
playerHand.getSize());
points.add(-stonePoints); points.add(-stonePoints);
pointSum += stonePoints; pointSum += stonePoints;

View file

@ -18,18 +18,6 @@ public class Hand extends StoneTray<Stone> implements IHand {
*/ */
public final static int WIDTH = 14; public final static int WIDTH = 14;
private GameSettings settings;
/**
* Create a new empty hand with given game settings
*
* @param settings
* the game settings
*/
public Hand(GameSettings settings) {
this.settings = settings;
}
@Override @Override
public int getFreeRowSpace(int row) { public int getFreeRowSpace(int row) {
int count = 0; int count = 0;
@ -74,7 +62,8 @@ public class Hand extends StoneTray<Stone> implements IHand {
} }
} }
public int getStonePoints() { @Override
public int getStonePoints(GameSettings settings) {
int points = 0; int points = 0;
for (Pair<Stone, Position> entry : this) { for (Pair<Stone, Position> entry : this) {
@ -89,7 +78,9 @@ public class Hand extends StoneTray<Stone> implements IHand {
} }
@Override @Override
public boolean isInitialMeldPossible() { public boolean isInitialMeldPossible(GameSettings settings) {
AIUtil aiUtil = new AIUtil(settings);
List<Stone> stones = new ArrayList<Stone>(); List<Stone> stones = new ArrayList<Stone>();
for (Iterator<Pair<Stone, Position>> iter = this.iterator(); iter.hasNext();) { for (Iterator<Pair<Stone, Position>> iter = this.iterator(); iter.hasNext();) {
@ -99,12 +90,10 @@ public class Hand extends StoneTray<Stone> implements IHand {
Pair<TreeMap<Pair<Integer, StoneColor>, Integer>, Integer> stoneCounts = AIUtil Pair<TreeMap<Pair<Integer, StoneColor>, Integer>, Integer> stoneCounts = AIUtil
.countStones(stones); .countStones(stones);
Pair<List<StoneSet>, Integer> result = AIUtil.findSetsWithTotalPoints( Pair<List<StoneSet>, Integer> result = aiUtil.findSetsWithTotalPoints(
settings.getInitialMeldThreshold(), stoneCounts.getFirst(), settings.getInitialMeldThreshold(), stoneCounts.getFirst(),
stoneCounts.getSecond()); stoneCounts.getSecond());
System.out.println(result);
return (result.getSecond() >= settings.getInitialMeldThreshold()); return (result.getSecond() >= settings.getInitialMeldThreshold());
} }

View file

@ -16,7 +16,7 @@ public interface IHand extends IStoneTray<Stone> {
* Gets the amount of free space in a hand row * Gets the amount of free space in a hand row
* *
* @param row * @param row
* the row number * the row number
* @return the number of stones that can fit into the row * @return the number of stones that can fit into the row
*/ */
int getFreeRowSpace(int row); int getFreeRowSpace(int row);
@ -24,17 +24,23 @@ public interface IHand extends IStoneTray<Stone> {
/** /**
* Get the accumulated number of points of stones in the hand * Get the accumulated number of points of stones in the hand
* *
* @param settings
* the game settings
*
* @return points * @return points
*/ */
int getStonePoints(); int getStonePoints(GameSettings settings);
/** /**
* Tests whether it is possible to lay down an initial meld using the stones * Tests whether it is possible to lay down an initial meld using the stones
* on the hand * on the hand
* *
* @param settings
* the game settings
*
* @return true if an initial meld is possible * @return true if an initial meld is possible
*/ */
public boolean isInitialMeldPossible(); public boolean isInitialMeldPossible(GameSettings settings);
/** /**
* Counts the pairs of identical stones * Counts the pairs of identical stones

View file

@ -10,14 +10,12 @@ public class Player implements IPlayer {
* Create a new player with a given name and color * Create a new player with a given name and color
* *
* @param settings * @param settings
* the player settings * the player settings
* @param gameSettings
* the game settings
*/ */
public Player(PlayerSettings settings, GameSettings gameSettings) { public Player(PlayerSettings settings) {
this.settings = settings; this.settings = settings;
hand = new Hand(gameSettings); hand = new Hand();
laidOut = false; laidOut = false;
} }

View file

@ -18,7 +18,7 @@ public class RoundState implements IRoundState {
* Create a new RoundState with an empty table * Create a new RoundState with an empty table
* *
* @param gameSettings * @param gameSettings
* the game settings * the game settings
*/ */
public RoundState(GameSettings gameSettings) { public RoundState(GameSettings gameSettings) {
this.gameSettings = gameSettings; this.gameSettings = gameSettings;
@ -27,10 +27,10 @@ public class RoundState implements IRoundState {
players = new ArrayList<Player>(); players = new ArrayList<Player>();
for (PlayerSettings playerSettings : gameSettings.getPlayerList()) { for (PlayerSettings playerSettings : gameSettings.getPlayerList()) {
players.add(new Player(playerSettings, gameSettings)); players.add(new Player(playerSettings));
} }
turnNumber = 1-gameSettings.getPlayerList().size(); turnNumber = 1 - gameSettings.getPlayerList().size();
activePlayer = 0; activePlayer = 0;
gameHeap = new StoneHeap(gameSettings); gameHeap = new StoneHeap(gameSettings);

View file

@ -675,7 +675,7 @@ public class RoundControlTest {
view.tablePanel.clickEvent.emit(new Position(0, 0)); view.tablePanel.clickEvent.emit(new Position(0, 0));
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
testRoundState.players.get(i).hand = new Hand(gameSettings); testRoundState.players.get(i).hand = new Hand();
} }
resetTurnStart(); resetTurnStart();
@ -816,7 +816,7 @@ public class RoundControlTest {
testRound.startRound(); testRound.startRound();
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
testRoundState.players.get(i).hand = new Hand(gameSettings); testRoundState.players.get(i).hand = new Hand();
} }
testRoundState.players.get(0).laidOut = true; testRoundState.players.get(0).laidOut = true;
@ -863,7 +863,7 @@ public class RoundControlTest {
testRound.startRound(); testRound.startRound();
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
testRoundState.players.get(i).hand = new Hand(gameSettings); testRoundState.players.get(i).hand = new Hand();
} }
testRoundState.players.get(0).laidOut = true; testRoundState.players.get(0).laidOut = true;
@ -932,7 +932,7 @@ public class RoundControlTest {
@Test @Test
public void testRedealDisallowed() { public void testRedealDisallowed() {
testRound.startRound(); testRound.startRound();
Hand hand = new Hand(gameSettings); Hand hand = new Hand();
hand.drop(new Stone(1, RED), new Position(0, 0)); hand.drop(new Stone(1, RED), new Position(0, 0));
hand.drop(new Stone(1, BLACK), new Position(0, 0)); hand.drop(new Stone(1, BLACK), new Position(0, 0));
hand.drop(new Stone(1, BLUE), new Position(0, 0)); hand.drop(new Stone(1, BLUE), new Position(0, 0));
@ -951,7 +951,7 @@ public class RoundControlTest {
@Test @Test
public void testRedealAllowed() { public void testRedealAllowed() {
testRound.startRound(); testRound.startRound();
Hand hand = new Hand(gameSettings); Hand hand = new Hand();
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
hand.drop(new Stone(i / 2, RED), new Position(0, 0)); hand.drop(new Stone(i / 2, RED), new Position(0, 0));
} }

View file

@ -24,7 +24,7 @@ public class HandTest {
/** */ /** */
@Before @Before
public void setUp() { public void setUp() {
hand = new Hand(new GameSettings()); hand = new Hand();
} }
/** */ /** */
@ -129,11 +129,11 @@ public class HandTest {
hand.drop(stone2, new Position(0, 0)); hand.drop(stone2, new Position(0, 0));
hand.drop(stone3, new Position(0, 0)); hand.drop(stone3, new Position(0, 0));
assertEquals(56, hand.getStonePoints()); assertEquals(56, hand.getStonePoints(new GameSettings()));
} }
private void dropStoneList(List<Stone> handStones) { private void dropStoneList(List<Stone> handStones) {
hand = new Hand(new GameSettings()); hand = new Hand();
for (Stone stone : handStones) { for (Stone stone : handStones) {
hand.drop(stone, new Position(0, 0)); hand.drop(stone, new Position(0, 0));
} }
@ -141,20 +141,19 @@ public class HandTest {
private void testInitialMeld(boolean possible, List<Stone> handStones) { private void testInitialMeld(boolean possible, List<Stone> handStones) {
dropStoneList(handStones); dropStoneList(handStones);
assertTrue(possible == hand.isInitialMeldPossible()); assertTrue(possible == hand.isInitialMeldPossible(new GameSettings()));
} }
/** */ /** */
@Test @Test
public void testInvalid() { public void testInvalid() {
testInitialMeld(false, Arrays.asList(new Stone(8, RED), new Stone(9, testInitialMeld(false, Arrays.asList(new Stone(8, RED), new Stone(9, RED),
RED), new Stone(10, RED), new Stone(12, RED), new Stone(10, RED), new Stone(12, RED), new Stone(13, RED)));
new Stone(13, RED)));
testInitialMeld(false, Arrays.asList(new Stone(10, RED), new Stone(10, testInitialMeld(false, Arrays.asList(new Stone(10, RED), new Stone(10,
BLACK), new Stone(11, RED), new Stone(11, BLACK))); BLACK), new Stone(11, RED), new Stone(11, BLACK)));
testInitialMeld(false, Arrays.asList(new Stone(10, RED), new Stone(10, testInitialMeld(false, Arrays.asList(new Stone(10, RED),
RED), new Stone(10, BLACK), new Stone(11, RED), new Stone(11, new Stone(10, RED), new Stone(10, BLACK), new Stone(11, RED),
BLACK))); new Stone(11, BLACK)));
testInitialMeld(false, Arrays.asList(new Stone(10, RED), new Stone(11, testInitialMeld(false, Arrays.asList(new Stone(10, RED), new Stone(11,
BLACK), new Stone(12, RED))); BLACK), new Stone(12, RED)));
@ -163,62 +162,62 @@ public class HandTest {
/** */ /** */
@Test @Test
public void testNotEnoughPoints() { public void testNotEnoughPoints() {
testInitialMeld(false, Arrays.asList(new Stone(8, RED), new Stone(9, testInitialMeld(false,
RED), new Stone(10, RED))); Arrays.asList(new Stone(8, RED), new Stone(9, RED), new Stone(10, RED)));
testInitialMeld(false, Arrays.asList(new Stone(1, RED), new Stone(2, testInitialMeld(false, Arrays.asList(new Stone(1, RED), new Stone(2, RED),
RED), new Stone(3, RED), new Stone(4, RED))); new Stone(3, RED), new Stone(4, RED)));
testInitialMeld(false, Arrays.asList(new Stone(1, RED), new Stone(2, testInitialMeld(false, Arrays.asList(new Stone(1, RED), new Stone(2, RED),
RED), new Stone(3, RED), new Stone(1, BLACK), new Stone(2, new Stone(3, RED), new Stone(1, BLACK), new Stone(2, BLACK), new Stone(
BLACK), new Stone(3, BLACK))); 3, BLACK)));
} }
/** */ /** */
@Test @Test
public void testNotEnoughPointsWithJoker() { public void testNotEnoughPointsWithJoker() {
testInitialMeld(false, Arrays.asList(new Stone(8, RED), new Stone(9, testInitialMeld(false, Arrays.asList(new Stone(8, RED), new Stone(9, RED),
RED), new Stone(RED), new Stone(3, BLACK))); new Stone(RED), new Stone(3, BLACK)));
testInitialMeld(false, Arrays.asList(new Stone(4, RED), new Stone(5, testInitialMeld(false, Arrays.asList(new Stone(4, RED), new Stone(5, RED),
RED), new Stone(4, BLACK), new Stone(5, BLACK), new Stone(RED))); new Stone(4, BLACK), new Stone(5, BLACK), new Stone(RED)));
} }
/** */ /** */
@Test @Test
public void testNotEnoughPointsWithTwoJokers() { public void testNotEnoughPointsWithTwoJokers() {
testInitialMeld(false, Arrays.asList(new Stone(1, RED), new Stone(2, testInitialMeld(false, Arrays.asList(new Stone(1, RED), new Stone(2, BLUE),
BLUE), new Stone(3, BLACK), new Stone(RED), new Stone(BLACK))); new Stone(3, BLACK), new Stone(RED), new Stone(BLACK)));
testInitialMeld(false, Arrays.asList(new Stone(8, RED), new Stone(RED), testInitialMeld(false,
new Stone(BLACK))); Arrays.asList(new Stone(8, RED), new Stone(RED), new Stone(BLACK)));
} }
/** */ /** */
@Test @Test
public void testValid() { public void testValid() {
testInitialMeld(true, Arrays.asList(new Stone(11, RED), new Stone(12, testInitialMeld(true, Arrays.asList(new Stone(11, RED), new Stone(12, RED),
RED), new Stone(13, RED))); new Stone(13, RED)));
testInitialMeld(true, Arrays.asList(new Stone(4, RED), testInitialMeld(true, Arrays.asList(new Stone(4, RED), new Stone(5, RED),
new Stone(5, RED), new Stone(6, RED), new Stone(5, ORANGE), new Stone(6, RED), new Stone(5, ORANGE), new Stone(5, BLACK),
new Stone(5, BLACK), new Stone(5, BLUE))); new Stone(5, BLUE)));
testInitialMeld(true, Arrays.asList(new Stone(10, RED), new Stone(10, testInitialMeld(true, Arrays.asList(new Stone(10, RED),
BLACK), new Stone(10, ORANGE))); new Stone(10, BLACK), new Stone(10, ORANGE)));
} }
/** */ /** */
@Test @Test
public void testValidWithJoker() { public void testValidWithJoker() {
testInitialMeld(true, Arrays.asList(new Stone(11, RED), new Stone(RED), testInitialMeld(true,
new Stone(13, RED))); Arrays.asList(new Stone(11, RED), new Stone(RED), new Stone(13, RED)));
testInitialMeld(true, Arrays.asList(new Stone(10, RED), testInitialMeld(true, Arrays.asList(new Stone(10, RED), new Stone(BLACK),
new Stone(BLACK), new Stone(10, ORANGE))); new Stone(10, ORANGE)));
testInitialMeld(true, Arrays.asList(new Stone(4, RED), testInitialMeld(true, Arrays.asList(new Stone(4, RED), new Stone(5, RED),
new Stone(5, RED), new Stone(6, RED), new Stone(5, BLACK), new Stone(6, RED), new Stone(5, BLACK), new Stone(5, BLUE), new Stone(
new Stone(5, BLUE), new Stone(RED))); RED)));
} }
/** */ /** */
@Test @Test
public void testValidWithTwoJokers() { public void testValidWithTwoJokers() {
testInitialMeld(true, Arrays.asList(new Stone(9, RED), new Stone(RED), testInitialMeld(true,
new Stone(BLACK))); Arrays.asList(new Stone(9, RED), new Stone(RED), new Stone(BLACK)));
} }
/** */ /** */
@ -235,27 +234,32 @@ public class HandTest {
/** */ /** */
@Test @Test
public void testInvalidHuge() { public void testInvalidHuge() {
testInitialMeld(false, Arrays.asList(new Stone(1, RED), new Stone(2, testInitialMeld(false, Arrays.asList(new Stone(1, RED), new Stone(2, RED),
RED), new Stone(4, RED), new Stone(6, RED), new Stone(8, RED), new Stone(4, RED), new Stone(6, RED), new Stone(8, RED), new Stone(10,
new Stone(10, RED), new Stone(13, RED), new Stone(1, BLACK), RED), new Stone(13, RED), new Stone(1, BLACK), new Stone(2, BLACK),
new Stone(2, BLACK), new Stone(4, BLACK), new Stone(5, BLACK), new Stone(4, BLACK), new Stone(5, BLACK), new Stone(8, BLACK),
new Stone(8, BLACK), new Stone(9, BLACK), new Stone(12, BLACK), new Stone(9, BLACK), new Stone(12, BLACK), new Stone(3, BLUE),
new Stone(3, BLUE), new Stone(5, BLUE), new Stone(7, BLUE), new Stone(5, BLUE), new Stone(7, BLUE), new Stone(11, BLUE), new Stone(
new Stone(11, BLUE), new Stone(RED))); RED)));
} }
/** */ /** */
@Test @Test
public void testCountIdenticalStones() { public void testCountIdenticalStones() {
dropStoneList(Arrays.asList(new Stone(1, RED), new Stone(2, RED), new Stone(1, BLUE))); dropStoneList(Arrays.asList(new Stone(1, RED), new Stone(2, RED),
new Stone(1, BLUE)));
assertEquals(0, hand.getIdenticalStoneCount()); assertEquals(0, hand.getIdenticalStoneCount());
dropStoneList(Arrays.asList(new Stone(1, RED), new Stone(1, RED), new Stone(1, BLUE))); dropStoneList(Arrays.asList(new Stone(1, RED), new Stone(1, RED),
new Stone(1, BLUE)));
assertEquals(1, hand.getIdenticalStoneCount()); assertEquals(1, hand.getIdenticalStoneCount());
dropStoneList(Arrays.asList(new Stone(1, RED), new Stone(1, RED), new Stone(1, BLUE), new Stone(1, BLUE))); dropStoneList(Arrays.asList(new Stone(1, RED), new Stone(1, RED),
new Stone(1, BLUE), new Stone(1, BLUE)));
assertEquals(2, hand.getIdenticalStoneCount()); assertEquals(2, hand.getIdenticalStoneCount());
dropStoneList(Arrays.asList(new Stone(1, RED), new Stone(1, RED), new Stone(1, RED))); dropStoneList(Arrays.asList(new Stone(1, RED), new Stone(1, RED),
new Stone(1, RED)));
assertEquals(1, hand.getIdenticalStoneCount()); assertEquals(1, hand.getIdenticalStoneCount());
dropStoneList(Arrays.asList(new Stone(1, RED), new Stone(1, RED), new Stone(1, RED), new Stone(1, RED))); dropStoneList(Arrays.asList(new Stone(1, RED), new Stone(1, RED),
new Stone(1, RED), new Stone(1, RED)));
assertEquals(2, hand.getIdenticalStoneCount()); assertEquals(2, hand.getIdenticalStoneCount());
dropStoneList(Arrays.asList(new Stone(RED), new Stone(RED))); dropStoneList(Arrays.asList(new Stone(RED), new Stone(RED)));
assertEquals(0, hand.getIdenticalStoneCount()); assertEquals(0, hand.getIdenticalStoneCount());