问题描述:

Ok, some random dude at CodeReview asked me to pass this over here, so be it.

I have a combination generation code based on this answer: StackOverflow answer

The basic idea is that I have a group of players (total of 6 - 14) and I need to form 2 teams each of having 3 players while the rest of the players are resting for that match. The code generates all the possible matches. The problem comes when I need to pick the next match setup randomly so that the players would only rest for, if possible, only 1 game. In addition, each teams should be as random as possible without having same players playing as a team as any previous game so far.

To clarify the problem this is a big no-no, that will happen if I just pick the next match from the array:

 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

... while this looks ok:

 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

I've modified the code so that now I have:

  • players with bitmask
  • teams with bitmask
  • matches array with 2 teams and 1 resting group (each of them with bitmasks)

Question

Given that each of those match components, i.e. player, team and resting, have a mask value, how should I calculate the next game? With bitwise operators, how? Push every resting player into an array and exclude those from being resting next game. I've tried some multiarray thing which was a complete chaos and didn't end up well. So, I need some help with this. This is the first time I'm dealing with bitmasks.

Code

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];

相关阅读:
Top