繁体   English   中英

比javascript中的“切换”更好的方式

[英]Better way than “switch” in javascript

我是javascript的新手,我有一点问题。

作为我的第一个“项目”,我希望我的程序能够随机给我一张扑克牌。 没什么好看的,但我想找出一种优雅的方式来做到这一点。 到目前为止,我唯一的想法就是在1到52之间给出一张特定卡片的随机数,但必须有更好的方法。

这是我目前的代码:

function newCard() {
var card_id = document.getElementById("card_id");
var c1 = Math.floor(Math.random() * 52) + 1;
switch(c1) {
    case 1:
        c1 = "ace of spades";
        break;
    case 2:
        c1 = "2 of spades";
        break;
    case 3:
        c1 = "3 of spades";
        break;  


    // ...I think you get the idea here


         } 

card_id.innerHTML = c1;
}

你有一个暗示我,如何使这更快/更好?

 function newCard() { // Pick from 0 to 51, not 1 to 52 var cardId = Math.floor(Math.random() * 52); var ranks = ["ace", "2", "3", "4", "5", "6", "7", "8", "9", "ten", "jack", "queen", "king"]; var suits = ["spades", "hearts", "diamonds", "clubs"]; // % is the modulo operator, so 0 => 0, 1 => 1, ... 12 => 12, 13 => 0, 14 => 1, ... // Math.floor(cardId / 13) gets the suit (0, 1, 2, 3) return ranks[cardId % 13] + " of " + suits[Math.floor(cardId / 13)]; } for (var i = 0; i < 10; i++) { console.log(newCard()); } 

UPDATE

因为这引发了关于从非无限套牌(不是重复卡片)处理的一些讨论,这里是一个典型的解决方案,产生一个完整的牌组,洗牌,然后处理牌。 cardIdToEnglish基本上就是上面的解决方案。 shuffleFisher-Yates shuffle 请注意,使用甲板末端pop交易,这可能看起来很奇怪,但也要注意这是无关紧要的。 :-)

 function cardIdToEnglish(id) { var ranks = ["ace", "2", "3", "4", "5", "6", "7", "8", "9", "ten", "jack", "queen", "king"]; var suits = ["clubs", "diamonds", "hearts", "spades"]; return ranks[id % 13] + " of " + suits[Math.floor(id / 13)]; } function shuffle(arr) { // Fisher-Yates shuffle var n = arr.length; for (var i = 0; i < arr.length - 2; i++) { var j = Math.floor(Math.random() * (n - i)) + i; // Swap a[i] and a[j] var temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } function newDeck() { var deck = []; for (var i = 0; i < 52; i++) { deck.push(i); } shuffle(deck); return deck; } var deck = newDeck(); for (var i = 0; i < 52; i++) { var card = deck.pop(); console.log(cardIdToEnglish(card)); } 

我会创建一个所有卡片的数组作为套装和等级的对象(使用嵌套的forEach循环轻松 - 迭代套装和排列数组)然后使用随机数生成卡片ID。 然后,这将给出该卡的等级和适合度。 然后我从卡片中取出卡片 - 以防止它被处理两次并减少可用卡片的数量)。 这样做意味着所选卡是随机的而不是重复的。 我还放了一个按钮,可以重置所有内容并允许进一步处理10张牌。

 var deck = []; function setCards(){ var suits = ["Spades", "Hearts", "Diamonds", "Clubs"]; var ranks = ["Ace", "2", "3", "4", "5", "6", "7", "8", "9", "Ten", "Jack", "Queen", "King"]; //creates an array of card objects that have the rank and suit as properties //eg: deck = [ {suit: "Spades", rank: "Ace"}, {suit: "Spades", rank: "2"},...etc] suits.forEach(function(suit){ ranks.forEach(function(rank){ var card = {}; card.suit = suit; card.rank = rank; deck.push(card); }); }); } function newCard(count) { //decreases the count of the deck since some cards have already been dealt var remainingCards = 52 - count; var index = Math.floor(Math.random() * remainingCards); var card= deck[index]; deck.splice(index,1); //removes the selected card from the deck return card; } function dealCards() { document.getElementById('hand').innerHTML = '<dt>My Hand </dt>'; setCards(); for (var i = 0; i < 10; i++) { var card = newCard(i); document.getElementById('hand').innerHTML += '<dd>'+ card.rank + ' of ' + card.suit + '</dd>'; } } 
 <button type="button" onclick="dealCards()">Deal New Hand</button> <hr/> <dt id = "hand"></dt> 

这是一个想法:

var deck = ['ace of spades', 'two of spades', 'three of spades', '...']; 
// and so on, all 52 cards
var rand = Math.floor(Math.random() * 52);

console.log(deck[rand]); // will print a random card from the deck

或者,如果您想继续“游戏”,也可以从套牌中删除抽出的卡片。

deck.splice(rand, 1);

在此之后,您需要为较小的套牌重新生成随机数:

rand = Math.floor(Math.random() * deck.length); 

这是一个有趣的问题。 这就是我的想法...数字卡从2到9.如果我们继续使用整数作为卡值,jack,queen,king和ace可以分别表示为10,11,12和13 。

但是,当然,我们在四件套装的形式中有四个这些价值观。 一个快速的谷歌搜索显示,在英语国家,西装的相对价值可以从俱乐部,钻石,心脏和黑桃的最低到最高排名。因此,我们可以说2 - 13是俱乐部,14 - 25钻石,心脏26-37,黑桃28-49。 遵循此公式,您的随机数应介于2到49之间。

因此,考虑到这一点,您可以编写一个函数来进行一些数学运算,以根据生成的数字确定确切的卡片。 显然,你不能两次处理相同的卡,所以一旦生成一个数字,它应该存储在一个已发卡的数组中。 每次生成一个数字时,您都需要检查该数字是否在处理过的卡片数组中。 如果是,您将需要生成另一个数字。 我有一个设置和检查此数组的方法的想法。 如果您认为我的想法值得追求,请告诉我,我会将其添加到此答案中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM