bot.UniversalBot.java Source code

Java tutorial

Introduction

Here is the source code for bot.UniversalBot.java

Source

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Andrzej Ressel (jereksel@gmail.com)
 * Copyright (c) 2014 Mateusz Kaleciski
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package bot;

import server.Card;
import server.Helpers;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;

public class UniversalBot extends Thread {

    private final Socket socket;
    private final BufferedReader in;
    private final PrintWriter out;
    private final String nick;

    private ArrayList<Card> hand = new ArrayList<Card>();

    private int pot = 0;
    private int startChips = 0;
    private int smallBlind = 0;
    private int bigBlind = 0;
    private boolean isPlaying = true;
    private int actualChips = 0;
    private int actualBet = 0;
    private boolean connection = true;
    private int maxBet = 0;

    public void chips(int startChips, int smallBlind, int bigBlind) {
        this.startChips = startChips;
        this.smallBlind = smallBlind;
        this.bigBlind = bigBlind;
    }

    /**
     * Method which returns cards to exchange.
     * @param hand List of cards.
     * @return List of cards to exchange.
     */
    public ArrayList<Card> cardsToExchange(ArrayList<Card> hand) {

        ArrayList<Card> cards2Exchange = new ArrayList<Card>(hand);
        System.out.println("[DEBUG] Actual hand: " + hand);
        System.out.println("[DEBUG] Best hand: " + Helpers.bestHand(cards2Exchange));

        ArrayList<Card> cards2Delete = Helpers.bestHand(cards2Exchange);

        for (Card card2Delete : cards2Delete) {
            cards2Exchange.remove(card2Delete);
        }

        return cards2Exchange;

    }

    /**
     * Method which gives bot information about real value of his cards.
     * @param hand list of cards.
     * @return Bet Ability.
     */
    public int betAbility(ArrayList<Card> hand) {

        int betAb = 0;
        betAb = Helpers.handValue(hand);

        if (betAb > 10000) {
            if (actualChips > startChips / 10) {
                betAb = startChips / 20;
            } else {
                betAb = actualChips;
            }
        } else if (betAb > 1000) {
            if (actualChips > startChips / 50) {
                betAb = startChips / 50;
            } else {
                betAb = actualChips;
            }
        } else
            betAb = 0;

        return betAb;
    }

    /**
     * Constructor of UniversalBot. 
     * @param socket Bot's socket.
     * @param in Bot's Buffered Reader.
     * @param out Bot's Print Writer.
     * @param nick Bot's unique name.
     */
    UniversalBot(final Socket socket, BufferedReader in, PrintWriter out, String nick) {
        this.socket = socket;
        this.in = in;
        this.out = out;
        this.nick = nick;
    }

