Esempio n. 1
0
def tournament(players=None):
    """
    Runs a Magic limited event (draft or sealed).
    players: List of player names (defaults to DEFAULT_PLAYERS, with the option
             to change the list).
    """
    if not players:
        players = DEFAULT_PLAYERS
        change = DEFAULT_STRING
        while change:
            change = menu("Players", players, footer="Enter a name to add or "
                          "remove a player (ENTER for none).")
            if change and (change in players):
                players -= {change}
            elif change:
                players.add(change)

    players = {p: Player(p) for p in players}

    items = MAIN_MENU.keys()
    items.sort()
    call = menu("Main Menu", items, input_range=range(1, len(items) + 1))
    while MAIN_MENU[items[int(call) - 1]]:
        MAIN_MENU[items[int(call) - 1]](players)
        call = menu("Main Menu", items, input_range=range(1, len(items) + 1))
Esempio n. 2
0
def seat_players(players):
    active = active_players(players)
    names = active.keys()
    random.shuffle(names)

    table_count = number_of_tables(len(active))
    table_size = int(math.ceil(float(len(active)) / table_count))

    print "Players: {}".format(len(active))
    print "Tables: {}".format(table_count)
    print "Seats per Table: {}".format(table_size)

    rows = []

    for table in xrange(table_count):
        for seat in xrange(table_size):
            index = (table * table_size) + seat
            if len(active) <= index:
                break
            else:
                active[names[index]].table = table + 1
                active[names[index]].seat = seat + 1
                rows.append((table + 1, seat + 1, names[index]))

    menu("Seating", *zip(*rows), headers=["Table", "Seat", "Player"],
         footer="ENTER to continue.")
Esempio n. 3
0
def standings(players):
    player_list = players.values()
    player_list.sort(reverse=True)

    names = [p.name for p in player_list]
    points = [p.points() for p in player_list]
    tiebreaker_1 = [p.tb_1() for p in player_list]
    tiebreaker_2 = [p.tb_2() for p in player_list]
    tiebreaker_3 = [p.tb_3() for p in player_list]
    dropped = ["" if p.active else "Yes" for p in player_list]

    menu("Standings", names, points, tiebreaker_1, tiebreaker_2, tiebreaker_3,
         dropped, footer="ENTER to continue.", headers=["Player", "Points",
         "TB 1", "TB 2", "TB 3", "Dropped?"])
Esempio n. 4
0
def drop_player(players):
    drop = DEFAULT_STRING
    while drop:
        drop = menu("Drop Players", players.keys(), ["" if players[k].active
                    else "Yes" for k in players.keys()], headers=["Player",
                    "Dropped?"], footer="Enter a name to drop that player "
                    "(ENTER for none).", input_range=players.keys()+[""])
        if drop: players[drop].drop()
Esempio n. 5
0
def player_stats(players):
    p = DEFAULT_STRING
    while p:
        p = menu("Display Player Stats", players.keys(), ["" if
                    players[k].active else "Yes" for k in players.keys()],
                    headers=["Player", "Dropped?"], footer="Enter a name to "
                    "view that player's stats. (ENTER for none).",
                    input_range=players.keys()+[""])
        if p: players[p].display()
Esempio n. 6
0
def label_episodes(series, directory, season, episode, dvd):
    episodes = season_information(series, dvd)

    if season not in episodes:
        print "No information found for season {}.".format(season)
        return

    files = os.listdir(directory)

    # Remove directories and files that don't match the pattern, if any.
    files = [f for f in files if os.path.isfile(os.path.join(directory, f)) and
             extension(f).lower() in FILE_TYPES]

    if len(files) < 1:
        print 'Found no media files in "{}".'.format(directory)
        return

    files.sort()

    rename = []
    s, e = season, episode - 1
    print 'Found {} media files in "{}".'.format(len(files), directory)
    print "Identifying episodes in season {}...".format(s)

    for f in files:
        if e >= len(episodes[s]):
            if s + 1 in episodes:
                e = 0
                s += 1
                print "Moving on to season {}...".format(s)
            else:
                print "Unable to rename {}: no episodes remain.".format(f)
                rename.append((f, None))
                continue

        file_name = create_file_name(series, episodes[s][e], extension(f))
        rename.append((f, file_name))

        e += 1

    choice = menu("Confirm New File Names", *zip(*rename),
                  headers=["Current Name", "New Name"],
                  input_range=["yes", "y", "no", "n"], footer="Would you like "
                  "to proceed with renaming the files? (yes/no)")

    if choice[0] == "n":
        return

    for r in rename:
        if r[1]:
            print "Renaming {} to {}...".format(*r)
            os.rename(os.path.join(directory, r[0]), os.path.join(directory,
                r[1]))
        else:
            print "Skipping {}...".format(r[0])

    print "Done."
