Skip to content

Commit

Permalink
Merge pull request #406 from Kyle-Sang/Texas-Holdem-Pygame
Browse files Browse the repository at this point in the history
  • Loading branch information
jkterry1 committed Jul 11, 2021
2 parents d12250d + de44bde commit 07e96c6
Show file tree
Hide file tree
Showing 66 changed files with 260 additions and 18 deletions.
Binary file added pettingzoo/classic/rlcard_envs/font/Minecraft.ttf
Binary file not shown.
Binary file added pettingzoo/classic/rlcard_envs/img/C2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/C3.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/C4.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/C5.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/C6.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/C7.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/C8.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/C9.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/CA.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/CJ.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/CK.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/CQ.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/CT.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/Card.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/ChipBlack.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/ChipBlue.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/ChipGreen.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/ChipOrange.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/ChipPink.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/ChipRed.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/ChipWhite.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/ChipYellow.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/D2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/D3.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pettingzoo/classic/rlcard_envs/img/D4.png
Binary file added pettingzoo/classic/rlcard_envs/img/D5.png
Binary file added pettingzoo/classic/rlcard_envs/img/D6.png
Binary file added pettingzoo/classic/rlcard_envs/img/D7.png
Binary file added pettingzoo/classic/rlcard_envs/img/D8.png
Binary file added pettingzoo/classic/rlcard_envs/img/D9.png
Binary file added pettingzoo/classic/rlcard_envs/img/DA.png
Binary file added pettingzoo/classic/rlcard_envs/img/DJ.png
Binary file added pettingzoo/classic/rlcard_envs/img/DK.png
Binary file added pettingzoo/classic/rlcard_envs/img/DQ.png
Binary file added pettingzoo/classic/rlcard_envs/img/DT.png
Binary file added pettingzoo/classic/rlcard_envs/img/H2.png
Binary file added pettingzoo/classic/rlcard_envs/img/H3.png
Binary file added pettingzoo/classic/rlcard_envs/img/H4.png
Binary file added pettingzoo/classic/rlcard_envs/img/H5.png
Binary file added pettingzoo/classic/rlcard_envs/img/H6.png
Binary file added pettingzoo/classic/rlcard_envs/img/H7.png
Binary file added pettingzoo/classic/rlcard_envs/img/H8.png
Binary file added pettingzoo/classic/rlcard_envs/img/H9.png
Binary file added pettingzoo/classic/rlcard_envs/img/HA.png
Binary file added pettingzoo/classic/rlcard_envs/img/HJ.png
Binary file added pettingzoo/classic/rlcard_envs/img/HK.png
Binary file added pettingzoo/classic/rlcard_envs/img/HQ.png
Binary file added pettingzoo/classic/rlcard_envs/img/HT.png
Binary file added pettingzoo/classic/rlcard_envs/img/S2.png
Binary file added pettingzoo/classic/rlcard_envs/img/S3.png
Binary file added pettingzoo/classic/rlcard_envs/img/S4.png
Binary file added pettingzoo/classic/rlcard_envs/img/S5.png
Binary file added pettingzoo/classic/rlcard_envs/img/S6.png
Binary file added pettingzoo/classic/rlcard_envs/img/S7.png
Binary file added pettingzoo/classic/rlcard_envs/img/S8.png
Binary file added pettingzoo/classic/rlcard_envs/img/S9.png
Binary file added pettingzoo/classic/rlcard_envs/img/SA.png
Binary file added pettingzoo/classic/rlcard_envs/img/SJ.png
Binary file added pettingzoo/classic/rlcard_envs/img/SK.png
Binary file added pettingzoo/classic/rlcard_envs/img/SQ.png
Binary file added pettingzoo/classic/rlcard_envs/img/ST.png
1 change: 1 addition & 0 deletions pettingzoo/classic/rlcard_envs/rlcard_base.py
Expand Up @@ -14,6 +14,7 @@ def __init__(self, name, num_players, obs_shape):
super().__init__()
self.name = name
self.env = rlcard.make(name)
self.screen = None
if not hasattr(self, "agents"):
self.agents = [f'player_{i}' for i in range(num_players)]
self.possible_agents = self.agents[:]
Expand Down
139 changes: 130 additions & 9 deletions pettingzoo/classic/rlcard_envs/texas_holdem.py
@@ -1,17 +1,33 @@
from numpy.lib.shape_base import tile
from pettingzoo import AECEnv
from pettingzoo.utils.agent_selector import agent_selector
from gym import spaces
import rlcard
import random
import pygame
from rlcard.utils.utils import print_card
import numpy as np
from pettingzoo.utils import wrappers
from .rlcard_base import RLCardBase
import os


