Rock Paper Scissors declare winner logic

Solution 1:

  • Your indexes logic is wrong Math.floor(Math.random() * 4) can give you 0,1,2,3 — but you only need 0,1,2.
  • The document tags that are part of your app should go in <body>, not in <head>

Also given Rock Paper Scissors is actually a game of indexes, you could convert your logic to something more simpler:

const fig = ["Rock", "Paper", "Scissors"];
const msg = ["You won", "You lost", "It's a draw"];
const score = [0, 0, 0]; // 0= PL's score,  1= AI's score, 2=Total Draws

function play() {
  const PL = Number(this.dataset.player);   // Get 0, 1, 2 from button data-player
  const AI = Math.floor(Math.random() * 3); // Generate random 0, 1, 2 integer

  let res; // Result to be determined:

  if (PL === AI) {
    res = 2;  // Draw
  } else if ((AI + 1) % 3 === PL) {
    res = 0;  // Player wins
  } else {
    res = 1;  // Computer wins
  }
  
  score[res] += 1;

  console.log(`
    ${msg[res]} 
    You played: ${fig[PL]}
    Computer played: ${fig[AI]} 
    Score: Player: ${score[0]} Computer: ${score[1]} Draws: ${score[2]}
  `);
}

document.querySelectorAll("[data-player]").forEach((el) => {
  el.addEventListener("click", play);
});
<button data-player="0" type="button">ROCK</button>
<button data-player="1" type="button">PAPER</button>
<button data-player="2" type="button">SCISSORS</button>

Let's examine the key concept of "RPS is a game if indexes".

The easiest logic is when PL equals AI. So having that one eliminated,
Player wins if: we add 1 to AI's result and after a Modulo %3 the values are equal. The last one possibility is: Computer has won.

Why the modulo logic works is because of the order R-P-S or 0 1 2, which is a linear wins-over sequence.

// Rock Paper Scissors - win logic:

 ...  0R  1P  2S  ...  wins over:
     /   /   /   /    
    /   /   /   /
 ...  0R  1P  2S  ...

by using % 3 (in the (AI + 1) % 3) we're just making sure to cover the above's ... cases.

Without the if, else the above can be also rewritten using the (Conditional) Ternary Operator statement ? ifTrue : ifFalse :

const fig = ["Rock", "Paper", "Scissors"];
const msg = ["You won", "You lost", "It's a draw"];
const score = [0, 0, 0];

function play() {
  const PL = Number(this.dataset.player);   // Get 0, 1, 2 from button data-player
  const AI = Math.floor(Math.random() * 3); // Generate random 0, 1, 2 integer
  let res = PL === AI ? 2 : (AI + 1) % 3 === PL ? 0 : 1; // Determine result
  score[res] += 1;
  console.log(`
    ${msg[res]}!
    You played: ${fig[PL]},
    Computer played: ${fig[AI]}
    Score: Player: ${score[0]} Computer: ${score[1]} Draws: ${score[2]}
  `);
}

document.querySelectorAll("[data-player]").forEach(el => el.addEventListener("click", play));
<button data-player="0" type="button">ROCK</button>
<button data-player="1" type="button">PAPER</button>
<button data-player="2" type="button">SCISSORS</button>