Skip to content

Latest commit

 

History

History
318 lines (255 loc) · 18.5 KB

documentation.md

File metadata and controls

318 lines (255 loc) · 18.5 KB

Documentation for the PokerBot of Group 15



Project Introduction

In this project, our aim is to design and program a pokerbot which is able to participate in a Kuhn Poker game with others. By classifying the received cards, it is supposed to make suitable actions based on our own designed strategy.

Game Introduction

Kuhn Poker is an extremely simplified poker game. As a simple model zero-sum two-player imperfect-information game, it is amenable to a complete game-theoretic analysis. More details of its rules will be introduced in our agent and strategy part.

Implementation Approach

To achieve the goal, our task is divided into two main parts. One part is to build and train a model to classify the cards given by the server. The other is to develop an agent with a suitable strategy to make actions after receiving these cards. Details are introduced as follow.

Data Sets and Model

1. Dataset
  • Initial Condition Setup Set the parameters noise level = 0.7 and rotation = 180.
    Generate 5000 training data and 1000 testing data with noise level randomly between 0 to 0.7 and rotation degree randomly between 0 to 180.

  For examples:

  A_9 A_12 A_33 A_36
  J_2 J_7 J_14 J_42
  K_21 K_39 K_75 K_119
  Q_0 Q_19 Q_49 Q_56

  • Feature Extraction Process Except change the value from analog (0 to 255) to digital (0 and 1), also apply noise cancellation in the extraction process.
    Step 1: Apply a light Gaussian Blur
    Step 2: Apply a loose single-value threshold to filter some light noise out
    Step 3: Apply a 3x3 averaging kernel to get a stronger blur effect
    Step 4: Apply a hysteresis threshold to nicely keep the shape of words

  • Result Comparison
        Before / After
    A_9:  A_9  A_9
    A_12: A_12  A_12
    J_14: J_14  J_14
    J_42: J_42  J_42
    K_39: K_39  K_39
    K_75: K_75  K_75
    Q_49: Q_49  Q_49
    Q_56: Q_56  Q_56

2. Model
  • Destination Classify four different cards J Q K A by using 32x32 pixel images.

  • Model Architecture Based on the concept of VGG structure, use TensorFlow package to create a small five-layer CNN model.
    Due to the easy classification task, only use three convolution layers to extract the feature and two fully connected layers to fulfill the goal.
    Take ReLU as the activation layer after each convolution layer and fully connected layer, except the last layer.
    Also, apply 2x2 max pooling layer after each convolution layer. At the end, apply Softmax as the activation function at the last layer to cooperate with cross-entropy loss function due to the one-hot coding labels.
    image

  • Traning Result With 5000 training data and 1000 testing generated by 0-180 degree rotation and 0-0.7 noise level, our testing accurcy is 0.973.
    It is robust enough to deal with high noisy inputs and still perform very well.

Agent and Strategy

1. Game Rules
  • Check https://en.wikipedia.org/wiki/Kuhn_poker.
  • Note that there is a difference between our project and the game introduced in Wikipedia. In this project, the cards can be 3 or 4, which is set by the backend.
2. Strategy Idea
  • The confidence of BET or CALL is different for different card in hand, last move and outcome from last round.
  • For example, the confidence of BET while having "J" in hand is small. And the confidence of BET is large for "A" or "K" in hand.
  • When last move is BET, the confidence of BET should be smaller than before for the purpose of being cautious. Vice versa. This is achieved by multiplying or dividing a number bigger than 1. It is called decay.
  • When outcome from last round is negative and last move is BET or CALL, then the confidence of BET is smaller to be more cautious. Vice versa. This is achieved by updating the decay.
  • While making actions, a random number flag in (0,1) is created. If flag > confidence, then we BET or CALL. Otherwise, we CHECK or FOLD.
  • Decay will be passed to next round. Confidence remains same all the time.
  • If we have J or A (or K for 3 cards game), decay will not be considered. That is, for J and A, we give a fixed confidence to bet.
