我正在开发一个类似于Risiko!的游戏的桌面应用程序,基于一些数据库程序。
我需要为每个玩家分配一组行,这些行彼此不等于其他玩家。
我尝试过类似的东西,但不起作用:
`create or replace PROCEDURE "giveterritory"
(idpartita NUMBER,nr_partecipanti number )
is
begin
DECLARE
CURSOR cur_file IS
SELECT *
FROM Player
WHERE idgame = Player.idgame ;
var_cur cur_file%ROWTYPE;
cont number ;
nr_territories_gioc_prec number ;
G1_Terr int ;
G2_Terr int ;
G3_Terr int ;
G1_ID number;
G2_ID number;
G3_ID number;
begin
cont:=0 ;
for var_cur in cur_file
loop
cont := cont + 1 ;
update territory
set Player_owner = var_cur.id_Player
where ROWNUM = MOD( MOD ( number_RANDOM(),42 ) ,ROWNUM );
G1_Terr := var_cur.number_territories_tot ; -- mi salvo i territories del primo Player
G1_ID := var_cur.id_Player ;
end if ;
if (cont=2 ) then
update territory
set Player_owner = var_cur.id_Player
where ROWNUM = MOD( MOD ( number_RANDOM(),42 -G1_Terr ) , ROWNUM ) and id_territory NOT IN ( select Player_owner from territory where ;
G2_Terr := var_cur.number_territories_tot ;
end if ;
if (cont=3 ) then
update territory
set Player_owner = var_cur.id_Player
where ROWNUM <= 42 - G1_Terr - G2_Terr;
--where ROWNUM <= 42 - var_cur.number_territories_tot * 2 ;
G3_Terr := var_cur.number_territories_tot ;
end if ;
end loop;
end;
end;`
number_random代码:
create or replace FUNCTION "NUMBER_RANDOM"
return NUMBER
is
numbrndm int;
begin
select dbms_random.value(1,99999999) into numbrndm
from dual;
return numbrndm;
end;
答案 0 :(得分:0)
如果我理解正确,您是否尝试为每位玩家分配一组随机区域?
如果是这样,请按随机顺序对区域进行排序,并将其分配给循环播放器。这是MERGE
语句,应该这样做。对于任何轻微的语法错误,我深表歉意:我现在不在Oracle数据库前面。
MERGE INTO territory t
USING (
WITH players AS ( SELECT rownum player#, id_player
FROM player
WHERE idgame=:idgame ),
players_count AS ( SELECT count(*) players_count FROM players )
-- Get the id_player for each assignment
SELECT assignedt.id_territory, p.id_player
FROM
(
-- Assign the randomly-ordered territories to players in round-robin format
SELECT randt.id_territory,
mod(rownum, pc.players_count)+1 player#
FROM (
-- Query the territories in a random order
SELECT t.id_territory
FROM territory t
ORDER BY dbms_random.random ) randt, players_count pc
-- Optional:
-- ... add a where clause to limit rownum <= some number to make
-- ... sure each player receives an even number of territories.
-- ... You'd need the count of territories to do that.
) assignedt inner join players p on p.player# = assignedt.player#
) u
ON ( u.id_territory = t.id_territory )
WHEN MATCHED THEN UPDATE SET t.id_player = u.id_player;
答案 1 :(得分:0)
我在每行的SQL选择中放了一个随机数列。然后,您可以直接在SQL中通过随机数订购记录集。
为玩家和地区列表执行此操作。
此示例适用于任意数量的地区和玩家。如果领土没有平均分配,那么玩家将获得一个额外的领域。
我们将以随机顺序遍历地区列表一次。我们将逐步完成播放器列表,直到结束,然后再次重新加载播放器列表。这种情况会根据需要多次发生。
可能需要修复此语法或逻辑。我没有Oracle实例来测试它。
CREATE OR REPLACE PROCEDURE giveterritory (pID_GAME PLS_INTEGER) IS
CURSOR c_player IS
SELECT id_player, dbms_random.value() rnd
FROM players
WHERE id_game = pID_GAME
ORDER BY 2 desc;
--
CURSOR c_territory IS
SELECT id_territory, dbms_random.value() rnd
FROM territories
WHERE id_game = pID_GAME
FOR UPDATE of id_player
ORDER BY 2 desc;
--
l_player_row c_player%ROWTYPE;
l_territory_row c_territory%ROWTYPE;
BEGIN
OPEN c_player;
FETCH c_player into l_player_row;
--
FOR r in c_territory
LOOP
UPDATE territories
SET id_player = l_player_row.id_player
WHERE CURRENT OF c_territory;
--
FETCH c_player INTO l_player_row;
IF c_player%NOTFOUND THEN
CLOSE c_player;
OPEN c_player;
FETCH c_player INTO l_player_row;
END IF;
END LOOP;
END;