悉野小楼

导航

游戏竞技对抗赛排队分组问题

游戏中要排一个对抗赛, 可以是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);

上面可以找出另几个队伍参加对抗赛, 一组为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 ~= nilthen
    PrintTable(usedlist);
    local usedlist2 = GetList(list);
    if(usedlist2 ~= nilthen
        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));

posted on 2012-09-11 17:29  悉野  阅读(602)  评论(0编辑  收藏  举报