def get_image(path):
from os import path as os_path
cwd = os_path.dirname(__file__)
image = pygame.image.load(cwd + '/' + path)
return image


def get_font(path, size):
from os import path as os_path
cwd = os_path.dirname(__file__)
font = pygame.font.Font((cwd + '/' + path), size)
return font


def env(**kwargs):
env = raw_env(**kwargs)
env = wrappers.CaptureStdoutWrapper(env)
env = wrappers.TerminateIllegalWrapper(env, illegal_reward=-1)
env = wrappers.AssertOutOfBoundsWrapper(env)
env = wrappers.OrderEnforcingWrapper(env)
Expand All @@ -20,17 +36,122 @@ def env(**kwargs):

class raw_env(RLCardBase):

metadata = {'render.modes': ['human'], "name": "texas_holdem_v3"}
metadata = {'render.modes': ['human', 'rgb_array'], "name": "texas_holdem_v3"}

def __init__(self):
super().__init__("limit-holdem", 2, (72,))

def render(self, mode='human'):
for player in self.possible_agents:

def calculate_width(self, screen_width, i):
return int(((((screen_width / ((np.ceil(len(self.possible_agents) / 2) + 1)) * np.ceil((i + 1) / 2))))) + (tile_size * 31 / 616))

def calculate_offset(hand, j, tile_size):
return int((len(hand) * (tile_size * 23 / 56)) - ((j) * (tile_size * 23 / 28)))

def calculate_height(screen_height, divisor, multiplier, tile_size, offset):
return int(multiplier * screen_height / divisor + tile_size * offset)

screen_height = 1000
screen_width = int(screen_height * (1 / 20) + np.ceil(len(self.possible_agents) / 2) * (screen_height * 1 / 2))

if self.screen is None:
if mode == "human":
pygame.init()
self.screen = pygame.display.set_mode((screen_width, screen_height))
else:
pygame.font.init()
self.screen = pygame.Surface((screen_width, screen_height))
if mode == "human":
pygame.event.get()

# Setup dimensions for card size and setup for colors
tile_size = screen_height * 2 / 10

bg_color = (7, 99, 36)
white = (255, 255, 255)
self.screen.fill(bg_color)

chips = {0: {'value': 10000, 'img': 'ChipOrange.png', 'number': 0},
1: {'value': 5000, 'img': 'ChipPink.png', 'number': 0},
2: {'value': 1000, 'img': 'ChipYellow.png', 'number': 0},
3: {'value': 100, 'img': 'ChipBlack.png', 'number': 0},
4: {'value': 50, 'img': 'ChipBlue.png', 'number': 0},
5: {'value': 25, 'img': 'ChipGreen.png', 'number': 0},
6: {'value': 10, 'img': 'ChipLightBlue.png', 'number': 0},
7: {'value': 5, 'img': 'ChipRed.png', 'number': 0},
8: {'value': 1, 'img': 'ChipWhite.png', 'number': 0}}

# Load and blit all images for each card in each player's hand
for i, player in enumerate(self.possible_agents):
state = self.env.game.get_state(self._name_to_int(player))
print("\n=============== {}'s Hand ===============".format(player))
print_card(state['hand'])
print("\n{}'s Chips: {}".format(player, state['my_chips']))
print('\n================= Public Cards =================')
print_card(state['public_cards']) if state['public_cards'] else print('No public cards.')
print('\n')
for j, card in enumerate(state['hand']):
# Load specified card
card_img = get_image(os.path.join('img', card + '.png'))
card_img = pygame.transform.scale(card_img, (int(tile_size * (142 / 197)), int(tile_size)))
# Players with even id go above public cards
if i % 2 == 0:
self.screen.blit(card_img, ((calculate_width(self, screen_width, i) - calculate_offset(state['hand'], j, tile_size)), calculate_height(screen_height, 4, 1, tile_size, -1)))
# Players with odd id go below public cards
else:
self.screen.blit(card_img, ((calculate_width(self, screen_width, i) - calculate_offset(state['hand'], j, tile_size)), calculate_height(screen_height, 4, 3, tile_size, 0)))

