示例#1
0
 def _choose_flag_to_deploy(self,
                            state: GameState,
                            card: PlayedCard,
                            discardable=False) -> Optional[Flag]:
     candidates = [0]
     is_troop = isinstance(card, TroopCard)
     print("please select the flag to deploy:")
     for i, flag in enumerate(state.get_flags()):
         # iterate flags can be placed
         deployable = (self._can_play_troop_tactic_morales_for_flag(flag)
                       if is_troop else
                       self._can_play_tactic_envs_for_flag(flag))
         stacked = flag.get_stacked_cards(self._id)
         opposite = flag.get_opposite_stacked_cards(self._id)
         stacked_envs = flag.get_stacked_envs(self._id)
         opposite_envs = flag.get_opposite_stacked_envs(self._id)
         formatted_line = (f"{repr(stacked_envs)} {repr(stacked)}"
                           "  vs  "
                           f"{repr(opposite)} {repr(opposite_envs)}")
         if deployable:
             print(f"[{i + 1}] -- {formatted_line}")
             candidates.append(i + 1)
         else:
             print(f"[x] -- {formatted_line}")
     if discardable:
         print("[0] -- discard from the game")
     else:
         print("[0] -- return to card selection")
     flag_index = await_user_num(candidates)
     return state.get_flags()[flag_index - 1] if flag_index > 0 else None
示例#2
0
def aggregate_used_troops(state: GameState) -> List[TroopCard]:
    cards: List[TroopCard] = []
    # aggregate from all flags
    for flag in state.get_flags():
        stacks = chain.from_iterable([
            flag.get_stacked_cards(PLAYER_A),
            flag.get_stacked_cards(PLAYER_B)
        ])
        cards.extend([c for c in stacks if isinstance(c, TroopCard)])
    # ... and discarded cards
    ops = chain.from_iterable(
        [state.get_operations(PLAYER_A),
         state.get_operations(PLAYER_B)])
    discards = [t for t in [op.get_discarded_troop_card() for op in ops] if t]
    cards.extend(discards)
    return cards
示例#3
0
def vshuman_main(arg: List[str]) -> None:
    game = Game(GameState.new(),
                (HumanPlayer(PLAYER_A), HumanPlayer(PLAYER_B)))
    while game.run() == PLAYER_UNRESOLVED:
        pass
    print(f"Player {game.run() + 1} win!")
    print(repr(game.get_state()))
示例#4
0
 def _play_scout(self, state: GameState,
                 card: TacticGuileCard) -> Optional[GameState]:
     assert card.get_tactics() == TacticGuiles.SCOUT
     print("choose draw pattern?")
     print("[1] -- draw 3 cards from troops deck")
     print(
         "[2] -- draw 2 cards from troops deck and draw 1 card from tactics deck"
     )
     print(
         "[3] -- draw 1 card from troops deck and draw 2 cards from tactics deck"
     )
     print("[4] -- draw 3 cards from tactics deck")
     print("[0] -- return to select a card")
     user_in = await_user_num(range(5))
     if user_in == 0:
         return None
     # copy to new state
     state = state.clone()
     draw_tactics_num = user_in - 1
     peek_cards: List[Card] = []
     peek_cards.extend(state.get_tactics_deck().peek(draw_tactics_num))
     peek_cards.extend(state.get_troops_deck().peek(3 - draw_tactics_num))
     print("scouted cards: ")
     copy_hands = self.get_hands(state).copy()
     # remove the used card
     copy_hands.remove(card)
     for i, c in enumerate(peek_cards):
         print(f"[{i}]: {repr(c)}")
         copy_hands.append(c)
     # sort my hands
     copy_hands.sort()
     # add to hand
     print("choose 2 cards return to decks:")
     for i, c in enumerate(copy_hands):
         print(f"[{i + 1}]: {repr(c)}")
     input_cand = list(range(1, len(copy_hands) + 1))
     in_1 = await_user_num(input_cand)
     ret_card_1 = copy_hands[in_1 - 1]
     input_cand.remove(in_1)
     in_2 = await_user_num(input_cand)
     ret_card_2 = copy_hands[in_2 - 1]
     return self._play_tactic_guile_scout(
         state,
         card,
         (draw_tactics_num, 3 - draw_tactics_num),
         (ret_card_1, ret_card_2),
     )
    def __init__(self, server_host, server_port):
        self.CLIENT = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.HOST = server_host
        self.PORT = server_port
        self.ADDR = (self.HOST, self.PORT)
        self.player_num = None

        gamestate = GameState()
