【发布时间】:2015-02-23 22:34:24
【问题描述】:
我正在努力提高例行程序的速度,并希望得到一些意见。 情况如下:
在锦标赛环境中使用拼字游戏,以下条件适用:
- 锦标赛由 20 名或更多玩家组成。
- 玩的游戏数量在 2 到 14 之间,具体取决于锦标赛。
- 玩家可能会根据锦标赛规模按年龄划分。
我们的目标是为锦标赛进行两个特殊的边注:
- 每场比赛的玩家将随机配对
- 玩家将被随机配对,但每场比赛都有相同的伙伴。
- 适用的条件是边注必须有偶数玩家。 有一个玩家桌:
ID:整数,名称:字符串,除法:整数;
有一个边注表:
PlayerID:整数,RandomeEachGame:布尔值,RandomAllSame:布尔值;
有一个分数表:
PlayerID: Integer, GameNumber: Integer, Score: Integer;
有一个 RandomSidebets 表:
Player1ID:整数;
Player2ID:整数
游戏编号:整数; // 哪个游戏得分
SameAllGames:布尔值; // 如果为真,则配对为同一个伙伴边注,否则为不同伙伴边注。
我正在尝试创建随机配对,但处理似乎过多。我将特定分区中的玩家加载到动态数组中,然后我从动态数组中随机拉出,从数组中删除该项目,因此我不会在每场比赛中多次使用同一个玩家,并对合作伙伴,然后将合作伙伴写到桌子上以了解谁是合作伙伴。
Var
Division : integer;
I, J : integer;
DSourceUsed : TIntArray;
DSource : TIntArray;
rndnum : integer;
Fld1 : TField;
for Division := 1 to NumberofDivisions do begin
SQLTEXT := 'SELECT sb.PlayerID FROM SIDEBET sb ';
SQLTEXT := SQLTEXT + ' INNER JOIN PLAYERS p ON Sb.PlayerID=p.BPlayerID ';
SQLTEXT := SQLTEXT + Format( ' WHERE (sb.RandomEachGame=) AND (p.Division=%d)', [ Division ] );
Qry.SQL.Text := SQLTEXT;
Qry.Open;
if ( Qry.RecordCount > 0 ) then begin
if RandomMethod = mrmAllSame then begin
SetLength( DSource, Qry.RecordCount );
SetLength( DSourceUsed, Qry.RecordCount );
Qry.First;
Fld1 := Qry.FieldByName( 'PlayerID' );
I := 0;
while not Qry.eof do begin
DSourceUsed[ I ] := Fld1.AsInteger;
DSource[ I ] := Fld1.AsInteger;
inc( I );
Qry.Next;
end;
for I := 0 to Qry.RecordCount - 1 do begin
rndnum := RandomRange( 0, Length( DSourceUsed ) - 1 );
DSource[ I ] := DSourceUsed[ rndnum ];
DeleteX( DSourceUsed, rndnum ); // Routine that removes index from array so we don't repeat partners
end;
for I := 0 to Qry.RecordCount - 1 do begin
if not Odd( I ) then begin
for J := 1 to NumberofGames do begin
QryGame.SQL.Text := Format( 'INSERT INTO RandomSideBets (Player11ID, Player2ID, Game) Values (%d, %d, %d, %d)', [ DSource[ I ], DSource[ I + 1 ], J, True ] );
QryGame.Execute;
end;
end;
end;
end
else begin
for J := 1 to NumberOfGames do begin
SetLength( DSource, Qry.RecordCount );
SetLength( DSourceUsed, Qry.RecordCount );
Qry.First;
Fld1 := Qry.FieldByName( 'PlayerID' );
I := 0;
while not Qry.eof do begin
DSourceUsed[ I ] := Fld1.AsInteger;
DSource[ I ] := Fld1.AsInteger;
inc( I );
Qry.Next;
end;
for I := 0 to Qry.RecordCount - 1 do begin
rndnum := RandomRange( 0, Length( DSourceUsed ) - 1 );
DSource[ I ] := DSourceUsed[ rndnum ];
DeleteX( DSourceUsed, rndnum ); // Delete index from array
end;
for I := 0 to Qry.RecordCount - 1 do begin
if not Odd( I ) then begin
QryGame.SQL.Text := Format( 'INSERT INTO RANDOMSIDEBET (Player1ID, Player2ID, Game, SameAllGames) Values (%d, %d, %d, %b)', [ DSource[ I ], DSource[ I + 1 ], J, FALSE ] );
QryGame.Execute;
end;
end;
end;
end;
end;
Qry.Close;
end;
【问题讨论】:
-
您的数据库引擎可能支持以随机顺序返回查询结果的方法。这将消除代码中的几个步骤,因为您只需将读取的每两个结果配对即可。您也许甚至可以将整个事情表达为单个
INSERT INTO SELECT语句。 -
我不明白你为什么在这里涉及数据库。这不只是一个概率问题吗?
标签: delphi