# Load and blit text for player name
font = get_font(os.path.join('font', 'Minecraft.ttf'), 36)
text = font.render("Player " + str(i + 1), True, white)
textRect = text.get_rect()
if i % 2 == 0:
textRect.center = (((((screen_width / ((np.ceil(len(self.possible_agents) / 2) + 1)) * np.ceil((i + 1) / 2))))), calculate_height(screen_height, 4, 1, tile_size, -(22 / 20)))
else:
textRect.center = (((((screen_width / ((np.ceil(len(self.possible_agents) / 2) + 1)) * np.ceil((i + 1) / 2))))), calculate_height(screen_height, 4, 3, tile_size, (23 / 20)))
self.screen.blit(text, textRect)

# Load and blit number of poker chips for each player
font = get_font(os.path.join('font', 'Minecraft.ttf'), 24)
text = font.render(str(state['my_chips']), True, white)
textRect = text.get_rect()

# Calculate number of each chip
total = (state['my_chips'])
height = 0
for key in chips:
num = total / chips[key]['value']
chips[key]['number'] = int(num)
total %= chips[key]['value']

chip_img = get_image(os.path.join('img', chips[key]['img']))
chip_img = pygame.transform.scale(chip_img, (int(tile_size / 2), int(tile_size * 16 / 45)))

# Blit poker chip img
for j in range(0, int(chips[key]['number'])):
if i % 2 == 0:
self.screen.blit(chip_img, ((calculate_width(self, screen_width, i) + tile_size * (8 / 10)), calculate_height(screen_height, 4, 1, tile_size, -1 / 2) - ((j + height) * tile_size / 15)))
else:
self.screen.blit(chip_img, ((calculate_width(self, screen_width, i) + tile_size * (8 / 10)), calculate_height(screen_height, 4, 3, tile_size, 1 / 2) - ((j + height) * tile_size / 15)))
height += chips[key]['number']

# Blit text number
if i % 2 == 0:
textRect.center = ((calculate_width(self, screen_width, i) + tile_size * (21 / 20)), calculate_height(screen_height, 4, 1, tile_size, -1 / 2) - ((height + 1) * tile_size / 15))
else:
textRect.center = ((calculate_width(self, screen_width, i) + tile_size * (21 / 20)), calculate_height(screen_height, 4, 3, tile_size, 1 / 2) - ((height + 1) * tile_size / 15))
self.screen.blit(text, textRect)

# Load and blit public cards
for i, card in enumerate(state['public_cards']):
card_img = get_image(os.path.join('img', card + '.png'))
card_img = pygame.transform.scale(card_img, (int(tile_size * (142 / 197)), int(tile_size)))
if len(state['public_cards']) <= 3:
self.screen.blit(card_img, (((((screen_width / 2) + (tile_size * 31 / 616)) - calculate_offset(state['public_cards'], i, tile_size)), calculate_height(screen_height, 2, 1, tile_size, -(1 / 2)))))
else:
if i <= 2:
self.screen.blit(card_img, (((((screen_width / 2) + (tile_size * 31 / 616)) - calculate_offset(state['public_cards'][:3], i, tile_size)), calculate_height(screen_height, 2, 1, tile_size, -21 / 20))))
else:
self.screen.blit(card_img, (((((screen_width / 2) + (tile_size * 31 / 616)) - calculate_offset(state['public_cards'][3:], i - 3, tile_size)), calculate_height(screen_height, 2, 1, tile_size, 1 / 20))))

if mode == "human":
pygame.display.update()

observation = np.array(pygame.surfarray.pixels3d(self.screen))

