Struggling to figure out how to properly shuffle my deck of cards array in JavaScript. Can't seem to grasp how to pass the array correctly

Currently, I am engrossed in my personal project and watching tutorials just for the fun of it. My goal is to create a game for my school project which is inspired by a war card game that I used to play as a child - where the highest number wins. I have meticulously organized 52 cards exactly how I want them, but now I've hit a roadblock.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>
            War Cards!
        </title>
    </head>
    <body>
        <div id="wrapper">
            <div id="start"></div>
            <div id="message"></div>
            <div id="board">
                <div id="player1" class="players">
                    <div class="score"></div>
                    <div class="hand"></div>
                </div>
                <div id="player2">
                    <div class="score"></div>
                    <div class="hand"></div>
                </div>
            </div>
            <div id="action">
                <button id="btnBattle" type="button" class="btn">
                    Fight!
                </button>
            </div>
        </div>

        <script src="js/jquery-3.3.1.min.js">
        </script>
        <script>
            $('document').ready(function() {
                var suits = ["spades", "hearts", "clubs", "diams"];
                var cardFace = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"];
                var cards = [];
                var players = [[], []];
                var firstRun = true;
                var fightButton = document.querySelector("#btnBattle");

                fightButton.addEventListener('click', battle);

                function battle()
                {
                    if (firstRun)
                    {
                        firstRun = false;
                        buildCards();
                        shuffleArray();
                    }
                    console.log('Works');
                }


                function buildCards()
                {
                    cards = [];
                    for (s in suits)
                    {
                        var suitNew = suits[s][0].toUpperCase();
                        for(n in cardFace)
                        {
                            var card = {
                                suit:suits[s],
                                num:cardFace[n],
                                cardValue:parseInt(n) +2,
                                icon:suitNew
                            }
                            cards.push(card);
                        }
                    }
                    console.log(cards);
                }

                function shuffleArray(array)
                {
                    for(var x = array.length -1; x > 0; x--)
                    {

                        var ii = Math.floor(Math.random() * (x + 1))
                        var temp = array[x];
                        console.log(temp)
                    }
                    return array;
                }





            });

        </script>
    </body>
</html>

Answer №1

It appears that there may be a confusion between formal and actual arguments in the context of declaring and calling functions.

Formal Arguments

When defining a function, you assign formal names to its arguments so that you can reference them within the function. These parameters do not have an actual value until the function is invoked. For example, in the declaration of the shuffle function:

function shuffle(array) {....

array serves as a formal argument.

Actual arguments

During the function call, formal arguments are replaced with actual values.

For instance, when shuffling the cards array, the shuffle function would be called like this:

shuffle(cards);

where cards is passed as the actual argument.


It's worth noting that the implementation of the shuffle function seems to follow the Fisher-Yates algorithm but overlooks two lines that swap entries in the array indexed by x and ii.

Below is a revised shuffle function with the missing swapping lines included:

function shuffle(a) { // fisher yates algorithm ;
    for(var i = a.length; --i;) {
        var j = Math.floor(Math.random() * (i+1));
        var temp = a[i]; // swap entries at i and j
        a[i] = a[j];
        a[j] = temp;
    }
}

If preferred, you can update the formal parameter name a along with any references to it in the function body to array.

Keep in mind that array elements are shuffled directly within the array, eliminating the need to return the array itself since it is modified in place.

Answer №2

It's important to avoid cluttering the global scope with unnecessary variables and functions. In the code snippet below, I demonstrate how to properly handle card shuffling by utilizing the buildCards() function and passing the cards through the shuffleArray() function (which was adapted from a source found at here, as the original shuffleArray implementation wasn't effective in rearranging elements):

var suits = ["spades", "hearts", "clubs", "diams"];
var cardFace = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"];
var players = [[], []];
var firstRun = true;

function battle()
{
    if (firstRun)
    {
        firstRun = false;
        var cards = buildCards();
        var randomized = shuffleArray(cards);
        console.log(randomized);
    }
    console.log('Works');
}


function buildCards()
{
    var cards = [];
    for (s in suits)
    {
        var suitNew = suits[s][0].toUpperCase();
        for(n in cardFace)
        {
            var card = {
                suit:suits[s],
                num:cardFace[n],
                cardValue:parseInt(n) +2,
                icon:suitNew
            }
            cards.push(card);
        }
    }
    
    return cards;
}

function shuffleArray(array) {
  var m = array.length, t, i;

  // While there remain elements to shuffle…
  while (m) {

    // Pick a remaining element…
    i = Math.floor(Math.random() * m--);

    // And swap it with the current element.
    t = array[m];
    array[m] = array[i];
    array[i] = t;
  }

  return array;
}

battle();

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

exchanging a library for a different one

I'm faced with a relatively simple task here, but as I am just beginning to delve into object-oriented programming, it is proving to be quite perplexing for me. Currently, I am using the lon_lat_to_cartesian function from the following source: functi ...

Issue with event.preventDefault() in Jquery not functioning as expected

My goal is to have the menu display and hide list items on click, with them being hidden by default. However, the issue I am facing is that the menu is generated in the admin section, so it automatically assigns a URL to each item. If I set the URL field o ...

