Вопрос по math, javascript – Как разделить количество игроков на 2 команды случайным образом несколько раз, каждый раз по-разному?

2

У меня есть математическая проблема в моем коде JavaScript. Мне нужно случайным образом разделить определенное количество игроков на 2 команды, чтобы каждый раз & # x2013; если игроки хотят играть снова & # x2013; команды формируются снова, и они должны быть разными, пока не сформированы все комбинации.

Допустим, у меня 4 игрока, поэтому все комбинации следующие:
[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]

Однако, поскольку сторона команды не учитывает, существует только 3 различные комбинации:

[1,2] vs [3,4]
[1,3] vs [2,4]
[1,4] vs [2,3]

Когда количество сыгранных игр превышает количество комбинаций, оно должно начинаться заново ... то есть случайным образом выбирается одна из трех комбинаций, случайным образом выбирается следующая и так далее ...

Но есть поворот ... и мои математические навыки идут довольно далеко на юг, когда число игроков нечетное, и один из игроков должен отдохнуть одну игру. Итак, с 5 игроками все комбинации совпадают (последний номер - это отдыхающий игрок):

[1,2] vs [3,4] [5]
[1,2] vs [3,5] [4]
[1,2] vs [4,5] [3]

[1,3] vs [2,4] [5]
[1,3] vs [2,5] [4]
[1,3] vs [4,5] [2]

[1,4] vs [2,3] [5]
[1,4] vs [2,5] [3]
[1,4] vs [3,5] [2]

[1,5] vs [2,3] [4]
[1,5] vs [2,4] [3]
[1,5] vs [3,4] [2]

[2,3] vs [4,5] [1]
[2,4] vs [3,5] [1]
[2,5] vs [3,4] [1]

Как в JavaScript возможно сформировать эти команды?

Одна вещь, которая пришла в голову, состояла в том, чтобы дать каждому игроку уникальное значение (10 ^ x), например:

player1.value = 10;
player2.value = 100;
player3.value = 1000;
player4.value = 10000;

... и затем при циклическом формировании команд проверяют, равно ли одно общее значение команды последним значениям.

Может кто-нибудь математически / более талантливо, пожалуйста, помогите мне с этой проблемой кодирования. Спасибо!

Ваш Ответ

2   ответа
1

Для четных случаев просто выберите числа, которые вы не использовали случайным образом, и составьте команды.

Для нечетных случаев, выберите число случайным образом, чтобы сидеть вне. Тогда оставшиеся числа похожи на четный случай.

По "выбору номеров, которые вы не использовали случайным образом, и составьте команды" Вы имеете в виду индекс массива всех игроков, верно? Как не сформировать ту же команду снова? И что еще более важно, как я делаю эти команды? Не могли бы вы привести пример реального / псевдокода. ти micadelli
3

Использование значений является хорошей идеей, но если вы сделаете их битовыми масками, легче будет проверить, какие игроки были подобраны. например

player1.value = 1 
player2.value = 2
player3.value = 4
//(dynamically player n would have value 1 << (n-1) )

Проверяя маску с другим игроком, можно проверить, были ли они уже связаны, так как у них уже есть собственное значение маски, они никогда не смогут соответствовать себе. Что касается случайного фактора, я думаю, что самый простой способ - сначала создать все комбинации, как вы это делали в своем примере, и использовать массив этих комбинаций в качестве основы для выбора случайного совпадения. Если вы считаете, что этот подход является хорошим способом, но у вас возникли проблемы с его реализацией, я могу попробовать составить пример кода.

