Spaces:
Sleeping
Sleeping
| """Briscola environment and players. Contains nn for deep player""" | |
| ### Briscola environment and players | |
| import numpy as np | |
| import pandas as pd | |
| import tensorflow as tf | |
| semi = ['bastoni', 'coppe', 'denari', 'spade'] | |
| numeri = ['2', '3', '4', '5', '6', '7', '8', '9', '0', '1'] | |
| my_points = [ 0, 10, 0, 0, 0, 0, 2, 3, 4, 11] | |
| my_cards = pd.DataFrame({i:[1 for j in numeri] for i in semi}, index = numeri) | |
| my_cards['points'] = my_points | |
| sorted_cards = my_cards.sort_values(by=['points'], ascending=False) | |
| class Briscola_env: | |
| def __init__(self): | |
| self.points_player_1 = 0 #player 1 is the first player at round 1 | |
| self.points_player_2 = 0 | |
| self.cards_in_the_deck = np.array([numero+seme for numero in numeri for seme in semi]) | |
| np.random.shuffle(self.cards_in_the_deck) | |
| self.round = 20 | |
| self.index_top_card = 0 | |
| #choose a briscola | |
| self.briscola = self.cards_in_the_deck[0] #pick a briscola | |
| self.index_top_card = 1 | |
| self.is_briscola_on_the_table = True | |
| def draw_cards(self, number_cards): | |
| """ | |
| Draws number_cards from the deck. | |
| Returns: a list of length number_cards | |
| Updades: self.cards_in_the_deck | |
| """ | |
| if len(self.cards_in_the_deck)- self.index_top_card > 0: | |
| drawn = [ _ for _ in self.cards_in_the_deck[self.index_top_card : self.index_top_card + number_cards]] | |
| self.index_top_card = self.index_top_card + number_cards | |
| return drawn | |
| else: | |
| if self.is_briscola_on_the_table: | |
| self.is_briscola_on_the_table = False | |
| return [self.briscola] | |
| else: | |
| raise ValueError('Tried to draw from an empty deck..') | |
| def start_game(self): | |
| """ | |
| Deals 3 cards for each player | |
| Returns: (first_three_cards, second_three_cards), briscola | |
| Updates: self.cards_in_the_deck by removing the 6 cards sampled | |
| """ | |
| first_three_cards = self.draw_cards(3) | |
| second_three_cards = self.draw_cards(3) | |
| return (first_three_cards, second_three_cards), self.briscola | |
| def which_card_wins_a_round(self, first_played_card, second_played_card, passed_briscola=None): | |
| """ | |
| Determines which card wins a round | |
| Returns: either 'first_played_card' or 'second_played_card' | |
| Updates: nothing | |
| """ | |
| if passed_briscola == None: | |
| briscola = self.briscola[1:] | |
| else: | |
| briscola = passed_briscola[1:] | |
| if first_played_card[1:] == briscola and second_played_card[1:]!= briscola: | |
| return 'first_played_card' | |
| elif first_played_card[1:] != briscola and second_played_card[1:] == briscola: | |
| return 'second_played_card' | |
| elif first_played_card[1:] != second_played_card[1:]: | |
| return 'first_played_card' | |
| else: | |
| if sorted_cards.loc[first_played_card[0], 'points'] > 0 or sorted_cards.loc[second_played_card[0], 'points'] > 0: | |
| return 'first_played_card' if sorted_cards.loc[first_played_card[0], 'points'] > sorted_cards.loc[second_played_card[0], 'points'] else 'second_played_card' | |
| else: | |
| return 'first_played_card' if int(first_played_card[0]) > int(second_played_card[0]) else 'second_played_card' | |
| def pre_step(self, player_1, player_2, epsilon, vs_human=False): | |
| """ | |
| The player who plays second decides his action based on the other player's action | |
| Returns: card_player_1, card_player_2 | |
| Updates: nothing | |
| """ | |
| if player_1.is_first_player: | |
| card_player_1 = player_1.policy(epsilon, None, vs_human) | |
| card_player_2 = player_2.policy(epsilon, card_player_1, vs_human) | |
| else: | |
| card_player_2 = player_2.policy(epsilon, None, vs_human) | |
| card_player_1 = player_1.policy(epsilon, card_player_2, vs_human) | |
| return card_player_1, card_player_2 | |
| def step(self, card_player_1, card_player_2, order, update_global_var=True): | |
| """ | |
| order == True -> card_first_player is played first | |
| - Determines if player_1 wins a round | |
| - Updates the points and the cards in the deck | |
| - Draws 2 cards after the round if there are cards in the deck | |
| Returns: new_card_player_1, new_card_player_2, played_cards, is_end_game, player_1_wins | |
| Updates: - self.cards_in_the_deck if it deals from the deck | |
| - self.points_player_1 | |
| - self.points_player_2 | |
| - self.round | |
| """ | |
| #Determines who wins and how many points | |
| [first_card, second_card] = [card_player_1, card_player_2] if order else [card_player_2, card_player_1] | |
| winner = self.which_card_wins_a_round(first_card, second_card) | |
| points = my_cards.loc[first_card[0], 'points'] + my_cards.loc[second_card[0], 'points'] | |
| played_cards = (first_card, second_card) | |
| player_1_wins = winner == 'first_played_card' if order else not winner == 'first_played_card' | |
| is_briscola_on_the_table = self.is_briscola_on_the_table | |
| if is_briscola_on_the_table: | |
| #draws the new cards | |
| card_winner = self.draw_cards(1) | |
| card_loser = self.draw_cards(1) | |
| if player_1_wins: | |
| if update_global_var: | |
| self.points_player_1 += points | |
| if is_briscola_on_the_table: #deals the new cards | |
| new_card_player_1 = card_winner | |
| new_card_player_2 = card_loser | |
| else: | |
| if update_global_var: | |
| self.points_player_2 += points | |
| if is_briscola_on_the_table: #deals the new cards | |
| new_card_player_2 = card_winner | |
| new_card_player_1 = card_loser | |
| if update_global_var: | |
| self.round = self.round - 1 | |
| is_end_game = self.round == 0 | |
| player_1_pts = points if player_1_wins else 0 | |
| player_2_pts = 0 if player_1_wins else points | |
| if is_briscola_on_the_table: | |
| return new_card_player_1[0], new_card_player_2[0], played_cards, is_end_game, player_1_wins, player_1_pts, player_2_pts | |
| else: | |
| return None, None, played_cards, is_end_game, player_1_wins, player_1_pts, player_2_pts | |
| def reset(self): | |
| self.points_player_1 = 0 #player 1 is the first player at round 1 | |
| self.points_player_2 = 0 | |
| np.random.shuffle(self.cards_in_the_deck) | |
| self.round = 20 | |
| self.index_top_card = 0 | |
| #choose a briscola | |
| self.briscola = self.cards_in_the_deck[0] #pick a briscola | |
| self.index_top_card = 1 | |
| self.is_briscola_on_the_table = True | |