Bash Shell 脚本:构建你的疯狂三月赛事预测

作者:Jim Hall

我必须承认,我并不真正关注篮球。但是,我喜欢与同事互动,而且每年春天,当我的工作同事填写他们的 NCAA 疯狂三月篮球赛事预测时,我总是感到有点被排除在外。如果你的办公室和我的一样,似乎每个人都非常兴奋地构建他们的预测,关注篮球比赛并在办公室博彩中玩乐。

我也想参与,但我只是对球队了解不够,无法做出明智的决定来填写我的疯狂三月赛事预测。所以几年前,我找到了另一种方法。我编写了一个程序来为我构建篮球赛事预测。

预测体育比赛结果的计算模型并不新鲜。稍微谷歌一下就会发现诸如毕达哥拉斯期望模型或其他基于先前球队表现来预测未来比赛结果的算法等方法。但这需要对体育统计数据进行一些研究,并跟踪每个球队整个赛季的表现。对我来说工作量太大了,所以我使用了另一种方法,这种方法对于我的许多书呆子同胞来说应该很熟悉:“龙与地下城模型”。

没错!你可以应用简单的 D16 方法来构建疯狂三月篮球赛事预测。这有多科学?可能不是很科学,但这足以让我在关注疯狂三月篮球赛中有所参与,但又不足以让我对我的预测表现不佳感到特别难过。这对我来说就足够了。

让我们构建一个 shell 脚本来构建 NCAA 疯狂三月篮球赛事预测。我将在以下假设下创建脚本

  1. NCAA 疯狂三月篮球赛事预测根据 NCAA 对 64 支大学篮球队的排名进行种子排序,分为四个赛区,排名从第 1 到第 16。

  2. NCAA 疯狂三月篮球赛事预测始终以相同的比赛初始化:#1 对阵 #16,#8 对阵 #9,#5 对阵 #12,等等。

  3. 排名第 1 的球队应该比排名第 16 的球队表现更好,但排名第 8 的球队应该与排名第 9 的球队表现大致相同。

有了这些假设,让我们研究一下 D16 方法。在桌面角色扮演游戏中,你可能会掷一个 1D16 来确定遭遇的结果。你会将 1D16 的值与玩家的统计数据(例如敏捷或力量)进行比较。这种投掷假设了基于玩家相对实力的结果的“概率”或“可能性”。

类似地,你可以将 1D16 的结果与球队的 NCAA 排名进行比较,以确定球队表现的结果。排名第 1 的球队应该是一支强队,所以让我们假设排名第 1 的球队有 16 分之 15 的“机会”获胜,以及 16 分之 1 的“机会”输球。在没有任何其他输入的情况下,如果 1D16 值大于等于 2,则排名第 1 的球队将获胜,如果 1D16 值为 1,则排名第 1 的球队将输球。

因此,你可以掷一个 1D16 来确定球队“A”是否获胜,以及掷一个 1D16 来确定球队“B”是否输球,反之亦然。如果两者一致,你就知道比赛的结果。

在 bash 中,每次引用$RANDOM环境变量时,都会生成一个随机数。该变量返回一个介于 0 和 32,767 之间的值,但你需要一个介于 1 和 16 之间的数字。你可以使用模数运算符将随机数的范围缩小到 16 个值。使用模 16返回一个介于 0 和 15 之间的值。将其调整为介于 1 和 16 之间的数字很简单,只需加法


d16=$(( ( $RANDOM % 16 ) + 1 ))

这是一个 bash 函数,它假设两个输入是两支球队(球队 A 和球队 B)的 NCAA 排名。使用 D16 方法,该函数预测比赛的获胜者,并在函数的退出值中返回获胜球队


function guesswinner {
        rankA=$1
        rankB=$2

        d16A=$(( ( $RANDOM % 16 ) + 1 ))
        d16B=$(( ( $RANDOM % 16 ) + 1 ))

        if [ $d16A -gt $rankA -a $d16B -le $rankB ] ; then
                # team A wins and team B loses
                return $rankA
        elif [ $d16A -le $rankA -a $d16B -gt $rankB ] ; then
                # team A loses and team B wins
                return $rankB
        else
                # no winner
                return 0
        fi
}

当然,D16 方法假设两个结果一致。虽然这种方法在大多数情况下都有效,但也有可能两个结果都无法产生获胜者。一个简单的解决方法是重试。我发现结果通常在一次或几次投掷中达成一致,但对于势均力敌的比赛,例如 #1 球队对阵 #2 球队,你可能在尝试太多次后不得不放弃。

有了这个假设,让我们编写一个 bash 函数来重复调用guesswinner直到两个结果一致。该函数打印出对阵情况,打印出获胜者,并通过退出值返回获胜球队


function winner {
        teamA=$1
        teamB=$2

        echo -n "$teamA vs $teamB : "

        count=0

        # iterate and return winner, if found

        while [ $count -lt 10 ] ; do
                guesswinner $teamA $teamB
                win=$?

        if [ $win -gt 0 ] ; then
                # winner found
                echo $win
                return $win
        fi

                count=$(( $count + 1 ))
        done

        # no winner found, return a default winner

        echo "=$teamA"
        return $teamA
}