Esempio n. 7
0
def pair_players(players):
    active = active_players(players)
    reported = [active[k].reported for k in active.keys()]
    pairs = []

    # Warn if some players have reported and some haven't.
    if any(reported) and not all(reported):
        print "Warning: Reporting is incomplete! Are you sure you want to "   \
              "re-pair?"
        response = DEFAULT_STRING
        while response[0].lower() not in ['y', 'n']:
            response = raw_input(">> ")

        if response[0].lower() == 'n':
            return

    # Begin a new round, by setting everyone's "reported" status to false.
    for p in active.keys():
        active[p].reported = False
        active[p].opponent = None

    # If no one has any points, it's the first round, so pair people by seat.
    bye_player = None
    player_list = active.values()
    player_count = len(active)
    table = 1
    if sum([p.points() for p in player_list]) == 0:
        if any([p.seat == None for p in player_list]):
            print "Warning: You must seat players before pairing! (ENTER to " \
                  "continue.)"
            raw_input(">> ")
            return

        # For each draft table, pair players as far as possible. Then pair any
        # leftover players together between tables. Then, if anyone is left
        # that player gets a bye.

        unpaired = []
        draft_tables = [[p for p in player_list if p.table == t] for t in
                        {p.table for p in player_list}]
        for current_players in draft_tables:
            current_players.sort(key=lambda p: p.seat)
            player_count = len(current_players)

            if player_count % 2 != 0:
                # The player in the last seat is not paired at this table.
                unpaired.append(current_players[player_count - 1])
                player_count -= 1

            # Each player will face an opponent halfway around their table.
            for i in xrange(player_count / 2):
                opponent = current_players[(i + (player_count / 2)) %
                                           player_count]

                current_players[i].opponent = opponent
                opponent.opponent = current_players[i]
                pairs.append((table, current_players[i].name, opponent.name))

                current_players[i].table = table
                opponent.table = table
                table += 1

        player_count = len(unpaired)
        # Pair any players that couldn't be paired with their own draft tables.
        if player_count:
            if player_count % 2 != 0:
                # The player in the last seat is not paired at this table.
                bye_player = unpaired[player_count - 1]
                player_count -= 1

            # Each player will face an opponent halfway around their table.
            for i in xrange(player_count / 2):
                opponent = unpaired[(i + (player_count / 2)) % player_count]

                unpaired[i].opponent = opponent
                opponent.opponent = unpaired[i]
                pairs.append((table, unpaired[i].name, opponent.name))

                unpaired[i].table = table
                opponent.table = table
                table += 1

    # First, assign BYE to worst player that hasn't had a BYE. Then, for each
    # player, generate a list of opponents they could play... Not sure that'd
    # work, and I don't have time to implement it... So never mind!

    # Pair based upon points.
    else:
        # player_list.sort(key=lambda p: p.points(), reverse=True)
        player_list.sort(reverse=True)

        # Each player faces an opponent not previously faced of similar rank.
        for i in xrange(player_count):
            for j in xrange(i + 1, player_count):
                if not player_list[i].opponent and not                        \
                        player_list[j].opponent and player_list[i].name not in\
                        [p.name for p in player_list[j].past_opponents]:
                    player_list[i].opponent = player_list[j]
                    player_list[j].opponent = player_list[i]

                    pair = (table, player_list[i].name, player_list[j].name)
                    pairs.append(pair)

                    player_list[i].table = table
                    player_list[j].table = table
                    table += 1
                    break
            else:
                if not player_list[i].opponent:
                    bye_player = player_list[i]

    if bye_player:
        pairs.append((table, bye_player.name, BYE))
        bye_player.opponent, BYE.opponent = BYE, bye_player
        bye_player.table, BYE.table = table, table

    menu("Pairings", *zip(*pairs), headers=["Table", "Player", "Opponent"],
         footer="ENTER to continue.")
