Rock Paper Scissors x99: question on the addWind function's "winner" parameter

Hello,
I see the following function in the solution of the Rock Paper Scissors x99 exercise:

function addWin(winner) {
    if (winner === 'Player One') {
        playerOneWins = (playerOneWins + 1) || 1;
    } else if (winner === 'Player Two') {
        playerTwoWins = (playerTwoWins + 1) || 1;
    }
}

The function simply adds + 1 to playerOneWins or to playerTwoWins variables based on the result
of the getRoundWinner function:

function getRoundWinner(roundNumber) {
    switch (roundNumber) {
        case 1:
            return getMoveWinner(playerOneMoveOneType, playerOneMoveOneValue, playerTwoMoveOneType, playerTwoMoveOneValue);
        case 2:
            return getMoveWinner(playerOneMoveTwoType, playerOneMoveTwoValue, playerTwoMoveTwoType, playerTwoMoveTwoValue);
        case 3:
            return getMoveWinner(playerOneMoveThreeType, playerOneMoveThreeValue, playerTwoMoveThreeType, playerTwoMoveThreeValue);
        default: 
            return null;
    }
}

My question is: how do the function “addWin” knows that the “winner” argument is the result of the “GetRoundWinner” function?
I dont’s see any “winner” variable in the code.

Hope question is clear.
Thank you

Post all of your code. That will reveal how arguments are being passed to different functions.

winner is not an argument. It is a parameter of the addWin function. Somewhere else in the rest of your code (which you haven’t pasted in your original post), a call is being made to the getRoundWinner function and the returned value is then being passed as the argument to the addWin in a different function call.

Something similar to:

function greeting(name) {
    console.log(`Hello ${name}. How are you?`)
}

function pickName() {
    const people = ["Jack", "Harry", "Susan", "Carol", "Jim"]
    return people[Math.floor(Math.random()*people.length)]
}

let person = pickName();
greeting(person);

Note that in the above snippet, name is the parameter (not the argument) of the greeting function. Whatever argument is passed to the greeting function will be assigned to the name parameter.
In the above snippet, I made a function call to the pickName function and stored the returned value in the person variable. Then in a fresh function call, I passed the value assigned to person as the argument to the greeting function in this statement:    greeting(person)
Whatever value is passed as the argument to the greeting person will be assigned to the name parameter and then the body of the greeting function will be executed. I don’t need to assign the argument to a name variable outside the greeting function. All of the following will work:

greeting("Mary") // "Hello Mary. How are you?"

greeting("abc") // "Hello abc. How are you?"

let x = "Gordon"
greeting(x) // "Hello Gordon. How are you?"
2 Likes

Hi @mtrtmk ,
first of all thank you for taking the time to answer.

I was confused about the terms, so thank you for clarifying the differences between ‘argument’, ‘parameter’, and ‘function as an argument’.

Ok, I guess I got it. Here’s the full code:

// All code should be written in this file.

// Player One moves and values
let playerOneMoveOneType = undefined;
let playerOneMoveOneValue = undefined;
let playerOneMoveTwoType = undefined;
let playerOneMoveTwoValue = undefined;
let playerOneMoveThreeType = undefined;
let playerOneMoveThreeValue = undefined;

// Player Two moves and values
let playerTwoMoveOneType = undefined;
let playerTwoMoveOneValue = undefined;
let playerTwoMoveTwoType = undefined;
let playerTwoMoveTwoValue = undefined;
let playerTwoMoveThreeType = undefined;
let playerTwoMoveThreeValue = undefined;

let playerOneWins;
let playerTwoWins;

// Funzione per impostare le mosse dei giocatori
const setPlayerMoves = (player, moveOneType, moveOneValue, moveTwoType, moveTwoValue, moveThreeType, moveThreeValue) => {
    // testfail return se le variabili non sono presenti
    if (!moveOneType || !moveOneValue || !moveTwoType || !moveTwoValue || !moveThreeType || !moveThreeValue) {
        return;
    }

    // Verifica se il tipo di mossa è valido
    if (!isValidMoveType(moveOneType) || !isValidMoveType(moveTwoType) || !isValidMoveType(moveThreeType)) {
        return;
    }

    // Verifica se il valore è valido
    if (!isValidMoveValue(moveOneValue) || !isValidMoveValue(moveTwoValue) || !isValidMoveValue(moveThreeValue)) {
        return;
    }

    // Verifica se la somma dei valori è maggiore di 99
    if (moveOneValue + moveTwoValue + moveThreeValue > 99) {
        return;
    }

    if (player === 'Player One') {
        playerOneMoveOneType = moveOneType;
        playerOneMoveOneValue = moveOneValue;
        playerOneMoveTwoType = moveTwoType;
        playerOneMoveTwoValue = moveTwoValue;
        playerOneMoveThreeType = moveThreeType;
        playerOneMoveThreeValue = moveThreeValue;
    } else if (player === 'Player Two') {
        playerTwoMoveOneType = moveOneType;
        playerTwoMoveOneValue = moveOneValue;
        playerTwoMoveTwoType = moveTwoType;
        playerTwoMoveTwoValue = moveTwoValue;
        playerTwoMoveThreeType = moveThreeType;
        playerTwoMoveThreeValue = moveThreeValue;       
    }

}

