Skip to content

Commit

Permalink
Add first trick cannot play score card limitation and heart broken ch…
Browse files Browse the repository at this point in the history
…ecking
  • Loading branch information
hisarack committed Sep 8, 2018
1 parent 3d71c5c commit 5efc701
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 10 deletions.
50 changes: 40 additions & 10 deletions gymhearts/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

class HeartsEnv(gym.Env):

CLUB_TWO = Card.new('2c')

def __init__(self, endgame_score=100):
self._evaluator = Evaluator()
self._number_of_players = 0
Expand All @@ -22,10 +24,33 @@ def __init__(self, endgame_score=100):
self._endgame_score = endgame_score
self._current_observation = {}
self._shooting_the_moon_enabled = False
self._is_heart_broken = False

def enable_shooting_the_moon(self):
self._shooting_the_moon_enabled = True


def _filter_valid_hand_cards(self, hand_cards):
if len(self._playing_cards) == 0:
if self._trick == 0:
if HeartsEnv.CLUB_TWO not in hand_cards:
raise Exception("oops, first player does not have club two")
valid_hand_cards = [HeartsEnv.CLUB_TWO]
elif self._is_heart_broken is True:
valid_hand_cards = hand_cards
else:
valid_hand_cards = [card for card in hand_cards if Card.get_suit_int(card) != Card.CHAR_SUIT_TO_INT_SUIT['h']]
else:
trick_suit = Card.get_suit_int(self._playing_cards[0])
valid_hand_cards = [card for card in hand_cards if Card.get_suit_int(card) == trick_suit]
if len(valid_hand_cards) == 0:
valid_hand_cards = hand_cards
if self._trick == 0:
valid_hand_cards = [card for card in valid_hand_cards if Card.get_suit_int(card) != Card.CHAR_SUIT_TO_INT_SUIT['h']]
if (self._trick == 0) and (Evaluator.SPADES_QUEEN in valid_hand_cards):
valid_hand_cards.remove(Evaluator.SPADES_QUEEN)
return valid_hand_cards

def get_observation(self):
ob = {}
ob['trick'] = self._trick
Expand All @@ -36,13 +61,7 @@ def get_observation(self):
ob['playing_ids'] = self._playing_ids.copy()
ob['hand_cards'] = self._players[self._current_player_id].get_hand_cards()
ob['current_player_id'] = self._current_player_id
if len(self._playing_cards) == 0:
ob['valid_hand_cards'] = ob['hand_cards']
else:
trick_suit = Card.get_suit_int(self._playing_cards[0])
ob['valid_hand_cards'] = [card for card in ob['hand_cards'] if Card.get_suit_int(card) == trick_suit]
if len(ob['valid_hand_cards']) == 0:
ob['valid_hand_cards'] = ob['hand_cards']
ob['valid_hand_cards'] = self._filter_valid_hand_cards(ob['hand_cards'])
ob['number_of_hand_cards_for_all_players'] = [len(player.get_hand_cards()) for player in self._players]
return ob

Expand Down Expand Up @@ -113,6 +132,8 @@ def step(self, action_card):
player.commit_new_round_score()
observation = self.get_observation()
self._current_observation = observation
if self._is_heart_broken is False and Card.get_suit_int(action_card) == Card.CHAR_SUIT_TO_INT_SUIT['h']:
self._is_heart_broken = True
self._players_watch(info)
return observation, rewards, done, info

Expand All @@ -129,13 +150,20 @@ def move(self):
def _start_new_round(self):
deck = Deck()
deck.shuffle()
for player in self._players:
player.reset_hand_cards(deck.draw(self._number_of_hand_card_per_player))
club_two_player_id = -1
for player_id, player in enumerate(self._players):
hand_cards = deck.draw(self._number_of_hand_card_per_player)
player.reset_hand_cards(hand_cards)
if HeartsEnv.CLUB_TWO in hand_cards:
club_two_player_id = player_id
if club_two_player_id == -1:
raise Exception("oops, it cannot find a player has club two")
self._trick = 0
self._playing_cards = []
self._playing_ids = []
self._current_player_id = 0
self._current_player_id = club_two_player_id
self._round += 1
self._is_heart_broken = False
self._current_observation = self.get_observation()

def reset(self):
Expand All @@ -148,11 +176,13 @@ def reset(self):
self._playing_ids = []
self._current_player_id = 0
self._round = 0
self._is_heart_broken = False

def render(self):
print("--------GAME-------")
print("round: {}".format(self._round))
print("trick: {}".format(self._trick))
print("heart broken: {}".format(self._is_heart_broken))
print("-------PLAYER------")
for i in range(self._number_of_players):
print("player {}".format(i))
Expand Down
11 changes: 11 additions & 0 deletions gymhearts/evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ def shooting_the_moon(self, players):
if player_id != max_score_player_id:
p.add_score(26)

def filter_score_cards(hand_cards, keep_spade_queen=False):
valid_hand_cards = []
for card in hand_cards:
if Card.get_suit_int(card) == Card.CHAR_SUIT_TO_INT_SUIT['h']:
pass
elif keep_spade_queen is False and Card.get_suit_int(card) == Evaluator.SPADES_QUEEN:
pass
else:
valid_hand_cards.append(card)
return valid_hand_cards

def evaluate(self, cards, ids):
return self.calculate_score(cards), self.identify_looser(cards, ids)

2 changes: 2 additions & 0 deletions release.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
rm -rf ./dist/
rm -rf ./gym_hearts.egg-info/
python3 setup.py sdist --formats=zip
python3 setup.py sdist --formats=zip upload

0 comments on commit 5efc701

Please sign in to comment.