async def manage(self): await super().manage() address = self.server_address print_header(f"Joining game @ {address.host}:{address.port}") await self._connect_to_server() game = await self._wait_for_game() await self.play_game(game)
async def handle(e: rnd.RoundEnd) -> None: get_username = lambda p: game.get_player(p).username # noqa await pause() print_header("Round end", filler="—") draw_game(game, reveal=True) print(">>>>> The round has ended! <<<<<") if e.reason == rnd.RoundEnd.Reason.EMPTY_DECK: print("There are no cards remaining in the deck.") if len(e.tie_contenders) == 1: print( f"{get_username(e.winner)} wins with a {e.winner.hand.card}, " f"which is the highest card among those remaining.") else: card = mitt.first(p.hand.card for p in e.tie_contenders) contenders = list(map(get_username, e.tie_contenders)) contenders_str = ( f"Both {contenders[0]} and {contenders[1]}" if len(contenders) == 2 else f"Each of {', '.join(contenders[:-1])} and {contenders[-1]}" ) print(f"{contenders_str} have the highest card: a {card}.") print( f"But {get_username(e.winner)} has a higher sum of discarded" f" values, so they win." if len(e.winners) == 1 else f"And they each have the same sum of discarded values," f" so they {'both' if len(contenders) == 2 else 'all'} win" f" in a tie.") elif e.reason == rnd.RoundEnd.Reason.ONE_PLAYER_STANDING: print( f"{get_username(e.winner)} is the only player still alive, " f"so they win the round.")
async def manage(self): import loveletter_cli.server_script await super().manage() print_header( f"Hosting game on {', '.join(f'{h}:{p}' for h, p in self.server_addresses)}" ) server_process = multiprocessing.Process( target=loveletter_cli.server_script.main, kwargs=dict( logging_level=LOGGER.getEffectiveLevel(), host=self.hosts, port=self.port, party_host_username=self.user.username, ), ) LOGGER.debug(f"Starting server process: %s", server_process) server_process.start() try: self.client = HostClient(self.user.username) connection = await self._connect_localhost() game = await self._ready_to_play() await self.play_game(game) await self.client.send_shutdown() await connection finally: if (exc_info := sys.exc_info()) == (None, None, None): LOGGER.info("Waiting on server process to end") else:
def main(logging_level: int = logging.INFO): setup_logging(logging_level) print_header("Welcome to Love Letter (CLI)!", filler="~") user = ask_user() print(f"Welcome, {user.username}!") mode = ask_play_mode() runners = {PlayMode.JOIN: join_game, PlayMode.HOST: host_game} while True: try: print() return runners[mode](user) except Exception as e: traceback.print_exc() time.sleep(0.2) print("Unhandled exception while running the session:") print_exception(e) time.sleep(0.2) choice = ask_valid_input( "What would you like to do?", choices=ErrorOptions, default=ErrorOptions.RETRY, ) if choice == ErrorOptions.RETRY: continue elif choice == ErrorOptions.QUIT: return else: assert False, f"Unhandled error option: {choice}"
async def handle(e: rnd.Turn) -> None: if e.turn_no > 1: await pause() player = game.get_player(e.current_player) is_client = player is game.client_player possessive = "Your" if is_client else f"{player.username}'s" print_header(f"{possessive} turn", filler="—") draw_game(game) if is_client: print(">>>>> It's your turn! <<<<<\a") else: print(f"It's {player.username}'s turn.")
async def _show_game_end(game: RemoteGameShadowCopy): assert game.ended print_header("GAME OVER", filler="#") end: loveletter.game.GameEnd = game.state # noqa try: winner = end.winner except ValueError: print("There were multiple winners!") print( f"{', '.join(p.username for p in end.winners)} all won in a tie." ) else: if winner is game.client_player: print("You win!") else: print(f"{winner.username} wins!")
async def handle(e: loveletter.game.PlayingRound) -> None: if e.points_update: # print updates from last round print("Points gained:") for player, delta in (+e.points_update).items(): print(f" {player.username}: {delta:+}") print() print("Leaderboard:") width = max(map(len, (p.username for p in game.players))) + 2 for i, (player, points) in enumerate(game.points.most_common(), start=1): print( f"\t{i}. {player.username:{width}}" f"\t{points} {pluralize('token', points)} of affection" ) print() await pause() print_header(f"ROUND {e.round_no}", filler="#")
def host_game(user: UserInfo): print_header("Hosting a game") mode = ask_valid_input( "Choose the server_addresses's visibility:", choices=HostVisibility, default=HostVisibility.PUBLIC, ) addresses = {"local": get_local_ip()} if mode == HostVisibility.PUBLIC: addresses["public"] = get_public_ip() hosts = ("",) else: hosts = ( "127.0.0.1", str(addresses["local"]), ) # allow either localhost or local net. print(f"Your address: {' | '.join(f'{v} ({k})' for k, v in addresses.items())}") port = ask_port_for_hosting() session = HostCLISession(user, hosts, port) asyncio.run(session.manage())
def join_game(user: UserInfo): print_header("Joining game") address = ask_address_for_joining() session = GuestCLISession(user, address) asyncio.run(session.manage())