How can I write a neater set of code for my rock paper scissors game?

纵饮孤独 提交于 2021-02-05 06:58:56

问题


Below is my JS file for a rock, paper, scissors game activity we had to do in my web development class. I was able to get everything to work, however I do not like how long my if-else statements made my code and was wondering how can I make this more concise and have it in less lines of code.

const imagePath=[];
imagePath.push("img/paper.png");
imagePath.push("img/rock.png");
imagePath.push("img/scissors.png");

let counter=1;
let counter2=1;
let images=document.querySelector("#player");
let images2=document.querySelector("#computer");
function ImageChange()
{

  images.src=imagePath[counter];
  counter++;
  if (counter == imagePath.length)
  {
    counter=0;
  }

  images2.src=imagePath[counter2];
  counter2++;
  if (counter2 == imagePath.length)
  {
    counter2=0;
  }
}

 let intervalObject=setInterval(ImageChange,500);


const playButton=document.querySelector("#play");

const div= document.querySelector("#message");

playButton.addEventListener("click",function(){

clearInterval(intervalObject);

let randomIndex=Math.floor(Math.random()*imagePath.length);
images.src=imagePath[randomIndex];

let randomIndex2=Math.floor(Math.random()*imagePath.length);
images2.src=imagePath[randomIndex2];


//paper=0,rock=1,scissors=2
if(randomIndex==randomIndex2)
{
  div.innerHTML="<h1>Tie!</h1>";
}

else if(randomIndex==0)
{
  if(randomIndex2==1)
  {
    div.innerHTML="<h1>Player Wins</h1>";
  }
  else
  {
    div.innerHTML="<h1>Computer Wins</h1>";
  }
}

else if(randomIndex==1)
{
   if(randomIndex2==2)
  {
    div.innerHTML="<h1>Player Wins</h1>";
  }
   else
  {
    div.innerHTML="<h1>Computer Wins</h1>";
  }
}

else if(randomIndex==2)
{
  if(randomIndex2==0)
  {
    div.innerHTML="<h1>Player Wins</h1>";
  }
  else
  {
    div.innerHTML="<h1>Computer Wins</h1>";
  }
}


});

Like I said everything works and I have my html/css files. However, my concern is just with the if statements I have. Is there a better way I can write them?


回答1:


I'd think something more like this would save you a lot of lines of code:

if(randomIndex==randomIndex2) {
  div.innerHTML="<h1>Tie!</h1>";
}
else {
  var playerWins = (randomIndex==0 && randomIndex2==1) || (randomIndex==1 && randomIndex2==2) || (randomIndex==2 && randomIndex2==0)
  div.innerHTML = playerWins ? "<h1>Player Wins</h1>" : "<h1>Computer Wins</h1>"
}

Edit: (Here's a quick rewrite using the mod (%) suggestion below, see Megaptera novaeangliae)

const imagePath = ["img/paper.png", "img/rock.png", "img/scissors.png"];

const playButton = document.querySelector("#play");
const playerImage = document.querySelector("#player");
const computerImage = document.querySelector("#computer");
const div = document.querySelector("#message");

let computerChoice, playerChoice;

function randomChoice() {
	return Math.floor(Math.random() * imagePath.length);
}

function randomize() {
	playerChoice = randomChoice();
	computerChoice = randomChoice();
	playerImage.src = imagePath[playerChoice];
	computerImage.src = imagePath[computerChoice];
}

let intervalObject = setTimeout(randomize, 500);

playButton.addEventListener("click", function() {
	clearInterval(intervalObject);

	// paper=0, rock=1, scissors=2
	if (playerChoice == computerChoice) {
		div.innerHTML = "<h1>Tie!</h1>";
	} else if (playerChoice == (computerChoice + 1) % imagePath.length) {
		div.innerHTML = "<h1>Player Wins</h1>";
	} else {
		div.innerHTML = "<h1>Computer Wins</h1>";
	}
});



回答2:


This might be a personal preference, but I find things much neater when there is space between operators and operands. And I also properly despise the

else
{
...
}

Formatting scheme. I would recommend, for neatness purposes, use

else { 
    ... 
}

Most people will also tell you not to, but I find it helps with neatness further: on single statement conditions or clauses, you can omit braces.

else 
    console.log("Else Clause")
console.log("Outside of Else");

I would also suggest using switch statements as these make code far more readable, although they have their own quirks, they are fantastic for making code readable. Further, I would also suggest to avoid one-liners. I fell into that habit for a while and it hit me hard. You haven't really done that in this case, but I'm just adding it for future references.

Another thing you might find useful is grouping variables of similar usage/purpose. So don't put newlines between them.

Again, another personal preference is using 4-space indentation. Makes it more visible where the indents start and end.

So in summary:

  • Leave enough space between tokens
  • Place braces on the same line
  • Blocks (Except try/catch) with only one statement can omit their braces
  • Use a switch statement
  • Group variables
  • Use four spaces (spaces, not tabs)

Hope that helps




回答3:


To put the entire game logic into a simple script:

Rock, Paper, Scissors to indexes: 0, 1, 2

result = PL === AI ? 2 : (AI + 1) % 3 === PL ? 0 : 1;
//                   |                         |   |
// 0 = PL wins --------------------------------┘   |
// 1 = AI wins ------------------------------------┘
// 2 = draw    ------┘

Having those three indexes in place you can now easily retrieve the respective played figure-names and the needed won/draw message from Arrays:

// RPS // 0=PLwon 1=AIwon 2=Draw!
const RPS = (PL, AI) => PL === AI ? 2 : (AI + 1) % 3 === PL ? 0 : 1;
const msg = ["Player won", "AI won", "Draw!"];
const fig = ["Rock", "Paper", "Scissors"];

// Example Demo:
const rnd = n => ~~(Math.random() * n);
const pl  = rnd(3);
const ai  = rnd(3);
const result = RPS(pl, ai);
console.log(`PL:${fig[pl]} AI:${fig[ai]} - ${msg[result]}`);

Dive deeper into the logic, see this answers:

  • js-rock-paper-scissors
  • how-do-i-make-a-function-that-reset-the-game-on-click


来源:https://stackoverflow.com/questions/58924599/how-can-i-write-a-neater-set-of-code-for-my-rock-paper-scissors-game

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!