From ee327cbc95d81f15f6698202268b349c8e2c7bbf Mon Sep 17 00:00:00 2001 From: Daochen Zha Date: Wed, 23 Mar 2022 23:14:39 -0500 Subject: [PATCH 1/6] update readme --- README.md | 1 + README.zh-CN.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index b952019d3..c9f76d686 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ RLCard is a toolkit for Reinforcement Learning (RL) in card games. It supports m * Group 2: 117349516 **News:** +* We have updated the tutorials in Jupyter Notebook to help you walk through RLCard! Please check [RLCard Tutorial](https://github.com/datamllab/rlcard-tutorial). * All the algorithms can suppport [PettingZoo](https://github.com/PettingZoo-Team/PettingZoo) now. Please check [here](examples/pettingzoo). Thanks the contribtuion from [Yifei Cheng](https://github.com/ycheng517). * Please follow [DouZero](https://github.com/kwai/DouZero), a strong Dou Dizhu AI and the [ICML 2021 paper](https://arxiv.org/abs/2106.06135). An online demo is available [here](https://douzero.org/). The algorithm is also integrated in RLCard. See [Training DMC on Dou Dizhu](docs/toy-examples.md#training-dmc-on-dou-dizhu). * Our package is used in [PettingZoo](https://github.com/PettingZoo-Team/PettingZoo). Please check it out! diff --git a/README.zh-CN.md b/README.zh-CN.md index 14f572981..171530216 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -27,6 +27,7 @@ RLCard是一款卡牌游戏强化学习 (Reinforcement Learning, RL) 的工具 * 二群:117349516 **新闻:** +* 我们更新Jupyter Notebook的教程帮助您快速了解RLCard!请看 [RLCard 教程](https://github.com/datamllab/rlcard-tutorial). * 所有的算法都已支持[PettingZoo](https://github.com/PettingZoo-Team/PettingZoo)接口. 请点击[这里](examples/pettingzoo). 感谢[Yifei Cheng](https://github.com/ycheng517)的贡献。 * 请关注[DouZero](https://github.com/kwai/DouZero), 一个强大的斗地主AI,以及[ICML 2021论文](https://arxiv.org/abs/2106.06135)。点击[此处](https://douzero.org/)进入在线演示。该算法同样集成到了RLCard中,详见[在斗地主中训练DMC](docs/toy-examples.md#training-dmc-on-dou-dizhu)。 * 我们的项目被用在[PettingZoo](https://github.com/PettingZoo-Team/PettingZoo)中,去看看吧! From 52b893c4098c5ba6dde6367010d8bd8a7643b764 Mon Sep 17 00:00:00 2001 From: szd <549845545@qq.com> Date: Wed, 25 May 2022 17:43:40 +0800 Subject: [PATCH 2/6] fix the bug of the Leduc Holdem Env's state representation of opp's chips --- rlcard/envs/leducholdem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rlcard/envs/leducholdem.py b/rlcard/envs/leducholdem.py index 280dee674..da389dd8e 100644 --- a/rlcard/envs/leducholdem.py +++ b/rlcard/envs/leducholdem.py @@ -61,7 +61,7 @@ def _extract_state(self, state): if public_card: obs[self.card2index[public_card]+3] = 1 obs[state['my_chips']+6] = 1 - obs[state['all_chips'][1]+20] = 1 + obs[sum(state['all_chips'])-state['my_chips']+21] = 1 extracted_state['obs'] = obs extracted_state['raw_obs'] = state From b63b5cde929dc2c270beefe00cd1f92da6ab34f9 Mon Sep 17 00:00:00 2001 From: szd <549845545@qq.com> Date: Thu, 26 May 2022 09:25:20 +0800 Subject: [PATCH 3/6] train the cfr agent in the fixed LeducHoldem env --- .../leduc_holdem_cfr/average_policy.pkl | Bin 40912 -> 38615 bytes .../pretrained/leduc_holdem_cfr/iteration.pkl | Bin 6 -> 15 bytes .../pretrained/leduc_holdem_cfr/policy.pkl | Bin 40914 -> 38623 bytes .../pretrained/leduc_holdem_cfr/regrets.pkl | Bin 40912 -> 38615 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/rlcard/models/pretrained/leduc_holdem_cfr/average_policy.pkl b/rlcard/models/pretrained/leduc_holdem_cfr/average_policy.pkl index 3cda26e01dd501f48b4f68114e8a25253281ca27..71236521e3e342ad626b9c91a05290dd0f6c658b 100644 GIT binary patch literal 38615 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 literal 40912 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 diff --git a/rlcard/models/pretrained/leduc_holdem_cfr/iteration.pkl b/rlcard/models/pretrained/leduc_holdem_cfr/iteration.pkl index bb130e6316000946d19328aec14692c0a6b57b19..36717717b9788fb1aad57415b3070724970c4269 100644 GIT binary patch literal 15 ScmZo*naaWd0lse!=>Y&0H3LWh literal 6 NcmZo*_Fb!{2LJ}j0nz{f diff --git a/rlcard/models/pretrained/leduc_holdem_cfr/policy.pkl b/rlcard/models/pretrained/leduc_holdem_cfr/policy.pkl index 2e48cb34a3c52d5a70348348cde2ef2f73ba81a3..daedbc2c4763c9faed773740ec2984b14fa15cb1 100644 GIT binary patch literal 38623 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 QFaH0)X{f3Z`1f!5FDe7-rvLx| diff --git a/rlcard/models/pretrained/leduc_holdem_cfr/regrets.pkl b/rlcard/models/pretrained/leduc_holdem_cfr/regrets.pkl index 8341caaf4b04c1bb5380a253b933a7237aa99a8a..8d4a6489eb90c56f2b745a575811f4c2d2a14243 100644 GIT binary patch literal 38615 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 From 65d669b3b12b39b18b71e2aaf54c38cd3f5004bb Mon Sep 17 00:00:00 2001 From: Daochen Zha Date: Wed, 22 Jun 2022 22:09:12 -0700 Subject: [PATCH 4/6] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c9f76d686..630dc22f7 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ RLCard is a toolkit for Reinforcement Learning (RL) in card games. It supports m * Dou Dizhu Demo: [Demo](https://douzero.org/) * Resources: [Awesome-Game-AI](https://github.com/datamllab/awesome-game-ai) * Related Project: [DouZero Project](https://github.com/kwai/DouZero) +* Zhihu: https://zhuanlan.zhihu.com/p/526723604 **Community:** * **Slack**: Discuss in our [#rlcard-project](https://join.slack.com/t/rlcard/shared_invite/zt-rkvktsaq-xkMwz8BfKupCM6zGhO01xg) slack channel. From 8e3f6b7bc59808d30563fe7e39de2384f5f441eb Mon Sep 17 00:00:00 2001 From: Daochen Zha Date: Wed, 22 Jun 2022 22:10:06 -0700 Subject: [PATCH 5/6] Update README.zh-CN.md --- README.zh-CN.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.zh-CN.md b/README.zh-CN.md index 171530216..b21a4c28e 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -19,6 +19,7 @@ RLCard是一款卡牌游戏强化学习 (Reinforcement Learning, RL) 的工具 * 斗地主演示:[Demo](https://douzero.org/) * 资源:[Awesome-Game-AI](https://github.com/datamllab/awesome-game-ai) * 相关项目:[DouZero项目](https://github.com/kwai/DouZero) +* 知乎:[https://zhuanlan.zhihu.com/p/526723604](https://zhuanlan.zhihu.com/p/526723604) **社区:** * **Slack**: 在我们的[#rlcard-project](https://join.slack.com/t/rlcard/shared_invite/zt-rkvktsaq-xkMwz8BfKupCM6zGhO01xg) slack频道参与讨论. From 1bf316953fa33d49b44d0c7920ce84313583a73a Mon Sep 17 00:00:00 2001 From: zesong Date: Mon, 25 Jul 2022 11:35:06 +0800 Subject: [PATCH 6/6] support bet with any amt and min raise is double --- examples/human/nolimit_holdem_human.py | 63 ++++++++-------- examples/run_rl.py | 2 +- .../nolimit_holdem_human_agent.py | 13 +++- rlcard/envs/env.py | 2 + rlcard/envs/nolimitholdem.py | 5 +- rlcard/games/nolimitholdem/game.py | 7 +- rlcard/games/nolimitholdem/round.py | 73 +++++++++++-------- 7 files changed, 96 insertions(+), 69 deletions(-) diff --git a/examples/human/nolimit_holdem_human.py b/examples/human/nolimit_holdem_human.py index 76f29da11..0afd2c213 100644 --- a/examples/human/nolimit_holdem_human.py +++ b/examples/human/nolimit_holdem_human.py @@ -6,46 +6,49 @@ from rlcard import models from rlcard.agents import NolimitholdemHumanAgent as HumanAgent from rlcard.utils import print_card - # Make environment env = rlcard.make('no-limit-holdem') human_agent = HumanAgent(env.num_actions) human_agent2 = HumanAgent(env.num_actions) +human_agent3 = HumanAgent(env.num_actions) +human_agent4 = HumanAgent(env.num_actions) # random_agent = RandomAgent(num_actions=env.num_actions) -env.set_agents([human_agent, human_agent2]) +env.set_agents([human_agent, human_agent2, human_agent3, human_agent4]) while (True): print(">> Start a new game") - - trajectories, payoffs = env.run(is_training=False) - # If the human does not take the final action, we need to - # print other players action - final_state = trajectories[0][-1] - action_record = final_state['action_record'] - state = final_state['raw_obs'] - _action_list = [] - for i in range(1, len(action_record)+1): - if action_record[-i][0] == state['current_player']: - break - _action_list.insert(0, action_record[-i]) - for pair in _action_list: - print('>> Player', pair[0], 'chooses', pair[1]) - - # Let's take a look at what the agent card is - print('=============== Cards all Players ===============') - for hands in env.get_perfect_information()['hand_cards']: - print_card(hands) - - print('=============== Result ===============') - if payoffs[0] > 0: - print('You win {} chips!'.format(payoffs[0])) - elif payoffs[0] == 0: - print('It is a tie.') - else: - print('You lose {} chips!'.format(-payoffs[0])) - print('') + while(True): + trajectories, payoffs = env.run(is_training=False) + # If the human does not take the final action, we need to + # print other players action + final_state = trajectories[0][-1] + action_record = final_state['action_record'] + state = final_state['raw_obs'] + _action_list = [] + for i in range(1, len(action_record)+1): + if action_record[-i][0] == state['current_player']: + break + _action_list.insert(0, action_record[-i]) + for pair in _action_list: + print('>> Player', pair[0], 'chooses', pair[1]) + + # Let's take a look at what the agent card is + print('=============== Cards all Players ===============') + for hands in env.get_perfect_information()['hand_cards']: + print_card(hands) + + print('=============== Result ===============') + print(payoffs) + # if payoffs[0] > 0: + # print('You win {} chips!'.format(payoffs[0])) + # elif payoffs[0] == 0: + # print('It is a tie.') + # else: + # print('You lose {} chips!'.format(-payoffs[0])) + # print('') + break input("Press any key to continue...") diff --git a/examples/run_rl.py b/examples/run_rl.py index 6bef00d2a..f4ad6a03d 100644 --- a/examples/run_rl.py +++ b/examples/run_rl.py @@ -125,7 +125,7 @@ def train(args): parser.add_argument( '--cuda', type=str, - default='', + default='0', ) parser.add_argument( '--seed', diff --git a/rlcard/agents/human_agents/nolimit_holdem_human_agent.py b/rlcard/agents/human_agents/nolimit_holdem_human_agent.py index 1d001b3f8..e0b982183 100644 --- a/rlcard/agents/human_agents/nolimit_holdem_human_agent.py +++ b/rlcard/agents/human_agents/nolimit_holdem_human_agent.py @@ -1,5 +1,5 @@ from rlcard.utils.utils import print_card - +from rlcard.games.nolimitholdem.round import Action class HumanAgent(object): ''' A human agent for No Limit Holdem. It can be used to play against trained models @@ -26,10 +26,16 @@ def step(state): ''' _print_state(state['raw_obs'], state['action_record']) action = int(input('>> You choose action (integer): ')) - while action < 0 or action >= len(state['legal_actions']): + amt = 0 + if state['raw_legal_actions'][action] == Action.RAISE: + amt = int(input('>> Choose your raise amount: ')) + while action < 0 or action >= len(state['legal_actions']) or\ + (state['raw_legal_actions'][action] == Action.RAISE and amt < state['last_raise'] * 2): print('Action illegel...') action = int(input('>> Re-choose action (integer): ')) - return state['raw_legal_actions'][action] + if state['raw_legal_actions'][action] == Action.RAISE: + amt = int(input('>> Choose your raise amount: ')) + return state['raw_legal_actions'][action], amt def eval_step(self, state): ''' Predict the action given the curent state for evaluation. The same to step here. @@ -70,4 +76,3 @@ def _print_state(state, action_record): print('\n=========== Actions You Can Choose ===========') print(', '.join([str(index) + ': ' + str(action) for index, action in enumerate(state['legal_actions'])])) print('') - print(state) diff --git a/rlcard/envs/env.py b/rlcard/envs/env.py index 93e239548..f736efc4b 100644 --- a/rlcard/envs/env.py +++ b/rlcard/envs/env.py @@ -163,6 +163,8 @@ def run(self, is_training=False): state = self.get_state(player_id) trajectories[player_id].append(state) + print(trajectories[0]) + # Payoffs payoffs = self.get_payoffs() diff --git a/rlcard/envs/nolimitholdem.py b/rlcard/envs/nolimitholdem.py index e7522cb44..811a941b5 100644 --- a/rlcard/envs/nolimitholdem.py +++ b/rlcard/envs/nolimitholdem.py @@ -9,7 +9,7 @@ from rlcard.games.nolimitholdem.round import Action DEFAULT_GAME_CONFIG = { - 'game_num_players': 2, + 'game_num_players': 4, 'chips_for_each': 100, 'dealer_id': None, } @@ -69,10 +69,10 @@ def _extract_state(self, state): obs[52] = float(my_chips) obs[53] = float(max(all_chips)) extracted_state['obs'] = obs - extracted_state['raw_obs'] = state extracted_state['raw_legal_actions'] = [a for a in state['legal_actions']] extracted_state['action_record'] = self.action_recorder + extracted_state['last_raise'] = state['last_raise'] return extracted_state @@ -114,6 +114,7 @@ def get_perfect_information(self): state['hand_cards'] = [[c.get_index() for c in self.game.players[i].hand] for i in range(self.num_players)] state['current_player'] = self.game.game_pointer state['legal_actions'] = self.game.get_legal_actions() + state['last_raise'] = self.game.round.last_raise return state diff --git a/rlcard/games/nolimitholdem/game.py b/rlcard/games/nolimitholdem/game.py index 86276fbe0..0df12b2d8 100644 --- a/rlcard/games/nolimitholdem/game.py +++ b/rlcard/games/nolimitholdem/game.py @@ -113,7 +113,7 @@ def get_legal_actions(self): """ return self.round.get_nolimit_legal_actions(players=self.players) - def step(self, action): + def step(self, action_tp): """ Get the next state @@ -126,7 +126,7 @@ def step(self, action): (dict): next player's state (int): next player id """ - + action, amt = action_tp if action not in self.get_legal_actions(): print(action, self.get_legal_actions()) print(self.get_state(self.game_pointer)) @@ -143,7 +143,7 @@ def step(self, action): self.history.append((r, b, r_c, d, p, ps)) # Then we proceed to the next round - self.game_pointer = self.round.proceed_round(self.players, action) + self.game_pointer = self.round.proceed_round(self.players, action_tp) players_in_bypass = [1 if player.status in (PlayerStatus.FOLDED, PlayerStatus.ALLIN) else 0 for player in self.players] if self.num_players - sum(players_in_bypass) == 1: @@ -206,6 +206,7 @@ def get_state(self, player_id): state['current_player'] = self.game_pointer state['pot'] = self.dealer.pot state['stage'] = self.stage + state['last_raise'] = self.round.last_raise return state def step_back(self): diff --git a/rlcard/games/nolimitholdem/round.py b/rlcard/games/nolimitholdem/round.py index 01d4cf875..9b0ff7e83 100644 --- a/rlcard/games/nolimitholdem/round.py +++ b/rlcard/games/nolimitholdem/round.py @@ -8,12 +8,13 @@ class Action(Enum): FOLD = 0 CHECK_CALL = 1 - #CALL = 2 + RAISE = 2 + # CALL = 2 # RAISE_3BB = 3 - RAISE_HALF_POT = 2 - RAISE_POT = 3 - # RAISE_2POT = 5 - ALL_IN = 4 + # RAISE_HALF_POT = 2 + # RAISE_POT = 3 + # # RAISE_2POT = 5 + # ALL_IN = 4 # SMALL_BLIND = 7 # BIG_BLIND = 8 @@ -45,6 +46,7 @@ def __init__(self, num_players, init_raise_amount, dealer, np_random): # Raised amount for each player self.raised = [0 for _ in range(self.num_players)] + self.last_raise = 0 def start_new_round(self, game_pointer, raised=None): """ @@ -58,12 +60,13 @@ def start_new_round(self, game_pointer, raised=None): """ self.game_pointer = game_pointer self.not_raise_num = 0 + self.last_raise = 0 if raised: self.raised = raised else: self.raised = [0 for _ in range(self.num_players)] - def proceed_round(self, players, action): + def proceed_round(self, players, action_tp): """ Call functions from other classes to keep one round running @@ -76,29 +79,38 @@ def proceed_round(self, players, action): """ player = players[self.game_pointer] + action = action_tp[0] if action == Action.CHECK_CALL: diff = max(self.raised) - self.raised[self.game_pointer] self.raised[self.game_pointer] = max(self.raised) player.bet(chips=diff) self.not_raise_num += 1 + + elif action == Action.RAISE: + raise_amt = action_tp[1] + self.last_raise = raise_amt + self.raised[self.game_pointer] += raise_amt + player.bet(chips=raise_amt) + self.not_raise_num = 1 - elif action == Action.ALL_IN: - all_in_quantity = player.remained_chips - self.raised[self.game_pointer] = all_in_quantity + self.raised[self.game_pointer] - player.bet(chips=all_in_quantity) - self.not_raise_num = 1 + # elif action == Action.ALL_IN: + # all_in_quantity = player.remained_chips + # self.raised[self.game_pointer] = all_in_quantity + self.raised[self.game_pointer] + # player.bet(chips=all_in_quantity) - elif action == Action.RAISE_POT: - self.raised[self.game_pointer] += self.dealer.pot - player.bet(chips=self.dealer.pot) - self.not_raise_num = 1 + # self.not_raise_num = 1 - elif action == Action.RAISE_HALF_POT: - quantity = int(self.dealer.pot / 2) - self.raised[self.game_pointer] += quantity - player.bet(chips=quantity) - self.not_raise_num = 1 + # elif action == Action.RAISE_POT: + # self.raised[self.game_pointer] += self.dealer.pot + # player.bet(chips=self.dealer.pot) + # self.not_raise_num = 1 + + # elif action == Action.RAISE_HALF_POT: + # quantity = int(self.dealer.pot / 2) + # self.raised[self.game_pointer] += quantity + # player.bet(chips=quantity) + # self.not_raise_num = 1 elif action == Action.FOLD: player.status = PlayerStatus.FOLDED @@ -142,22 +154,25 @@ def get_nolimit_legal_actions(self, players): diff = max(self.raised) - self.raised[self.game_pointer] # If the current player has no more chips after call, we cannot raise if diff > 0 and diff >= player.remained_chips: - full_actions.remove(Action.RAISE_HALF_POT) - full_actions.remove(Action.RAISE_POT) + # full_actions.remove(Action.RAISE_HALF_POT) + # full_actions.remove(Action.RAISE_POT) full_actions.remove(Action.ALL_IN) + full_actions.remove(Action.RAISE) # Even if we can raise, we have to check remained chips else: - if self.dealer.pot > player.remained_chips: - full_actions.remove(Action.RAISE_POT) + if player.remained_chips < self.last_raise: + full_actions.remove(Action.RAISE) + # if self.dealer.pot > player.remained_chips: + # full_actions.remove(Action.RAISE_POT) - if int(self.dealer.pot / 2) > player.remained_chips: - full_actions.remove(Action.RAISE_HALF_POT) + # if int(self.dealer.pot / 2) > player.remained_chips: + # full_actions.remove(Action.RAISE_HALF_POT) # Can't raise if the total raise amount is leq than the max raise amount of this round # If raise by pot, there is no such concern - if Action.RAISE_HALF_POT in full_actions and \ - int(self.dealer.pot / 2) + self.raised[self.game_pointer] <= max(self.raised): - full_actions.remove(Action.RAISE_HALF_POT) + # if Action.RAISE_HALF_POT in full_actions and \ + # int(self.dealer.pot / 2) + self.raised[self.game_pointer] <= max(self.raised): + # full_actions.remove(Action.RAISE_HALF_POT) return full_actions