return np.transpose(observation, axes=(1, 0, 2)) if mode == "rgb_array" else None
138 changes: 129 additions & 9 deletions pettingzoo/classic/rlcard_envs/texas_holdem_no_limit.py
Expand Up @@ -3,15 +3,30 @@
from gym import spaces
import rlcard
import random
import pygame
import os
from rlcard.utils.utils import print_card
import numpy as np
from pettingzoo.utils import wrappers
from .rlcard_base import RLCardBase


def get_image(path):
from os import path as os_path
cwd = os_path.dirname(__file__)
image = pygame.image.load(cwd + '/' + path)
return image


def get_font(path, size):
from os import path as os_path
cwd = os_path.dirname(__file__)
font = pygame.font.Font((cwd + '/' + path), size)
return font


def env(**kwargs):
env = raw_env(**kwargs)
env = wrappers.CaptureStdoutWrapper(env)
env = wrappers.TerminateIllegalWrapper(env, illegal_reward=-1)
env = wrappers.AssertOutOfBoundsWrapper(env)
env = wrappers.OrderEnforcingWrapper(env)
Expand All @@ -20,7 +35,7 @@ def env(**kwargs):

class raw_env(RLCardBase):

metadata = {'render.modes': ['human'], "name": "texas_holdem_no_limit_v3"}
metadata = {'render.modes': ['human', 'rgb_array'], "name": "texas_holdem_no_limit_v3"}

def __init__(self):
super().__init__("no-limit-holdem", 2, (54,))
Expand All @@ -29,11 +44,116 @@ def __init__(self):
'action_mask': spaces.Box(low=0, high=1, shape=(6,), dtype=np.int8)}) for _ in range(self.num_agents)])

def render(self, mode='human'):
for player in self.possible_agents:

def calculate_width(self, screen_width, i):
return int(((((screen_width / ((np.ceil(len(self.possible_agents) / 2) + 1)) * np.ceil((i + 1) / 2))))) + (tile_size * 31 / 616))

def calculate_offset(hand, j, tile_size):
return int((len(hand) * (tile_size * 23 / 56)) - ((j) * (tile_size * 23 / 28)))

def calculate_height(screen_height, divisor, multiplier, tile_size, offset):
return int(multiplier * screen_height / divisor + tile_size * offset)

screen_height = 1000
screen_width = int(screen_height * (1 / 20) + np.ceil(len(self.possible_agents) / 2) * (screen_height * 1 / 2))

if self.screen is None:
if mode == "human":
pygame.init()
self.screen = pygame.display.set_mode((screen_width, screen_height))
else:
pygame.font.init()
self.screen = pygame.Surface((screen_width, screen_height))
if mode == "human":
pygame.event.get()

# Setup dimensions for card size and setup for colors
tile_size = screen_height * 2 / 10

bg_color = (7, 99, 36)
white = (255, 255, 255)
self.screen.fill(bg_color)

chips = {0: {'value': 10000, 'img': 'ChipOrange.png', 'number': 0},
1: {'value': 5000, 'img': 'ChipPink.png', 'number': 0},
2: {'value': 1000, 'img': 'ChipYellow.png', 'number': 0},
3: {'value': 100, 'img': 'ChipBlack.png', 'number': 0},
4: {'value': 50, 'img': 'ChipBlue.png', 'number': 0},
5: {'value': 25, 'img': 'ChipGreen.png', 'number': 0},
6: {'value': 10, 'img': 'ChipLightBlue.png', 'number': 0},
7: {'value': 5, 'img': 'ChipRed.png', 'number': 0},
8: {'value': 1, 'img': 'ChipWhite.png', 'number': 0}}

# Load and blit all images for each card in each player's hand
for i, player in enumerate(self.possible_agents):
state = self.env.game.get_state(self._name_to_int(player))
print("\n=============== {}'s Hand ===============".format(player))
print_card(state['hand'])
print("\n{}'s Chips: {}".format(player, state['my_chips']))
print('\n================= Public Cards =================')
print_card(state['public_cards']) if state['public_cards'] else print('No public cards.')
print('\n')
for j, card in enumerate(state['hand']):
# Load specified card
card_img = get_image(os.path.join('img', card + '.png'))
card_img = pygame.transform.scale(card_img, (int(tile_size * (142 / 197)), int(tile_size)))
# Players with even id go above public cards
if i % 2 == 0:
self.screen.blit(card_img, ((calculate_width(self, screen_width, i) - calculate_offset(state['hand'], j, tile_size)), calculate_height(screen_height, 4, 1, tile_size, -1)))
# Players with odd id go below public cards
else:
self.screen.blit(card_img, ((calculate_width(self, screen_width, i) - calculate_offset(state['hand'], j, tile_size)), calculate_height(screen_height, 4, 3, tile_size, 0)))