示例#6
0
 def _draw_deck(self, state: GameState) -> Optional[Card]:
     troops_deck = state.get_troops_deck()
     tactics_deck = state.get_tactics_deck()
     draw_troops = troops_deck.is_remain()
     draw_tactics = tactics_deck.is_remain()
     if draw_troops and draw_tactics:
         print("draw card from?")
         print(f"[0] -- troops deck, remains {len(troops_deck)} cards")
         print(f"[1] -- tactics deck, remains {len(tactics_deck)} cards")
         if await_user_num([0, 1]) == 0:
             draw_tactics = False
         else:
             draw_troops = False
     if draw_troops:
         return troops_deck.draw()
     if draw_tactics:
         return tactics_deck.draw()
     # both decks are empty
     return None
示例#7
0
 def play(self, state: GameState) -> GameState:
     print(f"{self._get_user_repr()}: TURN START {'-'*60}")
     suppress_draw = False
     while True:
         card = self._choose_hand_to_play(state)
         if card is None:
             # pass
             print(" --> passed.")
             return state
         print(f"You chose: {repr(card)}")
         if isinstance(card, TroopAndTacticMoraleCard):
             flag = self._choose_flag_to_deploy(state, card)
             if flag is None:
                 print(" --> re-select the card")
                 continue
             state = self._play_troop_tactic_morales_for_flag(
                 state, flag, card)
             break
         if isinstance(card, TacticEnvironmentCard):
             flag = self._choose_flag_to_deploy(state, card)
             if flag is None:
                 print(" --> re-select the card")
                 continue
             state = self._play_tactic_envs_for_flag(state, flag, card)
             break
         if isinstance(card, TacticGuileCard):
             new_state = self._play_tactic_guile(state, card)
             if new_state is None:
                 print(" --> re-select the card")
                 continue
             if card.get_tactic_guiles() == TacticGuiles.SCOUT:
                 # card already drew
                 suppress_draw = True
             state = new_state
             break
         raise ValueError(f"Unknown card: {card}")
     if not suppress_draw:
         card = self._draw_deck(state)
         if card is not None:
             state = state.clone()
             state.add_hand(self.get_id(), card)
     print(f"{self._get_user_repr()}: TURN END {'-'*60}")
     return state
示例#8
0
def test_solve_failed_wedge_but_battalion_vs_battalion():  # noqa: D103
    state = GameState.new()
    flag: Flag = state.get_flags()[0]
    flag.add_stack(PLAYER_A, CardGenerator.troop(TroopColors.RED, 3))
    flag.add_stack(PLAYER_A, CardGenerator.troop(TroopColors.RED, 4))
    flag.add_stack(PLAYER_A, CardGenerator.troop(TroopColors.RED, 7))
    flag.add_stack(PLAYER_B, CardGenerator.troop(TroopColors.BLUE, 1))
    flag.add_stack(PLAYER_B, CardGenerator.troop(TroopColors.BLUE, 3))
    flag.add_stack(PLAYER_B, CardGenerator.troop(TroopColors.BLUE, 6))
    assert _check_resolve(flag, state) == PLAYER_A
示例#9
0
def test_solve_wild_wedge_vs_phalanx():  # noqa: D103
    state = GameState.new()
    flag: Flag = state.get_flags()[0]
    flag.add_stack(PLAYER_A, CardGenerator.troop(TroopColors.RED, 3))
    flag.add_stack(PLAYER_A, CardGenerator.troop(TroopColors.RED, 4))
    flag.add_stack(PLAYER_A, CardGenerator.tactic(TacticMorales.LEADER_ALEXANDER))
    flag.add_stack(PLAYER_B, CardGenerator.troop(TroopColors.BLUE, 8))
    flag.add_stack(PLAYER_B, CardGenerator.troop(TroopColors.GREEN, 8))
    flag.add_stack(PLAYER_B, CardGenerator.troop(TroopColors.YELLOW, 8))
    assert _check_resolve(flag, state) == PLAYER_A