// Helper function isValidMoveType() per validare rock, paper o scissor
function isValidMoveType(moveType) {
    return (moveType === 'rock') || (moveType === 'paper') || (moveType === 'scissors');
}

// Helper function per verificare i valori
function isValidMoveValue(moveValue) {
    return (moveValue >= 1) && (moveValue <= 99);
}

    function getRoundWinner(roundNumber) {
        switch (roundNumber) {
            case 1:
                return getMoveWinner(playerOneMoveOneType, playerOneMoveOneValue, playerTwoMoveOneType, playerTwoMoveOneValue);
            case 2:
                return getMoveWinner(playerOneMoveTwoType, playerOneMoveTwoValue, playerTwoMoveTwoType, playerTwoMoveTwoValue);
            case 3:
                return getMoveWinner(playerOneMoveThreeType, playerOneMoveThreeValue, playerTwoMoveThreeType, playerTwoMoveThreeValue);
            default: 
                return null;
        }
    }

function getMoveWinner(playerOneMoveType, playerOneMoveValue, playerTwoMoveType, playerTwoMoveValue) {
    if (!playerOneMoveType || !playerOneMoveValue || !playerTwoMoveType || !playerTwoMoveValue ) {
        return null;
    }

    if (playerOneMoveType === playerTwoMoveType) {
        if (playerOneMoveValue > playerTwoMoveValue) {
            return 'Player One';
        } else if (playerOneMoveValue < playerTwoMoveValue) {
            return 'Player Two';
        } else {
            return 'Tie';
        }
    }

    if (playerOneMoveType === 'rock') {
        if (playerTwoMoveType === 'scissors') {
            return 'Player One';
        } else {
            return 'Player Two';
        }
    } else if (playerOneMoveType === 'paper') {
        if (playerTwoMoveType === 'rock') {
            return 'Player One';
        } else {
            return 'Player Two';
        } 
    } else {
            if (playerTwoMoveType === 'paper') {
                return 'Player One';
            } else {
                return 'Player Two';
            }
    }
}

// A function called getGameWinner, which compares both player’s move types and values for the whole game and returns the appropriate winner ('Player One', 'Player Two', or 'Tie')

function getGameWinner() {

    if(!playerOneMoveOneType || !playerOneMoveTwoType || !playerOneMoveTwoType || !playerOneMoveOneValue || !playerOneMoveTwoValue || !playerOneMoveThreeValue || !playerTwoMoveOneType || !playerTwoMoveTwoType || !playerTwoMoveTwoType || !playerTwoMoveOneValue || !playerTwoMoveTwoValue || !playerTwoMoveThreeValue) {
        return null;
    }

    playerOneWins = 0;
    playerTwoWins = 0;

    const roundOneWinner = getRoundWinner(1);
    const roundTwoWinner = getRoundWinner(2);
    const roundThreeWinner = getRoundWinner(3);

    addWin(roundOneWinner);
    addWin(roundTwoWinner);
    addWin(roundThreeWinner);

    if (playerOneWins > playerTwoWins) {
        return 'Player One';
    } else if (playerOneWins < playerTwoWins) {
         return 'Player Two';
    } else {
        return 'Tie';
    }
}

function addWin(winner) {
    if (winner === 'Player One') {
        playerOneWins = (playerOneWins + 1) || 1;
    } else if (winner === 'Player Two') {
        playerTwoWins = (playerTwoWins + 1) || 1;
    }
}

In this case the addWin function is called for each round:

    addWin(roundOneWinner);
    addWin(roundTwoWinner);
    addWin(roundThreeWinner);

The value of the “winner” parameter for each case is defined here:

    const roundOneWinner = getRoundWinner(1);
    const roundTwoWinner = getRoundWinner(2);
    const roundThreeWinner = getRoundWinner(3);

Which is basically the result of the execution of the following function for round 1, 2 and 3:

function getRoundWinner(roundNumber) {
    switch (roundNumber) {
        case 1:
            return getMoveWinner(playerOneMoveOneType, playerOneMoveOneValue, playerTwoMoveOneType, playerTwoMoveOneValue);
        case 2:
            return getMoveWinner(playerOneMoveTwoType, playerOneMoveTwoValue, playerTwoMoveTwoType, playerTwoMoveTwoValue);
        case 3:
            return getMoveWinner(playerOneMoveThreeType, playerOneMoveThreeValue, playerTwoMoveThreeType, playerTwoMoveThreeValue);
        default: 
            return null;
    }
}

Could you please confirm if my analysis is correct?

Thank you

const roundOneWinner = getRoundWinner(1);

In the above statement, a function call is being made with an argument of 1 being passed to the getRoundWinner function. This argument of 1 will be assigned to the parameter roundNumber and then the body of the getRoundWinner function will be executed. When the function returns a value, we will exit the function and then because of the above statement, the returned value will be assigned to the roundOneWinner variable.

Later, we make the function call

addWin(roundOneWinner);

The value assigned to the roundOneWinner variable will be passed as the argument to the addWin function. This argument will be assigned to the parameter winner and then the body of the addWin function will be executed. The addWin function is not returning any value explicitly. Instead, during execution, it is updating the global variables playerOneWins or playerTwoWins.

When passing arguments to functions, there is no constraint on us to assign the argument to a variable with the same name as the parameter. Outside the function, the argument could have been assigned to a variable with a different name OR we could have skipped assignment to a variable altogether and just passed a literal string directly as the argument.

1 Like