Alter Fisher-Yates shuffle so that a value never ends up in the same place it started

275 Views Asked by At

I have an array of objects, a sample of which looks like this:

var allWorm = [
        {
            "name": "Null",
            "power": "Create an artificial cluster. Everyone added to this cluster has their parahuman abilities shared, but with a decrease in the power of each new ability.",
            "fromCanon": "Null"
        },
        {
            "name": "One",
            "power": "Thinker ability that allows for quick and efficient brainwashing given sufficient control over the victim's environment.",
            "fromCanon": "One"
        },
        {
            "name": "Two",
            "power": "Magnify other powers in close proximity.",
            "fromCanon": "Two"
        },
        {
            "name": "Four",
            "power": "Limited flight. Can hover between five and ten feet from the ground with a top speed of fifty to sixty miles per hour.",
            "fromCanon": "Four"
        },
        {
            "name": "Nine",
            "power": "Can push and pull on metals within a short range, accelerating both self and object away from or towards each other.",
            "fromCanon": "Nine"
        },
        {
            "name": "Thirteen",
            "power": "Forcefield creation.",
            "fromCanon": "Thirteen"
        }
]

In my HTML, I have a checkbox. If the box is checked, I'm fine with the shuffle function causing an entry to be randomly shuffled, perhaps leaving a value in the same place it started at. However, my attempt at altering the algorithm as shown in the else statement causes something to go wrong and the program, which gets stuck in an infinite loop.

function shuffle(){
    //see if box checked for duplicates
    var samePower = document.getElementById("samePower");
    
    let allWorm = JSON.parse(localStorage.getItem("allWorm"));
    
    var currentIndex = allWorm.length, temporaryValue, randomIndex;
    
    if(samePower.checked == true){
        //while non-shuffled elements remain
        while(0 !== currentIndex){
            //pick remaining element
            randomIndex = Math.floor(Math.random() * currentIndex);
            currentIndex -= 1;
            
            //swap with current element
            temporaryValue = allWorm[currentIndex].power;
            allWorm[currentIndex].power = allWorm[randomIndex].power;
            allWorm[randomIndex].power = temporaryValue;
                
            temporaryValue = allWorm[currentIndex].fromCanon;
            allWorm[currentIndex].fromCanon = allWorm[randomIndex].fromCanon;
            allWorm[randomIndex].fromCanon = temporaryValue;
        }
    }
    else{
        //while non-shuffled elements remain
        while(0 !== currentIndex){
            //pick remaining element
            randomIndex = Math.floor(Math.random() * currentIndex);
            currentIndex -= 1;
            //disallow same power
            while(allWorm[randomIndex].name === allWorm[randomIndex].fromCanon){
                randomIndex = Math.floor(Math.random() * currentIndex);
                break;
            }
            
            //swap with current element
            temporaryValue = allWorm[currentIndex].power;
            allWorm[currentIndex].power = allWorm[randomIndex].power;
            allWorm[randomIndex].power = temporaryValue;
                
            temporaryValue = allWorm[currentIndex].fromCanon;
            allWorm[currentIndex].fromCanon = allWorm[randomIndex].fromCanon;
            allWorm[randomIndex].fromCanon = temporaryValue;
        }
    }
    
    var allWorm_serialized = JSON.stringify(allWorm);
    localStorage.setItem("allWorm", allWorm_serialized);
    writeData();
}

How do I correctly modify the algorithm,?

0

There are 0 best solutions below