示例#10
0
def test_solve_same_wedge_reversed():  # noqa: D103
    state = GameState.new()
    flag: Flag = state.get_flags()[0]
    flag.add_stack(PLAYER_B, CardGenerator.troop(TroopColors.BLUE, 2))
    flag.add_stack(PLAYER_B, CardGenerator.troop(TroopColors.BLUE, 3))
    flag.add_stack(PLAYER_B, CardGenerator.troop(TroopColors.BLUE, 4))
    flag.add_stack(PLAYER_A, CardGenerator.troop(TroopColors.RED, 3))
    flag.add_stack(PLAYER_A, CardGenerator.troop(TroopColors.RED, 4))
    flag.add_stack(PLAYER_A, CardGenerator.troop(TroopColors.RED, 2))
    assert _check_resolve(flag, state) == PLAYER_B
示例#11
0
def test_solve_superwild_wedge_vs_wedge():  # noqa: D103
    state = GameState.new()
    flag: Flag = state.get_flags()[0]
    flag.add_stack(PLAYER_A, CardGenerator.troop(TroopColors.RED, 9))
    flag.add_stack(PLAYER_A, CardGenerator.tactic(TacticMorales.COMPANION_CAVALRY))
    flag.add_stack(PLAYER_A, CardGenerator.tactic(TacticMorales.LEADER_ALEXANDER))
    flag.add_stack(PLAYER_B, CardGenerator.troop(TroopColors.BLUE, 2))
    flag.add_stack(PLAYER_B, CardGenerator.troop(TroopColors.BLUE, 3))
    flag.add_stack(PLAYER_B, CardGenerator.troop(TroopColors.BLUE, 4))
    assert _check_resolve(flag, state) == PLAYER_A
示例#12
0
def resolve(state: GameState) -> None:
    used_cards = aggregate_used_troops(state)
    for flag in state.get_flags():
        if flag.is_resolved():
            # already resolved
            continue
        resolve = check_resolvable_for_single_flag(flag, used_cards)
        # resolve flag
        if resolve != PLAYER_UNRESOLVED:
            flag.resolve(resolve)
示例#13
0
def test_resolve_unresolvable():  # noqa: D103
    state = GameState.new()
    flag: Flag = state.get_flags()[0]
    assert _check_resolve(flag, state) == PLAYER_UNRESOLVED
    flag.add_stack(PLAYER_A, CardGenerator.troop(TroopColors.RED, 3))
    assert flag.get_last_stacked_player() == PLAYER_A
    assert len(flag.get_stacked_cards(PLAYER_A)) == 1
    assert len(flag.get_stacked_cards(PLAYER_B)) == 0
    assert _check_resolve(flag, state) == PLAYER_UNRESOLVED

    flag.add_stack(PLAYER_A, CardGenerator.troop(TroopColors.RED, 4))
    assert flag.get_last_stacked_player() == PLAYER_A
    assert len(flag.get_stacked_cards(PLAYER_A)) == 2
    assert len(flag.get_stacked_cards(PLAYER_B)) == 0
    assert _check_resolve(flag, state) == PLAYER_UNRESOLVED

    flag.add_stack(PLAYER_A, CardGenerator.troop(TroopColors.RED, 5))
    assert flag.get_last_stacked_player() == PLAYER_A
    assert len(flag.get_stacked_cards(PLAYER_A)) == 3
    assert len(flag.get_stacked_cards(PLAYER_B)) == 0
    assert _check_resolve(flag, state) == PLAYER_UNRESOLVED

    flag.add_stack(PLAYER_B, CardGenerator.troop(TroopColors.BLUE, 4))
    assert flag.get_last_stacked_player() == PLAYER_B
    assert len(flag.get_stacked_cards(PLAYER_A)) == 3
    assert len(flag.get_stacked_cards(PLAYER_B)) == 1
    assert _check_resolve(flag, state) == PLAYER_UNRESOLVED

    flag.add_stack(PLAYER_B, CardGenerator.troop(TroopColors.BLUE, 5))
    assert flag.get_last_stacked_player() == PLAYER_B
    assert len(flag.get_stacked_cards(PLAYER_A)) == 3
    assert len(flag.get_stacked_cards(PLAYER_B)) == 2
    assert _check_resolve(flag, state) == PLAYER_UNRESOLVED

    flag.remove_stack_troops(PLAYER_A, TroopColors.RED, 3)
    assert flag.get_last_stacked_player() == PLAYER_B
    assert len(flag.get_stacked_cards(PLAYER_A)) == 2
    assert len(flag.get_stacked_cards(PLAYER_B)) == 2
    assert _check_resolve(flag, state) == PLAYER_UNRESOLVED

    flag.add_stack(PLAYER_B, CardGenerator.troop(TroopColors.BLUE, 6))
    assert flag.get_last_stacked_player() == PLAYER_B
    assert len(flag.get_stacked_cards(PLAYER_A)) == 2
    assert len(flag.get_stacked_cards(PLAYER_B)) == 3
    assert _check_resolve(flag, state) == PLAYER_UNRESOLVED
