0

我正在尝试创建一个扑克程序,该程序将生成一手 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循环......只有一个在语法上有效?

谢谢!

4

4 回答 4

3

是的,添加更多括号。

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

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

于 2013-04-12T15:21:48.170 回答
1

你好像少了一个括号

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

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

}
于 2013-04-12T15:22:40.923 回答
1

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

while( (randFace == randFace2 && randSuit == randSuit2) || (randFace2 == randFace3 && randSuit2 == randSuit3)) { 
randSuit2 = Math.round(Math.random()*3);                    
randFace2 = Math.round(Math.random()*13);   
}
于 2013-04-12T15:22:43.867 回答
0

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

首先,你应该使用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 方法,模拟真实的甲板。

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

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

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

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

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

真的没关系。什么让你更容易处理。但是其余的方法仍然是相同的。

希望能帮助到你!

于 2013-04-12T16:26:41.103 回答