3. Confidence Tabel for 4 cards game
Possibility to bet (confidence) J Q K A
First Action(Player1) 0.05 0.3 0.55 0.9
Second Action(Player2) 0.05 0.3*decay or 0.3/decay 0.55*decay or 0.55/decay 0.9
Third Action(Player1) 0.05 0.3*decay or 0.3/decay 0.55*decay or 0.55/decay 0.9

Preparation

Before running our codes, some pakages are needed to be installed. These pakages has been listed in requirement-linux.txt and requirement-windows.txt. More specific steps to install them have been provided in README.md.

Tutorial

To play local game, we need to have a local KuhnPoker server installed and running in the background. With a token given by the local server, we can connect to it and then start our game automatically. We can also choose to play the game with others on the public server. We have to specify a --global flag for the script and then wait for others to join. More details about how to realize it have also been provided in README.md.


Software implementation

In this part, most of the important functions in our python files will be introduced.

data_sets

File data_sets is used to deal with data before training, including generating training and testing data.

extract_features

Function extract_features converts an image to features that serve as input to the image classifier.

Parameters:

  • img: Image
    Image to convert to features.
  • file_name: str, default = None
    Passing the file name to save_without_generate() to save the feature image for easy observation.

Returns:

  • featres: list/matrix/structure of int, int between zero and one
    Extracted features in a format that can be used in the image classifier.
load_data_set

Function load_data_set prepares features for the images in data_dir and divide in a training and validation set.

Parameters:

  • data_dir: str
    Directory of images to load.
  • n_validation: int, default = 0
    Number of images that are assigned to the validation set.

Returns:

  • featres: list/matrix/structure of int, int between zero and one
    Extracted features in a format that can be used in the image classifier.
generate_data_set

Function generate_data_set generates n_samples noisy images by using generate_noisy_image(), and store them in data_dir.

Parameters:

  • n_samples: int
    Number of train/test examples to generate.
  • data_dir: str in [TRAINING_IMAGE_DIR, TEST_IMAGE_DIR]
    Directory for storing images.
generate_noisy_image

Function generate_noisy_image generates a noisy image with a given noise corruption. This implementation mirrors how the server generates the images. However the exact server settings for noise_level and ROTATE_MAX_ANGLE are unknown.

Parameters:

  • rank: str in ['J', 'Q', 'K', 'A']
    Original card rank.
  • noise_level: int between zero and one
    Probability with which a given pixel is randomized.

Returns:

  • noisy_img: Image
    A noisy image representation of the card rank.
save_without_generate

Fuction save_without_generate is used to save image sperately with corresponding name.

Parameters:

  • img: Image
    Specific feature image for storing.
  • file_name: string
    Specific name correspond to the feature image.
  • data_dir_feature: string
    Target directory.

model

File model is used to build and train our own model for classifying card images given by the server in the games.

build_model

Function build_model adds convolutional layers and fully connected layers to define the model.

Returns:

  • model: model class
    Return the untrained model.
train_model

Function train_model fits the model on the training data set.

Parameters:

  • model: model class
    Model structure to fit, as defined by build_model.
  • n_validation: int
    Number of training examples used for cross-validation.
  • write_to_file bool
    Write model to file; can later be loaded through load_model.

Returns:

  • model: model class
    Return the trained model.
load_model

Function load_model is used to load a model from file using load_model in keras.

Returns:

  • model: model class
    Return the previously trained model.
evaluate_model

Function evaluate_model evaluates our model on the test set.

Parameters:

  • model: model class
    Model structure to fit, as defined by build_model.
  • data_dir: int
    Number of training examples used for cross-validation.

Returns:

  • score: float
    Return a measure of model performance.
identify

The function identify uses the trained model to classify a single card image.

Parameters:

  • image: Image
    Image to classify.
  • model: model class
    Trained model.

