Base AI is now able to meld initially properly

git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@346 72836036-5685-4462-b002-a69064685172
This commit is contained in:
Bennet Gerlach 2011-05-31 04:56:09 +02:00
parent 58d58c0c07
commit 061e7ab305
5 changed files with 129 additions and 65 deletions

View file

@ -114,8 +114,9 @@ public class RoundControl {
turnControl = TurnControlFactory.getFactory( turnControl = TurnControlFactory.getFactory(
roundState.getActivePlayer().getPlayerSettings().getTurnControlType()) roundState.getActivePlayer().getPlayerSettings().getTurnControlType())
.create(); .create();
turnControl.setup(roundState.getActivePlayer(), clonedTable, view, turnControl
inspectOnly, mayRedeal); .setup(roundState.getGameSettings(), roundState.getActivePlayer(),
clonedTable, view, inspectOnly, mayRedeal);
turnControl.getEndOfTurnEvent().add(new IListener() { turnControl.getEndOfTurnEvent().add(new IListener() {
@Override @Override
public void handle() { public void handle() {

View file

@ -1,5 +1,6 @@
package jrummikub.control.turn; package jrummikub.control.turn;
import jrummikub.model.GameSettings;
import jrummikub.model.IHand; import jrummikub.model.IHand;
import jrummikub.model.IPlayer; import jrummikub.model.IPlayer;
import jrummikub.model.ITable; import jrummikub.model.ITable;
@ -14,6 +15,7 @@ public abstract class AbstractTurnControl implements ITurnControl {
protected Event endOfTurnEvent = new Event(); protected Event endOfTurnEvent = new Event();
protected Event redealEvent = new Event(); protected Event redealEvent = new Event();
protected GameSettings settings;
protected IPlayer player; protected IPlayer player;
protected IHand hand; protected IHand hand;
protected ITable table; protected ITable table;
@ -21,7 +23,6 @@ public abstract class AbstractTurnControl implements ITurnControl {
protected boolean inspectOnly; protected boolean inspectOnly;
protected boolean mayRedeal; protected boolean mayRedeal;
@Override @Override
public IEvent getEndOfTurnEvent() { public IEvent getEndOfTurnEvent() {
return endOfTurnEvent; return endOfTurnEvent;
@ -33,8 +34,9 @@ public abstract class AbstractTurnControl implements ITurnControl {
} }
@Override @Override
public void setup(IPlayer player, ITable table, IView view, public void setup(GameSettings settings, IPlayer player, ITable table,
boolean inspectOnly, boolean mayRedeal) { IView view, boolean inspectOnly, boolean mayRedeal) {
this.settings = settings;
this.player = player; this.player = player;
this.hand = player.getHand(); this.hand = player.getHand();
this.table = table; this.table = table;

View file

@ -2,13 +2,20 @@ package jrummikub.control.turn;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.TreeMap;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import jrummikub.control.AIUtil;
import jrummikub.control.ITurnTimer; import jrummikub.control.ITurnTimer;
import jrummikub.control.TurnTimer; 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.Connection;
import jrummikub.util.IListener; import jrummikub.util.IListener;
import jrummikub.util.Pair;
/** /**
* Base class for AI players * Base class for AI players
@ -59,15 +66,61 @@ public class BaseAIControl extends AbstractTurnControl {
if (mayRedeal) { if (mayRedeal) {
emitRedeal(); emitRedeal();
} else { } else {
if (player.getLaidOut()) { turn();
layOut();
} else {
emitEndOfTurn();
}
} }
} }
private void layOut() { 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 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(); emitEndOfTurn();
} }
@ -75,8 +128,10 @@ public class BaseAIControl extends AbstractTurnControl {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
cleanUp(); if (!stopRunning) {
redealEvent.emit(); cleanUp();
redealEvent.emit();
}
} }
}); });
} }
@ -98,8 +153,10 @@ public class BaseAIControl extends AbstractTurnControl {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
cleanUp(); if (!stopRunning) {
endOfTurnEvent.emit(); cleanUp();
endOfTurnEvent.emit();
}
} }
}); });
} }

View file

@ -1,5 +1,6 @@
package jrummikub.control.turn; package jrummikub.control.turn;
import jrummikub.model.GameSettings;
import jrummikub.model.IPlayer; import jrummikub.model.IPlayer;
import jrummikub.model.ITable; import jrummikub.model.ITable;
import jrummikub.util.Event; import jrummikub.util.Event;
@ -10,19 +11,21 @@ public interface ITurnControl {
/** /**
* Start the turn * Start the turn
* *
* @param hand * @param settings
* active player's hand * the game settings
* @param player
* the active player
* @param table * @param table
* current table * current table
* @param view * @param view
* view for user interaction. * view for user interaction.
* @param inspectOnly * @param inspectOnly
* the current turn doesn't allow any table manipulation * the current turn doesn't allow any table manipulation
* @param mayRedeal * @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, public void setup(GameSettings settings, IPlayer player, ITable table,
boolean inspectOnly, boolean mayRedeal); IView view, boolean inspectOnly, boolean mayRedeal);
/** /**
* Get the event that is emitted when the turn is over * Get the event that is emitted when the turn is over

View file

@ -46,8 +46,8 @@ public class TurnControlTest {
return objects.keySet().toArray(new StoneSet[0]); return objects.keySet().toArray(new StoneSet[0]);
} }
AccessibleTable (){ AccessibleTable() {
super (new GameSettings()); super(new GameSettings());
} }
} }
@ -114,7 +114,8 @@ public class TurnControlTest {
mockPlayer = new MockPlayer(null, null); mockPlayer = new MockPlayer(null, null);
mockPlayer.hand = mockHand; mockPlayer.hand = mockHand;
testControl = new HumanTurnControl(mockTimer); 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() { public void showInitialHand() {
mockView.displayStartTurnPanel = true; mockView.displayStartTurnPanel = true;
List<Pair<Stone, Position>> stones = Arrays List<Pair<Stone, Position>> stones = Arrays.asList(
.asList(new Pair<Stone, Position>(new Stone(RED), new Position( new Pair<Stone, Position>(new Stone(RED), new Position(0, 0)),
0, 0)), new Pair<Stone, Position>(new Stone(BLACK), new Pair<Stone, Position>(new Stone(BLACK), new Position(1, 0)));
new Position(1, 0)));
mockHand.iterable = stones; mockHand.iterable = stones;
testControl = new HumanTurnControl(mockTimer); testControl = new HumanTurnControl(mockTimer);
testControl.setup(mockPlayer, mockTable, mockView, false, false); testControl.setup(new GameSettings(), mockPlayer, mockTable, mockView,
false, false);
testControl.startTurn(); testControl.startTurn();
int i = 0; int i = 0;
@ -266,8 +267,8 @@ public class TurnControlTest {
mockView.handPanel.stoneClickEvent.emit(firstStone, true); mockView.handPanel.stoneClickEvent.emit(firstStone, true);
mockView.handPanel.stoneClickEvent.emit(secondStone, true); mockView.handPanel.stoneClickEvent.emit(secondStone, true);
mockView.tablePanel.stoneCollectionPanel.stoneClickEvent.emit( mockView.tablePanel.stoneCollectionPanel.stoneClickEvent.emit(firstStone,
firstStone, false); false);
assertCollection(Arrays.asList(secondStone)); assertCollection(Arrays.asList(secondStone));
} }
@ -283,8 +284,8 @@ public class TurnControlTest {
mockView.handPanel.stoneClickEvent.emit(firstStone, true); mockView.handPanel.stoneClickEvent.emit(firstStone, true);
mockView.handPanel.stoneClickEvent.emit(secondStone, true); mockView.handPanel.stoneClickEvent.emit(secondStone, true);
mockView.tablePanel.stoneCollectionPanel.stoneClickEvent.emit( mockView.tablePanel.stoneCollectionPanel.stoneClickEvent.emit(firstStone,
firstStone, true); true);
assertCollection(Arrays.asList(secondStone, firstStone)); assertCollection(Arrays.asList(secondStone, firstStone));
} }
@ -300,8 +301,8 @@ public class TurnControlTest {
mockView.handPanel.stoneClickEvent.emit(firstStone, true); mockView.handPanel.stoneClickEvent.emit(firstStone, true);
mockView.handPanel.stoneClickEvent.emit(secondStone, true); mockView.handPanel.stoneClickEvent.emit(secondStone, true);
mockView.tablePanel.stoneCollectionPanel.stoneClickEvent.emit( mockView.tablePanel.stoneCollectionPanel.stoneClickEvent.emit(firstStone,
firstStone, true); true);
mockView.tablePanel.stoneCollectionPanel.setClickEvent.emit(firstStone, mockView.tablePanel.stoneCollectionPanel.setClickEvent.emit(firstStone,
true); true);
@ -408,8 +409,7 @@ public class TurnControlTest {
Stone stone2 = new Stone(2, StoneColor.RED); Stone stone2 = new Stone(2, StoneColor.RED);
Stone stone3 = new Stone(3, StoneColor.RED); Stone stone3 = new Stone(3, StoneColor.RED);
Stone stone4 = new Stone(4, StoneColor.RED); Stone stone4 = new Stone(4, StoneColor.RED);
StoneSet set1 = new StoneSet(Arrays.asList(stone1, stone2, stone3, StoneSet set1 = new StoneSet(Arrays.asList(stone1, stone2, stone3, stone4));
stone4));
mockTable.findStoneSet.put(stone1, set1); mockTable.findStoneSet.put(stone1, set1);
mockTable.findStoneSet.put(stone3, set1); mockTable.findStoneSet.put(stone3, set1);
@ -430,8 +430,7 @@ public class TurnControlTest {
Stone stone2 = new Stone(2, StoneColor.RED); Stone stone2 = new Stone(2, StoneColor.RED);
Stone stone3 = new Stone(3, StoneColor.RED); Stone stone3 = new Stone(3, StoneColor.RED);
Stone stone4 = new Stone(4, StoneColor.RED); Stone stone4 = new Stone(4, StoneColor.RED);
StoneSet set1 = new StoneSet(Arrays.asList(stone1, stone2, stone3, StoneSet set1 = new StoneSet(Arrays.asList(stone1, stone2, stone3, stone4));
stone4));
mockTable.findStoneSet.put(stone1, set1); mockTable.findStoneSet.put(stone1, set1);
mockTable.findStoneSet.put(stone3, set1); mockTable.findStoneSet.put(stone3, set1);
@ -454,8 +453,7 @@ public class TurnControlTest {
Stone stone2 = new Stone(2, StoneColor.RED); Stone stone2 = new Stone(2, StoneColor.RED);
Stone stone3 = new Stone(3, StoneColor.RED); Stone stone3 = new Stone(3, StoneColor.RED);
Stone stone4 = new Stone(4, StoneColor.RED); Stone stone4 = new Stone(4, StoneColor.RED);
StoneSet set1 = new StoneSet(Arrays.asList(stone1, stone2, stone3, StoneSet set1 = new StoneSet(Arrays.asList(stone1, stone2, stone3, stone4));
stone4));
mockTable.findStoneSet.put(stone1, set1); mockTable.findStoneSet.put(stone1, set1);
mockTable.findStoneSet.put(stone3, set1); mockTable.findStoneSet.put(stone3, set1);
@ -635,7 +633,8 @@ public class TurnControlTest {
public void testAddLeft() { public void testAddLeft() {
AccessibleTable table = new AccessibleTable(); AccessibleTable table = new AccessibleTable();
HumanTurnControl turnControl = new HumanTurnControl(mockTimer); HumanTurnControl turnControl = new HumanTurnControl(mockTimer);
turnControl.setup(mockPlayer, table, mockView, false, false); turnControl.setup(new GameSettings(), mockPlayer, table, mockView, false,
false);
turnControl.startTurn(); turnControl.startTurn();
Stone blueOne = new Stone(1, BLUE); Stone blueOne = new Stone(1, BLUE);
Stone redOne = new Stone(1, RED); Stone redOne = new Stone(1, RED);
@ -650,10 +649,10 @@ public class TurnControlTest {
Stone blackThree = new Stone(3, BLACK); Stone blackThree = new Stone(3, BLACK);
Stone blackFour = new Stone(4, BLACK); Stone blackFour = new Stone(4, BLACK);
Stone blackFive = new Stone(5, BLACK); Stone blackFive = new Stone(5, BLACK);
StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne, StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne, blackOne,
blackOne, redTwo, redThree, redFour, blackTwo, blackThree)); redTwo, redThree, redFour, blackTwo, blackThree));
StoneSet oldSet2 = new StoneSet(Arrays.asList(blueTwo, blackFour, StoneSet oldSet2 = new StoneSet(
blackFive)); Arrays.asList(blueTwo, blackFour, blackFive));
table.drop(oldSet1, new Position(0, 0)); table.drop(oldSet1, new Position(0, 0));
table.drop(oldSet2, new Position(0, 0)); table.drop(oldSet2, new Position(0, 0));
mockHand.drop(blueThree, new Position(0, 0)); mockHand.drop(blueThree, new Position(0, 0));
@ -752,7 +751,8 @@ public class TurnControlTest {
public void testAddRight() { public void testAddRight() {
AccessibleTable table = new AccessibleTable(); AccessibleTable table = new AccessibleTable();
HumanTurnControl turnControl = new HumanTurnControl(mockTimer); HumanTurnControl turnControl = new HumanTurnControl(mockTimer);
turnControl.setup(mockPlayer, table, mockView, false, false); turnControl.setup(new GameSettings(), mockPlayer, table, mockView, false,
false);
turnControl.startTurn(); turnControl.startTurn();
Stone blueOne = new Stone(1, BLUE); Stone blueOne = new Stone(1, BLUE);
Stone redOne = new Stone(1, RED); Stone redOne = new Stone(1, RED);
@ -767,10 +767,10 @@ public class TurnControlTest {
Stone blackThree = new Stone(3, BLACK); Stone blackThree = new Stone(3, BLACK);
Stone blackFour = new Stone(4, BLACK); Stone blackFour = new Stone(4, BLACK);
Stone blackFive = new Stone(5, BLACK); Stone blackFive = new Stone(5, BLACK);
StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne, StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne, blackOne,
blackOne, redTwo, redThree, redFour, blackTwo, blackThree)); redTwo, redThree, redFour, blackTwo, blackThree));
StoneSet oldSet2 = new StoneSet(Arrays.asList(blueTwo, blackFour, StoneSet oldSet2 = new StoneSet(
blackFive)); Arrays.asList(blueTwo, blackFour, blackFive));
table.drop(oldSet1, new Position(0, 0)); table.drop(oldSet1, new Position(0, 0));
table.drop(oldSet2, new Position(0, 0)); table.drop(oldSet2, new Position(0, 0));
mockHand.drop(blueThree, new Position(0, 0)); mockHand.drop(blueThree, new Position(0, 0));
@ -869,7 +869,8 @@ public class TurnControlTest {
public void testAddNewSet() { public void testAddNewSet() {
AccessibleTable table = new AccessibleTable(); AccessibleTable table = new AccessibleTable();
HumanTurnControl turnControl = new HumanTurnControl(mockTimer); HumanTurnControl turnControl = new HumanTurnControl(mockTimer);
turnControl.setup(mockPlayer, table, mockView, false, false); turnControl.setup(new GameSettings(), mockPlayer, table, mockView, false,
false);
turnControl.startTurn(); turnControl.startTurn();
Stone blueOne = new Stone(1, BLUE); Stone blueOne = new Stone(1, BLUE);
Stone redOne = new Stone(1, RED); Stone redOne = new Stone(1, RED);
@ -884,10 +885,10 @@ public class TurnControlTest {
Stone blackThree = new Stone(3, BLACK); Stone blackThree = new Stone(3, BLACK);
Stone blackFour = new Stone(4, BLACK); Stone blackFour = new Stone(4, BLACK);
Stone blackFive = new Stone(5, BLACK); Stone blackFive = new Stone(5, BLACK);
StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne, StoneSet oldSet1 = new StoneSet(Arrays.asList(blueOne, redOne, blackOne,
blackOne, redTwo, redThree, redFour, blackTwo, blackThree)); redTwo, redThree, redFour, blackTwo, blackThree));
StoneSet oldSet2 = new StoneSet(Arrays.asList(blueTwo, blackFour, StoneSet oldSet2 = new StoneSet(
blackFive)); Arrays.asList(blueTwo, blackFour, blackFive));
table.drop(oldSet1, new Position(0, 0)); table.drop(oldSet1, new Position(0, 0));
table.drop(oldSet2, new Position(0, 0)); table.drop(oldSet2, new Position(0, 0));
mockHand.drop(blueThree, 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>>( List<Pair<Stone, Position>> stones = new ArrayList<Pair<Stone, Position>>(
mockHand.stones); mockHand.stones);
Collections.sort(stones, Collections
new HumanTurnControl.HandStonePositionComparator()); .sort(stones, new HumanTurnControl.HandStonePositionComparator());
assertEquals(stones.size(), 13); assertEquals(stones.size(), 13);
@ -1053,8 +1054,8 @@ public class TurnControlTest {
List<Pair<Stone, Position>> stones = new ArrayList<Pair<Stone, Position>>( List<Pair<Stone, Position>> stones = new ArrayList<Pair<Stone, Position>>(
mockHand.stones); mockHand.stones);
Collections.sort(stones, Collections
new HumanTurnControl.HandStonePositionComparator()); .sort(stones, new HumanTurnControl.HandStonePositionComparator());
assertEquals(stones.size(), 13); assertEquals(stones.size(), 13);