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
public int getStonePoints() {
public int getStonePoints(GameSettings settings) {
// TODO Auto-generated method stub
return 0;
}
public boolean isInitialMeldPossible() {
public boolean isInitialMeldPossible(GameSettings settings) {
return false;
}

View file

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

View file

@ -7,18 +7,33 @@ import java.util.Comparator;
import java.util.List;
import java.util.TreeMap;
import jrummikub.model.GameSettings;
import jrummikub.model.Stone;
import jrummikub.model.StoneColor;
import jrummikub.model.StoneSet;
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 {
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 {
@ -47,7 +62,7 @@ public class AIUtil {
* @return the sets that have the desired point total or the highest found
*/
@SuppressWarnings("unchecked")
public static Pair<List<StoneSet>, Integer> findSetsWithTotalPoints(
public Pair<List<StoneSet>, Integer> findSetsWithTotalPoints(
int pointsMissing,
TreeMap<Pair<Integer, StoneColor>, Integer> stoneCounts, int jokerCount) {
@ -63,14 +78,13 @@ public class AIUtil {
bestResult = new Pair<List<StoneSet>, Integer>(
Collections.<StoneSet> emptyList(), 0);
for (int value = 13; value >= 1; value--) {
for (StoneColor color : StoneColor.values()) {
for (int value = settings.getHighestValue(); value >= 1; value--) {
for (StoneColor color : stoneColors) {
Pair<Integer, StoneColor> stone = new Pair<Integer, StoneColor>(value,
color);
if (stoneCounts.containsKey(stone)) {
decrementStoneCount(stoneCounts, stone);
result = findRunsWithTotalPoints(new SearchState(pointsMissing
- value, stoneCounts, jokerCount), stone, 1);
if (result.getSecond() >= pointsMissing)
@ -109,7 +123,7 @@ public class AIUtil {
return bestResult;
}
private static Pair<List<StoneSet>, Integer> findGroupsWithTotalPoints(
private Pair<List<StoneSet>, Integer> findGroupsWithTotalPoints(
SearchState searchState, int value, List<StoneColor> chosenColors,
StoneColor testedColor) {
@ -175,7 +189,7 @@ public class AIUtil {
return bestResult;
}
private static Pair<List<StoneSet>, Integer> findRunsWithTotalPoints(
private Pair<List<StoneSet>, Integer> findRunsWithTotalPoints(
SearchState searchState, Pair<Integer, StoneColor> testedStone,
int runLength) {
@ -262,12 +276,12 @@ public class AIUtil {
}
}
static StoneColor getNextColor(StoneColor color) {
int index = Arrays.binarySearch(StoneColor.values(), color) + 1;
if (index >= StoneColor.values().length) {
StoneColor getNextColor(StoneColor color) {
int index = stoneColors.indexOf(color) + 1;
if (index >= stoneColors.size()) {
return null;
}
return StoneColor.values()[index];
return stoneColors.get(index);
}
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
*
* @param roundState
* initial round state
* initial round state
* @param view
* view used for user interaction
* view used for user interaction
*/
public RoundControl(IRoundState roundState, IView view) {
this.roundState = roundState;
@ -89,10 +89,10 @@ public class RoundControl {
}
view.getTablePanel().setStoneSets(clonedTable);
view.setCurrentPlayerName(roundState.getActivePlayer()
.getPlayerSettings().getName());
view.setCurrentPlayerColor(roundState.getActivePlayer()
.getPlayerSettings().getColor());
view.setCurrentPlayerName(roundState.getActivePlayer().getPlayerSettings()
.getName());
view.setCurrentPlayerColor(roundState.getActivePlayer().getPlayerSettings()
.getColor());
view.setHasLaidOut(roundState.getActivePlayer().getLaidOut());
if (!isHuman)
@ -106,15 +106,14 @@ public class RoundControl {
.getTurnControlType() == HUMAN;
boolean inspectOnly = roundState.getTurnNumber() < 1;
boolean mayRedeal = inspectOnly
&& roundState.getActivePlayer().getHand()
.getIdenticalStoneCount() >= 3;
&& roundState.getActivePlayer().getHand().getIdenticalStoneCount() >= 3;
if (isHuman) {
view.getPlayerPanel().setEndTurnMode(inspectOnly, mayRedeal);
}
turnControl = TurnControlFactory.getFactory(
roundState.getActivePlayer().getPlayerSettings()
.getTurnControlType()).create();
roundState.getActivePlayer().getPlayerSettings().getTurnControlType())
.create();
turnControl.setup(roundState.getActivePlayer(), clonedTable, view,
inspectOnly, mayRedeal);
turnControl.getEndOfTurnEvent().add(new IListener() {
@ -136,10 +135,8 @@ public class RoundControl {
void deal() {
for (int i = 0; i < roundState.getPlayerCount(); i++) {
IHand hand = roundState.getNthNextPlayer(i).getHand();
for (int j = 0; j < roundState.getGameSettings()
.getNumberOfStonesDealt(); j++) {
hand.drop(roundState.getGameHeap().drawStone(), new Position(0,
0));
for (int j = 0; j < roundState.getGameSettings().getNumberOfStonesDealt(); j++) {
hand.drop(roundState.getGameHeap().drawStone(), new Position(0, 0));
}
}
}
@ -150,13 +147,11 @@ public class RoundControl {
int totalValue = 0;
for (StoneSet set : newSets) {
totalValue += set.classify(roundState.getGameSettings())
.getSecond();
totalValue += set.classify(roundState.getGameSettings()).getSecond();
}
return totalValue == 0
|| totalValue >= roundState.getGameSettings()
.getInitialMeldThreshold();
|| totalValue >= roundState.getGameSettings().getInitialMeldThreshold();
}
private void endOfTurn() {
@ -195,8 +190,7 @@ public class RoundControl {
}
if (!roundState.getActivePlayer().getLaidOut()) {
// Player touched forbidden stones
if (!tableSetDifference(clonedTable, roundState.getTable())
.isEmpty()) {
if (!tableSetDifference(clonedTable, roundState.getTable()).isEmpty()) {
rejectMove();
return;
}
@ -205,8 +199,7 @@ public class RoundControl {
return;
}
}
Set<Stone> tableDiff = tableDifference(roundState.getTable(),
clonedTable);
Set<Stone> tableDiff = tableDifference(roundState.getTable(), clonedTable);
roundState.setTable(clonedTable);
@ -222,8 +215,7 @@ public class RoundControl {
}
private void rejectMove() {
Set<Stone> tableDiff = tableDifference(roundState.getTable(),
clonedTable);
Set<Stone> tableDiff = tableDifference(roundState.getTable(), clonedTable);
// deal penalty, reset
roundState.getGameHeap().putBack(tableDiff);
dealPenalty(tableDiff.size());
@ -310,13 +302,13 @@ public class RoundControl {
int stonePoints = 0;
if (!player.getLaidOut()) {
stonePoints = playerHand.isInitialMeldPossible() ? 200 : 100;
stonePoints = playerHand.isInitialMeldPossible(roundState
.getGameSettings()) ? 200 : 100;
} else {
stonePoints = playerHand.getStonePoints();
stonePoints = playerHand.getStonePoints(roundState.getGameSettings());
}
bestScore = updateBestScore(bestScore, -stonePoints,
playerHand.getSize());
bestScore = updateBestScore(bestScore, -stonePoints, playerHand.getSize());
points.add(-stonePoints);
pointSum += stonePoints;

View file

@ -18,18 +18,6 @@ public class Hand extends StoneTray<Stone> implements IHand {
*/
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
public int getFreeRowSpace(int row) {
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;
for (Pair<Stone, Position> entry : this) {
@ -89,7 +78,9 @@ public class Hand extends StoneTray<Stone> implements IHand {
}
@Override
public boolean isInitialMeldPossible() {
public boolean isInitialMeldPossible(GameSettings settings) {
AIUtil aiUtil = new AIUtil(settings);
List<Stone> stones = new ArrayList<Stone>();
for (Iterator<Pair<Stone, Position>> iter = this.iterator(); iter.hasNext();) {
@ -99,11 +90,9 @@ public class Hand extends StoneTray<Stone> implements IHand {
Pair<TreeMap<Pair<Integer, StoneColor>, Integer>, Integer> stoneCounts = AIUtil
.countStones(stones);
Pair<List<StoneSet>, Integer> result = AIUtil.findSetsWithTotalPoints(
Pair<List<StoneSet>, Integer> result = aiUtil.findSetsWithTotalPoints(
settings.getInitialMeldThreshold(), stoneCounts.getFirst(),
stoneCounts.getSecond());
System.out.println(result);
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
*
* @param row
* the row number
* the row number
* @return the number of stones that can fit into the 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
*
* @param settings
* the game settings
*
* @return points
*/
int getStonePoints();
int getStonePoints(GameSettings settings);
/**
* Tests whether it is possible to lay down an initial meld using the stones
* on the hand
*
* @param settings
* the game settings
*
* @return true if an initial meld is possible
*/
public boolean isInitialMeldPossible();
public boolean isInitialMeldPossible(GameSettings settings);
/**
* 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
*
* @param settings
* the player settings
* @param gameSettings
* the game settings
* the player settings
*/
public Player(PlayerSettings settings, GameSettings gameSettings) {
public Player(PlayerSettings settings) {
this.settings = settings;
hand = new Hand(gameSettings);
hand = new Hand();
laidOut = false;
}

View file

@ -12,13 +12,13 @@ public class RoundState implements IRoundState {
private int activePlayer;
private StoneHeap gameHeap;
private IPlayer lastPlayer;
private int turnNumber;
private int turnNumber;
/**
* Create a new RoundState with an empty table
*
* @param gameSettings
* the game settings
* the game settings
*/
public RoundState(GameSettings gameSettings) {
this.gameSettings = gameSettings;
@ -27,11 +27,11 @@ public class RoundState implements IRoundState {
players = new ArrayList<Player>();
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;
gameHeap = new StoneHeap(gameSettings);
}
@ -73,7 +73,7 @@ public class RoundState implements IRoundState {
}
return players.get(j);
}
@Override
public IPlayer getNthPlayer(int i) {
int j = i % players.size();
@ -107,7 +107,7 @@ public class RoundState implements IRoundState {
public IPlayer getLastPlayer() {
return lastPlayer;
}
@Override
public int getTurnNumber() {
return turnNumber;

View file

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

View file

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