Giter Club home page Giter Club logo

gambit's Introduction

Gambit

Project Information

This is the README file for Gambit, software tools for game theory. The latest information on Gambit can be obtained from the Gambit website at http://www.gambit-project.org

Installation Instructions

Instructions on installing Gambit can be found in the PERSONAL_INSTALL file in this directory.

How to Use:

You'll need to change the directory to:

src/python/gambit/tests/test_games/personal_test_games

Configurations

If you'd like to change the default configuration. Open the config.ini file.

Run the program.

To run the program open the command and input:

python gen_tree_manila_poker.py

How the Program Works

Step 1: Create the Saver Object The saver object is an object that holds all the information given in the config.ini file pertaining to writing to files. Therefore, it's needed to print the games (their original and reduced forms) and their solutions.

Step 2: Create the Poker Game Object Every other bit of information not stored in the Saver object is stored in the Poker game object. This is also where we verify that any information given pertaining to the game is inspected to ensure we don't get errors deep in the code.

Step 3: Create the Game Tree Here we create the Game tree following the (potentially restriced) rules of Texas Hold'Em Poker. This game is printed to OUTPUTS_DIRECTORY/OUTPUT_DIRECTORY/ORIGINAL_GAME_TREE_FILE in .nfg and .gte format.

Step 4: Prune the Game Tree Here, we remove actions that lead to player giving himself a strictly worse payoff. This game is printed to OUTPUTS_DIRECTORY/OUTPUT_DIRECTORY/PRINT_PRUNED_GAME_TREE in .nfg and .gte format.

Step 5: Convert the Game to Matrix of Undominated Strategies This is not verified as working, at the moment. Moreover, we're not sure it's what we want. This game is printed to OUTPUTS_DIRECTORY/OUTPUT_DIRECTORY/UNDOMINATED_GAME_MATRIX_FILE in .nfg and .gte format.

Step 6: Solve the Game With a throughly reduced game, the game can be solve for pure/mixed strategies. For more information on this, see the "Some Gambit Information" section. These solutions are printed to OUTPUTS_DIRECTORY/OUTPUT_DIRECTORY/SOLUTIONS_FILE. We're working on cleaning up these solutions to give a user-friendly and readable solutions file.

Some Gambit Information

How do we prune the tree of strictly dominated strategies? First, we gather all information sets we'd like to possibly remove actions from. Then, for each information set, we gather all contingencies (all possible events) that reach this information set. Then, we get the outcomes of all these contingencies and compute the expected payoff for a player who owns the information set for each action they can take. We then remove the actions that are strictly dominated.

How do we solve the game? Gambit handles this in the backend when we call:

# create solver
solver = gambit.nash.ExternalEnumMixedSolver()

# solve game
solutions = solver.solve(g)

What this does is it converts the game tree to matrix-form by gathering all contingencies (all possible events) by calling g.tree.contingencies and setting the payoffs to be the payoffs given those contingencies occurred.

gambit's People

Contributors

tturocy avatar robert-7 avatar albertjiang avatar skunath avatar andrioni avatar hokein avatar robert-lech avatar jchbenjamin avatar marius-avram avatar sksavant avatar

Watchers

James Cloos avatar  avatar

gambit's Issues

We should assign payoffs/outcomes to terminal nodes

Right now, this is a sample terminal node:

t "C1004-A0-B0-A0-C19-A0-B0-A0-C1-A0-B0-A0-C0-A1-B1-T - Terminal node. No More Rounds." 0

The 0 at the end of the line implies the outcome is zero (well, in our code, there is no outcome assigned, yet, so I'm not sure if there's a default value assigned). The point is, we need to assign a payoff.

Create a Game Tree for a Simple Poker Game