示例#14
0
 def _choose_deployed_troops(
     self,
     state: GameState,
     player: int,
     troops_only: bool = False
 ) -> Optional[Tuple[Flag, TroopAndTacticMoraleCard]]:
     flags = state.get_flags()
     while True:
         print("choose the flag: ")
         input_candidates = [0]
         for i, f in enumerate(flags):
             stacked_cards_of_flag = f.get_stacked_cards(player)
             stack_cards_repr = ", ".join(
                 [repr(c) for c in stacked_cards_of_flag])
             if f.is_resolved():
                 print(f"[-]: resolved, {stack_cards_repr}")
             else:
                 input_candidates.append(i + 1)
                 print(f"[{i + 1}]: {stack_cards_repr}")
         print("[0]: return to select the card to play")
         flag_index = await_user_num(input_candidates)
         if flag_index == 0:
             return None
         flag = flags[flag_index - 1]
         cards = flag.get_stacked_cards(player)
         print("choose the card: ")
         input_candidates = [0]
         for i, c in enumerate(cards):
             if troops_only and isinstance(c, TacticCard):
                 print(f"[x]: {repr(c)}")
             else:
                 print(f"[{i + 1}]: {repr(c)}")
                 input_candidates.append(i + 1)
         print("[0]: return to select the flag")
         card_index = await_user_num(input_candidates)
         if card_index == 0:
             continue
         return flag, cards[card_index - 1]
示例#15
0
def start_server():
    """
    Sets up server and begins listening for
    client connections.
    """

    # Use the global variables
    global gamestate
    global client_count

    # Create a socket object
    SERVER = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # Use localhost and grab port from commandline arg
    HOST = sys.argv[1]
    PORT = int(sys.argv[2])

    # Attempt bind to (host, port) pair
    try:
        SERVER.bind((HOST, PORT))
    except socket.error:
        print("Binding to " + HOST + ":" + str(PORT) + "failed.")
        SERVER.close()
        sys.exit()

    # Start listeing for connections, max of two
    SERVER.listen(2)
    print("SERVER listening on " + HOST + ":" + str(PORT))

    # Main server loop
    while True:
        if client_count < 2:
            # Accept incoming connection
            print("Waiting for client {}...".format(client_count + 1))
            connection, address = SERVER.accept()
            print("Established connection with " + address[0] + ":" +
                  str(address[1]))

            # Increment global client counter
            client_count += 1
            # Keep track of whose turn it is
            player_num = 1

            if client_count == 1:
                # Create new gamestate object
                gamestate = GameState()
            else:
                # One client already connected so
                # this connection will be player 2
                player_num = 2

            # Create thread to handle client
            t = threading.Thread(target=client_thread,
                                 args=(connection, player_num))
            t.start()

        if client_count < 2 and gamestate.ready():
            # Game over, exit loop
            break

    print("\nServer closing...")
    SERVER.close()