diff options
-rw-r--r-- | src/jrummikub/control/RoundControl.java | 5 | ||||
-rw-r--r-- | src/jrummikub/control/turn/AbstractTurnControl.java | 12 | ||||
-rw-r--r-- | src/jrummikub/control/turn/BaseAIControl.java | 75 | ||||
-rw-r--r-- | src/jrummikub/control/turn/ITurnControl.java | 19 | ||||
-rw-r--r-- | test/jrummikub/control/turn/TurnControlTest.java | 81 |
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); |