We'd like to create a game tree for a simple game of poker. This will consist of:

  • There will be two players
  • Each player will get 2 hole cards
    • ISSUE: They currently see each others hands! This is because every node is its own infoset. (See #12)
  • There will be 1 round of betting
    • Player 1 will have the choice of betting a fixed number or checking after receiving his cards
    • Player 2 will have the choice of calling or folding if Player 1 bets
  • The flop will be revealed.
  • The appropriate winner will be declared.
    • ISSUE: The appropriate winner is not chosen. We currently use the deuces library which assumes you're using a full deck and is basing the ranking of the hand on that. (See #15)

Create River Round

We need to create the branches that indicate all possibilities for a river card.

Add code to account for rank-adjusting when ace wrapping

We'd like to specify whether the ace wraps around (specifically if our lowest card is not a 2), and if so, the ranking should be adjusted accordingly.

Therefore, when ACE_WRAPS is true, a hand with cards [Ac, 6h, 7h, 8h, 9h] should count as a straight. Otherwise, it's just [6h, 7h, 8h, 9h, Ac] which is an Ace-High.

Remove is_terminal

We don't need the variable since node.player == None tells us the node must be terminal.

Enhance the output EVEN more for readability

Change

<NashProfile for 'PSP Game with 2 players and 3 cards': [[1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0]]>
<NashProfile for 'PSP Game with 2 players and 3 cards': [[0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0]]>

To

Strategy A: Rose should never bet while Colin should call 100% of the time if he has a 4.
Strategy B: Rose should bet 100% of the time if she has a 4 (and she should fold otherwise) while Colin should call 100% of the time if he has a 4 (and he should fold otherwise).

Get the expected index, given a pair or triplet of cards

NUMBER_OF_SUITS = 3
LOWEST_CARD = 13
=> deck = ["Kc", "Kd", "Kh", "Ac", "Ad", "Ah"]

get_order(["Kc", "Kd"] = [0,1]) ==> 0
get_order(["Kc", "Kh"] = [0,2]) ==> 1
get_order(["Kc", "Ac"] = [0,3]) ==> 2
get_order(["Kc", "Ad"] = [0,4]) ==> 3
get_order(["Kc", "Ah"] = [0,5]) ==> 4

get_order(["Kd", "Kh"] = [1,2]) ==> 5
get_order(["Kh", "Ac"] = [1,3]) ==> 6
get_order(["Kh", "Ad"] = [1,4]) ==> 7
get_order(["Kh", "Ah"] = [1,5]) ==> 8

get_order(["Kh", "Ac"] = [2,3]) ==> 9
get_order(["Kh", "Ad"] = [2,4]) ==> 10
get_order(["Kh", "Ah"] = [2,5]) ==> 11

get_order(["Ac", "Ad"] = [3,4]) ==> 12
get_order(["Ac", "Ah"] = [3,5]) ==> 13

get_order(["Ad", "Ah"] = [4,5]) ==> 14

Implement Raise/Bet for Player 2

When Player 1 bets, Player 2 should be able to raise. When Player 1 checks, Player 2 should be able to bet. Moreover, Player 1 needs to have a response to this. Therefore, Player 1 should be able to Call or Fold in either of these two cases.

Implement Big Blind / Small Blind

In actual poker, there is no set ante for both players to participate in the game. In actual poker, a chosen player, say player 1, is the small blind and posts half the ante, while the big blind, player 2, posts the ante. Player 1 then has the choice to check or bet. The rest of the action round is identical to others.

Approach:

ASSUME bet_round=0
if outcome == (0,0):
    impossible (that would imply both people 
if outcome == (0,2)
    return ...
etc.

Print and Solve a Subtree

We currently don't uniquely determine expected/actual payoffs for nodes because we don't take into consideration all possible actions.

This is blocked by the relabeling of actions.

Clean solutions output

Change

<NashProfile for 'PSP Game with 2 players and 3 cards': [[Fraction(1, 1), Fraction(0, 1), Fraction(0, 1), Fraction(0, 1), Fraction(0, 1), Fraction(0, 1), Fraction(0, 1), Fraction(0, 1)], [Fraction(0, 1), Fraction(0, 1), Fraction(0, 1), Fraction(0, 1), Fraction(1, 1), Fraction(0, 1), Fraction(0, 1), Fraction(0, 1)]]>
<NashProfile for 'PSP Game with 2 players and 3 cards': [[Fraction(0, 1), Fraction(0, 1), Fraction(0, 1), Fraction(0, 1), Fraction(1, 1), Fraction(0, 1), Fraction(0, 1), Fraction(0, 1)], [Fraction(0, 1), Fraction(0, 1), Fraction(0, 1), Fraction(0, 1), Fraction(1, 1), Fraction(0, 1), Fraction(0, 1), Fraction(0, 1)]]>

To

<NashProfile for 'PSP Game with 2 players and 3 cards': [[1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0]]>
<NashProfile for 'PSP Game with 2 players and 3 cards': [[0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0]]>

Create Turn Round

We need to create the branches that indicate all possibilities for a turn card.

We should only compute the winner once

Right now, we compute the winner for every terminal node. This occurs 4 times (for each terminal node preceeded by a call/check action). Therefore, we should only do it once and pass it in as an argument.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.