/** The HumanPlayer wants a move from the user */ private void getMoveFromUser() { // Indicate that we should get a move from the user this.userMoveNeeded = true; // Move to the last board this.setCurrentBoard(boardHistory.size() - 1); Board bb = (Board) boardHistory.get(currentBoard); statusLabel.setText("Waiting for user to play as " + bb.getNameForID(bb.getTurn()) + "..."); }
/** Called by server on update */ void boardUpdated(Board b, Move m) { moveHistory.add(m); this.moveListModel.addedMove(); board = b; boardHistory.add(b); // If displaying the last board, update to the current if (currentBoard == boardHistory.size() - 2) setCurrentBoard(boardHistory.size() - 1); if (board != null) // Might be calling from gameEnded... statusLabel.setText("Game in progress, " + board.getNameForID(board.getTurn()) + " to play."); }
public PokerHand calculatePokerHand(TexasHand texasHand, Board board) { if (board.isPreFlop()) return null; ArrayList<Card> sequence = new ArrayList<Card>(); sequence.add(texasHand.getCard0()); sequence.add(texasHand.getCard1()); sequence.add(board.getFlop()[0]); sequence.add(board.getFlop()[1]); sequence.add(board.getFlop()[2]); if (board.isFlop()) return boardOnFlop(sequence); if (board.isTurn()) { sequence.add(board.getTurn()); boardOnTurn(sequence); } if (board.isRiver()) { sequence.add(board.getTurn()); sequence.add(board.getRiver()); boardOnRiver(sequence); } return comparePokerHands(); }
/** Called by server on game start */ void gameStarted(Board b, int gameID, String[] players) { clearData(); getContentPane().remove(boardPanel); boardPanel = b.createBoardPanel(); boardPanel.setPreferredSize(new Dimension(BOARD_SIZE, BOARD_SIZE)); getContentPane().add(boardPanel, BorderLayout.CENTER); pack(); repaint(); StringBuffer title = new StringBuffer("Game " + gameID + ": "); for (int i = 0; i < players.length; i++) title.append(players[i] + (i < players.length - 1 ? " vs. " : "")); this.setTitle(title.toString()); this.board = b; boardUpdated(b, null); setCurrentBoard(0); enableLaunchActions(false); enableServerActions(false); openAction.setEnabled(false); closeAction.setEnabled(false); killServerAction.setEnabled(true); statusLabel.setText("Game in progress, " + board.getNameForID(board.getTurn()) + " to play."); }
// MF Re-enable all this once you have the AJAX working // LV That would be now. Took some time to get all the errors out. Sure it could be implemented // better and more Java-like. public static Integer[] minMax(int p, Board b, int d) { // p: player designation // b: current board state // d: iteration depth Integer score = getScore(b, p); // some game states do not require any thinking (e.g. already lost or won) if (d == 0) return new Integer[] {null, score}; // max depth reached. just return the score. if (score == -WIN_SCORE) return new Integer[] {null, score}; // we lose, not good. if (score == WIN_SCORE) return new Integer[] {null, score}; // we win, good. if (b.isFull()) return new Integer[] {null, 8888}; // board is full, pretty good, but not as good as winning. if (moveCache == null) { System.out.println("moveCache was null."); moveCache = new Hashtable<String, Integer[]>(); } // LV See if we can get the next move from the cache. // System.out.println(d+": "+b.getHash()); if (moveCache.containsKey(b.getHash())) { Integer[] c = moveCache.get(b.getHash()); // System.out.println("cache possible for hash = " + b.getHash()); if (c[0] >= (Integer) d) { // System.out.println("cache hit!"); return new Integer[] {c[1], c[2]}; } } // LV No cache. /* // simple optimization attempt. look ahead two moves to see if win or lose possible. // this prevents the algorithm from exploring parts of the state space that are unrealistic to occur. if (d > 2) { for (int q = 0; q < b.getSize(); ++q) { // for each possible move. Board n = b.clone(); // copy current state. if (n.playColumn(q)) { // make move. Integer[] qs = minMax(p,n,2); // look ahead one move. if (qs[1] == WIN_SCORE || qs[1] == -WIN_SCORE) { return new Integer[] {q,qs[1]}; // if I win or lose, stop exploring. }}}} */ // algorithm considers best and worst possible moves in one loop to save lines of code. Integer maxv = 0; // best score. Integer maxc = -1; // column where best score occurs. Integer minv = 999999; // worst score. Integer minc = -1; // colum where worst score occurs. for (int q = 0; q < b.getSize(); ++q) { // for each possible move. Board n = b.clone(); // copy current state. if (n.playColumn(q)) { // make move. Integer[] next = minMax(p, n, d - 1); // look ahead d-1 moves. if (maxc == -1 || next[1] > maxv) { maxc = q; maxv = next[1]; } // compare to previous best. if (minc == -1 || next[1] < minv) { minc = q; minv = next[1]; } // compare to previous worst. } } if (b.getTurn() == p) { // if it is our turn. moveCache.put(b.getHash(), new Integer[] {d, maxc, maxv / 2 + score / 2}); return new Integer[] {maxc, maxv / 2 + score / 2}; // make best possible move. } else { // otherwise. moveCache.put(b.getHash(), new Integer[] {d, minc, minv / 2 + score / 2}); return new Integer[] {minc, minv / 2 + score / 2}; // make worst possible move. } }