summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/jrummikub/control/RoundControl.java5
-rw-r--r--src/jrummikub/control/turn/AbstractTurnControl.java12
-rw-r--r--src/jrummikub/control/turn/BaseAIControl.java75
-rw-r--r--src/jrummikub/control/turn/ITurnControl.java19
-rw-r--r--test/jrummikub/control/turn/TurnControlTest.java81
5 files changed, 128 insertions, 64 deletions
diff --git a/src/jrummikub/control/RoundControl.java b/src/jrummikub/control/RoundControl.java
index 6a1befa..67c177f 100644
--- a/src/jrummikub/control/RoundControl.java
+++ b/src/jrummikub/control/RoundControl.java
@@ -114,8 +114,9 @@ public class RoundControl {
turnControl = TurnControlFactory.getFactory(
roundState.getActivePlayer().getPlayerSettings().getTurnControlType())
.create();
- turnControl.setup(roundState.getActivePlayer(), clonedTable, view,
- inspectOnly, mayRedeal);
+ turnControl
+ .setup(roundState.getGameSettings(), roundState.getActivePlayer(),
+ clonedTable, view, inspectOnly, mayRedeal);
turnControl.getEndOfTurnEvent().add(new IListener() {
@Override
public void handle() {
diff --git a/src/jrummikub/control/turn/AbstractTurnControl.java b/src/jrummikub/control/turn/AbstractTurnControl.java
index e493718..3c89708 100644
--- a/src/jrummikub/control/turn/AbstractTurnControl.java
+++ b/src/jrummikub/control/turn/AbstractTurnControl.java
@@ -1,5 +1,6 @@
package jrummikub.control.turn;
+import jrummikub.model.GameSettings;
import jrummikub.model.IHand;
import jrummikub.model.IPlayer;
import jrummikub.model.ITable;
@@ -8,19 +9,19 @@ import jrummikub.util.IEvent;
import jrummikub.view.IView;
/**
- * Abstract base class for TurnControls
+ * Abstract base class for TurnControls
*/
public abstract class AbstractTurnControl implements ITurnControl {
protected Event endOfTurnEvent = new Event();
protected Event redealEvent = new Event();
+ protected GameSettings settings;
protected IPlayer player;
protected IHand hand;
protected ITable table;
protected IView view;
protected boolean inspectOnly;
protected boolean mayRedeal;
-
@Override
public IEvent getEndOfTurnEvent() {
@@ -31,10 +32,11 @@ public abstract class AbstractTurnControl implements ITurnControl {
public Event getRedealEvent() {
return redealEvent;
}
-
+
@Override
- public void setup(IPlayer player, ITable table, IView view,
- boolean inspectOnly, boolean mayRedeal) {
+ public void setup(GameSettings settings, IPlayer player, ITable table,
+ IView view, boolean inspectOnly, boolean mayRedeal) {
+ this.settings = settings;
this.player = player;
this.hand = player.getHand();
this.table = table;
diff --git a/src/jrummikub/control/turn/BaseAIControl.java b/src/jrummikub/control/turn/BaseAIControl.java
index fc1b97d..fbd9c75 100644
--- a/src/jrummikub/control/turn/BaseAIControl.java
+++ b/src/jrummikub/control/turn/BaseAIControl.java
@@ -2,13 +2,20 @@ package jrummikub.control.turn;
import java.util.ArrayList;
import java.util.List;
+import java.util.TreeMap;
import javax.swing.SwingUtilities;
+import jrummikub.control.AIUtil;
import jrummikub.control.ITurnTimer;
import jrummikub.control.TurnTimer;
+import jrummikub.model.Position;
+import jrummikub.model.Stone;
+import jrummikub.model.StoneColor;
+import jrummikub.model.StoneSet;
import jrummikub.util.Connection;
import jrummikub.util.IListener;
+import jrummikub.util.Pair;
/**
* Base class for AI players
@@ -59,15 +66,61 @@ public class BaseAIControl extends AbstractTurnControl {
if (mayRedeal) {
emitRedeal();
} else {
- if (player.getLaidOut()) {
- layOut();
- } else {
- emitEndOfTurn();
+ turn();
+ }
+ }
+
+ private Stone findMatchingStone(Stone target) {
+ for(Pair<Stone, Position> entry : hand){
+ Stone stone = entry.getFirst();
+ if (stone.getValue() == target.getValue() && stone.getColor() == target.getColor()) {
+ return stone;
+ }
+ }
+ for(Pair<Stone, Position> entry : hand){
+ Stone stone = entry.getFirst();
+ if (stone.isJoker()) {
+ return stone;
}
}
+ return null;
}
- private void layOut() {
+ private Stone pickUpMatchingStone(Stone target) {
+ Stone match = findMatchingStone(target);
+ hand.pickUp(match);
+ return match;
+ }
+
+ private void turn() {
+ List<Stone> stones = new ArrayList<Stone>();
+
+ for (Pair<Stone, Position> entry : hand) {
+ stones.add(entry.getFirst());
+ }
+
+ Pair<TreeMap<Pair<Integer, StoneColor>, Integer>, Integer> counts = AIUtil
+ .countStones(stones);
+
+ AIUtil aiUtil = new AIUtil(settings);
+
+ Pair<List<StoneSet>, Integer> result = aiUtil.findSetsWithTotalPoints(
+ Integer.MAX_VALUE, counts.getFirst(), counts.getSecond());
+
+ if (!player.getLaidOut()
+ && result.getSecond() < settings.getInitialMeldThreshold()) {
+ emitEndOfTurn();
+ return;
+ }
+
+ for (StoneSet set : result.getFirst()) {
+ List<Stone> handStones = new ArrayList<Stone>();
+ for (Stone stone : set) {
+ handStones.add(pickUpMatchingStone(stone));
+ }
+ table.drop(new StoneSet(handStones), new Position(0, 0));
+ }
+
emitEndOfTurn();
}
@@ -75,8 +128,10 @@ public class BaseAIControl extends AbstractTurnControl {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
- cleanUp();
- redealEvent.emit();
+ if (!stopRunning) {
+ cleanUp();
+ redealEvent.emit();
+ }
}
});
}
@@ -98,8 +153,10 @@ public class BaseAIControl extends AbstractTurnControl {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
- cleanUp();
- endOfTurnEvent.emit();
+ if (!stopRunning) {
+ cleanUp();
+ endOfTurnEvent.emit();
+ }
}
});
}
diff --git a/src/jrummikub/control/turn/ITurnControl.java b/src/jrummikub/control/turn/ITurnControl.java
index 5d0cd49..decd718 100644
--- a/src/jrummikub/control/turn/ITurnControl.java
+++ b/src/jrummikub/control/turn/ITurnControl.java
@@ -1,5 +1,6 @@
package jrummikub.control.turn;
+import jrummikub.model.GameSettings;
import jrummikub.model.IPlayer;
import jrummikub.model.ITable;
import jrummikub.util.Event;
@@ -10,19 +11,21 @@ public interface ITurnControl {
/**
* Start the turn
*
- * @param hand
- * active player's hand
+ * @param settings
+ * the game settings
+ * @param player
+ * the active player
* @param table
- * current table
+ * current table
* @param view
- * view for user interaction.
+ * view for user interaction.
* @param inspectOnly
- * the current turn doesn't allow any table manipulation
+ * the current turn doesn't allow any table manipulation
* @param mayRedeal
- * true when the current player may decide to redeal
+ * true when the current player may decide to redeal
*/
- public void setup(IPlayer player, ITable table, IView view,
- boolean inspectOnly, boolean mayRedeal);
+ public void setup(GameSettings settings, IPlayer player, ITable table,
+ IView view, boolean inspectOnly, boolean mayRedeal);
/**
* Get the event that is emitted when the turn is over
diff --git a/test/jrummikub/control/turn/TurnControlTest.java b/test/jrummikub/control/turn/TurnControlTest.java
index db382ca..89d22bf 100644
--- a/test/jrummikub/control/turn/TurnControlTest.java
+++ b/test/jrummikub/control/turn/TurnControlTest.java
@@ -45,9 +45,9 @@ public class TurnControlTest {
StoneSet[] getSetArray() {
return objects.keySet().toArray(new StoneSet[0]);
}
-
- AccessibleTable (){
- super (new GameSettings());
+
+ AccessibleTable() {
+ super(new GameSettings());
}
}
@@ -114,7 +114,8 @@ public class TurnControlTest {
mockPlayer = new MockPlayer(null, null);
mockPlayer.hand = mockHand;
testControl = new HumanTurnControl(mockTimer);
- testControl.setup(mockPlayer, mockTable, mockView, false, false);
+ testControl.setup(new GameSettings(), mockPlayer, mockTable, mockView,
+ false, false);
}
/** */
@@ -131,15 +132,15 @@ public class TurnControlTest {
public void showInitialHand() {
mockView.displayStartTurnPanel = true;
- List<Pair<Stone, Position>> stones = Arrays
- .asList(new Pair<Stone, Position>(new Stone(RED), new Position(
- 0, 0)), new Pair<Stone, Position>(new Stone(BLACK),
- new Position(1, 0)));
+ List<Pair<Stone, Position>> stones = Arrays.asList(
+ new Pair<Stone, Position>(new Stone(RED), new Position(0, 0)),
+ new Pair<Stone, Position>(new Stone(BLACK), new Position(1, 0)));
mockHand.iterable = stones;
testControl = new HumanTurnControl(mockTimer);
- testControl.setup(mockPlayer, mockTable, mockView, false, false);
+ testControl.setup(new GameSettings(), mockPlayer, mockTable, mockView,
+ false, false);
testControl.startTurn();
int i = 0;
@@ -266,8 +267,8 @@ public class TurnControlTest {
mockView.handPanel.stoneClickEvent.emit(firstStone, true);
mockView.handPanel.stoneClickEvent.emit(secondStone, true);
- mockView.tablePanel.stoneCollectionPanel.stoneClickEvent.emit(
- firstStone, false);
+ mockView.tablePanel.stoneCollectionPanel.stoneClickEvent.emit(firstStone,
+ false);
assertCollection(Arrays.asList(secondStone));
}
@@ -283,8 +284,8 @@ public class TurnControlTest {
mockView.handPanel.stoneClickEvent.emit(firstStone, true);
mockView.handPanel.stoneClickEvent.emit(secondStone, true);
- mockView.tablePanel.stoneCollectionPanel.stoneClickEvent.emit(
- firstStone, true);
+ mockView.tablePanel.stoneCollectionPanel.stoneClickEvent.emit(firstStone,
+ true);
assertCollection(Arrays.asList(secondStone, firstStone));
}
@@ -300,8 +301,8 @@ public class TurnControlTest {
mockView.handPanel.stoneClickEvent.emit(firstStone, true);
mockView.handPanel.stoneClickEvent.emit(secondStone, true);
- mockView.tablePanel.stoneCollectionPanel.stoneClickEvent.emit(
- firstStone, true);
+ mockView.tablePanel.stoneCollectionPanel.stoneClickEvent.emit(firstStone,
+ true);
mockView.tablePanel.stoneCollectionPanel.setClickEvent.emit(firstStone,
true);
@@ -408,8 +409,7 @@ public class TurnControlTest {
Stone stone2 = new Stone(2, StoneColor.RED);
Stone stone3 = new Stone(3, StoneColor.RED);
Stone stone4 = new Stone(4, StoneColor.RED);
- StoneSet set1 = new StoneSet(Arrays.asList(stone1, stone2, stone3,
- stone4));
+ StoneSet set1 = new StoneSet(Arrays.asList(stone1, stone2, stone3, stone4));
mockTable.findStoneSet.put(stone1, set1);
mockTable.findStoneSet.put(stone3, set1);
@@ -430,8 +430,7 @@ public class TurnControlTest {
Stone stone2 = new Stone(2, StoneColor.RED);
Stone stone3 = new Stone(3, StoneColor.RED);
Stone stone4 = new Stone(4, StoneColor.RED);
- StoneSet set1 = new StoneSet(Arrays.asList(stone1, stone2, stone3,
- stone4));
+ StoneSet set1 = new StoneSet(Arrays.asList(stone1, stone2, stone3, stone4));
mockTable.findStoneSet.put(stone1, set1);
mockTable.findStoneSet.put(stone3, set1);
@@ -454,8 +453,7 @@ public class TurnControlTest {
Stone stone2 = new Stone(2, StoneColor.RED);
Stone stone3 = new Stone(3, StoneColor.RED);
Stone stone4 = new Stone(4, StoneColor.RED);
- StoneSet set1 = new StoneSet(Arrays.asList(stone1, stone2, stone3,
- stone4));
+ StoneSet set1 = new StoneSet(Arrays.asList(stone1, stone2, stone3, stone4));
mockTable.findStoneSet.put(stone1, set1);
mockTable.findStoneSet.put(stone3, set1);
@@ -635,7 +633,8 @@ public class TurnControlTest {
public void testAddLeft() {
AccessibleTable table = new AccessibleTable();
HumanTurnControl turnControl = new HumanTurnControl(mockTimer);
- turnControl.setup(mockPlayer, table, mockView, false, false);
+ turnControl.setup(new GameSettings(), mockPlayer, table, mockView, false,
+ false);
turnControl.startTurn();
Stone blueOne = new Stone(1, BLUE);
Stone redOne = new Stone(1, RED);
@@ -650,10 +649,10 @@ public class TurnControlTest {
Stone blackThree = new Stone(3, BLACK);
Stone blackFour = new Stone(4, BLACK);
Stone blackFive = new Stone(5, BLACK);
- StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne,
- blackOne, redTwo, redThree, redFour, blackTwo, blackThree));
- StoneSet oldSet2 = new StoneSet(Arrays.asList(blueTwo, blackFour,
- blackFive));
+ StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne, blackOne,
+ redTwo, redThree, redFour, blackTwo, blackThree));
+ StoneSet oldSet2 = new StoneSet(
+ Arrays.asList(blueTwo, blackFour, blackFive));
table.drop(oldSet1, new Position(0, 0));
table.drop(oldSet2, new Position(0, 0));
mockHand.drop(blueThree, new Position(0, 0));
@@ -752,7 +751,8 @@ public class TurnControlTest {
public void testAddRight() {
AccessibleTable table = new AccessibleTable();
HumanTurnControl turnControl = new HumanTurnControl(mockTimer);
- turnControl.setup(mockPlayer, table, mockView, false, false);
+ turnControl.setup(new GameSettings(), mockPlayer, table, mockView, false,
+ false);
turnControl.startTurn();
Stone blueOne = new Stone(1, BLUE);
Stone redOne = new Stone(1, RED);
@@ -767,10 +767,10 @@ public class TurnControlTest {
Stone blackThree = new Stone(3, BLACK);
Stone blackFour = new Stone(4, BLACK);
Stone blackFive = new Stone(5, BLACK);
- StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne,
- blackOne, redTwo, redThree, redFour, blackTwo, blackThree));
- StoneSet oldSet2 = new StoneSet(Arrays.asList(blueTwo, blackFour,
- blackFive));
+ StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne, blackOne,
+ redTwo, redThree, redFour, blackTwo, blackThree));
+ StoneSet oldSet2 = new StoneSet(
+ Arrays.asList(blueTwo, blackFour, blackFive));
table.drop(oldSet1, new Position(0, 0));
table.drop(oldSet2, new Position(0, 0));
mockHand.drop(blueThree, new Position(0, 0));
@@ -869,7 +869,8 @@ public class TurnControlTest {
public void testAddNewSet() {
AccessibleTable table = new AccessibleTable();
HumanTurnControl turnControl = new HumanTurnControl(mockTimer);
- turnControl.setup(mockPlayer, table, mockView, false, false);
+ turnControl.setup(new GameSettings(), mockPlayer, table, mockView, false,
+ false);
turnControl.startTurn();
Stone blueOne = new Stone(1, BLUE);
Stone redOne = new Stone(1, RED);
@@ -884,10 +885,10 @@ public class TurnControlTest {
Stone blackThree = new Stone(3, BLACK);
Stone blackFour = new Stone(4, BLACK);
Stone blackFive = new Stone(5, BLACK);
- StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne,
- blackOne, redTwo, redThree, redFour, blackTwo, blackThree));
- StoneSet oldSet2 = new StoneSet(Arrays.asList(blueTwo, blackFour,
- blackFive));
+ StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne, blackOne,
+ redTwo, redThree, redFour, blackTwo, blackThree));
+ StoneSet oldSet2 = new StoneSet(
+ Arrays.asList(blueTwo, blackFour, blackFive));
table.drop(oldSet1, new Position(0, 0));
table.drop(oldSet2, new Position(0, 0));
mockHand.drop(blueThree, new Position(0, 0));
@@ -991,8 +992,8 @@ public class TurnControlTest {
List<Pair<Stone, Position>> stones = new ArrayList<Pair<Stone, Position>>(
mockHand.stones);
- Collections.sort(stones,
- new HumanTurnControl.HandStonePositionComparator());
+ Collections
+ .sort(stones, new HumanTurnControl.HandStonePositionComparator());
assertEquals(stones.size(), 13);
@@ -1053,8 +1054,8 @@ public class TurnControlTest {
List<Pair<Stone, Position>> stones = new ArrayList<Pair<Stone, Position>>(
mockHand.stones);
- Collections.sort(stones,
- new HumanTurnControl.HandStonePositionComparator());
+ Collections
+ .sort(stones, new HumanTurnControl.HandStonePositionComparator());
assertEquals(stones.size(), 13);