# Load and blit text for player name
font = get_font(os.path.join('font', 'Minecraft.ttf'), 36)
text = font.render("Player " + str(i + 1), True, white)
textRect = text.get_rect()
if i % 2 == 0:
textRect.center = (((((screen_width / ((np.ceil(len(self.possible_agents) / 2) + 1)) * np.ceil((i + 1) / 2))))), calculate_height(screen_height, 4, 1, tile_size, -(22 / 20)))
else:
textRect.center = (((((screen_width / ((np.ceil(len(self.possible_agents) / 2) + 1)) * np.ceil((i + 1) / 2))))), calculate_height(screen_height, 4, 3, tile_size, (23 / 20)))
self.screen.blit(text, textRect)

# Load and blit number of poker chips for each player
font = get_font(os.path.join('font', 'Minecraft.ttf'), 24)
text = font.render(str(state['my_chips']), True, white)
textRect = text.get_rect()

# Calculate number of each chip
total = (state['my_chips'])
height = 0
for key in chips:
num = total / chips[key]['value']
chips[key]['number'] = int(num)
total %= chips[key]['value']

chip_img = get_image(os.path.join('img', chips[key]['img']))
chip_img = pygame.transform.scale(chip_img, (int(tile_size / 2), int(tile_size * 16 / 45)))

# Blit poker chip img
for j in range(0, int(chips[key]['number'])):
if i % 2 == 0:
self.screen.blit(chip_img, ((calculate_width(self, screen_width, i) + tile_size * (8 / 10)), calculate_height(screen_height, 4, 1, tile_size, -1 / 2) - ((j + height) * tile_size / 15)))
else:
self.screen.blit(chip_img, ((calculate_width(self, screen_width, i) + tile_size * (8 / 10)), calculate_height(screen_height, 4, 3, tile_size, 1 / 2) - ((j + height) * tile_size / 15)))
height += chips[key]['number']

# Blit text number
if i % 2 == 0:
textRect.center = ((calculate_width(self, screen_width, i) + tile_size * (21 / 20)), calculate_height(screen_height, 4, 1, tile_size, -1 / 2) - ((height + 1) * tile_size / 15))
else:
textRect.center = ((calculate_width(self, screen_width, i) + tile_size * (21 / 20)), calculate_height(screen_height, 4, 3, tile_size, 1 / 2) - ((height + 1) * tile_size / 15))
self.screen.blit(text, textRect)

# Load and blit public cards
for i, card in enumerate(state['public_cards']):
card_img = get_image(os.path.join('img', card + '.png'))
card_img = pygame.transform.scale(card_img, (int(tile_size * (142 / 197)), int(tile_size)))
if len(state['public_cards']) <= 3:
self.screen.blit(card_img, (((((screen_width / 2) + (tile_size * 31 / 616)) - calculate_offset(state['public_cards'], i, tile_size)), calculate_height(screen_height, 2, 1, tile_size, -(1 / 2)))))
else:
if i <= 2:
self.screen.blit(card_img, (((((screen_width / 2) + (tile_size * 31 / 616)) - calculate_offset(state['public_cards'][:3], i, tile_size)), calculate_height(screen_height, 2, 1, tile_size, -21 / 20))))
else:
self.screen.blit(card_img, (((((screen_width / 2) + (tile_size * 31 / 616)) - calculate_offset(state['public_cards'][3:], i - 3, tile_size)), calculate_height(screen_height, 2, 1, tile_size, 1 / 20))))

if mode == "human":
pygame.display.update()

observation = np.array(pygame.surfarray.pixels3d(self.screen))

return np.transpose(observation, axes=(1, 0, 2)) if mode == "rgb_array" else None

0 comments on commit 07e96c6

Please sign in to comment.