What are some ways to streamline and improve the readability of my if/else if statement?

I've created a Rock Paper Scissors game that runs in the console. It currently uses multiple if/else if statements to compare user input against the computer's selection and determine a winner. The code is quite lengthy and repetitive, so I'm exploring ways to streamline it.

Here's a snippet of the current code:

function start(computerSelection, playerSelection){
  
  // Game logic here...
 
}

This excerpt showcases the part of the code that I aim to simplify without compromising functionality.

Answer №1

One effective approach is to implement a data-driven system:


const winningMoves = { scissors: 'rock', rock: 'paper', paper: 'scissors' }
  
function playRound(computerMove, playerMove) {
  if (computerMove === playerMove) return "It's a tie!";
  if (playerMove === winningMoves[computerMove]) { playerScore++; return "You win!"; }
  if (computerMove === winningMoves[playerMove]) { computerScore++; return "Computer wins!"; }
  return "Invalid move!";
}

Answer №2

How to implement the game logic:

function determineWinner(computerChoice, playerChoice) {
  const options = {
    rock: "scissors",
    paper: "rock",
    scissors: "paper"
  };

  if (computerChoice === playerChoice) {
    return "It's a tie!";
  } else if (options[computerChoice] === playerChoice) {
    playerScore += 1;
    return "You win!";
  } else if (options[playerChoice] === computerChoice) {
    computerScore += 1;
    return "Computer wins!";
  } else {
    return "Invalid selection!";
  }
}

Answer №3

Efficiently streamlined without resorting to switch/case and minimal alterations from the original code:

function start(computerSelection, playerSelection){
  if (computerSelection === playerSelection){
    return "It's a tie!"
  }
  if ((computerSelection === "rock" && playerSelection === "paper") ||
     (computerSelection === "paper" && playerSelection === "scissors") ||
     (computerSelection === "scissors" && playerSelection === "rock")){
    playerScore += 1;
    return "You win!";
  }
  if ((computerSelection === "rock" && playerSelection === "scissors") ||
     (computerSelection === "paper" && playerSelection === "rock") || 
     (computerSelection === "scissors" && playerSelection === "paper")){
    computerScore += 1;
    return "Computer wins!"; 
  }
  return "Invalid entry!"
}

I believe removing else statements and condensing similar conditions is sufficient here.

Please keep in mind that there could be ways to further shorten the code, but readability should also be considered alongside brevity. I intentionally opted for code that closely resembled the original.

Answer №4

This code simplifies a game of rock-paper-scissors.

function initiateGame(computerChoice, playerChoice) {
  let playerScore = 0;
  let computerScore = 0;
  const results = {
    rock: { scissors: 'Computer wins!', paper: 'Player wins!' },
    paper: { rock: 'Computer wins!', scissors: 'Player wins!' },
    scissors: { paper: 'Computer wins!', rock: 'Player wins!' }
  };
  if (!(computerChoice in results) || !(playerChoice in results)) {
    return 'Invalid selection!';
  }
  if (computerChoice === playerChoice) {
    return "It's a draw!";
  }
  const result = results[computerChoice][playerChoice];
  if (result) {
    if (result === 'Computer wins!') {
      computerScore += 1;
    } else {
      playerScore += 1;
    }
    return result;
  }
}
console.log(initiateGame("scissors","rock"))

Answer №5

This content is brief

let computerPoints = 0;
let playerPoints = 0;
const victory = {"rock"    : "scissors", 
                  "paper"   : "rock", 
                  "scissors": "paper"};
const initializeGame = (computerChoice, playerChoice) => {
  if(computerChoice === playerChoice) return "It's a draw!";
  if(victory[computerChoice] === playerChoice) return ++computerPoints, "Computer emerges victorious!";
  if(victory[playerChoice] === computerChoice) return ++playerPoints, "You are the winner!";
  return "Invalid input!";
};

/// sample tests
console.log("rock","scissors",initializeGame("rock","scissors"))
console.log("paper","scissors",initializeGame("paper","scissors"))
console.log("rock","rock",initializeGame("rock","rock"))
console.log("scissors","paper",initializeGame("scissors","paper"))
console.log("paper","rock",initializeGame("paper","rock"))

console.log(computerPoints,playerPoints)

Answer №6

Is this kind of what you're looking for?

