【CS50】Lab6:World Cup世界杯

296 阅读1分钟

Background

模拟世界杯球队出线的过程。 使用 Python 进行 coding。

截屏2021-12-21 下午2.38.14.png

几个需要注意的地方

在 Python 中创建一个 list

  • teams = []
  • 创建了一个 list,命名为 teams。

读取文件

  • 注意csv.DictReader这个功能,可以将读取内容每一行作为 dictionary。
  • list.append()在 Python 中,在一个 list 中增加 item 的表达。
import csv
import sys

with open (filename) as f:
    reader = csv.DictReader(f)
    # csv.DictReader功能:逐行读取文件,并且将每一行作为一个dictionary
    for team in reader:
    # 这里把 reader 读取到的内容作为`team`这个 dictionary
        team ["rating"] = int ( team["rating"] )
        # 记得 Python 读取到的数字都是 string 形式的,如果后续需要进行计算,还是需要转化成 int 格式。
        teams.append(team)
        # 把转化后的 team 这个 dictionary添加到 teams 这个 list 中

Simulate_Game 和 Simulate_Round

首先来归纳一下逻辑,如何产生 world cup 的冠军?

  1. 首先,把球队两两分组,每两队之间比赛,得到一个 winner。
  2. 这些 winners 构成了一群新的参赛者,这一步可以认为是返回步骤 1 重新开始一次两两比拼。
  3. 步骤 1 和 2 不断重复,直到最后剩下两只队伍,并且角逐出了冠军。

sumulate_game

那么在这个逻辑中,我们首先需要一个最小的 function,即**「如何得出两个球队比赛的 winner?」**。 实现过程:

  • 用之前我们从 csv 中读到的每个 team 的 rating 来进行预测。
  • random.random():返回随机生成的一个实数,它在[0,1)范围内。
def simulate_game(team1, team2):
    # 模拟两队之间比赛。如果 team1 赢了,return True,如果 team2 赢了,return False。
    rating1 = team1["rating"]
    rating2 = team2["rating"]
    probability = 1 / (1 + 10 ** ((rating2 - rating1) / 600))
    return random.random() < probability

simulate_round

上一个功能定义了两支队伍比赛如何挑出 winner 的规则。 这个功能中,我们需要完成:挑选两只队伍进行比赛,并输出 winner 的规则。 实现过程:

def simulate_round(teams):
    winners = []
    # 定义一个新的 list,命名为 winners
    for i in range(0, len(teams), 2):
        if simulate_game(teams[i], teams[i + 1]):
            winners.append(teams[i])
        else:
            winners.append(teams[i + 1])
    return winners
    # 两两之间进行比赛,这样全部过一次后,产生了一群winners,他们将作为新的 teams 再次进行比赛。

simulate_tournament

最后我们需要定义这样循环的次数。 只要 teams 中有大于 2 只队伍,就要一直比赛下去。 而比赛的 teams 其实每一次都被 update 成了 simulate_round中输出的 winners。

实现过程:

def simulate_tournament(teams):
    while len(teams) > 1:
        teams = simulate_round(teams)
        # update 过程:输出的 winners 作为下一次的 teams
    return teams[0]["team"]