【问题标题】:How can I create a while loop with many conditions in javascript?如何在 javascript 中创建具有多个条件的 while 循环?
【发布时间】:2013-04-05 04:54:18
【问题描述】:

我正在尝试创建一个扑克程序,该程序将生成一手 5 张随机牌。我遇到的一个问题是程序偶尔会生成同一张卡片两次。

我想到的解决此问题的最佳方法是实现一个看起来像这样的 while 循环。

while (randFace == randFace2 && randSuit == randSuit2) || (randFace2 == randFace3 && randSuit2 == randSuit3) { 

randSuit2 = Math.round(Math.random()*3);                    
randFace2 = Math.round(Math.random()*13);   

}

这会破坏 while 循环的语法并拒绝运行。

有没有什么方法可以创建一个类似于上面的带有许多复杂条件的 while 循环......只有一个在语法上有效?

谢谢!

【问题讨论】:

  • 将整个条件包装在() 中,它可能会起作用。

标签: javascript random while-loop multiple-conditions


【解决方案1】:

这听起来像XY problem,所以请注意,这个答案不是针对问题的主题,而是针对问题本身。

首先,你应该使用Math.floor,因为Math.round会给你一个不均匀的分布:

function randomInt(max) {
    return Math.floor(Math.random() * (max + 1))
} 

那么您必须将所有这些值存储在某个地方,对吗?那么为什么不使用对象或数组呢?我假设您使用的是一副 52 张牌。如果您有这样的约定:

  • 心:索引 0 - 12
  • 钻石:索引 13 - 25
  • 俱乐部:索引 26 - 38
  • 黑桃:索引 39 - 51

那么你的“甲板”表示只是一个 int 数组:

var deck = [];
for (var i = 0; i < 52; i++)
  deck.push(i);

现在您可以创建一个“游戏牌组”,只需将常规牌洗牌即可:

// Using the Fisher Yates shuffle: http://en.wikipedia.org/wiki/Fisher-Yates_shuffle

function shuffle(array) {
  var len = array.length;
  var shuffled = array.slice();

  while (len--) {
    random = randomInt(len + 1);
    // swap
    shuffled[len] = [shuffled[random], shuffled[random] = shuffled[len]][0];
  }

  return shuffled;
}

// creating a new, shuffled deck from the original
var playingDeck = shuffle(deck);

并使用playingDeck 实际分发您的卡。假设您想将前 5 张牌交给玩家 1:

var player1Hand = playingDeck.splice(0, 5);

那么你的 player1Hand 将是一个五元素数组,其中元素是来自“游戏牌组顶部”的标记(前五个元素)。因此,如果您现在查询playingDeck.length,则将是47。你想给玩家 2 其他 5 张牌吗?相同的代码:

var player2Hand = playingDeck.splice(0, 5);

如果你想在游戏中途洗牌?只需洗牌 playingDeck 并将其分配给自己:

playingDeck = shuffle(playingDeck);

你也可以从上面抽一张牌:

var card = playingDeck.shift();

(请注意,在这种情况下,它不是卡片列表 - 数组 - 而是卡片本身 - 编号。)

并且基本上使用任何你想要的Array methods,模拟一个真实的牌组。

正如您所见,这是一种处理模拟卡片的更自然的方法,您不必在循环中连接许多条件来绘制一些卡片。

我会使用我在开头提到的约定,但请记住,如果您想要卡片的不同表示形式,也可以:所描述的方法仍然有效,您不必更改代码;只有数组的值不同,所以只有deck的生成。例如,你可以有字符串:

var deck = ["1H", "2H", /*etc*/, "10H", "JH", "QH", "KH", /* etc */];

最后一个字母是花色,剩下的就是卡片的价值。或者你也可以实际使用一个对象:

var deck = [{"suit": "Hearts", "face": "1"}, /* etc */];

真的没关系。什么让你更容易处理。但是其余的方法还是一样的。

希望对你有帮助!

【讨论】:

  • 非常感谢零!非常感谢您的回复。
  • 其中一些建议有点超出我的水平......但我绝对好奇的一件事是 Math.random 方法。我正在尝试生成四种随机套装中的一种。每个都与 0 和 3 之间的数组索引配对。如果我使用 randSuit2 = Math.floor(Math.random()*4);我没有机会生成数字 4 吗?我将如何避免这种情况?再次感谢!这些 cmets 非常有用。
  • 如果您有任何疑问,请随时提出,我可以想象有几件事可能无法立即理解。关于您的问题,如果您使用Math.floor(Math.random() * 4),则不可能生成数字 4。那是因为Math.random 生成介于 0(含)和 1(不含)之间的浮点数,因此您可能有 @ 987654341@,也就是3.96,因为Math.floor返回小于等于某个数的最大整数,所以结果会是3
  • 完美!这更有意义。谢谢!
【解决方案2】:

只需使用括号对条件进行分组,如下所示:

while( (randFace == randFace2 && randSuit == randSuit2) || (randFace2 == randFace3 && randSuit2 == randSuit3)) { 
randSuit2 = Math.round(Math.random()*3);                    
randFace2 = Math.round(Math.random()*13);   
}

【讨论】:

    【解决方案3】:

    你好像少了一个括号

    while ((randFace == randFace2 && randSuit == randSuit2) || (randFace2 == randFace3 &&      randSuit2 == randSuit3)) { 
    
    randSuit2 = Math.round(Math.random()*3);                    
    randFace2 = Math.round(Math.random()*13);   
    
    }
    

    【讨论】:

      【解决方案4】:

      是的,添加更多括号。

      while ((randFace == randFace2 && randSuit == randSuit2) || (randFace2 == randFace3 && randSuit2 == randSuit3))  {
          // Do whatever
      }
      

      while 循环将测试紧跟在while 关键字后面的括号中的所有内容。您可以使用更多括号或任何您喜欢的运算符在这些括号内无限嵌套条件,只要这些括号中的任何内容都可以评估为真或假。

      【讨论】:

      • 非常感谢!我现在就试试这个。
      猜你喜欢
      • 1970-01-01
      • 2015-02-14
      • 2013-06-30
      • 1970-01-01
      • 2016-04-08
      • 2017-05-03
      • 1970-01-01
      • 1970-01-01
      • 2011-01-09
      相关资源
      最近更新 更多