function initiate(computerPick, playerPick) {
  // Different outcomes
  const possibilities = {
    rock: { scissors: 'Computer wins!', paper: 'You win!', rock: "It's a tie!" },
    paper: { rock: 'Computer wins!', scissors: 'You win!', paper: "It's a tie!" },
    scissors: { paper: 'Computer wins!', rock: 'You win!', scissors: "It's a tie!" }
  };

  // Is it a tie?
  if (computerPick === playerPick) {
    return "It's a tie!";
  }

  // Who is the winner?
  if (possibilities[computerPick][playerPick] === 'You win!') {
    playerScore += 1; // Increase player score
  } else {
    computerScore += 1; // Increase computer score
  }

  // Show the result of the round
  return possibilities[computerPick][playerPick];
}

You may want to include this as well:

// Are the picks valid?
  if (!(computerPick in possibilities) || !(playerPick in possibilities)) {
    return 'Invalid choice!';
  }

Answer №7

Implementing a different strategy without using if-else statements. Leveraging TypeScript template literal types for enhanced type safety

type Move = "rock" | "paper" | "scissors";

const drawResult = { player: 0, computer: 0 };
const playerVictory = { player: 1, computer: 0 };
const computerVictory = { player: 0, computer: 1 };

const scorePoints: Record<`${Move}-${Move}`, { player: number; computer: number }> =
  {
    "paper-paper": drawResult,
    "rock-rock": drawResult,
    "scissors-scissors": drawResult,
    "paper-rock": playerVictory,
    "rock-scissors": playerVictory,
    "scissors-paper": playerVictory,
    "rock-paper": computerVictory,
    "scissors-rock": computerVictory,
    "paper-scissors": computerVictory,
  };

function determineWinner(playerMove: Move, computerMove: Move) {
  return scorePoints[`${playerMove}-${computerMove}`];
}

console.log(determineWinner("paper", "rock")); // {player: 1, computer: 0}


Answer №8

One easy way to determine the winner in a game is by following this concept.

Check out further details here

const wins = {rock: `paper`, paper: `scissors`, scissors: `rock`};
const choices = Object.keys(wins);

function play(youSelection, pcSelection) {
  return `(you) ${youSelection} > (computer) ${pcSelection} => ${
    youSelection === pcSelection 
    ? `TIE` : youSelection === wins[pcSelection]
    ? `You win` : `Computer wins`}`;
}

// demo
for (let i=0; i < 10; i+=1) {
  const me = choices[Math.floor(Math.random() * choices.length)];
  const pc = choices[Math.floor(Math.random() * choices.length)];
  console.log(play(me, pc));
}
.as-console-wrapper {
    max-height: 100% !important;
}

Answer №9

Initially, there is no need for this type of if/else logic when returning in each block:

if (x) {
  return 'foo';
} else if (y) {
  return 'bar';
else {
  return 'lorem ipsum';
}

You can simplify it to just

if (x) {
  return 'foo';
} 

if (y) {
  return 'bar';
}

return 'lorem ipsum';

Secondly, if you want to utilize a switch statement because you're not only checking a single value, you might consider:

switch (true) {
    case computerSelection === playerSelection:
        return "It's a tie!";
    case computerSelection === "rock" && playerSelection === "paper":
        return "You win!";
    case computerSelection === "rock" && playerSelection === "scissors": 
        return "Computer wins!"; 
    ... etc
    
    default:
        return "Invalid entry!"
}

Finally, the function in which you increment playerScore and computerScore lacks initialization and usage, so I have omitted them from my response.

Answer №10

To handle these scenarios, implementing a switch case structure can be an effective solution. Here is an example:

function determineWinner(computerChoice, playerChoice) {
  let outcome = "";
  switch (true) {
    case computerChoice === playerChoice:
      outcome = "It's a tie!";
      break;
    case computerChoice === "rock":
      outcome = playerChoice === "paper" ? "You win!" : "Computer wins!";
      break;
    case computerChoice === "paper":
      outcome = playerChoice === "scissors" ? "You win!" : "Computer wins!";
      break;
    case computerChoice === "scissors":
      outcome = playerChoice === "rock" ? "You win!" : "Computer wins!";
      break;
    default:
      outcome = "Invalid entry!";
  }
  if (outcome === "You win!") {
    playerScore += 1;
  } else if (outcome === "Computer wins!") {
    computerScore += 1;
  }
  return outcome;
}

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

Looking to replace a background image using javascript?

(apologies for any language mistakes) I have multiple divs with a common background image. I assigned them the same class and set the background image using CSS in style.css which worked perfectly fine. Now, I want to change the background image dynamical ...

JavaScript library for making HTTP requests

Can someone provide guidance on creating a JavaScript command line application that interacts with a public API using an HTTP client library? What is the preferred JavaScript HTTP library for this task? ...

Submitting values using the serialize method and Ajax involves sending placeholders

Looking for a solution: <form class="pure-form pure-form-stacked" method="post" enctype="multipart/form-data"> <input type="text" name="name" class="button-size-1" placeholder="*Name"> <input type="text" name="email" class="but ...

Canceling a promise in a Vuex action

I am looking to implement the ability to cancel a running promise in my Vue component, specifically a promise returned by a Vuex action. In my scenario, the Vuex action is continuously polling an endpoint for status updates, and I need the capability to s ...

The Javascript functionality does not seem to be functioning properly within the Bootstrap navigation

I'm having an issue with my Bootstrap navbar JavaScript. Below is the code that's causing the problem: <script type="text/javascript"> $(".nav a").on("click", function () { $(".nav").find(".active").removeClass("active"); $(this).p ...

Set boundaries for the width and height of an image in the input field

Looking to restrict the size of an image in an input field using HTML, CSS, and JavaScript/jQuery. Goal is to maintain a perfect square aspect ratio for profile photo uploads (for example, 200x200 or 300x300). ...

Identify the opening of the console for the background page of a Chrome

Is it possible to detect when I click on the "Background Page" for my test plugin on the "chrome://extensions/" page? This question has been boggling my mind. Currently, whenever I open the background page, the console remains undocked. After reading a po ...

Invoking functions from controllers to mongoose schema module in Node.js

Greetings everyone, I am fairly new to working with Node.js so let me share my current dilemma. I have set up a mongoose schema for handling comments in the following structure: const mongoose = require("mongoose"); const Schema = mongoose.Schema; const ...

Showing information in a modal dialog in an Angular 4 application

As an Angular 4 developer, I am working on an application where I need to display data in a dialog. To achieve this, I am using @Output to pass data from the child component to the parent component. In the parent component, my code looks like this: expor ...

JavaScript returns the value 'undefined' when a function variable is used with an array of objects

Here is an example of an array of objects: var theArray = [ {theId:'1', num: 34}, {theId:'2', num: 23}, {theId:'5', num: 26} ]; This function successfully loops through the array: function printValues() { va ...

What is the procedure for passing arguments to Google signIn in a NextJS backend?

I am currently working on implementing a role-based Google sign-in feature in a Next.js 13 app using next-auth. This setup involves calling two different tables to create users based on their assigned roles. For the database, I am utilizing mongodb/mongoo ...

Tips for transforming numerical date data into a string format

Is there a method to convert the numeric month in a table into a string format? <table style="width: 100%;"> <tr> <th>Date</th> <th>Total</th> </tr> <tr> <td id="date ...

Connect ngOptions to an array beyond the current scope

Can the ngOptions be bound to a value that is not within the $scope? I have enums that will be generated as JavaScript code. These enums are not currently part of "the angular domain", but I want to bind an ngOptions to one of the arrays without manually ...

What is the best way to customize the style using a CSS class?

Is it possible to alter a specific style with a CSS class using jQuery or JavaScript? For example, if the HTML looks like this: <tab> <a class="anchor">a</a> </tab> And the CSS looks like this: a {border:1px} .anchor {color: ...

What is the reason behind Typescript flagging a potential undefined value when checking for array length using a greater than comparison but not with an

Consider the following excerpt from a React component: const AccountInformation = (props: { readonly accountData: AccountData | undefined | null }) => { const hasMultipleAccounts: boolean = props.accountData?.customerAccounts?.length === 1 ? false : t ...

Guide to importing images (.svg, .png) into a React component

I'm currently facing an issue trying to upload an image file in one of my React components using webpack. My project is already set up with web pack. Below is the code snippet for the component: import Diamond from '../../assets/linux_logo.jpg& ...

What could be causing the responsive grid to not stack items properly?

I'm struggling to make my page responsive on mobile devices. The elements are not stacking as intended, but rather aligning side by side. How can I fix this issue? My attempts to adjust spacing, padding, and flex-grow values have not yielded the desi ...

Adding the victory chart in react-native slider causes performance issues, as the slider becomes laggy and there is a delayed reflection

When I use a slider in my application without including a Victory chart, the slider functions smoothly with no issues. However, integrating the slider with the Victory chart causes lag and delays in updating the state value on screen. For more detailed in ...

The loading spinner fails to function when triggered by the ng-click or ng-change events in an AngularJS application

I have implemented a loading spinner to display while the page is loading. App.controller('MailFolderController', ['$scope', '$http',function ($scope, $http){ $scope.loading = true; $scope.allotmentStatus = [ {"value ...

Utilizing URL-based conditions in Reactjs

Currently, I am working with Reactjs and utilizing the Next.js framework. My goal is to display different text depending on whether the URL contains "?id=pinned". How can I achieve this? Below is the snippet of my code located in [slug.js] return( ...