Untitled
Includes risky min maxunknown
python
a year ago
10 kB
8
Indexable
import logging
import random
import math
import numpy as np
from CardGame import Card, Deck, Player
logging.basicConfig(filename='group7.log',
level=logging.DEBUG, # Set to DEBUG to capture all messages
filemode='w', # Clear the log file each time the program runs
format='%(message)s',) # Only the message will be logged
logging.disable(logging.CRITICAL)
# G7 is the best
#Stores guesses by player and round
player_guesses = {}
SUITS = ["Clubs", "Diamonds", "Hearts", "Spades"]
VALUES = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
NUM_CARDS = len(SUITS) * len(VALUES)
CARD_PROBABILITIES = {num:1/39 for num in range(NUM_CARDS)}
TEAMMATE = {"North": "South", "South": "North", "East": "West", "West": "East"}
# Create a dictionary that maps 0-51 to (value, suit)
NUM_TO_CARD = {
i: (SUITS[i // 13], VALUES[i % 13]) # i % 13 gives the card value, i // 13 gives the suit
for i in range(NUM_CARDS)
}
REV_CARD_TO_NUM = {value:key for key, value in NUM_TO_CARD.items()}
MU = 25.5
SIGMA = 100
def gaussian_pdf(x, mu, sigma):
return (1 / (sigma * math.sqrt(2 * math.pi))) * math.exp(-0.5 * ((x - mu) / sigma) ** 2)
def update_prob_based_on_correct_answers(player,probability_dict, guessed_cards, correct_answers, round):
"""
Updates the probabilities for the cards in the guessed_cards list.
Args:
probability_dict (dict): A dictionary where keys are integers (0-51) representing cards
and probabilities.
guessed_cards (list): A list of card indices representing the guessed cards.
Returns:
None: The probability_dict is updated in-place.
"""
#print(f"Number of correct answers {correct_answers}")
#print(correct_answers)
perc_correct = correct_answers / len(guessed_cards) # Factor to boost guessed cards
perc_wrong = 1 - perc_correct
var_rounds = round/13
var_round = var_rounds**2
#print(f"Perc of correct answers {perc_correct}")
for card in guessed_cards:
probability_dict[card] *= perc_correct
non_guessed_cards = [card for card in probability_dict if card not in guessed_cards]
for card in non_guessed_cards:
probability_dict[card] *= perc_wrong
normalize_probabilities(player)
print(player.name)
#print(probability_dict)
def normalize(probability_dict):
total_prob = sum(probability_dict.values())
if total_prob > 0:
for card in probability_dict:
probability_dict[card] /= total_prob
def playing(player, deck):
turn = len(player.played_cards) + 1
round = turn
print(f"The current turn is {turn}")
if round < 7:
return risky_min_max(player,deck)
else:
flag = (turn % 2)
if flag == 0:
flag = 1
return max_first(player, deck)
else:
flag = 0
return min_first(player, deck)
def risky_min_max(player, deck):
if not player.hand:
return None
# Find highets card
highest_card = -1
for i, card in enumerate(player.hand):
card_value = REV_CARD_TO_NUM[(card.suit, card.value)]
if card_value > highest_card:
highest_card = card_value
max_index = i
#Find lowest card
lowest_card = 52
for i, card in enumerate(player.hand):
card_value = REV_CARD_TO_NUM[(card.suit, card.value)]
if card_value < lowest_card:
lowest_card = card_value
min_index = i
print(f"Minindex for {player.name} is {lowest_card}")
print(f"Max index for {player.name} is {highest_card}")
# If max index is further from 52 than min index from 0
if (lowest_card < 52 - highest_card):
print(f"Player using risky minmax {player.name} zeroing above {highest_card}")
return max_index
else:
print(f"Player using risky minmax {player.name} zeroing below {lowest_card}")
return min_index
def max_first(player, deck):
"""
Max First strategy.
This strategy always plays the highest-value card in the player's hand.
Parameters:
player (Player): The current player object.
deck (Deck): The current deck object.
Returns:
int or None: The index of the card to be played, or None if no card can be played.
"""
if not player.hand:
return None
value_order = deck.values
max_index = 0
highest_card = -1
for i, card in enumerate(player.hand):
card_value = REV_CARD_TO_NUM[(card.suit, card.value)]
if card_value > highest_card:
highest_card = card_value
max_index = i
print(highest_card, NUM_TO_CARD[highest_card])
return max_index
def min_first(player, deck):
"""
Min First strategy.
This strategy always plays the lowest-value card in the player's hand.
Parameters:
player (Player): The current player object.
deck (Deck): The current deck object.
Returns:
int or None: The index of the card to be played, or None if no card can be played.
"""
if not player.hand:
return None
lowest_card = 52
for i, card in enumerate(player.hand):
card_value = REV_CARD_TO_NUM[(card.suit, card.value)]
if card_value < lowest_card:
lowest_card = card_value
min_index = i
return min_index
def normalize_probabilities(player):
total = sum(player.card_probabilities.values())
if total > 0:
for card in player.card_probabilities:
player.card_probabilities[card] /= total
else:
# This is after all the cards have been played - so no exception
player.card_probabilities[0] = 1
def zero_probabilities(player, cards):
print(cards)
for card in cards:
suit = card.suit
val = card.value
num = REV_CARD_TO_NUM[(suit, val)]
player.card_probabilities[num] = 0.0
normalize_probabilities(player)
def zero_below_card(player, card):
# for each card below the card, set probability to 0
suit = card.suit
val = card.value
num = REV_CARD_TO_NUM[(suit, val)]
logging.debug(f"The lowest card number is (in number form) {num}")
for i in range(num):
player.card_probabilities[i] = 0.0
logging.debug(f"Setting probability of card {i} to 0")
normalize_probabilities(player)
def zero_above_card(player, card):
# for each card above the card, set probability to 0
suit = card.suit
val = card.value
num = REV_CARD_TO_NUM[(suit, val)]
logging.debug(f"The highest card number is (in number form) {num}")
for i in range(num, 52):
player.card_probabilities[i] = 0.0
logging.debug(f"Setting probability of card {i} to 0")
normalize_probabilities(player)
def choose_cards(player, round, max_probs=False):
if not max_probs:
choices = np.random.choice(
list(player.card_probabilities.keys()),
13 - round,
p=list(player.card_probabilities.values()),
replace=False)
else:
choices = sorted(player.card_probabilities.keys(), key=lambda x:player.card_probabilities[x])[-(13 - round):]
card_choices = [NUM_TO_CARD[card] for card in choices]
card_choices_obj = [Card(card[0], card[1]) for card in card_choices]
return card_choices_obj
def guessing(player, cards, round):
global player_guesses
if round == 1:
# global player.card_probabilities
player.card_probabilities = {num:gaussian_pdf(num, MU, SIGMA) for num in range(NUM_CARDS)}
zero_probabilities(player, player.hand)
normalize_probabilities(player)
exposed_cards = [i for j in list(player.exposed_cards.values()) for i in j]
zero_probabilities(player, exposed_cards)
zero_probabilities(player, player.played_cards)
last_exposed_card = player.exposed_cards[TEAMMATE[player.name]][-1]
last_exposed_card_index = REV_CARD_TO_NUM[(last_exposed_card.suit, last_exposed_card.value)]
# # if even round, guess the highest card
if round >= 7:
if round % 2 == 0:
logging.debug(f"Zeroing highest card and above")
print(f"Player {player.name} zeroing above {last_exposed_card}")
zero_above_card(player, last_exposed_card)
else:
logging.debug(f"Zeroing below card and above")
print(f"Player {player.name} zeroing below {last_exposed_card}")
zero_below_card(player, last_exposed_card)
# we guess min or max based on if the number is closer to 0 or 52
else:
if (last_exposed_card_index < 52 - last_exposed_card_index):
# Assume min card as its closer to 0 index
zero_below_card(player, last_exposed_card)
else:
zero_above_card(player, last_exposed_card)
if round > 1: # We have c values
correct_answers = player.cVals[-1]
previous_guesses = player_guesses[player.name].get(round - 1, [])
print(correct_answers)
print(len(previous_guesses))
previous_guess_indices = [REV_CARD_TO_NUM[(card.suit, card.value)] for card in previous_guesses]
update_prob_based_on_correct_answers(player, player.card_probabilities, previous_guess_indices, correct_answers, round)
#logging.debug(f"Current Player: {player.name}")
#logging.debug(f"Current Teammate: {TEAMMATE[player.name]}")
#logging.debug(f"The player, {player.name}, is examining card: {player.exposed_cards[TEAMMATE[player.name]][-1]}")
#logging.debug(f"Summary of Player: {player.name}")
#logging.debug(player.card_probabilities)
# sum of probabilities should be 1
#logging.debug(f"Total probability: {sum(player.card_probabilities.values())}")
card_choices_obj = choose_cards(player, round, max_probs=True)
if player.name not in player_guesses:
player_guesses[player.name] = {} # Initialize if not present
player_guesses[player.name][round] = card_choices_obj
return card_choices_obj
Editor is loading...
Leave a Comment