def test_finished(): p1 = Player(9, 3).card_making() pl_1, pl_1_list = p1[0], p1[1] p2 = Player(9, 3).card_making() pl_2, pl_2_list = p2[0], p2[1] playing = Play(100, pl_1, pl_2, pl_1_list, pl_2_list) assert playing.finished(player_1_list, player_1) == 0
def naive2_player(state: None, log: List[NamedTuple], hands: List[List[Card]], rules: Rules, tokens: Tokens, slots: List[int], discard_pile: List[List[int]]) -> Tuple[None, NamedTuple]: """ Zvika and Ofer's naive player """ my_id = len(log) % len(hands) my_card_ids = [card.id for card in hands[my_id]] hinted_cards = set() for move in log[-len(hands):]: if isinstance(move, ResolvedClue): if move.player == my_id: hinted_cards = hinted_cards.union(card.id for card in move.cards) # Its better to play than hint if hinted_cards: play_card = max(hinted_cards) return state, Play.create(play_card), '' # Its better to hint than discard if tokens.clues > 0: for i in range(len(hands) - 1): player = (my_id + i + 1) % len(hands) player_suits = set([card.data.suit for card in hands[player]]) player_ranks = set([card.data.rank for card in hands[player]]) playable_suits = set() playable_ranks = set() for suit in player_suits: card = max( [card for card in hands[player] if card.data.suit == suit]) if slots[card.data.suit] == card.data.rank: playable_suits.add(card.data.suit) for rank in player_ranks: card = max( [card for card in hands[player] if card.data.rank == rank]) if slots[card.data.suit] == card.data.rank: playable_ranks.add(card.data.rank) # its better to go up then sideways clue = None clue_rank = 0 if playable_ranks: clue = Clue.create(player, 'rank', max(playable_ranks)) clue_rank = max(player_ranks) for suit in playable_suits: if slots[suit] > clue_rank: clue = Clue.create(player, 'suit', suit) clue_rank = slots[suit] if clue: return state, clue, '' # Its better to discard then playing like an idiot if tokens.clues < rules.max_tokens.clues: return state, Discard.create(min(my_card_ids)), '' # If all else fails, play like an idiot return state, Play.create(max(my_card_ids)), 'idiot'
def _add_to_game(username, requested_players): """Add user to a game that is not started, or create a new game.""" user = User.objects.get(username=username) # Get game. if (requested_players == "two" and TwoPlayerGame.objects.filter(started=False)): game = TwoPlayerGame.objects.get(started=False) user.two_player_game_id = game.game_id elif (requested_players == "four" and FourPlayerGame.objects.filter(started=False)): game = FourPlayerGame.objects.get(started=False) user.four_player_game_id = game.game_id else: # If there is no unstarted game. Play.new(user, requested_players) return # Add the user. if not game.player1: game.player1 = user elif not game.player2: game.player2 = user elif not game.player3: game.player3 = user elif not game.player4: game.player4 = user if not game.turn: game.turn = user # Check to see if there are enough players to start. # Start if so. if requested_players == "two": if (game.player1 and game.player2): game.started = True game.last_status = json.dumps({"status": "Starting game.", "turn": game.turn.username, "new": True}) if requested_players == "four": if (game.player1 and game.player2 and game.player3 and game.player4): game.started = True game.last_status = json.dumps({"status": "Starting game.", "turn": game.turn.username, "new": True}) game.save() user.save()
def pressed(self, idx, btn): self.screen.blit(self.submenu, (20, 490)) self.screen.blit(self.explosion, (20, btn[1] + 4)) update() if idx != 3: delay(200) if idx == 0: a = Play(self.screen, self.bg_color, self.fps) scores = a.scores if a.result != 0: if 'tabl' not in self.__dict__: self.read_scores() new_record = len(self.tabl) < 10 if not new_record: for (name, score) in self.tabl: if score < scores: new_record = True break if new_record: self.update_scores(scores) elif idx == 1: self.instructions() elif idx == 2: if 'tabl' not in self.__dict__: self.read_scores() self.scores() else: exit() self.reload()
def random_player(state: None, log: List[NamedTuple], hands: List[List[Card]], rules: Rules, tokens: Tokens, slots: List[int], discard_pile: List[List[int]]) -> Tuple[None, Move, str]: """ Tsvika and Ofer's random player Usage: h = Hanabi([random_player] * 3) """ my_id = len(log) % len(hands) possible_actions = [] if tokens.lives > 1: possible_actions.append(Play) if tokens.clues > 0: possible_actions.append(Clue) if tokens.clues < rules.max_tokens.clues: possible_actions.append(Discard) action = random.choice(possible_actions) if action == Play: return state, Play.create(random.choice(hands[my_id]).id), '' if action == Discard: return state, Discard.create(random.choice(hands[my_id]).id), '' if action == Clue: player = random.choice([i for i in range(len(hands)) if i != my_id]) clue_type = random.choice(['suit', 'rank']) return state, Clue.create( player, clue_type, getattr(random.choice(hands[player]).data, clue_type)), ''
def io_player(state: None, log: List[NamedTuple], hands: List[List[Card]], rules: Rules, tokens: Tokens, slots: List[int], discard_pile: List[List[int]]) -> Tuple[None, Move, str]: print(f"{name}'s turn") pprint(log[-len(hands):]) pprint(hands) pprint(tokens) pprint(slots) pprint(discard_pile) print('What will it be?') print('[c]lue <player><type><n>\t\t[p]lay <card>\t\t[d]iscard <card>') move = input().split() try: if move[0] == 'c': _, (player, clue_type, param) = move return state, Clue.create(int(player), { 's': 'suit', 'n': 'rank' }[clue_type], { 's': Suit, 'n': Rank }[clue_type].from_str(param)), '' elif move[0] == 'p': _, card_id = move return state, Play.create(int(card_id)), '' elif move[0] == 'd': _, card_id = move return state, Discard.create(int(card_id)), '' else: raise ValueError("not a valid move type") except (ValueError, KeyError): print('illegal move') return io_player(state, log, hands, rules, tokens, slots, discard_pile)
def naive_player(log: List[NamedTuple], hands: List[List[Card]], rules: Rules, tokens: Tokens, slots: List[int], discard_pile: List[List[int]]) -> Tuple: """ Zvika and Ofer's naive player """ my_id = len(log) % len(hands) my_card_ids = [card.id for card in hands[my_id]] hinted_cards = set() for move in log[-len(hands):]: if isinstance(move, ResolvedClue) and move.player == my_id: hinted_cards = hinted_cards.union(card.id for card in move.cards) # Its better to play than hint if hinted_cards: play_card = max(hinted_cards) return Play.create(play_card), 'Play hinted card' # Its better to hint than discard if tokens.clues > 0: for i in range(len(hands) - 1): player = (my_id + i + 1) % len(hands) player_suits = set([card.data.suit for card in hands[player]]) player_ranks = set([card.data.rank for card in hands[player]]) for card in hands[player]: if slots[card.data.suit] != card.data.rank: player_suits -= set([card.data.suit]) player_ranks -= set([card.data.rank]) if player_ranks: # its better to go up then sideways return Clue.create( player, 'rank', max(player_ranks)), 'Given actionable rank clue' if player_suits: return Clue.create( player, 'suit', player_suits.pop()), 'Given actionable suit clue' # Its better to discard then playing like an idiot if tokens.clues < rules.max_tokens.clues: return Discard.create(min(my_card_ids)), 'Discard oldest card' # If all else fails, play like an idiot return Play.create(max(my_card_ids)), 'Play like an idiot'
def leave(request): """To stop and leave the game. If one player chooses to leave the game, the whole game will be stopped and other users will be notified. """ # Check permission. if not request.session.has_key("username"): return HttpResponseForbidden( json.dumps({"error": "You are not logged in."})) # Check to see if game has been chosen. (game, requested_players) = Play.get_game(request.session["username"]) if not game: return HttpResponseBadRequest( json.dumps({"error": "You have not chosen a game."})) # Stops the game. last_status = json.loads(game.last_status) already_stopped = ("winner" in last_status or "stopped" in last_status) response = Play.stop(game, requested_players, request.session["username"], already_stopped=already_stopped) return response
def signin(request): """Sign into the server.""" # Check to see if user is already logged in. if request.session.has_key("username"): return HttpResponseBadRequest("Error: You are already logged in.") if request.method != "POST": return HttpResponseBadRequest("Error: Send your data via POST.") post = request.POST.dict() # Check data validity. if (set(post.keys()) != {"username", "password"} or not _is_username_valid(post["username"].lower()) or not _is_password_valid(post["password"]) ): return HttpResponseBadRequest("Error: Your POST data is corrupted.") # Get user from database. try: user = User.objects.get(username=post["username"].lower()) except User.DoesNotExist: return HttpResponseForbidden("No such user exists.") # Verify password hash. if not pbkdf2_sha256.verify(post["password"], user.password_hash): return HttpResponseForbidden("Your password is incorrect.") # Set up session. request.session["username"] = user.username # Check to see if the user is already in a game. (game, requested_players) = Play.get_game(request.session["username"]) if game: return HttpResponse("You're already in a game.") return HttpResponse("You are now logged in, %s." % user.name)
def two_or_four(request): """Page to choose the number of players.""" # Check permission. if not request.session.has_key("username"): return HttpResponseForbidden("Error: You are not logged in.") # Check to see if the user is already in a game. (game, requested_players) = Play.get_game(request.session["username"]) if game: return HttpResponseBadRequest("Error: You're already in a game.") # Check data validity. if request.method != "POST": return HttpResponseBadRequest("Error: Send your data via POST.") post = request.POST.dict() if (set(post.keys()) != {"players"} or (post["players"] != "two" and post["players"] != "four") ): return HttpResponseBadRequest("Error: Your POST data is corrupted.") # Add user to a new game. _add_to_game(request.session["username"], post["players"]) return HttpResponse("You've been added to the waitlist.")
from deck import Deck from deck import Card from game import Play # It is a slightly different variation of the 'WAR' card game. Users can select which card to throw unless # they are in a WAR situation, which all the cards will be from the top. if __name__ == "__main__": deck = Deck() player_pc = [] player_real = [] for i in range(len(deck.get_deck())): if i % 2 == 0: player_pc.append(deck.get_deck()[i]) else: player_real.append(deck.get_deck()[i]) game = Play(player_pc, player_real) # game = Play([Card('S', '2', False), Card('D', '2', False), Card('H', '2', False), Card('C', '2', False)], # [Card('S', 'A', False), Card('D', 'A', False), Card('H', 'A', False), Card('C', 'A', False)]) game.play()
def humanlike_player(state, log, hands, rules, tokens, slots, discard_pile): """ Ofer's humanlike player """ def add_card_to_state(given_state, card_id): if card_id not in given_state: given_state[card_id] = CardInfo( Info(None, None), Info([True for _ in range(rules.suits)], [True for _ in rules.ranks]) ) def update_cards(cards, player_id=None, clue=None): if player_id is None: player_id = my_id hinted_cards = set() _log = log[-len(hands):] if clue is not None: _log.append(clue) for move in _log: if isinstance(move, ResolvedClue): if move.player == player_id: for card in move.cards: hinted_cards.add(card.id) card_ids_in_hint = set() for card in move.cards: add_card_to_state(cards, card.id) card_ids_in_hint.add(card.id) cards[card.id] = cards[card.id]._replace(positive=cards[card.id].positive._replace(**{move.type: move.param})) for card in hands[player_id]: if card.id not in card_ids_in_hint: add_card_to_state(cards, card.id) new_negative = getattr(cards[card.id].negative, move.type) new_negative[move.param] = False cards[card.id] = cards[card.id]._replace(negative=cards[card.id].negative._replace(**{move.type: new_negative})) # Consolidate negatives in hand for card_id in hinted_cards: if cards[card_id].negative.suit.count(True) == 1: cards[card.id]._replace(positive=cards[card.id].positive._replace( suit=[i for i, v in enumerate(cards[card_id].negative.suit) if v])) if cards[card_id].negative.rank.count(True) == 1: cards[card.id]._replace(positive=cards[card.id].positive._replace( rank=[i for i, v in enumerate(cards[card_id].negative.rank) if v])) return cards, hinted_cards def get_max_rank_in_suit(suit, _slots, _discard_pile): max_rank_in_suit = None for rank in range(len(rules.ranks)): left_in_rank = rules.ranks[rank] - _discard_pile[suit][rank] if rank >= _slots[suit] and left_in_rank == 0: max_rank_in_suit = rank break return max_rank_in_suit def is_playable_suit(suit, _slots, _discard_pile): if _slots[suit] > len(rules.ranks): return False max_rank_in_suit = get_max_rank_in_suit(suit, _slots, _discard_pile) if max_rank_in_suit is not None and max_rank_in_suit < _slots[suit]: return False return True def should_play_card(cards, cards_in_hand, hinted_cards, _slots=None, _discard_pile=None): if _slots is None: _slots = slots if _discard_pile is None: _discard_pile = discard_pile hinted_cards = hinted_cards.intersection(cards_in_hand) definate_cards_to_play = set() cards_to_play = set() for card_id in cards_in_hand: add_card_to_state(cards, card_id) if cards[card_id].positive.suit is not None and cards[card_id].positive.rank is not None: if is_play_legal(cards[card_id].positive.suit, cards[card_id].positive.rank, _slots): definate_cards_to_play.add(card_id) if card_id in sorted(hinted_cards): if cards[card_id].positive.rank is not None and cards[card_id].positive.suit is None and any( [is_playable_suit(suit, _slots, _discard_pile) and cards[card_id].positive.rank == _slots[suit] for suit in range(len(_slots))]): cards_to_play.add(card_id) if cards[card_id].positive.suit is not None and cards[card_id].positive.rank is None \ and is_playable_suit(cards[card_id].positive.suit, _slots, _discard_pile): cards_to_play.add(card_id) if definate_cards_to_play: # its better to go up than go sideways! highest_rank = 0 cards_in_highest_rank = set() for card_id in definate_cards_to_play: if cards[card_id].positive.rank > highest_rank: highest_rank = cards[card_id].positive.rank cards_in_highest_rank = set() if cards[card_id].positive.rank == highest_rank: cards_in_highest_rank.add(card_id) return sorted(cards_in_highest_rank)[-1] # play newest card if cards_to_play: return sorted(cards_to_play)[-1] # play newest card return None def what_will_player_play(cards, hand, player_id, clue, _slots, _discard_pile): cards, _hinted_cards = update_cards(cards, player_id, clue) card_id = should_play_card(cards, [card.id for card in hand], _hinted_cards, _slots, _discard_pile) if card_id is not None: card = [card for card in hand if card.id == card_id][0] legal = is_play_legal(card.data.suit, card.data.rank, _slots) return cards, legal, card_id else: return cards, None, None def is_play_legal(suit, rank, _slots): return _slots[suit] == rank def create_clue(my_id, _player, type, param): cards = [card for card in hands[_player] if getattr(card.data, type) == param] cards_neg = [card for card in hands[_player] if getattr(card.data, type) != param] return ResolvedClue.create(my_id, _player, type, param, cards, cards_neg) # Start if state is None: state = {} my_id = len(log) % len(hands) state, state_actions = update_cards(state) my_card_ids = [card.id for card in hands[my_id]] card_to_play = should_play_card(state, my_card_ids, state_actions, slots, discard_pile) if card_to_play is not None: # Its better to play than hint return state, Play.create(card_to_play), 'Played card' if tokens.clues > 0: # Its better to hint than discard foreseen_slots = list(slots) foreseen_state = dict(state) for i in range(len(hands) - 1): player = (my_id + i + 1) % len(hands) foreseen_state, is_legal, play = what_will_player_play( foreseen_state, hands[player], player, None, foreseen_slots, discard_pile) player_state, player_hinted = update_cards(foreseen_state, player) player_play = should_play_card(state, [card.id for card in hands[player]], player_hinted) if player_play is not None: card = [card for card in hands[player] if card.id == player_play][0] if is_play_legal(card.data.suit, card.data.rank, slots): foreseen_slots[card.data.suit] = card.data.rank continue else: # try and rectify stupidity for card in hands[player]: suit_clue = create_clue(my_id, player, 'suit', card.data.suit) _, is_legal, play = what_will_player_play( dict(foreseen_state), hands[player], player, suit_clue, foreseen_slots, discard_pile) if is_legal or play is None: return state, Clue.create(player, 'suit', card.data.suit), 'Gave hint against stupid play' rank_clue = create_clue(my_id, player, 'rank', card.data.rank) _, is_legal, play = what_will_player_play( dict(foreseen_state), hands[player], player, rank_clue, foreseen_slots, discard_pile) if is_legal or play is None: return state, Clue.create(player, 'rank', card.data.rank), 'Gave hint against stupid play' good_clues = set() for card in hands[player]: if slots[card.data.suit] == card.data.rank: suit_clue = create_clue(my_id, player, 'suit', card.data.suit) _, is_legal, play = what_will_player_play( dict(foreseen_state), hands[player], player, suit_clue, foreseen_slots, discard_pile) if is_legal and play == card.id: good_clues.add(PossibleClue(player=player, card=card, type='suit')) rank_clue = create_clue(my_id, player, 'rank', card.data.rank) _, is_legal, play = what_will_player_play( dict(foreseen_state), hands[player], player, rank_clue, foreseen_slots, discard_pile) if is_legal and play == card.id: good_clues.add(PossibleClue(player=player, card=card, type='rank')) if good_clues: # make sure highest card possible is played highest_rank = 0 given_clue = None for clue in good_clues: if given_clue is None: given_clue = clue if clue.card.data.rank > highest_rank: highest_rank = clue.card.data.rank given_clue = clue return state, Clue.create(given_clue.player, given_clue.type, getattr(given_clue.card.data, given_clue.type)), 'Gave actionable clue' if tokens.clues < rules.max_tokens.clues: # Its better to discard then playing like an idiot protected_cards = set() for card_id in my_card_ids: # Throw away useless cards if state[card_id].positive.suit is not None and not is_playable_suit(state[card_id].positive.suit, slots, discard_pile): return state, Discard.create(card_id), 'Discarded unplayable suit' if state[card_id].positive.rank is not None and all([slot<state[card_id].positive.rank for slot in slots]): return state, Discard.create(card_id), 'Discarded Unplayable rank' if state[card_id].positive.suit is not None and state[card_id].positive.rank is not None: if slots[state[card_id].positive.suit] < state[card_id].positive.rank: return state, Discard.create(card_id), 'Discarded unplayable known card' # Don't throw away lone copies avaiable_copies = rules.ranks[state[card_id].positive.rank] discarded_copies = discard_pile[state[card_id].positive.suit][state[card_id].positive.rank] if avaiable_copies - discarded_copies == 1: protected_cards.add(card_id) # Don't throw away 5s if state[card_id].positive.rank is not None: avaiable_copies = rules.ranks[state[card_id].positive.rank] if avaiable_copies == 1: protected_cards.add(card_id) throwaways = set(my_card_ids) - protected_cards if throwaways: return state, Discard.create(min(throwaways)), 'Discarded unprotected card' return state, Discard.create(min(my_card_ids)), 'Discarded oldest card' if tokens.clues > 0: # give random clue to the player playing before you so the other players may fix it player = (my_id -1) % len(hands) if hands[player]: highest_rank_in_hand = sorted([card.data.rank for card in hands[player]])[-1] return state, Clue.create(player, 'rank', highest_rank_in_hand), 'Gave random clue' # If all else fails, play like an idiot return state, Play.create(max(my_card_ids)), 'Played random card'
def oracle_player(log: List[NamedTuple], hands: List[List[Card]], rules: Rules, tokens: Tokens, slots: List[int], discard_pile: List[List[int]]) -> Tuple: """ Zvika and Ofer's oracle player """ my_id = len(log) % len(hands) my_hand = hands[my_id] if my_hand[0].data is None: raise RuntimeError("I need to be omniscient") # play something playable playable_card = None for card in my_hand: if slots[card.data.suit] == card.data.rank: if playable_card is None or playable_card.data.rank < card.data.rank: playable_card = card if playable_card is not None: return Play.create(playable_card.id), 'playable' def get_card_to_discard(): # discard already played for card in my_hand: if slots[card.data.suit] > card.data.rank: return card.id, 'low' # discard unreachable for suit in range(rules.suits): max_rank_in_suit = None for rank in range(len(rules.ranks)): left_in_rank = rules.ranks[rank] - discard_pile[suit][rank] if rank >= slots[suit] and left_in_rank == 0: max_rank_in_suit = rank break if max_rank_in_suit: for card in my_hand: if card.data.suit == suit and card.data.rank > max_rank_in_suit: return card.id, 'high' # discard duplicates in own hand knowns = [card.data for card in my_hand] if len(set(knowns)) < len(knowns): for i, known in enumerate(knowns): for known2 in knowns[i+1:]: if known == known2: return my_hand[i].id, 'dup' # discard duplicates with others knowns = [card.data for card in my_hand] for hand in hands[:my_id]+hands[my_id+1:]: knowns2 = [card.data for card in hand] if len(set(knowns+knowns2)) < len(knowns)+len(set(knowns2)): for i, known in enumerate(knowns): for known2 in knowns2: if known == known2: return my_hand[i].id, 'dup2' return None, '' # discard something discardable if tokens.clues < rules.max_tokens.clues: card, note = get_card_to_discard() if card is not None: return Discard.create(card), 'pass/d/' + note # nothing useful to do # try to pass with useless clue if tokens.clues > 0: player = (my_id + 1) % len(hands) if hands[player]: return Clue.create(player, 'suit', hands[player][0].data.suit), 'pass/c' # try to pass with false play if tokens.lives > 1: card, note = get_card_to_discard() if card is not None: return Play.create(card), 'pass/p/' + note # you have to throw something useful. try the farthest from the suit # look for an expandable card diff = None throw = None for card in my_hand: card_diff = card.data.rank - slots[card.data.suit] if diff is None or card_diff > diff: if rules.ranks[card.data.rank] - discard_pile[card.data.suit][card.data.rank] > 1: diff = card_diff throw = card note = '' # look for a non expandable card, if you must (BOO!) if diff is None: note = '/bad' for card in my_hand: card_diff = card.data.rank - slots[card.data.suit] if diff is None or card_diff > diff: diff = card_diff throw = card # throw by discard if tokens.clues < rules.max_tokens.clues: return Discard.create(throw.id), 'throw/d' + note # throw by false play return Play.create(throw.id), 'throw/p' + note
if mess[0].startswith(".j"): if dealt: irc.sendMessage(chan, "Already dealt") elif nick not in players: players[nick] = Player(nick, gameP) irc.sendMessage(chan, nick + " joined") print(players) else: irc.sendMessage(chan, "You are already in") if mess[0].startswith(".de"): if play is None and len(players) > 1: play = Play(players.pop(owner.getName())) for pl in players: play.addPlayer(players[pl]) print(play) dealt = True irc.sendMessage(chan, "Dealt") for st in gameP.print(): irc.sendMessage(chan, st) sleep(0.49) else: irc.sendMessage(chan, "Already dealt") if mess[0].startswith(".e"):
def play_and_status(request): """Play moves if game has started. If not, check waitlist and start a new game. """ # Check permission. if not request.session.has_key("username"): return HttpResponseForbidden( json.dumps({"error": "You are not logged in."})) # Check to see if game has been chosen. (game, requested_players) = Play.get_game(request.session["username"]) if not game: return HttpResponseBadRequest( json.dumps({"error": "You have not chosen a game."})) # Check to see if game has started. if not game.started: return HttpResponse(game.last_status) # Check to see if the game has been won by someone. if "winner" in json.loads(game.last_status): response = HttpResponse(game.last_status + "\n" + game.main_grid + "\n" + game.wallh_grid + "\n" + game.wallv_grid + "\n" + game.wallfills_grid + "\n" + json.dumps(dict())) Play.stop(game, requested_players, request.session["username"], already_stopped=True) return response if "stopped" in json.loads(game.last_status): response = Play.stop(game, requested_players, request.session["username"], already_stopped=True) return response # Check turn. if game.turn.username != request.session["username"]: return HttpResponse(game.last_status + "\n" + game.main_grid + "\n" + game.wallh_grid + "\n" + game.wallv_grid + "\n" + game.wallfills_grid + "\n" + Play.get_walls(game, requested_players)) # Check to see if any move has been made. if request.method != "POST": return HttpResponse(game.last_status + "\n" + game.main_grid + "\n" + game.wallh_grid + "\n" + game.wallv_grid + "\n" + game.wallfills_grid + "\n" + Play.get_walls(game, requested_players)) post = request.POST.dict() # Check data validity. if (set(post.keys()) != {"move"} or not _is_move_format_valid(json.loads(post["move"])) ): return HttpResponseBadRequest( json.dumps({"error": "Your POST data is corrupted."})) # Play the move. return Play.play(game, requested_players, json.loads(post["move"]))
str(self._player_2_cards[i][lastIndex].getSuit())) image = pygame.image.load(img_string) screen.blit(image, ((DIST_BETWEEN_COLUMNS * (i + 1)) + (TRANS_COL_WIDTH / 4), (HEIGHT / 3.3) + ((lastIndex + 1) * DIST_BETWEEN_NUMBERS) + DIST_FROM_BOTTOM + 10)) except IndexError: pass def displaySideCard(self, screen, card): if card is None: SIDE_CARD_IMG = pygame.image.load('resources/backCard.gif') screen.blit(SIDE_CARD_IMG, (WIDTH - DIST_FROM_RIGHT_SIDE, HEIGHT // 2)) else: try: img_string = 'resources/{0}{1}.gif'.format( str(card.getRank()), str(card.getSuit())) image = pygame.image.load(img_string) screen.blit(image, (WIDTH - DIST_FROM_RIGHT_SIDE, HEIGHT // 2)) except IndexError: pass if __name__ == '__main__': play = Play() view = GameView() game = GameController(play, view, play.__getPlayer1Hands__(), play.__getPlayer2Hands__()) game.start()
def naive2_with_2nd_degree_player(log: List[NamedTuple], hands: List[List[Card]], rules: Rules, tokens: Tokens, slots: List[int], discard_pile: List[List[int]]) -> Tuple: """ Zvika and Ofer's naive player Improved with 2nd degree clues by Ofer This player only gives 2nd degree clues to the next player """ def relative_position(player_id): return (player_id - my_id) % len(hands) def is_playable(card): return slots[card.data.suit] == card.data.rank my_id = len(log) % len(hands) my_card_ids = [card.id for card in hands[my_id]] hinted_cards = set() for move in log[-len(hands):]: if isinstance(move, ResolvedClue): if move.player == my_id: hinted_cards = hinted_cards.union(card.id for card in move.cards) # Its better to play than hint if hinted_cards: play_card = max(hinted_cards) return Play.create(play_card), 'Play hinted card' # Play 2nd degree clues for move in log[-len(hands) + 1:]: if isinstance(move, ResolvedClue): if relative_position(move.cur_player) > relative_position( move.player): hinted_card = max([card.id for card in move.cards]) known_card = [ card for card in hands[move.player] if card.id == hinted_card ][0] if slots[known_card.data.suit] == known_card.data.rank - 1: return Play.create( max(my_card_ids)), 'play 2nd degree clue' # Its better to hint than discard if tokens.clues > 0: # If possible give 2nd degree clue hintable_card = hands[(my_id + 1) % len(hands)][-1] if is_playable(hintable_card): player_id = (my_id + 2) % len(hands) for card in hands[player_id]: if card.data.suit == hintable_card.data.suit and card.data.rank == hintable_card.data.rank + 1: # suit clue if max([card.id for card in hands[player_id] if card.data.suit == hintable_card.data.suit])\ == card.id: return Clue.create( player_id, 'suit', card.data.suit), 'give 2nd degree suit clue' # rank clue if max([card.id for card in hands[player_id] if card.data.rank == hintable_card.data.rank+1])\ == card.id: return Clue.create( player_id, 'rank', card.data.rank), 'give 2nd degree rank clue' # Give regular clue for i in range(len(hands) - 1): player = (my_id + i + 1) % len(hands) player_suits = set([card.data.suit for card in hands[player]]) player_ranks = set([card.data.rank for card in hands[player]]) playable_suits = set() playable_ranks = set() for suit in player_suits: card = max( [card for card in hands[player] if card.data.suit == suit]) if slots[card.data.suit] == card.data.rank: playable_suits.add(card.data.suit) for rank in player_ranks: card = max( [card for card in hands[player] if card.data.rank == rank]) if slots[card.data.suit] == card.data.rank: playable_ranks.add(card.data.rank) # its better to go up then sideways clue = None clue_rank = 0 if playable_ranks: clue = Clue.create(player, 'rank', max(playable_ranks)) clue_rank = max(player_ranks) for suit in playable_suits: if slots[suit] > clue_rank: clue = Clue.create(player, 'suit', suit) clue_rank = slots[suit] + 1 if clue: return clue, 'Given actionable clue' # Its better to discard then playing like an idiot if tokens.clues < rules.max_tokens.clues: return Discard.create(min(my_card_ids)), 'Discard oldest card' # If all else fails, play like an idiot return Play.create(max(my_card_ids)), 'Play like an idiot'