【问题标题】:Random number generator to not generate same number随机数生成器不生成相同的数字
【发布时间】:2021-12-31 10:38:46
【问题描述】:

我在 javascript 中创建一个地雷游戏,在其中我生成一个分配给一个 div 的随机数,这个 div 将是一个地雷,但问题是例如(我将地雷数设置为 8,而不是获得 8 个不同的地雷 我获得了 8 个地雷,但其中 2 个地雷在同一个地方,所以算作我有 6 个地雷,我该如何解决?这是 codem 的重要部分,还有关于如何改进的任何提示在我的代码中,它会被认为是我非常新的程序)

let tiles = document.getElementsByClassName('tile');
let numMines = 6

for (i = 0; i < 1; i++) {
    bomb = [tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))],
    tiles[(Math.floor(Math.random ()* tiles.length))]]
    bomb.splice(numMines) 


    bomb[0].style.backgroundColor = "red"; 
    bomb[1].style.backgroundColor = "red";  
    bomb[2].style.backgroundColor = "red";
    bomb[3].style.backgroundColor = "red"; 
    bomb[4].style.backgroundColor = "red";  
    bomb[5].style.backgroundColor = "red";
    bomb[6].style.backgroundColor = "red"; 
    bomb[7].style.backgroundColor = "red";  
    bomb[8].style.backgroundColor = "red";
    bomb[9].style.backgroundColor = "red"; 
    bomb[10].style.backgroundColor = "red";  
    bomb[11].style.backgroundColor = "red";
    bomb[12].style.backgroundColor = "red";
    bomb[13].style.backgroundColor = "red"; 
    bomb[14].style.backgroundColor = "red";  
    bomb[15].style.backgroundColor = "red";
    bomb[16].style.backgroundColor = "red"; 
    bomb[17].style.backgroundColor = "red";  
    bomb[18].style.backgroundColor = "red";
    bomb[19].style.backgroundColor = "red";  
    bomb[20].style.backgroundColor = "red";
    bomb[21].style.backgroundColor = "red"; 
    bomb[22].style.backgroundColor = "red";  
    bomb[23].style.backgroundColor = "red";
    bomb[24].style.backgroundColor = "red"; 
    bomb[24].style.backgroundColor = "red";   
} ```

【问题讨论】:

  • 老兄为什么只需要循环一次i &lt; 1
  • 很抱歉,但我对你的问题没有确切的答案,但我希望这个逻辑适用于你的情况。您可以记录以前出现过哪些号码,因此在创建地雷时,在使用该号码之前,您可以检查是否以前使用过此号码,如果没有,则可以部署我的号码,否则您可以跳过部署我的号码。 我不懂我的游戏,所以如果我使用了一些错误的术语,我很抱歉

标签: javascript html random grid


【解决方案1】:

另一种方法是将相关的 ID 存储在一个数组中,以便于查找:

let tiles = document.getElementsByClassName('tile');
let numMines = 6;
let tileIndexes = Array();
let i = 0;

while (i < 6) {
  const rand = Math.floor(Math.random() * tiles.length);
           
  if (!tileIndexes.includes(rand)) {
    tileIndexes.push(rand);
    i++;
  }
}

tileIndexes.forEach(e => {
  tiles[e].style.backgroundColor = "red";
});

为确保您获得一组独特的 ID,请将这些数字添加到一个数组中,并将所有新随机生成的数字与数组中的数字进行比较。 while 循环将迭代,直到数组中有 numMines 个元素。

【讨论】:

    【解决方案2】:

    简要说明:

    这里有一些逻辑可以解决您面临的问题,它与@Hackytech 所说的类似,但我选择了跟踪瓷砖的缺陷。您基本上可以创建 n 个炸弹并为每个炸弹选择一个独特的图块。选择唯一磁贴的方式是在getTileIndex 函数中,它本质上会一直调用自身,直到找到尚未使用的索引并返回该索引。下面是一个不涉及 DOM 的示例。

    对你来说,tiles 最终会变成 document.getElementsByClassName("tile"),我将其设为随机数数组只是为了提供一些占位符信息。

    您提到您是编程新手,因此这里逐行详细解释了正在发生的事情。第一行,我创建了一个大小为 100 的空数组并用空值填充它,所以它最终是 [null, null, null ... 100 times]。然后我调用.map,这就像一个创建新数组的for循环,其中数组中的每个项目取决于回调返回的内容。由于回调是item =&gt; Math.random(),我为数组中的每个项目返回一个随机数。然后我创建了一个名为tileIndex 的新数组,我在其中跟踪已经使用了哪些图块索引,这样我们就不会重叠图块。 getTileIndex 函数确实可以解决您的问题。这是一个recursive function,它只是不断地调用自己,直到找到一个尚未添加到炸弹数组中的索引。然后它返回该索引。最后一行代码创建一个大小为 27 的空数组并用null 填充它。与之前类似,该数组随后被映射,但我们不是返回一个随机数,而是通过调用我们的 getTileIndex 函数返回一个唯一索引的瓦片,该函数返回一个唯一的瓦片索引。

    如果这里有不明白的地方,欢迎在 cmets 中提问!

    const tiles = new Array(100).fill(null).map(item => Math.random());
    const tileIndex = [];
    
    function getTileIndex() {
      const i = Math.floor(Math.random() * tiles.length);
      if(tileIndex.findIndex(item => i == item) < 0) {
        tileIndex.push(i);
        return i;
      }
      
      return getTileIndex();
    }
    
    let bombs = new Array(27).fill(null).map(bomb => tiles[getTileIndex()]);
    
    console.log(tiles)

    【讨论】:

      【解决方案3】:

      确保您获得正确数量且没有重复的随机地雷的一种方法是创建一个包含所有图块的临时数组,然后在随机选择每个图块时将其移除。第一次从 24、23、22 等中选择。

      这里有一些示例代码:

      const { floor, random } = Math;
      const tiles = document.getElementsByClassName('tile');
      const numMines = 6;
      const t2 = [...tiles]; // clone of tiles, since we're going to mutate it
      const b = [];
      for (let i = 0; i < numMines; i++) {
        const j = floor(random() * t2.length);
        b.push(t2[j]); // add bomb tile to b array
        t2.splice(j, 1); // remove tile from t2
      }
      
      // loop through all tiles, make tile red if it's a bomb, black if not
      for (const tile of tiles) {
        const isMine = b.indexOf(tile) >= 0;
        tile.style.backgroundColor = isMine ? 'red' : 'black';
      }
      

      还有一个工作示例:

      const { floor, random } = Math;
      const tiles = document.getElementsByClassName('tile');
      const numMines = 6;
      const t2 = [...tiles];
      const b = [];
      for (let i = 0; i < numMines; i++) {
        const j = floor(random() * t2.length);
        b.push(t2[j]);
        t2.splice(j, 1);
      }
      const bomb = [];
      
      for (const tile of tiles) {
        const isMine = b.indexOf(tile) >= 0;
        bomb.push(isMine);
        tile.style.backgroundColor = isMine ? 'red' : 'black';
      }
      .tile {
        display: inline-block;
        width: 1em;
        height: 1em;
      }
      <div class='row'>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
      </div>
      <div class='row'>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
      </div>
      <div class='row'>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
      </div>
      <div class='row'>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
      </div>
      <div class='row'>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
      </div>
      <div class='row'>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
        <span class='tile'></span>
      </div>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-10
        相关资源
        最近更新 更多