最后一个echo语句中的 = 帮助你查看该函数是否在尝试十次后仍无法确定获胜者。

有了这两个函数,运行所有第一轮比赛以确定获胜者,然后迭代这些获胜者以构建剩余的篮球赛事预测就非常简单了。一些echo语句帮助你跟踪预测中的每一轮。该函数通过返回值返回预测的获胜者


function playbracket {
        echo -e '\nround 1\n'

        winner 1 16
        round1A=$?

        winner 8 9
        round1B=$?

        winner 5 12
        round1C=$?

        winner 4 13
        round1D=$?

        winner 6 11
        round1E=$?

        winner 3 14
        round1F=$?

        winner 7 10
        round1G=$?

        winner 2 15
        round1H=$?

        echo -e '\nround 2\n'

        winner $round1A $round1B
        round2A=$?

        winner $round1C $round1D
        round2B=$?

        winner $round1E $round1F
        round2C=$?

        winner $round1G $round1H
        round2D=$?

        echo -e '\nround 3\n'

        winner $round2A $round2B
        round3A=$?

        winner $round2C $round2D
        round3B=$?

        echo -e '\nround 4\n'

        winner $round3A $round3B

        return $?
}

最后,你只需要为四个赛区中的每一个调用playbracket函数。你将得到“最终四强”,其中包含每个赛区的获胜者,但我将把这些比赛的最终决定留给你自己解决


#!/bin/bash

function guesswinner {
        ...
}
function winner {
        ...
}
function playbracket {
        ...
}

echo -e '\n___ MIDWEST ___'

playbracket

echo -e '\n___ EAST ___'

playbracket

echo -e '\n___ WEST ___'

playbracket

echo -e '\n___ SOUTH ___'

playbracket

每次运行脚本时,你都会生成一个新的 NCAA 疯狂三月篮球赛事预测。它是完全随机的,基于类似于 龙与地下城 的 D16 预测,因此预测的每次迭代都会有所不同。这是我的示例运行


$ ./basketball.sh 

___ MIDWEST ___

round 1

1 vs 16 : 1
8 vs 9 : 8
5 vs 12 : 5
4 vs 13 : 4
6 vs 11 : 6
3 vs 14 : 3
7 vs 10 : 10
2 vs 15 : 2

round 2

1 vs 8 : 1
5 vs 4 : 5
6 vs 3 : 6
10 vs 2 : 2

round 3

1 vs 5 : 1
6 vs 2 : 2

round 4

1 vs 2 : 1

___ EAST ___

round 1

1 vs 16 : 1
8 vs 9 : 8
5 vs 12 : 5
4 vs 13 : 4
6 vs 11 : 6
3 vs 14 : 3
7 vs 10 : 7
2 vs 15 : 2

round 2

1 vs 8 : 8
5 vs 4 : 4
6 vs 3 : 3
7 vs 2 : 7

round 3

8 vs 4 : 4
3 vs 7 : 7

round 4

4 vs 7 : 7

___ WEST ___

round 1

1 vs 16 : 1
8 vs 9 : 8
5 vs 12 : 5
4 vs 13 : 4
6 vs 11 : 6
3 vs 14 : 3
7 vs 10 : 7
2 vs 15 : 2

round 2

1 vs 8 : 1
5 vs 4 : 5
6 vs 3 : 6
7 vs 2 : 2

round 3

1 vs 5 : 1
6 vs 2 : 2

round 4

1 vs 2 : 1

___ SOUTH ___

round 1

1 vs 16 : 1
8 vs 9 : 8
5 vs 12 : 12
4 vs 13 : 4
6 vs 11 : 11
3 vs 14 : 3
7 vs 10 : 10
2 vs 15 : 2

round 2

1 vs 8 : 1
12 vs 4 : 4
11 vs 3 : 3
10 vs 2 : 2

round 3

1 vs 4 : 1
3 vs 2 : 3

round 4

1 vs 3 : 3

根据我的经验,D16 预测在前几轮效果很好,但通常预测 #1 球队将进入第四轮。这不是一个非常科学的方法,但我会分享我的计算机生成的预测通常比我办公室里的其他人表现更好。

使用脚本构建你的 NCAA 疯狂三月篮球赛事预测的目的不是为了剥夺游戏的乐趣。相反,由于我对篮球不太熟悉,以编程方式构建我的预测让我能够参与办公室篮球博彩。它很有趣,而且不需要太熟悉体育统计数据。我的脚本给了我一个关注比赛的理由,但如果我的预测表现不佳,我不会有情感上的投入。这对我来说就足够了。

Jim Hall 是一位开源软件倡导者和开发者,可能最出名的是 FreeDOS 的创始人。Jim 还非常积极地参与 GNOME 等开源软件项目的可用性测试。在工作中,Jim 是 Hallmentum 的 CEO,这是一家 IT 执行咨询公司,帮助 CIO 和 IT 领导者进行战略规划和组织发展。

加载 Disqus 评论