package jrummikub.control.turn; import java.util.ArrayList; import java.util.List; import javax.swing.SwingUtilities; import jrummikub.control.ITurnTimer; import jrummikub.control.TurnTimer; import jrummikub.util.Connection; import jrummikub.util.IListener; /** * Base class for AI players * */ public class BaseAIControl extends AbstractTurnControl { long startTime; private ITurnTimer turnTimer; private List connections = new ArrayList(); private Thread computeThread; private volatile boolean stopRunning = false; @Override public void startTurn() { turnTimer = new TurnTimer(view); connections.add(turnTimer.getTimeRunOutEvent().add(new IListener() { @Override public void handle() { cleanUp(); endOfTurnEvent.emit(); } })); computeThread = new Thread(new Runnable() { @Override public void run() { compute(); } }); startTime = System.currentTimeMillis(); turnTimer.startTimer(); computeThread.start(); } private void cleanUp() { turnTimer.stopTimer(); for (Connection c : connections) { c.remove(); } stopRunning = true; } private void compute() { if (mayRedeal) { emitRedeal(); } else { if (player.getLaidOut()) { layOut(); } else { emitEndOfTurn(); } } } private void layOut() { emitEndOfTurn(); } private void emitRedeal() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { cleanUp(); redealEvent.emit(); } }); } private void emitEndOfTurn() { long timeElapsed = System.currentTimeMillis() - startTime; long timeNeeded = Math.min((long) (1000 + Math.random() * hand.getSize() * 100), 50000); long waitTime = timeNeeded - timeElapsed; if (waitTime > 0) { try { Thread.sleep(waitTime); } catch (InterruptedException e) { // This shouldn't happen } } SwingUtilities.invokeLater(new Runnable() { @Override public void run() { cleanUp(); endOfTurnEvent.emit(); } }); } /** * Get the factory for the base AI control * * @return the factory */ static public TurnControlFactory getFactory() { return new TurnControlFactory() { @Override public ITurnControl create() { return new BaseAIControl(); } }; } }