【发布时间】:2015-02-03 15:48:46
【问题描述】:
我有一个脚本用于计算垒球(实际上是任何运动)的比赛对决。该脚本使用循环式计算来创建对决,以便每支球队至少与对方球队交手一次。此特定脚本允许您输入团队数量和游戏数量。根据比赛的数量,您可能会让球队互相比赛 2 或 3 次。因此,我还让脚本反转对战以模拟主客场比赛,因此如果比赛超过一次,任何球队都不会在主场占据优势。
当显示最终输出时,我的问题就出现了。我没有意识到对于每场“比赛”(所有球队的一系列对决),一些球队在同一场比赛/周中被列出两次。我们不希望任何球队在同一周/比赛中打两次。 在脚本中,我获取了一组比赛并将它们转换为一个哈希表,其中将比赛分组为球队数/2。
如何重新排列存在重复值的哈希表值并将它们与另一个“游戏”交换以创建没有团队玩两次的游戏(见下文)?
# Show input box popup and return the value entered by the user.
function Read-InputBoxDialog([string]$Message, [string]$WindowTitle, [string]$DefaultText)
{
Add-Type -AssemblyName Microsoft.VisualBasic
return [Microsoft.VisualBasic.Interaction]::InputBox($Message, $WindowTitle, $DefaultText)
}
#define numbers of teams and games maybe use fields later
$teams = Read-InputBoxDialog -Message "Number of teams:" -WindowTitle "Teams" -DefaultText "3"
if ($teams -eq "0") { Write-Host "You clicked Cancel" }
elseif ([int]$teams -gt "2" -and [int]$teams -lt 13) { Write-Host -foreground yellow "$teams Teams" }
else { Write-Host "You entered $teams which is higher than the 12 teams this was designed for" }
$fields = Read-InputBoxDialog -Message "Number of fields:" -WindowTitle "Teams" -DefaultText "2"
if ($fields -eq $null) { Write-Host "You clicked Cancel" }
elseif ([int]$fields -gt "0" -and [int]$fields -lt "4") { Write-Host -foreground green "$fields Fields" }
else { Write-Host "You entered $fields which is higher than the 3 fields this was designed for" }
$gamess= "0"
$allplay= [int]$teams-1
$gamess = Read-InputBoxDialog -Message "Number of Games:" -WindowTitle "Games" -DefaultText "12"
if ($gamess -eq 0) { Write-Host "No value specified" }
elseif ([int]$gamess -lt $allplay) {Write-host -foreground red "You must have more than 2 minus the number of teams or there won't be enough matches" }
elseif ([int]$gamess -lt "34") { Write-Host -foreground cyan "$gamess Games" }
else { Write-Host "You entered $gamess which is more than 3 times the number of teams" }
#build array of teams
$a= 1..$teams
#if teams is odd number add a bye team to symbolize a bye for the opponent, thus making the number of teams even again
if ($teams % 2 -eq 1){$a += "bye"}
$parts = $a.length/2
#functions for game and rotating arrays borrowed most of the code for this from: http://www.hanselman.com/blog/2008WindowScriptingGamesAdvancedPowerShellEvent7.aspx
[array]$global:games = $nul
function rotateArray($a)
{
$first, $rest = $a
$a = $rest + $first
return $a
}
#function for creating away matchups 1 at a time
function makeGamesA($a)
{
$i = 0;
while($i -lt $a.Length/2)
{
$global:games = $global:games + ($a[$i].ToString() + " v " + $a[$a.Length-1-$i].ToString())
$i++
}
}
#function for creating home matchups one at a time
function makeGamesH($a)
{
$i = 0;
while($i -lt $a.Length/2)
{
$global:games = $global:games + ($a[$a.Length-1-$i].ToString() + " v " + $a[$i].ToString())
$i++
}
}
#here we create X as the variable that decides whether this is an away or home game and run the matching function based on even or odd value.
$x = 1
$z = 0
while($z -lt $gamess)
{
if ($z -eq [int]$x*($a.length-1)) {$x++}
if ($x % 2 -eq 1) {makeGamesA($a)}
else {makeGamesH($a)}
# hold on to the first one
$first, $rest = $a
#rotate the rest
$rest = rotateArray($rest)
$a = [array]$first + $rest
$z++
}
#Collect into long array of match ups
$a = [collections.arraylist]$global:games
#convert values into hash table for each game played
$b = @{}
$count = 1
$a |% {$b[$count % $gamess] += @($_);$count++}
$b= $b.getEnumerator() | sort-object Name
# Setting formatting specifications for each column in a hash table:
$column1 = @{expression="Name"; width=10; `
label="Game"; alignment="left"}
$column2 = @{expression="Value"; width=40; `
label="Team Matchups: Home vs. Away"; alignment="right"}
$f= $b | Format-table $column1, $column2
#print it out on the screen.
$f
read-host -foreground cyan "press any key to when finished"
【问题讨论】:
标签: arrays powershell hashtable