游戏竞技对抗赛排队分组问题
游戏中要排一个对抗赛, 可以是nVSn, 如3v3, 5v5, 20v20, 玩家可以以小队形式参加排队, 也可以个人参加排队.
用一个数据记录每种队的的个数, 没有这种类型的队, 用0表示, 下面是一个11v11的组合. 如下
local strData = "5,8,7,3,1,0,0,1,0,1,0";
表示1个人的队伍为5个, 2人的队伍为8个, ...11人的队伍为0个.
============================
function Split(szFullString, szSeparator)
local nFindStartIndex = 1
local nSplitIndex = 1
local nSplitArray = {}
while true do
local nFindLastIndex = string.find(szFullString, szSeparator, nFindStartIndex)
if not nFindLastIndex then
nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, string.len(szFullString))
break
end
nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, nFindLastIndex - 1)
nFindStartIndex = nFindLastIndex + string.len(szSeparator)
nSplitIndex = nSplitIndex + 1
end
return nSplitArray
end
function GetList(list)
local usedlist = {};
i = #list;
total = 0;
repeat
local num = tonumber(list[i]);
if num > 0 and total + i <= #list then
usedlist[#usedlist + 1] = i;
total = total + i;
list[i] = tostring(num - 1);
if(total == #list) then
return usedlist;
end
else
i = i - 1;
end
until i < 1
return nil;
end
function PrintTable(list)
for i = 1, #list
do
str = string.format("index %d: value = %s", i, list[i]);
print(str);
end
end
--1人队伍有5个, 2人队伍有8个,..11人队伍有0个.
local strData = "5,8,7,3,1,0,0,1,0,1,0";
local list = Split(strData, ",");
--GetList会修改list的值, 移除已经用过的值
local usedlist = GetList(list);
local usedlist2 = GetList(list);
PrintTable(usedlist);
PrintTable(usedlist2);
local nFindStartIndex = 1
local nSplitIndex = 1
local nSplitArray = {}
while true do
local nFindLastIndex = string.find(szFullString, szSeparator, nFindStartIndex)
if not nFindLastIndex then
nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, string.len(szFullString))
break
end
nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, nFindLastIndex - 1)
nFindStartIndex = nFindLastIndex + string.len(szSeparator)
nSplitIndex = nSplitIndex + 1
end
return nSplitArray
end
function GetList(list)
local usedlist = {};
i = #list;
total = 0;
repeat
local num = tonumber(list[i]);
if num > 0 and total + i <= #list then
usedlist[#usedlist + 1] = i;
total = total + i;
list[i] = tostring(num - 1);
if(total == #list) then
return usedlist;
end
else
i = i - 1;
end
until i < 1
return nil;
end
function PrintTable(list)
for i = 1, #list
do
str = string.format("index %d: value = %s", i, list[i]);
print(str);
end
end
--1人队伍有5个, 2人队伍有8个,..11人队伍有0个.
local strData = "5,8,7,3,1,0,0,1,0,1,0";
local list = Split(strData, ",");
--GetList会修改list的值, 移除已经用过的值
local usedlist = GetList(list);
local usedlist2 = GetList(list);
PrintTable(usedlist);
PrintTable(usedlist2);
上面可以找出另几个队伍参加对抗赛, 一组为10人队与一个1人队合成一方, 另一组是一个8人队与另外一个3人队合成一方.
另外还要一个表格来记录, 1人队具体玩家的id, 2人队具体玩家的id, 3人队具体玩家的id...
...
===================
新版本:
--分隔字符串变为表格
function Split(szFullString, szSeparator)
local nFindStartIndex = 1
local nSplitIndex = 1
local nSplitArray = {}
while true do
local nFindLastIndex = string.find(szFullString, szSeparator, nFindStartIndex)
if not nFindLastIndex then
nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, string.len(szFullString))
break
end
nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, nFindLastIndex - 1)
nFindStartIndex = nFindLastIndex + string.len(szSeparator)
nSplitIndex = nSplitIndex + 1
end
return nSplitArray
end
--从队列中取得一种队伍分法
--list表如果长度为n, 就会尝试找出一种n人的方案
function GetList(list)
local usedlist = {};
i = #list;
total = 0;
repeat
local num = tonumber(list[i]);
if num > 0 and total + i <= #list then
usedlist[#usedlist + 1] = i;
total = total + i;
list[i] = tostring(num - 1);
if(total == #list) then
return usedlist;
end
else
i = i - 1;
end
until i < 1
return nil;
end
--打印表格中的数据
function PrintTable(list)
for i = 1, #list
do
str = string.format("index %d: value = %s", i, list[i]);
print(str);
end
end
--表格转成字符串, 用seperator相间隔
function List2Str(list, seperator)
local str = "";
for i = 1, #list do
str = str..tostring(list[i])..seperator
end
return TrimEnd(str, seperator);
end
--去除结尾指定一个字符
function TrimEnd(str, seperator)
if(string.sub(str, -1) == seperator) then
return string.sub(str, 0, -2);
end
return str;
end
--在players列表中增加players
function AddPalyers(strPlayers, players)
--修改strPlayers中的players
local list = Split(strPlayers, "|");
local count = table.getn(Split(players, ","));
if(list[count] == "") then
list[count] = players;
else
list[count] = list[count]..","..players;
end
--重组字符串
return List2Str(list, "|");
end
--移除players列表中的player count为位置, 也是移除的个数
function RemovePlayers(strPlayers, count)
local list = Split(strPlayers, "|");
local players = Split(list[count], ",");
if(#players <= count) then
list[count] = "";
else
local str = "";
for i = count + 1, #players do
str = str..tostring(players[i])..","
end
list[count] = TrimEnd(str, ",");
end
return List2Str(list, "|");
end
--得到队列中玩家总人数
function GetPlayerCount(strQueue)
local list = Split(strQueue, ",");
local total = 0;
for i = 1, #list do
total = total + tonumber(list[i]) * i;
end
return total;
end
--检查玩家是否在列表中
function PlayerIsInList(strPlayers, playerId)
local strPlayerId = tostring(playerId);
local list = Split(strPlayers, "|");
for i = 1, #list do
if list[i] ~= nil and list[i] ~= "" then
local players = Split(list[i], ",");
for j= 1, #players do
if players[j] == strPlayerId then
return true;
end
end
end
end
return false;
end
--1人队伍有5个, 2人队伍有8个,..11人队伍有0个.
local strQueue = "5,8,7,3,1,0,0,1,0,1,0";
local list = Split(strQueue, ",");
--GetList会修改list的值, 移除已经用过的值
local usedlist = GetList(list);
if(usedlist ~= nil) then
PrintTable(usedlist);
local usedlist2 = GetList(list);
if(usedlist2 ~= nil) then
PrintTable(usedlist2);
end
end
print(List2Str(list, ","));
--strPlayers各队类型之间用|相隔, 各player之间用, 相隔. 同一类型的队在一起, 用,相隔
local strPlayers = "123,123,213|213,213,123,213|||||||||";
local result = AddPalyers(strPlayers, "444,4444,444,4444");
print(result);
result = RemovePlayers(strPlayers, 2);
print(result);
print(tostring(GetPlayerCount(strQueue)));
print(PlayerIsInList(strPlayers, 723));
local nFindStartIndex = 1
local nSplitIndex = 1
local nSplitArray = {}
while true do
local nFindLastIndex = string.find(szFullString, szSeparator, nFindStartIndex)
if not nFindLastIndex then
nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, string.len(szFullString))
break
end
nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, nFindLastIndex - 1)
nFindStartIndex = nFindLastIndex + string.len(szSeparator)
nSplitIndex = nSplitIndex + 1
end
return nSplitArray
end
--从队列中取得一种队伍分法
--list表如果长度为n, 就会尝试找出一种n人的方案
function GetList(list)
local usedlist = {};
i = #list;
total = 0;
repeat
local num = tonumber(list[i]);
if num > 0 and total + i <= #list then
usedlist[#usedlist + 1] = i;
total = total + i;
list[i] = tostring(num - 1);
if(total == #list) then
return usedlist;
end
else
i = i - 1;
end
until i < 1
return nil;
end
--打印表格中的数据
function PrintTable(list)
for i = 1, #list
do
str = string.format("index %d: value = %s", i, list[i]);
print(str);
end
end
--表格转成字符串, 用seperator相间隔
function List2Str(list, seperator)
local str = "";
for i = 1, #list do
str = str..tostring(list[i])..seperator
end
return TrimEnd(str, seperator);
end
--去除结尾指定一个字符
function TrimEnd(str, seperator)
if(string.sub(str, -1) == seperator) then
return string.sub(str, 0, -2);
end
return str;
end
--在players列表中增加players
function AddPalyers(strPlayers, players)
--修改strPlayers中的players
local list = Split(strPlayers, "|");
local count = table.getn(Split(players, ","));
if(list[count] == "") then
list[count] = players;
else
list[count] = list[count]..","..players;
end
--重组字符串
return List2Str(list, "|");
end
--移除players列表中的player count为位置, 也是移除的个数
function RemovePlayers(strPlayers, count)
local list = Split(strPlayers, "|");
local players = Split(list[count], ",");
if(#players <= count) then
list[count] = "";
else
local str = "";
for i = count + 1, #players do
str = str..tostring(players[i])..","
end
list[count] = TrimEnd(str, ",");
end
return List2Str(list, "|");
end
--得到队列中玩家总人数
function GetPlayerCount(strQueue)
local list = Split(strQueue, ",");
local total = 0;
for i = 1, #list do
total = total + tonumber(list[i]) * i;
end
return total;
end
--检查玩家是否在列表中
function PlayerIsInList(strPlayers, playerId)
local strPlayerId = tostring(playerId);
local list = Split(strPlayers, "|");
for i = 1, #list do
if list[i] ~= nil and list[i] ~= "" then
local players = Split(list[i], ",");
for j= 1, #players do
if players[j] == strPlayerId then
return true;
end
end
end
end
return false;
end
--1人队伍有5个, 2人队伍有8个,..11人队伍有0个.
local strQueue = "5,8,7,3,1,0,0,1,0,1,0";
local list = Split(strQueue, ",");
--GetList会修改list的值, 移除已经用过的值
local usedlist = GetList(list);
if(usedlist ~= nil) then
PrintTable(usedlist);
local usedlist2 = GetList(list);
if(usedlist2 ~= nil) then
PrintTable(usedlist2);
end
end
print(List2Str(list, ","));
--strPlayers各队类型之间用|相隔, 各player之间用, 相隔. 同一类型的队在一起, 用,相隔
local strPlayers = "123,123,213|213,213,123,213|||||||||";
local result = AddPalyers(strPlayers, "444,4444,444,4444");
print(result);
result = RemovePlayers(strPlayers, 2);
print(result);
print(tostring(GetPlayerCount(strQueue)));
print(PlayerIsInList(strPlayers, 723));