Edit вот пример кода, надеюсь, что комментарии помогут разобраться в их значении Edit2 изменились командные комбинации

    var playercount = 5; 

    //add players
    var players = new Array();
    for (var i = 0; i < playercount; i++) {
        players[i] = { Index: i, Mask: 1 << i, Name: "Player" + (i + 1), toString: function () { return this.Name; } };
        //about the 1 << i:  "<<" is a so called bit wise shift to the left.
        //1 << i has the same outcome as 2 to the power of i
    }

    //the line below would print all players
    //for (var pi in players) { var p = players[pi]; document.write(p + " (Mask:" + p.Mask + ")<br>"); } document.writeln("<br>"); 

    //create all possible team combinations
    var teams = new Array();

    var playersPerTeam = Math.floor(playercount / 2);
    function Team(){
        this.list = new Array();
        this.mask = 0;
        this.count = 0;
        this.full  =false;

        this.Add = function (i) {
            this.list.push(players[i]);
            this.mask |= players[i].Mask;
            this.full = ++this.count === playersPerTeam;
        }

        this.toString = function () {
            var res = "", cnt = this.list.length;
            for (var i = 0; i < cnt; i++) {
                if (i > 0)
                    res += i == cnt - 1 ? " and " : ",";
                res += this.list[i].Name;
            }
            return res;
        }
    }


    function addplayers() {
        var indices = new Array(playersPerTeam);
        for (var p = 0; p < playersPerTeam; p++) indices[p] = p;
        var l = playersPerTeam - 1;

        function addteam() {
            var team = new Team();
            for (var p = 0; p < playersPerTeam; p++) team.Add(indices[p]);
            teams.push(team);
        }

        function addplayer(start, depth) {
            var target = players.length - playersPerTeam + depth + 1;
            var team;
            for (var i = start; i < target; i++) {
                indices[depth] = i;
                if (depth == l)
                    addteam();
                else
                    addplayer(i + 1, depth + 1);
            }
        }

        addplayer(0, 0);

    }
    addplayers();




    //the line below would print the team combinations
    //for (var te in teams) { var t = teams[te]; document.write(t + " (mask:" + t.mask + ")<br>"); } document.writeln("<br>");

    //create matches
    var matches = new Array();
    //the matches can be created in the same way as the teams, only the first team cannot have players of the second team
    for (var i = 0; i < teams.length; i++) {
        for (var j = i + 1; j < teams.length; j++) {
            var t1 = teams[i], t2 = teams[j];
            if ((t1.mask & t2.mask) === 0) //this is where the masks come in, 
                matches.push({ Team1: t1, Team2: t2, toString: function () { return this.Team1 + " versus " + this.Team2 } });
        }
    }

    //randomize matches. Instead of picking a random match per turn, we can randomize at the
    //start, so we know all the matches in advance.
    //this can be done by using a sort on the array with a random index
    //NB, this isn't the most random randomness (or whatever you call it LOL). For better shuffling
    //there are several alternatives, but perhaps this one is enough
    matches.sort(function() { return (parseInt(Math.random() * 100) % 2);});


    //the line below prints the matches
    for (var mi in matches) { document.write(matches[mi] + "<br>"); } document.writeln("<br>");
звучит хорошо & # x2013; создавать все комбинации, а затем выбирать случайным образом & # x2013; но ничего не понял в «битовой маске» ни "1" & lt; (П-1) & Quot ;. Некоторый пример кода был бы великолепен! micadelli
Привет, я создал дополнительный вопрос здесь:stackoverflow.com/questions/12046888/… если бы вы могли взглянуть, спасибо. micadelli
Ах, извините, не получил это. Я изменил создание команды. Забавно, что рекурсия, связанная с этим, относительно сложнее, чем маскировка: D В любом случае, о маскировке, & amp; возвращает значение с битами, установленными в позиции, где обе маски имеют бит. Таким образом, если оно равно 0, биты не соответствуют, что мы и ищем. Подробнее о битовой маскировке здесь:en.wikipedia.org/wiki/Mask_(computing)
качественный товар! Попытался запустить это, и это работает, хотя я до сих пор не получил "маску": Players [i] .Mask | игроки [J] .Mask & Quot; и "если ((t1.mask & t2.mask) === 0)" ... но я буду. Тем не менее, я не знаю, было ли это из-за моего плохого английского, но это делит игроков на команду из 2 игроков, и я только хотел разделить всех игроков на 2 отдельные команды. Итак, 9 игроков будут разделены 5 против 4. Как код должен быть изменен. micadelli
Извините за поздний ответ, я отсутствовал на кофе и ужин :) Я добавил образец в пост выше

Похожие вопросы