JavaScript:洗牌,但每次使用原始列表不会创建新的洗牌

JavaScript: Shuffling a deck, but it does NOT create a new shuffled deck each time using the original list

我正在尝试洗牌。我将一些卡片作为输入。例如,numCards = 5,所以牌组(列表)变为 [0,1,2,3,4]。问题是 test_order(i,j,l) 函数中的 while 循环没有正确洗牌。函数 console.log(m) 应该使用原始列表 (l) 打印一个新的洗牌后的 deck/list,但在第一次正确洗牌后它会继续打印 [0,1,2,3,4]。它应该每次使用原始列表创建一个新洗牌的牌组,相反,它会不断重复原始列表或第一个洗牌列表。

该程序的目的是计算洗牌后标有 i 的牌在标有 j 的牌上方的次数的概率。

function list(numCards){
    var newList = []
    var i = 0;
    while (i < numCards){
        newList.push(i);
        i++;
    }
    return newList
}

function top_to_random(l){
    while(numPerformed != 0){
        var x = Math.floor(Math.random() * l.length);
        l.splice(x, 0, l.shift())
        numPerformed--;
    }
    return l
}

function test_order(i,j,l){ //PROBLEM IS IN HERE!!!!
    var n = 0
    var trials = 10
    var count = 0
    while (count < trials){ // PROBLEM IN WHILE LOOP
        let arrayCopy = JSON.parse(JSON.stringify(l));
        //console.log(arrayCopy)
        var m = top_to_random(arrayCopy)
        m.indexOf(i) < m.indexOf(j) ? n++ : n = n + 0
        
        //console.log(arrayCopy)
        console.log(m)
        count++
    }
    var prob = n/trials
    return  prob
}

//Argument Inputs
var numCards = parseInt(prompt("Enter number of cards in deck: "))
var l = list(numCards)
var numPerformed = parseInt(prompt("Enter number of shuffles to perform on deck: "));
var i = parseInt(prompt("i: "))
var j = parseInt(prompt("j: "))

//Execution
console.log(test_order(i,j,l))

问题不在您认为的地方,而是在您的 top_to_random 函数中。您从 numPerformed 开始计算随机播放中完成的混合次数,但这是一个全局范围的变量,因此它不会在每次调用时重置。您应该像这样将混合计数作为参数传递:

function top_to_random(l, mixNum){
    for (;mixNum > 0; mixNum--) {
        var x = Math.floor(Math.random() * l.length);
        l.splice(x, 0, l.shift());
    }
    return l;
}

修正了一些你的语法结构,我得到了这个代码:

function list(numCards){
    var newList = [];
    var i = 0;
    while (i < numCards){
        newList.push(i);
        i++;
    }
    return newList;
}

function top_to_random(l, mixNum){
    for (;mixNum > 0; mixNum--) {
        var x = Math.floor(Math.random() * l.length);
        l.splice(x, 0, l.shift());
    }
    return l;
}

function test_order(i,j,l){ //Problem is NOT in here
    let n = 0;
    let trials = 10;
    for (let count = 0; count < trials; count++) { // No not here
        let arrayCopy = [...l];
        top_to_random(arrayCopy, numPerformed);
        console.log(arrayCopy)
        if (arrayCopy.indexOf(i) < arrayCopy.indexOf(j)) n++;
        
        console.log(arrayCopy);
    }
    var prob = n/trials;
    return  prob;
}

// Argument Inputs
var numCards = parseInt(prompt("Enter number of cards in deck: "));
var l = list(numCards);
var numPerformed = parseInt(prompt("Enter number of shuffles to perform on deck: "));
var i = parseInt(prompt("i: "));
var j = parseInt(prompt("j: "));

//Execution
console.log(test_order(i,j,l));

此外,您在编码时应更加注意细节:

  • 你少了很多分号
  • 您将函数参数和全局变量混合在一起,没有任何决策逻辑
  • 当你应该使用 for
  • 时不要使用 while
  • 执行简单 if 的三元运算符?
  • 您最好使用 constlet 而不是 var。一方面,它可以避免这个错误

更好的代码编写:

const SHUFFLE_REPEATS = 10;

function list(numCards) {
    const newList = [];
    for (let i = 0; i < numCards; i++)
        newList.push(i);
    return newList;
}

function top_to_random(l, mixNum) {
    for (; mixNum > 0; mixNum--) {
        const x = Math.floor(Math.random() * l.length);
        l.splice(x, 0, l.shift());
    }
    return l;
}

function test_order(i, j, l) {
    let n = 0;
    for (let count = 0; count < SHUFFLE_REPEATS; count++) {
        const arrayCopy = [...l];
        top_to_random(arrayCopy, numPerformed);
        console.log(arrayCopy)
        if (arrayCopy.indexOf(i) < arrayCopy.indexOf(j)) n++;
    }
    return n / SHUFFLE_REPEATS;
}

// Argument Inputs
const numCards = parseInt(prompt("Enter number of cards in deck: "));
const l = list(numCards);
const numPerformed = parseInt(prompt("Enter number of shuffles to perform on deck: "));
const i = parseInt(prompt("i: "));
const j = parseInt(prompt("j: "));

//Execution
console.log(test_order(i,j,l));