Beispiel #1
0
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
Beispiel #2
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'
Beispiel #3
0
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()
Beispiel #4
0
 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()
Beispiel #5
0
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)), ''
Beispiel #6
0
 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)
Beispiel #7
0
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'
Beispiel #8
0
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
Beispiel #9
0
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)
Beispiel #10
0
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.")
Beispiel #11
0
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()
Beispiel #12
0
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'
Beispiel #13
0
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
Beispiel #14
0
            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"):
Beispiel #15
0
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"]))
Beispiel #16
0
                    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()
Beispiel #17
0
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'