Displaying images with text below on the navigation bar, complemented by a sleek dividing line

I have a design in mind where I want to display 3 images at the top of a navbar, followed by centered text directly underneath each image. The spacing of the images seems to be even, but I'm not sure if this is just a coincidence or if I need to speci ...

emulating an android device to test html5 applications

Recently, I embarked on developing an HTML5 game with the help of VS Code. I envision it being predominantly accessed from PCs and laptops. I successfully configured the Chrome debugger to facilitate debugging the webpage in Chrome. However, I am eager to ...

Evaluate the advancement of a test using a promise notification for $httpBackend

I am currently utilizing a file upload feature from https://github.com/danialfarid/angular-file-upload in my project. This library includes a progress method that is triggered when the xhr request receives the progress event. Here is an excerpt from the so ...

Transforming PHP JSON into JavaScript with getJSON

Hello everyone, I must admit my lack of knowledge in javascript/ajax as I am struggling to convert this php json into a javascript function $json = file_get_contents('http://videoapi.my.mail.ru/videos/mail/alex.costantin/_myvideo/4375.json'); ...

Videos embedded using the React HTML video tag are not automatically playing on mobile devices

I have implemented a jsx variable to insert a video into my html. Despite following the advice to include muted defaultMuted, and playsinline (which I have already done), the videos autoplay on safari, chrome, and firefox on my computer but not on mobile ...

Unable to display MongoDB collection in React application

I've been working on showcasing my projects using React and Meteor. I have two collections, Resolutions and Projects. The issue I'm facing is that while I can successfully display the Resolution collection on the frontend, I'm struggling to ...

Is Optional Chaining supported by Next.js on Vercel?

While Next.js does support Optional Chaining, I have encountered an issue when trying to deploy the following code snippet: module.exports = { experimental: { outputStandalone: true, }, images: { domains: process.env.NEXT_PUBLIC_IMAGE_DOMAINS ...

Choosing groupings of courses

I am looking to dynamically load divs with different combinations of classes from an external file using jQuery's load function, but I am struggling with grouping them correctly. $("#somediv").load("somefile.html .class1"); // loads all divs with c ...

Tips on transferring a value from one JavaScript file to another JavaScript file

Currently, I am able to pass parameters from one JavaScript file to another using the jQuery method "$.getScript". For example, in the "secondJavaScript.js" file, I use a $.getScript call to invoke the function callMemoPage() from "firstJavaScript.js", p ...

Error Encountered with Next.js 13.4.1 when using styled-components Button in React Server-Side Rendering

I am currently working on a React project using Next.js version 13.4.1 and styled-components. One problem I'm facing is with a custom Button component that I've created: import React from 'react'; import styled from 'styled-compone ...

creating a spherical image mapping with three.js

I am currently facing a challenge in UV mapping a cube-map texture onto a sphere. The process of mapping a cube-map onto a cube was straightforward for me. I successfully mapped an image onto a cube using the following steps: Click here to open the image ...

Is there a way to exclusively utilize CSS in order to achieve bottom alignment for this btn-group?

I currently have a series of div elements that I transformed into two columns. https://i.stack.imgur.com/xG7zT.png My goal is to align the PDF/XML button group at the bottom, creating a layout like this: https://i.stack.imgur.com/ijtuH.png This is an e ...

Get rid of the arrow that is displayed when using the `time` input type in HTML5

Recently, I encountered an issue with the default HTML5 code snippet. My custom background looked perfect except for a pesky black arrow appearing on the right side. In this image, you can see the problematic black arrow that needs to be removed. I attemp ...

Using Angular 4 constructor value in a condition with *ngIf

Within this TypeScript snippet, there is a variable called moreinfo that is initially set to 1. In the constructor, however, the value of moreinfo is changed to 2. Subsequently, based on whether the value is 1 or 2, different div elements are displayed usi ...

What is the best way to specify the JSDoc types for this.field within the Mocha TestContext during the before() hook, in order to provide clarity for other it() tests as well as IntelliJ?

I am looking for IntelliJ, or a similar IDE like WebStorm or VSCode, to provide auto-complete for the fields I define in my Mocha.js before() hook within my test context. Furthermore, I want to have access to the auto-complete documentation of those fields ...

Tips for managing state updates in React Redux

Currently, I am utilizing a reducer to manage the state in Redux. The current structure of my state is as follows: { activeConversation: "Jim" conversations: (7) [{…}, {…}, {…}, {…}, {…}, {…}, {…}] user: {id: 8, username: &quo ...

Continuously I am being informed that the value is null

Check out this code snippet: var Ribbon = /** @class */ (function () { function Ribbon(svg) { // Code here... } Ribbon.prototype.init = function() { // Initialization code here... }; Ribbon.prototype.updateR ...

When working with AngularJS routing, utilize a function for the templateUrl to dynamically load the appropriate template

Can a function be used as the templateUrl in angularjs routing? The $routeProvider official documentation states: templateUrl – {string=|function()=} Check out the $routeProvider official documentation here In javascript, a function is typically def ...