agent

File agent is used to make actions based on our designed strategy in the game. Some important functions used in agent are introduced in the following.

__init__

Function __init__ is use to load our trained model, determine the game type and initialize other parameters in our agent.

Parameters:

  • game_type: str, {'3', '4'}
    The parameter game_type determines how many cards we have when playing the game. With different numbers of cards, our __init__ function will choose different confidence designed for the game.
make_action

Function make_action is used to choose a new action depending on the current state of the game. This method implements our PokerBot strategy designed above. By using the state and round arguments, we can decide our next best move.

Parameters:

  • state: ClientGameState
    The parameter ClientGameState tracks the state object of the current game. A game consists of multiple rounds from deal to showdown.
  • round: ClientGameRoundState
    The parameter ClientGameRoundState tracks the state object of the current round, from deal to showdown.

Returns:

  • Actions : str, {'BET', 'CALL', 'CHECK', 'FOLD'} (and in round.get_available_actions()) A string representation of the next action an agent wants to do next, should be from a list of available actions.
on_image

Function on_image is called every time when the card image changes. Use this method for image recongition procedure.

Parameters:

  • image: Image
    The parameter image tracks the current Image object.
on_error

Function on_error will be called in case of error either from server backend or from client itself. It is easy to use this function for error handling, including logging and raising error.

Parameters:

  • error: str
    The parameter error records a string representation of the current error.
on_game_start

Function on_game_start will be called once at the beginning of the game when server confirms both players have connected. It will check whether .\log folder exists or not. If not then, it will make one. Meanwhile, it can initialize the conf and decay array.

on_new_round_request

Function on_new_round_request is called every time before a new round is started. A new round is started automatically.

Parameters:

  • state: ClientGameState
    State object of the current game.
on_round_end

Funtion on_round_end is called every time a round has ended. A round ends automatically. It will log last round's result, if any, update current decay and log it.

Parameters:

  • state: ClientGameState
    State object of the current game.
  • round: ClientGameRoundState
    State object of the current round.
on_game_end

Function on_game_end is called once after the game has ended. A game ends automatically and it will print the result of the game.

Parameters:

  • state: ClientGameState
    State object of the current game.

Result: str, {'WIN', 'DEFEAT'} End result of the game.

__init_conf_decay

Function __init_conf_decay is called at game start to initialize conf and decay array according to the game type ['3', '4']. The array is in the order of ['J', 'Q', 'K', 'A'(if game type='4')]. Tune the numbers for Q and K to raise possibility to win.

__update_decay

Function __update_decay is called to update decay when every round ends. New values of decay depend on the last game's result and the last move.

Parameters:

  • outcome: str
    The parameter outcome records the result of the last game.
  • last_move: str
    The parameter last_move records the last move.

Project management

Software project management is a sub-discipline of project management in which software projects are planned, implemented, monitored and controlled..1

In this part, the planning, implementing, monitoring and controlling are introduced. The team is gathered by Detian Guo based on personal relationship and team member's availability.

Project Planning

At the beginning of a project, the team identified the scope of the project, and split it to a set of tasks must be completed. Based on a naïve work load estimation, the team set up a project schedule as below.

Project Execution

The team is split to two sub teams. One focused on how to find and realize the strategy to win a Kuhn Poker game. The other one focused on find the best model for poker card identification. Plan was monitored and adjusted according to project status.

Project Monitoring

The team scheduled a weekly meeting to check how did the plan went in the last week. Difficulties by achieving the best strategy and/or the best model were also discussed. The plan was adjusted according to real workload rather than estimated workload.

Project Control

The quality, time plan and risk of a project are the three primary elements to be managed for a project. In this assignment, our keen resource to manage is the available time of team members, which plays an important role on the three pillars mentioned above. This is achieved by the weekly meeting.


Reference

- [1][WikiPedia](https://en.wikipedia.org/wiki/Software_project_management)