    /**
     * Method which sends data to server. (take a look at sleep(100))
     * @param data see description
     */
    private void sendData(String data) {
        try {
            sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("[DEBUG] Sending: " + data);
        out.println(data);
    }

    @Override
    public void run() {

        ArrayList<String> choices = new ArrayList<String>();
        int betAbility = 0;

        System.out.println("[DEBUG] Nick: " + nick);

        JSONArray toSend = new JSONArray();
        JSONObject object;

        try {
            object = new JSONObject().put("action", "first_connection");
            toSend.put(object);
            object = new JSONObject().put("nick", nick);
            toSend.put(object);
        } catch (JSONException e1) {
            e1.printStackTrace();
        }

        sendData(toSend.toString());

        String wynik;
        JSONArray jsonMainArr;
        JSONObject childJSONObject;

        while (isPlaying && connection) {

            try {
                wynik = in.readLine();
                System.out.println("[DEBUG] Get: " + wynik);

                jsonMainArr = new JSONArray(wynik);

                switch (jsonMainArr.getJSONObject(0).getString("action")) {

                /**
                * Getting cards for the first time from Server. Receiving cards from server.
                */
                case "cards":
                    hand.clear();

                    for (int i = 1; i < jsonMainArr.length(); i++) {
                        childJSONObject = jsonMainArr.getJSONObject(i);
                        final String rank = childJSONObject.getString("rank");
                        final String suit = childJSONObject.getString("suit");
                        hand.add(new Card(suit, rank));
                    }

                    betAbility = betAbility(hand) - (pot) / 2;

                    System.out.println("[DEBUG] Rka bota " + hand);

                    System.out.println("[DEBUG] OTO " + betAbility);

                    break;

                /**
                 * Overwriting:
                 * bet
                 * maxBet
                 * chips 
                 */
                case "bet_change":

                    int bet = jsonMainArr.getJSONObject(1).getInt("bet");
                    int chips = jsonMainArr.getJSONObject(1).getInt("chips");

                    if (bet > maxBet)
                        maxBet = bet;

                    if (jsonMainArr.getJSONObject(1).getString("player").equals(nick)) {
                        actualChips = chips;
                        actualBet = bet;
                    }
                    System.out.println("[DEBUG] Actual maxbet: " + maxBet + " Actual bet: " + actualBet
                            + " Actual chips: " + chips);
                    //System.out.println("OTO "+jsonMainArr.getJSONObject(1).getString("player"));

                    break;

                case "first_connection":

                    chips(jsonMainArr.getJSONObject(1).getInt("chips"),
                            jsonMainArr.getJSONObject(2).getInt("chips"),
                            jsonMainArr.getJSONObject(3).getInt("chips"));

                    break;

                /**
                 * Sending cards to server.
                 */
                case "exchange_cards":

                    hand.clear();

                    for (int i = 1; i < jsonMainArr.length(); i++) {
                        childJSONObject = jsonMainArr.getJSONObject(i);
                        final String rank = childJSONObject.getString("rank");
                        final String suit = childJSONObject.getString("suit");
                        hand.add(new Card(suit, rank));
                    }

                    betAbility = betAbility(hand) - (pot) / 2;
                    System.out.println("[DEBUG] OTO " + hand);
                    break;

                /**
                 * Main bot's AI (actually it is ordinary behavior). Order has got the meaning.
                 */
                case "available_choices":

                    choices.clear(); // czyszcz list z poprzednich moliwoci

                    for (int i = 1; i < jsonMainArr.length(); i++) {
                        childJSONObject = jsonMainArr.getJSONObject(i);
                        choices.add(childJSONObject.getString("choice"));
                    }

                    JSONArray doWyslania = new JSONArray();

                    System.out.println("[DEBUG] OTO " + choices.toString()); // ok wszystko dziaa

                    if (choices.contains("Bet") && betAbility > (pot) / 2
                            && !(betAbility + (maxBet - actualBet) >= actualChips) && betAbility >= maxBet) {

                        betAbility = betAbility(hand) - (pot) / 2;

                        doWyslania.put(new JSONObject().put("action", "bet"));
                        doWyslania.put(new JSONObject().put("bet", betAbility));
                        sendData(doWyslania.toString());

                    } else if (choices.contains("Small Blind")) {
                        doWyslania.put(new JSONObject().put("action", "small_blind"));
                        sendData(doWyslania.toString());
                    } else if (choices.contains("Big Blind")) {

                        doWyslania.put(new JSONObject().put("action", "big_blind"));
                        sendData(doWyslania.toString());
                    } else if (choices.contains("Raise") && betAbility > (pot) / 2
                            && !(betAbility + (maxBet - actualBet) >= actualChips) && betAbility >= maxBet) {

                        betAbility = betAbility(hand) - (pot) / 2;

                        doWyslania.put(new JSONObject().put("action", "raise"));
                        doWyslania.put(new JSONObject().put("bet", betAbility));
                        sendData(doWyslania.toString());

                    } else if (choices.contains("Exchange cards")) {

                        doWyslania.put(new JSONObject().put("action", "exchange_cards"));
                        System.out.println("[DEBUG] OTO " + hand);

                        for (int i = 0; i < cardsToExchange(hand).size(); i++) {
                            doWyslania.put(new JSONObject().put("suit", cardsToExchange(hand).get(i).getSuit())
                                    .put("rank", cardsToExchange(hand).get(i).getRank()));
                        }
                        sendData(doWyslania.toString());
                        System.out.println("[DEBUG] OTO " + doWyslania);

                    } else if (choices.contains("All-In")) {
                        doWyslania.put(new JSONObject().put("action", "all-in"));
                        sendData(doWyslania.toString());

                    } else if (choices.contains("Call") && (maxBet - actualBet) <= actualChips
                            && (Math.random() < 0.6)) {
                        doWyslania.put(new JSONObject().put("action", "call"));
                        sendData(doWyslania.toString());
                    } else if (choices.contains("Check")) {
                        doWyslania.put(new JSONObject().put("action", "check"));
                        sendData(doWyslania.toString());
                    } else if (choices.contains("Fold")) {
                        doWyslania.put(new JSONObject().put("action", "fold"));
                        sendData(doWyslania.toString());
                    }

                    break;

                case "pot":
                    pot = jsonMainArr.getJSONObject(1).getInt("pot_size");
                    maxBet = 0;
                    break;

                case "exit":
                    connection = false;
                    break;

                case "the_same_nick":
                    System.out.println("[FATAL] Another player has the same nick");
                    connection = false;
                    break;

                case "you_lost":
                    System.out.println("I lost ;-(");
                    connection = false;
                    break;

                case "you_won":
                    System.out.println("I won :-)");
                    connection = false;
                    break;

                case "message":
                    final String message = jsonMainArr.getJSONObject(1).getString("message");
                    System.out.println("[DEBUG] Message from server" + message);
                    break;

                case "connection_successful":
                    break;

                default:
                    System.out
                            .println("[ERROR] Unknown command " + jsonMainArr.getJSONObject(0).getString("action"));

                }
            } catch (NullPointerException | IOException | JSONException e) {
                e.printStackTrace();
                break;
            }
        }

        try {
            socket.close();
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        out.close();

    }

}