几年前我做过这样的事情.这是很久以前的事了,我不确定我会以同样的方式做到(它没有真正扩展到双重限制等)你如何输出它可能是一个不同的问题.我使用了2002 - 2003年的表格.今天肯定有更好的技术.
锦标赛中的回合数量为log2(玩家)+ 1,只要玩家是您在上面指定的数字之一.使用此信息,您可以计算出有多少回合.最后一轮包含最终的赢家.
我存储了类似这样的玩家信息(调整这个以获得最佳实践)
Tournament
Name
Size
Players
Tournament
Name
Position (0 to tournament.size - 1)
Rounds
Tournament
Round
Position (max halves for each round)
Winner (player position)
Run Code Online (Sandbox Code Playgroud)
请注意,在下面的所有查询中,我都不包括"锦标赛= [锦标赛]"来识别锦标赛.他们都需要它.
使用一个查询查询它并根据不同轮次的需要将其拆分出来相当简单.你可以做这样的事情来获得下一个对手(假设有一个).对于第1轮,你只需要根据它是偶数还是奇数来获得下一个/前一个玩家:
SELECT * FROM Players WHERE Position = PlayerPosition + 1
SELECT * FROM Players WHERE Position = PlayerPosition - 1
Run Code Online (Sandbox Code Playgroud)
对于下一轮,如果用户的最后一个Round.Position是偶数,你需要做出下一个位置有赢家的说法:SELECT Player FROM Rounds WHERE Position = [playerRoundPosition] - 1
如果没有,下一个玩家没有决定,或者存在差距(不允许间隙!)
如果用户上次Round.Position很奇怪,你需要确保他们下面有一个用户并且他们下面有一个胜利者,否则他们应该自动晋升到下一轮(因为没有人可以玩)
SELECT COUNT(*) FROM Players WHERE Position > [Player.Position]
SELECT Player FROM Rounds WHERE Position = [playerRoundPosition] + 1
Run Code Online (Sandbox Code Playgroud)
最后,我非常确定你可以使用类似下面的内容来减少你写的查询:
SELECT Player FROM Rounds WHERE Position + Position % 2 = [playerRoundPosition]
SELECT Player FROM Rounds WHERE Position - Position % 2 = [playerRoundPosition]
Run Code Online (Sandbox Code Playgroud)
更新:
看着我的原帖,我发现Rounds表有点暧昧.实际上,它应该命名为匹配.比赛是两名获胜者之间的比赛.决赛桌看起来应该更像这样(只改名):比赛锦标赛圆位(每轮最多一半)获胜者(球员位置)
希望这会让它更加清晰.当两个玩家相互竞争时(在匹配中),您将该信息存储在此匹配表中.这个特定的实现取决于比赛的位置,以了解哪些球员参加.
我开始将轮数编号为1,因为在我的实现中更清楚.如果你愿意,你可以选择0(或甚至做一些完全不同的东西,如后退词).
在第一轮比赛中,比赛1表示球员1和2参加.在比赛2中,球员3-4参加.基本上第一轮只是球员的位置和位置+ 1参加.如果您需要更多访问权限,也可以将此信息存储在轮次表中.每次我在程序中使用这些数据时,我都需要所有的回合和玩家信息.
在第一轮比赛之后,你看看最后一轮比赛.在第2轮比赛中,比赛1和2的获胜者参加比赛.第2轮比赛,比赛2,比赛3和4的获胜者参加.它应该看起来很熟悉,除了它在第1轮之后使用匹配表.我确信有更好的方法来完成这个重复的任务,我只是没有足够的时间来重构代码(它被重构,只是不是那样的许多).