gpt4 book ai didi

javascript - 使用 Javascript 和不一致的数组值洗牌?

转载 作者:行者123 更新时间:2023-12-03 10:15:42 25 4
gpt4 key购买 nike

我正在用 javascript 构建一个小模块,就像一副卡片一样。我的第一个方法有效,但非常简单,所以我想创建一些模仿现实世界洗牌背后的想法的洗牌方法。

在其他一些有用的函数中,我创建了 riffle、overhand 和 cut 函数,这些函数似乎都完成了工作,但是当按顺序重复调用它们时,返回的包数量不一致,从一遍又一遍地运行它看起来是某种竞争条件,但我似乎不知道如何避免它。

相关的私有(private)方法是:

riffle : function riffle() {
var top = Pack.slice(0, 26);
var bottom = Pack.slice(26, 52);
Pack = [];
console.log('top is '+top.length+" and bottom is "+bottom.length);
var hand = 'right';
var result = [];
var i = 52;

while (i > 0) {
var drop = Math.floor(Math.random()*3)+1;
var cards;



if (hand === 'right' ) {
if (drop >= top.length) {
cards = top;
} else {
cards = top.splice(0, drop);
}
hand = 'left';

} else {
if (drop >= bottom.length) {
cards = bottom;
} else {
cards = bottom.splice(0, drop);
}
hand = 'right';
}

result = result.concat(cards);
i -= drop;

}
Pack = result;
console.log(Pack.length+" after riffle");
return this;
},

cut : function cut(fn) {
var top = Pack.slice(0, 26);
var bottom = Pack.slice(26, 52);
Pack = [];
console.log(top);
Pack = bottom.concat(top);
console.log(Pack.length+" after cut");
if (fn && typeof(fn) === 'function') { fn(); }
return this;
}

后来我有一个名为 shuffle 的特权方法来调用它们:

    shuffle   : function shuffle(cb) {
State.cardsOut = [];
Internal.generatePack().cut().riffle().riffle()
.riffle().riffle().riffle();

if (cb && typeof(cb) === 'function') { cb(); }
}

注意:我从一个生成函数开始,该函数创建代表一整包 52 张卡片的对象数组。当我在洗牌和剪切后的不同时间控制台记录包时,得到的结果各不相同,我似乎无法弄清楚为什么。

你可以在这里看到我正在做什么

https://gist.github.com/Pushplaybang/66bc7a1fa5d84eee2236

任何帮助都会很棒。

最佳答案

drop 变量存储您应该从左手或右手翻动的卡片数量。但是,有两种情况:

if (drop >= top.length) {
cards = top;
}

if (drop >= bottom.length) {
cards = bottom;
}

其中 drop 可以大于半副牌中剩余牌的数量,因此从 i 中减去的牌数量会多于您实际翻开的牌数量。您可以通过以下方式解决此问题:

if (drop >= top.length) {
drop = top.length;
cards = top;
top = [];
}

if (drop >= bottom.length) {
drop = top.length;
cards = bottom;
bottom = [];
}

(您需要清空数组,否则您可能最终会添加相同的卡片两次)。

其他问题

  • 代码中存在魔数(Magic Number)(2652),这些可能是在类中定义的常量并给出适当的名称(即 PACK_SIZE = 52) 这意味着如果您创建一个代表不同数量卡片的子类,那么它仍然可以工作。
  • hand 有两个可能的值,可以表示为 bool 值,但您可以为其分配字符串(同样可以使用常量LEFT_HAND = true, RIGHT_HAND = !LEFT_HAND)。
  • Pack 似乎是一个全局变量 - 我认为它应该是该类的成员。
  • 您不需要为函数命名,因为这只会污染全局命名空间: riffle : function riffle() { 可以只是一个匿名函数 riffle : function() {
  • 性能 - 每次迭代都会创建额外的数组,并且卡片会移动多次。这可能会更有效率。

类似这样的事情:

PACK_SIZE: 52,
riffle : function() {
var index_of_cards_riffled_from_top = 0;
var index_of_cards_riffled_from_bottom = this.PACK_SIZE / 2;
var riffled_cards = [];
while ( index_of_cards_riffled_from_top < this.PACK_SIZE / 2
|| index_of_cards_riffled_from_bottom < this.PACK_SIZE ) {
var num_cards_to_riffle_top = Math.min( this.PACK_SIZE / 2 - index_of_cards_riffled_from_top, Math.floor( Math.random() * 3 ) + 1 );
var num_cards_to_riffle_bottom = Math.min( this.PACK_SIZE - index_of_cards_riffled_from_bottom, Math.floor( Math.random() * 3 ) + 1 );
while ( num_cards_to_riffle_top > 0 ) {
riffled_cards.push( this.Pack[ index_of_cards_riffled_from_top++ ] );
num_cards_to_riffle_top--;
}
while ( num_cards_to_riffle_bottom > 0 ) {
riffled_cards.push( this.Pack[ index_of_cards_riffled_from_bottom++ ] );
num_cards_to_riffle_bottom--;
}
}
this.Pack = riffled_cards;
}

关于javascript - 使用 Javascript 和不一致的数组值洗牌?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29885020/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com