Esempio n. 8
0
def report_results(players):
    active = active_players(players)
    reported = [active[k].reported for k in active.keys()]

    while not all(reported):
        pairs, choices = [], []
        for p in active.values():
            if p.opponent and not p.reported:
                if p.opponent is BYE:
                    p.reported = True
                    p.byes += 1
                    p.opponent = None
                elif p.name not in [i.name for sub in pairs for i in sub if
                                    isinstance(i, Player)]:
                    pairs.append((p.table, p, p.opponent))
                    choices.append(p.table)

        if not pairs:
            print "Warning: You must pair players before reporting! (ENTER "  \
                  "to continue.)"
            raw_input(">> ")
            return

        pairs.sort()    # Sort by table number.
        choices.sort()

        choice = menu("Report Match Results", *zip(*pairs), 
                      headers=["Table", "Player", "Opponent"],
                      footer="Select a table to report (ENTER to cancel).",
                      input_range=choices+[""])
        if not choice: return

        # Convert from table number to list index.
        choice = choices.index(int(choice))
        p = pairs[choice][1]
        wins = menu("Match Results: {} versus {}".format(p.name,
                    p.opponent.name), ["How many games did {} "
                    "win?".format(p.name)], footer="ENTER to cancel.",
                    input_range=[0, 1, 2, ""])
        if not wins: continue
        losses = menu("Match Results: {} versus {}".format(p.name,
                      p.opponent.name), ["How many games did {} "
                      "win?".format(p.opponent.name)], footer="ENTER to "
                      "cancel.", input_range=[0, 1, 2, ""])
        if not losses: continue
        draws = menu("Match Results: {} versus {}".format(p.name,
                     p.opponent.name), ["How many games did ended in a draw?"],
                     footer="ENTER to cancel.", input_range=[0, 1, 2, ""])
        if not draws: continue

        wins, losses, draws = int(wins), int(losses), int(draws)
        games = sum([wins, losses, draws])
        if games < 1 or games > 3:
            print "Warning: Matches are best two of three. You have reported" \
                  " an invalid number of matches. (ENTER to continue.)"
            raw_input(">> ")
            continue

        p.matches += 1
        p.opponent.matches += 1
        p.games += games
        p.opponent.games += games

        p.match_wins += wins > losses
        p.opponent.match_wins += wins < losses
        p.match_draws += wins == losses
        p.opponent.match_draws += wins == losses

        p.game_wins += wins
        p.opponent.game_wins += losses
        p.game_draws += draws
        p.opponent.game_draws += draws
        
        p.reported, p.opponent.reported = True, True
        p.past_opponents.append(p.opponent)
        p.opponent.past_opponents.append(p)
        p.opponent.opponent = None
        p.opponent = None

        reported = [active[k].reported for k in active.keys()]

    print "All players have reported. (ENTER to continue.)"
    raw_input(">> ")
Esempio n. 9
0
def edit_pairings(players):
    active = active_players(players)
    player_list = active.values()
    reported = [p.reported for p in player_list]
    opponents = [p.opponent for p in player_list]

    if any(reported):
        print "Warning: You cannot edit pairings after reporting has begun!"  \
              " (ENTER to continue.)"
        raw_input(">> ")
        return

    if not any(opponents):
        print "Warning: You must pair players before editing the pairings."   \
              " (ENTER to continue.)"
        raw_input(">> ")
        return

    while True:
        player_list.sort(key=lambda p: p.table)
        pairs = [(player_list[i].table, player_list[i].name,
                 player_list[i].opponent.name) for i in range(0,
                 len(player_list), 2)]

        player_1 = menu("Pairings", *zip(*pairs), headers=["Table", "Player",
                        "Opponent"], footer="Enter a player's name to change "
                        "that player's opponent. (ENTER to cancel.)",
                        input_range=[p.name for p in player_list] + [""])
        if not player_1: return

        other_players = [p.name for p in player_list if p.name != player_1]
        print "Pair {} with which player? (ENTER to cancel.)".format(player_1)

        player_2 = DEFAULT_STRING
        while player_2:
            player_2 = raw_input(">> ")
            if player_2 in other_players:
                player_1, player_2 = players[player_1], players[player_2]
                opponent_1, opponent_2 = player_1.opponent, player_2.opponent

                player_1.opponent = player_2
                player_2.opponent = player_1
                player_2.table = player_1.table

                opponent_1.opponent = opponent_2
                opponent_2.opponent = opponent_1
                opponent_1.table = opponent_2.table

                text = "{} is now paired with {}. ".format(player_1.name,
                       player_2.name)

                if opponent_1 is BYE:
                    text += "As a result, {} now has a BYE.".format(
                            opponent_2.name)
                elif opponent_2 is BYE:
                    text += "As a result, {} now has a BYE.".format(
                            opponent_1.name)
                else:
                    text += "As a result, {} is now paired with {}.".format(
                            opponent_1, opponent_2)

                text += " (ENTER to continue.)"

                print text
                raw_input(">> ")
                break
Esempio n. 10
0
def season_information(series, dvd):
    # Randomly selects a mirror to connect to.
    response = urllib2.urlopen(MIRROR_URL.format(key=KEY))
    xml = response.read()
    root = et.fromstring(xml)

    mirrors = root.findall("Mirror")
    if len(mirrors) < 1:
        print "Warning: No mirrors found. Failing over to TheTVDB.com..."
        mirror = "http://thetvdb.com"
    else:
        mirror = grab(mirrors[random.randint(0, len(mirrors) - 1)],
                      "mirrorpath")
        print "Mirror: {}".format(mirror)

    # Identify the series by name, and retrieve its ID from TheTVDB.com.
    print "Search: {}".format(series)

    series = series.replace(" ", "%20")
    response = urllib2.urlopen(SERIES_URL.format(mirror=mirror, name=series))
    xml = response.read()
    root = et.fromstring(xml)

    series = root.findall("Series")

    if len(series) == 1:
        series_id = grab(series[0], "seriesid")
        series_name = grab(series[0], "SeriesName")

    else:
        rows = []
        for i in xrange(len(series)):
            name = grab(series[i], "SeriesName")
            aired = grab(series[i], "FirstAired")
            if aired is not None:
                aired = "{:%Y}".format(datetime.datetime.strptime(aired,
                                       "%Y-%m-%d"))
            rows.append((i + 1, name, aired))

        choice = menu("Matches", *zip(*rows), headers=["#", "Series Name",
                      "First Aired"], input_range=range(1, len(series) + 1),
                      footer="To select a series, enter its number.")
        series_id = grab(series[int(choice) - 1], "seriesid")
        series_name = grab(series[int(choice) - 1], "SeriesName")

    print "Series Name: {}".format(series_name)
    print "Series ID: {}".format(series_id)

    # Retrieve the episode list for the series.
    response = urllib2.urlopen(EPISODE_URL.format(mirror=mirror, key=KEY,
                               series_id=series_id))
    xml = response.read()
    root = et.fromstring(xml)

    episodes = [{"season": grab(e, SEASON, int),
                "episode": grab(e, EPISODE, int),
                "dvd_season": grab(e, DVD_S, int),
                "dvd_episode": grab(e, DVD_E, int),
                "name": grab(e, EPISODE_NAME),
                "date": grab(e, AIR_DATE, DATE_CONVERSION),
                "description": grab(e, DESCRIPTION)}
                for e in root.findall("Episode")]

    if dvd:
        dvd_episodes = [{"season": e["dvd_season"],
                        "episode": e["dvd_episode"],
                        "name": e["name"],
                        "date": e["date"],
                        "description": e["description"]}
                        for e in episodes if e["dvd_season"] is not None and
                        e["dvd_episode"] is not None]

        # If no DVD information is defined, just use the aired information.
        if dvd_episodes: episodes = dvd_episodes

    # Show table of seasons, with the number of episodes in them.
    episodes.sort(key=lambda e: e["episode"])
    episodes.sort(key=lambda e: e["season"])

    season_list = list({e["season"] for e in episodes})
    season_list.sort()

    # Turn episodes into a dictionary, organizing the episodes into seasons.
    # The reason I chose a dict of lists, rather than a list of lists, is
    # because some shows have a season 0 (which usually means specials, etc.),
    # while others start at season 1. A dict allows us to index directly to
    # season 1 in either case.
    episodes = {s: [e for e in episodes if e["season"] == s]
                for s in season_list}

    # Optionally display episode information for each season.
    done = False
    while not done:
        s = menu("Season Information", season_list, [len(episodes[s]) for s in
                 season_list], headers=["Season", "Episodes"],
                 footer="Enter a season number for more information. (ENTER to"
                 " continue.)", input_range=season_list+[""])
        if s:
            s = int(s)
            rows = [(e["episode"], e["name"], e["date"],
                    short_description(e["description"])) for e in episodes[s]]
            #print rows
            menu("Season {}".format(s), *zip(*rows), headers=["Episode",
                 "Name", "Air Date", "Description"],
                 footer="ENTER to continue.")
        else:
            done = True

    return episodes