Created
April 17, 2018 21:25
-
-
Save eliotb/82d970d48f283ae4b01ff8940e05734f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import logging | |
import string | |
def is_yes(prompt="", default=True): | |
"""Ask user to enter Y or N in response to a prompt. | |
returns True if answer is Y, Falseif N or default if answer is empty""" | |
if default: | |
prompt += " [Y/n]" | |
else: | |
prompt += " [y/N]" | |
while True: | |
response = input(prompt).upper() | |
if len(response) == 0: | |
return default | |
elif response.startswith("Y"): | |
return True | |
elif response.startswith("N"): | |
return False | |
else: | |
print("Please enter Y or N") | |
def input_positive(prompt="Enter a number:"): | |
"""Get a number from the user. Keep retrying until one is entered""" | |
while True: | |
response = input(prompt) | |
try: | |
num = int(response) | |
except ValueError: | |
print("Oops, please enter a number") | |
if num >= 0: | |
break | |
else: | |
print("Please enter a positive number") | |
return num | |
def print_player_list(pl, title="Player Pool"): | |
print() | |
if title is not None: | |
print(title) | |
if not pl: | |
print("[empty]") | |
for i, n in enumerate(pl): | |
print(i + 1, n) | |
def print_team(team): | |
print_player_list(team[1], 'Team: ' + team[0]) | |
def add_players(players): | |
"""Add players to the player pool""" | |
while True: | |
while True: | |
player = input("Name of player to add (empty to finish): ") | |
if player in players: | |
print("There is already a player with that name." | |
" Try a different one.") | |
else: | |
break | |
if player == "": | |
break | |
players.append(player) | |
return players | |
def remove_players(players, num_teams): | |
"""Remove a specified number of players from the member_list | |
""" | |
# This is simpler than add_players, because there is aready a player | |
# list to validate input against | |
# Ensure we retain at least one player per team! | |
player = "nobody" | |
while len(players) > num_teams and player != "": | |
players, player = select_player( | |
players, | |
"Remove a player (empty to finish)", | |
allow_empty=True) | |
return players | |
def edit_player_list(players, num_teams): | |
"""Allow user to add and remove players, ensuring that the final number | |
of players available is a multiple of the number of teams. | |
""" | |
while True: | |
print("Player list must finish up with a multiple of %d players" | |
" so the teams can be even." % num_teams) | |
players = add_players(players) | |
players = remove_players(players, num_teams) | |
print_player_list(players) | |
num_players = len(players) | |
# Must have same number of players per team | |
if num_players % num_teams == 0: | |
break | |
print("Player list not multiple of %d" | |
" Add or remove some more players:" % num_teams) | |
assert(num_players % num_teams == 0) | |
return players | |
def select_player(players, prompt="", remove=True, allow_empty=False): | |
"""Prints the player list, then | |
asks the user to select a player by number or name. | |
returns remaining player list, selected player name. | |
If remove==true, selected player is removed from players list | |
If allow_empty==true, and empty player name can be returned, the | |
player list is unchanged. | |
""" | |
if len(players) > 1: | |
while True: | |
print_player_list(players) | |
response = input( | |
(prompt + | |
". Choose a player by name or number: ") | |
) | |
if response == "" and allow_empty: | |
return players, "" | |
if response in players: | |
selected_player = response | |
break | |
else: | |
try: | |
selected_player = players[int(response) - 1] | |
break | |
except (IndexError, ValueError) as e: | |
pass | |
print("\n*** Oops, that player is not in the list. Try again. ***") | |
else: | |
selected_player = players[0] | |
print("And finally", selected_player, "goes to", prompt) | |
logging.debug("Selected %s", selected_player) | |
if remove: | |
players.remove(selected_player) | |
return players, selected_player | |
def select_players(players, teams): | |
"""The teams take turns to choose players until there are none left. | |
Returns list of teams | |
""" | |
print("Ok teams - let's begin selecting players") | |
while len(players): | |
for team in teams: | |
players, selected_player = select_player(players, "Team " + team[0]) | |
team[1].append(selected_player) | |
print_player_list(team[1], "Team " + team[0]) | |
return teams | |
def get_team_name(prompt, teams): | |
while True: | |
team_name = input(prompt) | |
if len(team_name) < 1: | |
print("Oops, you must enter some letters") | |
elif (team_name[0] in string.whitespace or | |
team_name[0] not in string.printable): | |
print("Oops, name must start with something sensible") | |
elif team_name in [team[0] for team in teams]: | |
print("Oops, that name has already been taken") | |
else: | |
break | |
return team_name | |
def initialise_teams(num_teams): | |
"""Initialise team list. Each team is a tuple (team_name, member_list) | |
The member list starts off empty. | |
""" | |
teams = [] | |
for i in range(num_teams): | |
team_name = get_team_name( | |
"What is the name of team#%d? " % (i + 1), teams) | |
teams.append((team_name, [])) | |
return teams | |
def build_teams(players, num_teams): | |
teams = initialise_teams(num_teams) | |
teams = select_players(players, teams) | |
return teams | |
def game(players=[], num_teams=0): | |
print_player_list(players, "Initial Player Pool") | |
if not num_teams: | |
num_teams = input_positive("How many teams do you want to make? ") | |
players = edit_player_list(players, num_teams) | |
num_players = len(players) | |
print("There are %d players to sort into %d teams of %d ..." % | |
(num_players, num_teams, num_players / num_teams)) | |
teams = build_teams(players, num_teams) | |
print('=' * 40) | |
print("\nThe teams have been selected!") | |
for t in teams: | |
print_team(t) | |
if __name__ == '__main__': | |
logging.basicConfig(level=logging.WARNING) | |
# Note: The number of players must be even. Two per row makes this clear | |
players = [ | |
"Thor", "Odin", | |
"Frigg", "Balder", | |
"Tyr", "Freyr", | |
"Freyja", "Loki", | |
"Bragi", "Forsetti", | |
"Jones", "Mozart" | |
] | |
game(players, num_teams=2) | |
#game([]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment