如何将对象添加到数组中但仅当数组的当前元素为0时?

时间:2021-11-17 08:43:26

I have the code below and when both classes (Player,Game) are instantiated, a specific number of players are inserted in the Player.gameBoard array. I'm trying to add the Player class into the array only if the array element is 0. So if a Player object is inserted into gameboard[0][0] position, no other player can overwrite him. Currently, if a choose a large number of players (e.g.20) some of them are overriden and not all of them appear. So I suppose there is something wrong with the while loop.

我有下面的代码,当实例化两个类(播放器,游戏)时,在Player.gameBoard数组中插入特定数量的播放器。我只是在数组元素为0时尝试将Player类添加到数组中。因此,如果将Player对象插入到gameboard [0] [0]位置,则没有其他玩家可以覆盖他。目前,如果选择大量玩家(例如20),则其中一些玩家被覆盖而不是全部玩家都出现。所以我认为while循环有问题。

var question = prompt('how many players');
var numOfPlayers = parseInt(question);

class Game {
  constructor(){
    this.health = 100;
    this.hammer = false
    this.knife = false;
    this.sword = false;
    this.baseballbat = false;
    this.damage = 0;
    this.gameBoard = [
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
    ];
    }
  }

class Player {
  constructor(id){
    this.id=id;
    this.location = {
      x:Math.floor(Math.random()*8),
      y:Math.floor(Math.random()*8)
    };
  }
}

var play = new Game();
let player =[];
for (i=0; i <numOfPlayers; i++ ){
    player.push(new Player(i));
    while (play.gameBoard[player[i].location.y][player[i].location.x]===0){
    play.gameBoard[player[i].location.y][player[i].location.x] = player[i];
    }
}

console.log(play);

2 个解决方案

#1


2  

Instead of assigning a random x/y to each player as they are created, you should create a list of all possible locations and pick one at random for each new player instance. You have an 8x8 grid. So there are 64 possible locations

您应该创建所有可能位置的列表,并为每个新玩家实例随机选择一个,而不是在创建每个玩家时为其分配随机x / y。你有一个8x8网格。所以有64个可能的位置

If for each player you:

如果每个玩家你:

  • pick a random position
  • 选择一个随机的位置

  • remove that position
  • 删除该位置

You will never have overlaps.

你永远不会有重叠。

var positions = [];
for(var x=0;x<8;x++){
   for(var y=0;y<8;y++){
      positions.push({x,y});
   }
}

// pick 5 random positions for demo

for(var i=0;i<5;i++){
   var rnd = Math.floor(Math.random()*positions.length);
   console.log("random position chosen:", positions[rnd]);
   //remove this so its not picked again
   positions.splice(rnd,1);
}

Applied to your code looks like this:

应用于您的代码如下所示:

var question = prompt('how many players');
var numOfPlayers = parseInt(question);

class Game {
  constructor(){
    this.health = 100;
    this.hammer = false
    this.knife = false;
    this.sword = false;
    this.baseballbat = false;
    this.damage = 0;
    this.gameBoard = [
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
    ];
    }
  }

class Player {
  constructor(id, location){
    this.id=id;
    this.location = location;
  }
}

var positions = [];
for(var x=0;x<8;x++){
   for(var y=0;y<8;y++){
      positions.push({x,y});
   }
}

var play = new Game();
let player =[];
for (i=0; i <numOfPlayers; i++ ){
    var rndPos = Math.floor(Math.random()*positions.length);    
    player.push(new Player(i, positions[rndPos]));
    positions.splice(rndPos,1);
    play.gameBoard[player[i].location.y][player[i].location.x] = player[i];
}

console.log(play);

You could even consider making the availablePositions array a property of your Game if that makes sense.

如果有意义的话,您甚至可以考虑将availablePositions数组作为游戏的属性。

#2


1  

You will need to make sure there are new coordinates generated for the player if their position is already filled on the board.

如果玩家的位置已在棋盘上填充,您需要确保为玩家生成新的坐标。

This makes the for-loop code look like the following:

这使得for循环代码如下所示:

for (i=0; i <numOfPlayers; i++ ){
   var tempPlayer = new Player(i);
   while (play.gameBoard[tempPlayer.location.y][tempPlayer.location.x]!=0){
      tempPlayer = new Player(i)
    }
   player.push(tempPlayer);
   play.gameBoard[player[i].location.y][player[i].location.x] = player[i];
}

At first, you store the new Player locally. Then while the generated coordinates are occupied, you will recreate the Player with the same id. Once the coordinates give an empty space, you will push the player to the player array and assign it to the gameboard.

首先,您在本地存储新播放器。然后在生成的坐标被占用时,您将重新创建具有相同ID的Player。一旦坐标给出一个空的空间,您将把玩家推到玩家阵列并将其分配给游戏板。

This is an answer based on your current code, but it would be neater to generate the coordinates outside of the Player() constructor and assign them to the player when set.

这是基于您当前代码的答案,但是生成Player()构造函数之外的坐标并在设置时将它们分配给播放器将更加简洁。

#1


2  

Instead of assigning a random x/y to each player as they are created, you should create a list of all possible locations and pick one at random for each new player instance. You have an 8x8 grid. So there are 64 possible locations

您应该创建所有可能位置的列表,并为每个新玩家实例随机选择一个,而不是在创建每个玩家时为其分配随机x / y。你有一个8x8网格。所以有64个可能的位置

If for each player you:

如果每个玩家你:

  • pick a random position
  • 选择一个随机的位置

  • remove that position
  • 删除该位置

You will never have overlaps.

你永远不会有重叠。

var positions = [];
for(var x=0;x<8;x++){
   for(var y=0;y<8;y++){
      positions.push({x,y});
   }
}

// pick 5 random positions for demo

for(var i=0;i<5;i++){
   var rnd = Math.floor(Math.random()*positions.length);
   console.log("random position chosen:", positions[rnd]);
   //remove this so its not picked again
   positions.splice(rnd,1);
}

Applied to your code looks like this:

应用于您的代码如下所示:

var question = prompt('how many players');
var numOfPlayers = parseInt(question);

class Game {
  constructor(){
    this.health = 100;
    this.hammer = false
    this.knife = false;
    this.sword = false;
    this.baseballbat = false;
    this.damage = 0;
    this.gameBoard = [
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0],
    ];
    }
  }

class Player {
  constructor(id, location){
    this.id=id;
    this.location = location;
  }
}

var positions = [];
for(var x=0;x<8;x++){
   for(var y=0;y<8;y++){
      positions.push({x,y});
   }
}

var play = new Game();
let player =[];
for (i=0; i <numOfPlayers; i++ ){
    var rndPos = Math.floor(Math.random()*positions.length);    
    player.push(new Player(i, positions[rndPos]));
    positions.splice(rndPos,1);
    play.gameBoard[player[i].location.y][player[i].location.x] = player[i];
}

console.log(play);

You could even consider making the availablePositions array a property of your Game if that makes sense.

如果有意义的话,您甚至可以考虑将availablePositions数组作为游戏的属性。

#2


1  

You will need to make sure there are new coordinates generated for the player if their position is already filled on the board.

如果玩家的位置已在棋盘上填充,您需要确保为玩家生成新的坐标。

This makes the for-loop code look like the following:

这使得for循环代码如下所示:

for (i=0; i <numOfPlayers; i++ ){
   var tempPlayer = new Player(i);
   while (play.gameBoard[tempPlayer.location.y][tempPlayer.location.x]!=0){
      tempPlayer = new Player(i)
    }
   player.push(tempPlayer);
   play.gameBoard[player[i].location.y][player[i].location.x] = player[i];
}

At first, you store the new Player locally. Then while the generated coordinates are occupied, you will recreate the Player with the same id. Once the coordinates give an empty space, you will push the player to the player array and assign it to the gameboard.

首先,您在本地存储新播放器。然后在生成的坐标被占用时,您将重新创建具有相同ID的Player。一旦坐标给出一个空的空间,您将把玩家推到玩家阵列并将其分配给游戏板。

This is an answer based on your current code, but it would be neater to generate the coordinates outside of the Player() constructor and assign them to the player when set.

这是基于您当前代码的答案,但是生成Player()构造函数之外的坐标并在设置时将它们分配给播放器将更加简洁。