0

わかりました、 CodeReviewの何人かのランダムな男が私にこれをここに渡すように頼んだので、それでいいです。

この回答に基づいた組み合わせ生成コードがあります: StackOverflow 回答

基本的な考え方は、プレーヤーのグループ (合計 6 ~ 14 人) があり、残りのプレーヤーがその試合のために休んでいる間に、それぞれ 3 人のプレーヤーを持つ 2 つのチームを形成する必要があるということです。コードは、可能なすべての一致を生成します。問題は、次の試合のセットアップをランダムに選択する必要があるときに発生します。これにより、プレーヤーは、可能であれば 1 つのゲームだけを休むことができます。さらに、各チームは、これまでのゲームのように同じプレイヤーがチームとしてプレーすることなく、可能な限りランダムにする必要があります。

問題を明確にするために、これは大したことではありません。配列から次の一致を選択するだけで発生します。

        Team 1 | Team 2 | Resting
Game 1: A B C    D E F    G H I J
Game 2: A B D    C E F    G H I J
Game 3: A B E    C D F    G H I J

...これは問題ないように見えますが:

        Team 1 | Team 2 | Resting
Game 1: A B C    D E F    G H I J
Game 2: C G H    F I J    A B D E
Game 3: A D I    B E J    C F G H

コードを変更して、次のようになりました。

  • ビットマスクを持つプレーヤー
  • ビットマスクを持つチーム
  • 2 つのチームと 1 つの休憩グループ (それぞれにビットマスクがある) の配列に一致します

質問
選手、チーム、休息などの試合コンポーネントのそれぞれにマスク値があるとすると、次の試合はどのように計算すればよいですか? ビットごとの演算子では、どのように? 休んでいるすべてのプレイヤーを配列にプッシュし、次のゲームで休んでいるプレイヤーを除外します。完全な混乱でうまくいかなかったマルチアレイのことを試しました。だから、私はこれについて助けが必要です。ビットマスクを扱うのはこれが初めてです。

コード

players: [],
teams: [],
matches: [],
Team: function () {
    this.list           = [];
    this.mask           = 0;
    this.count          = 0;
    this.full           = false;
    this.Add            = function (i) {
        this.list.push(GAME.players[i]);
        this.mask       |= GAME.players[i].mask;
        this.full       = ++this.count === 3;
    }
},

Resting: function () {
    this.list           = [];
    this.mask           = 0;
    this.count          = 0;
    this.full           = false;
    this.Add            = function (i) {
        this.list.push(GAME.players[i]);
        this.mask       |= GAME.players[i].mask;
        this.full       = ++this.count === (GAME.players.length - 2*3);
    }
},

addPlayers: function () {
    var indexes         = [],
        p,
        playersPerTeam  = 3,
        l               = playersPerTeam - 1;

    for (var p = 0; p < playersPerTeam; p += 1) {
        indexes[p] = p;
    }

    function addteam() {
        var team = new GAME.Team();

        for (var p = 0; p < playersPerTeam; p++) {
            team.Add(indexes[p]);
        }

        GAME.teams.push(team);
    }

    function addplayer(start, depth) {
        var target = GAME.players.length - playersPerTeam + depth + 1;

        for (var i = start; i < target; i++) {
            indexes[depth] = i;
            if (depth == l) {
                addteam();
            } else {
                addplayer(i + 1, depth + 1);
            }
        }
    }

    addplayer(0, 0);
}

// The code below runs during game initializing,
// before any round has started
var playerCount         = GAME.addedPlayers.length,
    i;

for (i = 0; i < playerCount; i += 1) {
    GAME.players[i] = {
        index: i,
        mask: 1 << i,
        name: GAME.addedPlayers[i].name
    };
}

GAME.addPlayers();

// The matches creation
for (var i = 0; i < GAME.teams.length; i++) {
    for (var j = i + 1; j < GAME.teams.length; j++) {
        var t1      = GAME.teams[i],
            t2      = GAME.teams[j],
            r1      = (GAME.players.length > 2*3) ? new GAME.Resting() : false;

        if ((t1.mask & t2.mask) === 0) { //this is where the masks come in
            if (r1) {
                var resting = t1.mask ^ t2.mask;

                for (var k = 0; k < GAME.players.length; k++) {
                    if ((resting & 1) === 0) {
                        r1.Add(k);
                    }
                    resting >>>= 1;
                }
            }

            GAME.matches.push({
                Team1: t1,
                Team2: t2,
                Resting: r1
            });
        }
    }
}

// The code below start a new round
// This should start a new randomly selected game described in my question
// and not like I'm doing it now
var gamesPlayed         = GAME.gamesPlayed,
    match               = GAME.matches[gamesPlayed];
4

0 に答える 0