package bots; import com.biotools.meerkat.Action; import com.biotools.meerkat.Card; import com.biotools.meerkat.GameInfo; import com.biotools.meerkat.Player; import com.biotools.meerkat.util.Preferences; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; /** * TCP-IP Bridge for Meerkat API. Found on poker-ai and poker-bot.ru forums. Never tested myself. * * @author Unknown */ public class ComBot implements Player { private int ourSeat; // our seat for the current hand private GameInfo gi; // general game information private Preferences prefs; // the configuration options for this bot private Socket connection; public JPanel getSettingsPanel() { JPanel jp = new JPanel(); SpinnerModel PortNumberModel = new SpinnerNumberModel(prefs.getIntPreference("PORT_NUMBER"), 1024, // min 65535, // max 1); // step final JSpinner PortNumber = new JSpinner(PortNumberModel); class PortNumberListener implements ChangeListener { public void stateChanged(ChangeEvent evt) { prefs.setPreference("PORT_NUMBER", ((Integer) ((JSpinner) evt.getSource()).getModel().getValue()).intValue()); } } PortNumber.addChangeListener(new PortNumberListener()); jp.add(new JLabel("Port Number")); jp.add(PortNumber); return jp; } public Preferences getPreferences() { return prefs; } public void comSend(String s) { try { connection.getOutputStream().write(s.getBytes()); } catch (IOException ex) { ex.printStackTrace(); } } public void init(Preferences playerPrefs) { this.prefs = playerPrefs; } public void gameStateChanged() { } public void gameStartEvent(GameInfo gInfo) { this.gi = gInfo; try { connection = new Socket("127.0.0.1", prefs.getIntPreference("PORT_NUMBER", 50000)); } catch (UnknownHostException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } String s = String.format("01;%4.2f;%d;%d;%d;%d\n", gi.getBigBlindSize(), gi.getNumPlayers(), gi.getButtonSeat(), gi.getGameID(), gi.isFixedLimit() ? 1 : 0); comSend(s); for (int seat = 0; seat < 10; seat++) { if (gi.inGame(seat)) { s = String.format("02;%d;%s;%4.2f;\n", seat, gi.getPlayer(seat).getName(), gi.getPlayer(seat).getBankRoll()); comSend(s); } } } public void stageEvent(int stage) { String s = String.format("03;%d;%s;\n", stage, gi.getBoard().toString()); comSend(s); } public void actionEvent(int pos, Action act) { double toCall = gi.getPlayer(pos).getAmountToCall(); double toRaise = gi.isFixedLimit() ? gi.getPlayer(pos).getAmountRaiseable() : act.getAmount(); String s = ""; switch (act.getType()) { case Action.SMALL_BLIND: case Action.BIG_BLIND: case Action.POST_BLIND: case Action.POST_ANTE: case Action.POST_DEAD_BLIND: case Action.INVALID: case Action.FOLD: case Action.CHECK: case Action.ALLIN_PASS: case Action.MUCK: case Action.SIT_OUT: case Action.BET: s = String.format("04;%d;%d;%4.2f;\n", pos, act.getType(), act.getAmount()); break; case Action.CALL: s = String.format("04;%d;%d;%4.2f;\n", pos, act.getType(), toCall); break; case Action.RAISE: s = String.format("04;%d;%d;%4.2f;\n", pos, act.getType(), toCall + toRaise); } comSend(s); } public void dealHoleCardsEvent() { comSend("05;\n"); } public void holeCards(Card c1, Card c2, int seat) { String s = String.format("06;%d;%s %s;\n", seat, c1.toString(), c2.toString()); comSend(s); this.ourSeat = seat; } public Action getAction() { double toCall = gi.getAmountToCall(ourSeat); double toRaise = gi.getPlayer(ourSeat).getAmountRaiseable(); Action act; act = Action.foldAction(toCall); StringBuilder raiseString = new StringBuilder(""); String s = String.format("07;%4.2f;%4.2f;\n", toCall, toRaise); comSend(s); int f = 0; int b = 0; while (true) { try { b = connection.getInputStream().read(); } catch (IOException ex) { ex.printStackTrace(); } if (b == 10) break; if (f != 0 && b != -1) { raiseString.append((char) b); } else { switch (b) { case 48: s = s.concat("0"); break; case 49: s = s.concat("1"); break; case 50: s = s.concat("2"); break; case 59: s = s.concat(";"); f = 1; } if (b == -1) { try { Thread.sleep(20); } catch (InterruptedException ex) { ex.printStackTrace(); } } } } String s2 = raiseString.toString(); double stakes = 0; if (!s2.isEmpty()) stakes = Double.valueOf(s2); if (s.compareTo("0;") == 0) act = Action.foldAction(gi); if (s.compareTo("1;") == 0) act = Action.callAction(gi); if (s.compareTo("2;") == 0) { if (s2.isEmpty() || stakes - toCall < gi.getMinRaise()) act = Action.betAction(gi); else if (toCall == 0) act = Action.betAction(stakes); else act = Action.raiseAction(toCall, stakes - toCall); } return act; } public void showdownEvent(int seat, Card c1, Card c2) { String s = String.format("08;%d;%s %s;\n", seat, c1.toString(), c2.toString()); comSend(s); } public void winEvent(int pos, double amount, String handName) { String s = String.format("09;%d;%4.2f;%s;\n", pos, amount, handName); comSend(s); } public void gameOverEvent() { comSend("10;\n"); try { connection.close(); } catch (IOException ex) { ex.printStackTrace(); } } }