How to decide a winner in rock, paper, scissors? - javascript

I'm trying to program the game "rock, paper, scissors", so far it's working but when I want to display the winner I can't seem to know how to. If you look at my javascript you can see what I tried.
HTML:
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="mycss.css">
<script src="myjavascript2.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<div id="center">
<button onclick="myFunction1()">Play</button>
<p id="rolled">You rolled:</p>
<p id="test"></p>
<p id="rolled1">Your opponent rolled:</p>
<p id="test1"></p>
<p id="test2"></p>
<p id="test3"></p>
</div>
</body>
</html>
Javascript:
var things = [ 'rock', 'paper', 'scissors'];
function myFunction1() {
var random1 = Math.floor((Math.random()*things.length));
var random2 = Math.floor((Math.random()*things.length));
document.getElementById("test").innerHTML=things[random1];
document.getElementById("test1").innerHTML=things[random2];
document.getElementById("test2").innerHTML='';
document.getElementById("test3").innerHTML='';
The displaying of draw works perfect.
if (random1 == random2) {
document.getElementById("test2").innerHTML="<h3>It's a draw.</h3>";
}
However this doesn't:
else if (random1 == 1 && random2 == 3) {
document.getElementById("test3").innerHTML="You win!";
}
} //End of myFunction1
I want to know why I can't use this solution and what would be the correct one. Thanks.

First way:
switch (random1) {
case 0:
if (random2 == 1)
// player 1 loses
else
// player 1 wins
case 1:
//...
}
Keep the equality case before, put this in the else statement.
Second way :
I'd create an object to handle this.
function Thing (name) {
this.Name = name;
this.LoseOpponents = new Array ();
}
Thing.prototype.AddLoseOpponent = function (obj) {
this.LoseOpponents.push(obj);
}
Thing.prototype.WinsAgainst = function (obj) {
for (var i = 0; i < LoseOpponents.length; i++) {
if (LoseOpponents[i] === obj) {
return false;
}
}
return true;
}
Thing.prototype.IsDraw = function (obj) {
if (this.Name == obj.Name)
return true;
return false;
}
var paper = new Thing ('paper');
var scissors = new Thing ('scissors');
var rock = new Thing ('rock');
paper.AddLoseOpponent(scissors);
scissors.AddLoseOpponent(rock);
rock.AddLoseOpponent(paper);
//...
var things = [rock, paper, scissors];
var random1 = Math.floor((Math.random()*things.length));
var random2 = Math.floor((Math.random()*things.length));
var player1 = things[random1];
var player2 = things[random2];
document.getElementById("test").innerHTML=player1.Name;
document.getElementById("test1").innerHTML=player2.Name;
//...
if (player1.IsDraw(player2)) {
//draw
} else {
if (player1.WinsAgainst(player2)) {
// player1 wins
} else {
// player2 wins
}
}
In this way you can easily add new opponents, imagine more draw cases, add power ups...
Hope this can give you ideas. :)

With the conditional operator ?: and some constants you can express the problem as you would to a person: Rock beats scissors, paper beats rock, scissors beats paper.
http://jsfiddle.net/E9Ysa/1/
function play() {
var ROCK = 0;
var PAPER = 1;
var SCISSORS = 2;
var choices = ['rock', 'paper', 'scissors'];
var yourRoll = Math.floor(Math.random() * choices.length);
var opponentRoll = Math.floor(Math.random() * choices.length);
$('#test').text(choices[yourRoll]);
$('#test1').text(choices[opponentRoll]);
$('#test2').text('');
$('#test3').text('');
if (yourRoll == opponentRoll) {
$('#test2').text("It's a draw!");
return
}
/* Rock beats scissors
* Paper beats rock
* Scissors beats paper
*/
switch (yourRoll) {
case ROCK:
$('#test3').text(opponentRoll == SCISSORS ? 'You win!' : 'You lose!');
return;
case PAPER:
$('#test3').text(opponentRoll == ROCK ? 'You win!' : 'You lose!');
return;
case SCISSORS:
$('#test3').text(opponentRoll == PAPER ? 'You win!' : 'You lose!');
return;
}
}
$(document).ready(function () {
$('#play').click(function () {
play();
});
});

Related

How to design/redesign a JavaScript function to end and reset the rock paper scissors game after 9 rounds? The current function not working correctly

The following code is the totality of a version of paper rock scissors. The function: limitGameToBestOutOfNine () is only working some of the time. There are instances where the user or computer score increments above 9 wins. How do I fix this? Thanks in advance.
Code:
/*variable statements follow*/
const computerChoiceDisplay = document.getElementById('computer-choice');
const buttons = document.getElementsByClassName('control');
const userChoiceDisplay = document.getElementById('player-choice');
const resultDisplay = document.getElementById('result');
const possibleChoices = document.getElementsByClassName('control');
const resultOutput = document.getElementById('result-output');
const playerImage = document.getElementById('player-image');
const computerImage = document.getElementById('computer-image');
const choices = ["rock", "paper", "scissors"];
let userChoice;
let computerChoice;
let result ;
let playerChoice ;
let score = 0;
let mistakes = 0;
let scoreContainer;
let userSpan;
let computerSpan;
let playerScore = document.getElementById("userScore");
let compScore = document.getElementById("compScore");
let resetButton = document.getElementById("resetScore");
let compChoice;
let completedRounds = 0;
/**
* This Array from statement sets event listener to the button class control array
* which listens for the user and computer choices which are fed to the getresult function
*/
Array.from(possibleChoices).forEach(possibleChoice => possibleChoice.addEventListener('click', (e) => {
userChoice = e.target.id;
resultDisplay.innerHTML = userChoice;
compChoice = generateComputerChoice();
gameImages(userChoice, computerChoice);
getResult();
}));
/**
* This adds an event listener for the reset button
*/
document.getElementById("resetScore").addEventListener("click", resetScore);
/**
* This function generates a random number for the computer and displays
* the output to the innerHTML
*/
function generateComputerChoice() {
const randomNumber = Math.floor(Math.random() * 3) + 1;
if (randomNumber === 1) {
computerChoice = 'rock';
}
if (randomNumber === 2) {
computerChoice = 'paper';
}
if (randomNumber === 3) {
computerChoice = 'scissors';
}
computerChoiceDisplay.innerHTML = computerChoice;
}
/**
* Provides the logic to determin what to do in the event that either
* the user or computer wins, as well as what to do in the even of a draw.
*/
function getResult () {
if (computerChoice === userChoice) {
result = "It's a draw!";
}
if (computerChoice === 'rock' && userChoice === 'paper') {
result = "You Win!";
incrementUserScore();
console.log("paperWin");
}
if (computerChoice === 'rock' && userChoice === 'scissors') {
result = "You lost!";
incrementComputerScore();
}
if (computerChoice === 'paper' && userChoice === 'scissors') {
result = "You Win!";
incrementUserScore();
}
if (computerChoice === 'paper' && userChoice === 'rock') {
result = "You lost!";
incrementComputerScore();
}
if (computerChoice === 'scissors' && userChoice === 'rock') {
result = "You win!";
incrementUserScore();
}
if (computerChoice === 'scissors' && userChoice === 'paper') {
result = "You lost!";
incrementComputerScore();
}
resultOutput.innerHTML = result;
toggleBackgroundColor()
}
/**
* This function allows for the dynamic change of images based on user or
* computer choices.
*/
function gameImages(playerChoice, computerChoice) {
console.log(playerChoice, computerChoice);
playerImage.src = `assets/images/${playerChoice}.jpg`;
playerImage.alt = choices [userChoice];
computerImage.src = `assets/images/${computerChoice}.jpg`;
computerImage.alt = choices[computerChoice];
}
/**
* Gets the user score from the DOM and increments it by 1
*/
function incrementUserScore() {
console.log("incrementing");
// playerScore = playerScore++
score++;
playerScore.innerHTML = score;
console.log(playerScore);
completeRound()
}
/**
* Gets the computer score from the DOM and increments it by 1
*/
function incrementComputerScore() {
mistakes++;
compScore.innerHTML = mistakes;
console.log(compScore);
completeRound()
}
/**
* This function provides the logic used to reset the user and
* computer score back to zero, upon the user request.
*/
function resetScore() {
score = 0;
mistakes = 0;
playerScore.innerHTML = score;
compScore.innerHTML = mistakes;
}
/**
* This function is to limit the amount of playable paper, rock, and scissors game to best out of 9
*/
function limitGameToBestOutOfNine () {
// Check who has the higher score
if (score > mistakes) {
console.log('Player has won the game!');
alert('Player has won the game!');
} else if (mistakes > score) {
console.log('Computer has won the game!');
alert('Computer has won the game!');
} else {
console.log('It\'s a tie!');
alert('It\'s a tie!');
}
// Reset the scores
score = 0;
mistakes = 0;
}
function completeRound() {
// increment a completed round
completedRounds++;
console.log("Completed Rounds: " + completedRounds)
if (completedRounds == 10) {
limitGameToBestOutOfNine()
}
}
/***
* This function toggles the background color of the .player .computer class
* based on the winner of the current game. The winner color is green and the loser color is red
*/
function toggleBackgroundColor() {
const player = document.getElementById('player');
const computer = document.getElementById('computer');
const winner = resultOutput.innerHTML.toLowerCase();
console.log(winner)
if (winner.includes('you win')) {
console.log('win')
player.style.backgroundColor = "#00FF00";
computer.style.backgroundColor = "#FF0000";
}
else if (winner.includes('you lost')) {
console.log('lose')
player.style.backgroundColor = "#FF0000";
computer.style.backgroundColor = "#00FF00";
}
else {
console.log('draw')
player.style.backgroundColor = "#00FF00";
computer.style.backgroundColor = "#00FF00";
}
}
I have reviewed the code and do not know what the issue is. The problem started happening after I added the toggleBackgroundColor() function.

How I make my function in a rock, pepper, scissors game wait for a button press in Javascript?

So I have this code(I added the whole JS code but the part I want help is in the function game) that simply runs 5 rounds of a game of rock, papper, scissors with a press of a button in my html file.
The thing is that each round I want the function to wait for a button click of any of the three buttons (rock, papper or scissors)
I will appriciate any help, thank you and have a nice day!
let rock = "Rock";
let papper = "Papper";
let scissors = "Scissors";
let wins = 0;
let playerSelection;
const btnrock = document.getElementById('btn1');
const btnpapper = document.getElementById('btn2');
const btnscissors = document.getElementById('btn3');
const btnplay = document.getElementById('game')
function getPlayerChoice() {
btnrock.addEventListener('click', () => {
playerSelection = rock;
return playerSelection;
});
btnpapper.addEventListener('click', () => {
playerSelection = papper;
return playerSelection;
});
btnscissors.addEventListener('click', () => {
playerSelection = scissors;
return playerSelection;
});
}
btnplay.addEventListener('click', game)
function getComputerChoice() {
let min = Math.ceil(0);
let max = Math.floor(2);
let random = Math.floor(Math.random() * (max - min + 1) + min);
if (random == 0)
{
return rock;
}
if (random == 1){
return papper;
}
if (random == 2){
return scissors;
}
}
function playRound(playerSelection,pcChoice) {
if(pcChoice == rock && playerSelection == papper) {
wins++;
return "Player Wins!";
}
else if (pcChoice == rock && playerSelection == scissors) {
return "Player Loses!"
}
else if (pcChoice == scissors && playerSelection == rock){ wins++; return "Player Wins!"}
else if (pcChoice == scissors && playerSelection == papper){return "Player Loses!"}
else if (pcChoice == papper && playerSelection == rock){return "Player Loses!"}
else if (pcChoice == papper && playerSelection == scissors){wins++; return "Player Wins!"}
else {return "It's a Draw!"}
}
function game() {
for(let i = 0; i < 5; i++){
const pcChoice = getComputerChoice();
playerSelection = getPlayerChoice(); // I want this to wait
console.log("PC "+ pcChoice );
console.log('Player '+playerSelection);
let roundwinner = playRound(playerSelection,pcChoice);
console.log(roundwinner);
if(i === 2 && wins == 0){
break;
}
if(i === 3 && wins <= 1) {
break;
}
if(wins==3){
break;
}
}
if(wins >= 3) {
console.log("You are the winner of this match")
}
else {console.log('You lost the game');}
}
getPlayerChoice doesn't really get the player's choice - it adds event listeners. Run it 5 times and you get 5 listeners hooked up to the same event. I don't think you can wait for an event to fire in a loop like you're currently trying to. This would be a perfectly fine design in a console app when you want some input from the user, but in JS when working with events you have to leverage the events to execute your game's logic.
In other words, you might want to get rid of the for loop and consider moving that logic to event chain with a listener that first adds the user's input to the board and then executes the follow logic - e.g. gets the computer choice or determines whether the game is finished or not.

JS DOM: How to stop click event from firing?

I'm trying to get my buttons to stop working when a certain condition is met. For some reason, whenever I get to score 5, on either side, it just keeps going and doesn't even display the score and I don't know why. I've tried using a while loop but it kept crashing. Is there a simple way of just turning it off like there is in jQuery?
const rock = document.querySelector('.rock');
const paper = document.querySelector('.paper');
const scissors = document.querySelector('.scissors');
const h3 = document.querySelector('h3');
const pscore = document.querySelector('#pscore');
const cscore = document.querySelector('#cscore');
let computerScore = 0;
let playerScore = 0;
function computerPlay() {
var choice = Math.floor(Math.random() * 3 ) + 1; //generate a number 1-3 to find computer choice
if(choice == 1) {
return 'rock';
}
else if(choice == 2) {
return 'paper';
}
else {
return 'scissors'
}
}
let result; // simpler way of rewriting code?
rock.addEventListener('click', () => {
if(computerPlay() == 'rock') {
result = `The computer chose rock and you chose rock! It's a tie! No change in score.`;
h3.textContent = result;
}
else if(computerPlay() == 'paper') {
result = `The computer chose paper and you chose rock! You lose! Computer Score +1!`;
h3.textContent = result;
computerScore++;
cscore.textContent = computerScore;
}
else {
result = `The computer chose scissors and you chose rock! You win! Player Score +1!`;
h3.textContent = result;
playerScore++;
pscore.textContent = playerScore;
}
});
let playerPaper = paper.addEventListener('click', () => {
if(computerPlay() == 'paper') {
result = `The computer chose paper and you chose paper! It's a tie!`;
h3.textContent = result;
}
else if(computerPlay() == 'scissors') {
result = `The computer chose scissors and you chose paper! You lose!`;
h3.textContent = result;
computerScore++;
cscore.textContent = computerScore;
}
else {
result = `The computer chose rock and you chose paper! You win!`;
h3.textContent = result;
playerScore++;
pscore.textContent = playerScore;
}
});
let playerScissors = scissors.addEventListener('click', () => {
if(computerPlay() == 'scissors') {
result = `The computer chose scissors and you chose scissors! It's a tie!`;
h3.textContent = result;
}
else if(computerPlay() == 'rock') {
result = `The computer chose rock and you chose scissors! You lose!`;
h3.textContent = result;
computerScore++;
cscore.textContent = computerScore;
}
else {
result = `The computer chose paper and you chose scissors! You win!`;
h3.textContent = result;
playerScore++;
pscore.textContent = playerScore;
}
})
function playGame(computerChoice) {
computerChoice = computerPlay();
if(playerScore == 5) {
h3.textContent = `The score is 5 to ${computerScore}! You win!`;
}
else if(computerScore == 5) {
h3.textContent = `The score is 5 to ${playerScore}! The computer wins!`;
}
}
Everything works perfectly except for the 'end game' feature. Thanks in advance for all the help or critiques!
How to disable a "click" event
The people in the comments have some brilliant ideas on how you can improve your game. I would suggest looking into that. Although, if you want to prevent click events there are several ways to achieve that.
1. Add a disabled attribute to your button.
window.onload = () => {
const button = document.getElementById("myClicker")
button.disabled = true
}
<button id="myClicker">Click</button>
2. Add a CSS property pointer-events: none;
window.onload = () => {
const button = document.getElementById("myClicker")
button.addEventListener("click",function(){console.log("hi")})
button.style.pointerEvents = "none";
}
<button id="myClicker">Click</button>
The second method is for the situation when you don't need to indicate to the user that the button is no longer interactable.
3. Prevent Default event.
window.onload = () => {
const button = document.getElementById("myClicker")
button.addEventListener("click",function(e){
e.preventDefault;
})
}
<button id="myClicker">Click</button>
4. Remove Event listener.
document.getElementById("yourButtonId").removeEventListener("Click", yourFunctinoNameHere);
and welcome Charles. So, as #StackSlave mentioned, you keep querying computerPlay(), which will skew the results, probably favouring the last else (for each button respectively). This is a logic mistake - but the programme will still run.
You're trying to do quite a lot on the onclick events, and you're not paying attention to any kind of enable indicator. So.. here we go. I've seperated the programme into two pieces:
Round
Ui
The Round takes a user-choice, generates a computer-choice, and reports the score. The Ui attaches the buttons to choosing one of the options in the round, generating some output, updating scores and possibly ending the game. There's also a reset on the Ui which would allow you to start a new game ;) Note I've grouped things into objects (vs just functions) since each piece tracks a little state. I'd likely provide the constants at the top (rock..cscore) to the Ui constructor rather than use globals.
const rock = document.querySelector(".rock");
const paper = document.querySelector(".paper");
const scissors = document.querySelector(".scissors");
const h3 = document.querySelector("h3");
const pscore = document.querySelector("#pscore");
const cscore = document.querySelector("#cscore");
const NO_PICK = -1;
const PICK_ROCK = 0;
const PICK_PAPER = 1;
const PICK_SCISSORS = 2;
class Round {
constructor() {
this.player = NO_PICK;
this.computer = NO_PICK;
}
computerPlay() {
if (this.computer != NO_PICK) return; //Prevent double play - you might want to throw an exception instead?
this.computer = Math.floor(Math.random() * 3);
}
playAsString(number) {
switch (number) {
case PICK_ROCK:
return "rock";
case PICK_PAPER:
return "paper";
case PICK_SCISSORS:
return "scissors";
}
}
chooseRock() {
if (this.player !== NO_PICK) return; //Prevent double play
this.player = PICK_ROCK;
}
choosePaper() {
if (this.player !== NO_PICK) return; //Prevent double play
this.player = PICK_PAPER;
//return computerWinner(PICK_PAPER);
}
chooseScissors() {
if (this.player !== NO_PICK) return; //Prevent double play
this.player = PICK_SCISSORS;
//return computerWinner(PICK_SCISSORS);
}
reset() {
this.player = -1;
this.computer = -1;
}
//Return 0: tie, +1 player won, -1 computer won
playerScore() {
this.computerPlay();
if (this.player === NO_PICK) throw "Player hasn't played yet";
if (this.computer === this.player) return 0;
switch (this.computer) {
case PICK_ROCK:
return this.player === PICK_SCISSORS
? -1 //Rock beats scissors
: 1; //Paper beats rock
case PICK_SCISSORS:
return this.player === PICK_PAPER
? -1 //Scissors beat paper
: 1; //Rock beats scissors
case PICK_PAPER:
return this.player === PICK_ROCK
? -1 //Paper beats rock
: 1; //Scissors beat paper
}
}
winDescription(score) {
switch (score) {
case -1:
return "You lose! Computer score +1!";
case 0:
return "It's a tie! No change in score.";
case 1:
return "You win! Play score +1!";
}
}
gameDescription(score) {
return (
"The computer chose " +
this.playAsString(this.computer) +
" and you chose " +
this.playAsString(this.player) +
"! " +
this.winDescription(score)
);
}
}
class Ui {
constructor() {
this.playScore = 0;
this.compScore = 0;
this.enabled = true;
this.round = new Round();
rock.addEventListener("click", () => {
this.rockPress();
});
paper.addEventListener("click", () => {
this.paperPress();
});
scissors.addEventListener("click", () => {
this.scissorsPress();
});
//Bonus: you can have a reset button that calls this.reset
}
gameOver() {
this.enabled = false;
if (this.playScore > this.compScore) {
this.report("You win " + this.playScore + ":" + this.compScore + "!");
} else {
this.report("You lose " + this.playScore + ":" + this.compScore + "!");
}
}
sharedProcess() {
let gameScore = this.round.playerScore(); //Note this might throw if one of the press functions hasn't been called
this.report(this.round.gameDescription(gameScore));
if (gameScore < 0) {
this.compScore -= gameScore;
} else if (gameScore > 0) {
this.playScore += gameScore;
}
cscore.textContent = this.compScore;
pscore.textContent = this.playScore;
//Note this condition isn't exactly what you wrote so you may want to change, but you could do some sort of
// one has to be +2 over the other (win by two)
if (this.compScore >= 5 || this.playScore >= 5) {
this.gameOver();
}
this.round.reset(); //Setup for next game
}
rockPress() {
if (!this.enabled) return;
this.round.chooseRock();
this.sharedProcess();
}
paperPress() {
if (!this.enabled) return;
this.round.choosePaper();
this.sharedProcess();
}
scissorsPress() {
if (!this.enabled) return;
this.round.chooseScissors();
this.sharedProcess();
}
report(message) {
h3.textContent = message;
}
reset() {
this.playScore = 0;
this.compScore = 0;
this.enabled = true;
this.report("Game on!");
}
}
//Start the game - you don't need this ui variable
// unless you want to call one of the methods
const ui = new Ui();
I wouldn't disable anything. Just add and remove classes instead. Here is a very simple RockPaperScissors game. I put a small Library above // magic under here. Hopefully you can learn something here:
//<![CDATA[
/* js/external.js */
let get, post, doc, htm, bod, nav, M, I, mobile, S, Q, hC, aC, rC, tC, shuffle, rand, RockPaperScissors; // for use on other loads
addEventListener('load', ()=>{
get = (url, success, responseType = 'json', context = null)=>{
const x = new XMLHttpRequest;
const c = context || x;
x.open('GET', url); x.responseType = responseType;
x.onload = ()=>{
if(success)success.call(c, x.response);
}
x.send();
return x;
}
post = function(url, send, success, responseType ='json', context = null){
const x = new XMLHttpRequest;
const c = context || x;
x.open('POST', url); x.responseType = responseType;
x.onload = ()=>{
if(success)success.call(c, x.response);
}
if(typeof send === 'object' && send && !(send instanceof Array)){
if(send instanceof FormData){
x.send(send);
}
else{
const fd = new FormData;
let s;
for(let k in send){
s = send[k];
if(typeof s === 'object' && s)s = JSON.stringify(s);
fd.append(k, s);
}
x.send(fd);
}
}
else{
throw new Error('send argument must be an Object');
}
return x;
}
doc = document; htm = doc.documentElement; bod = doc.body; nav = navigator; M = tag=>doc.createElement(tag); I = id=>doc.getElementById(id);
mobile = nav.userAgent.match(/Mobi/i) ? true : false;
S = (selector, within)=>{
let w = within || doc;
return w.querySelector(selector);
}
Q = (selector, within)=>{
let w = within || doc;
return w.querySelectorAll(selector);
}
hC = function(node, className){
return node.classList.contains(className);
}
aC = function(){
const a = [].slice.call(arguments), n = a.shift();
n.classList.add(...a);
return aC;
}
rC = function(){
const a = [].slice.call(arguments), n = a.shift();
n.classList.remove(...a);
return rC;
}
tC = function(){
const a = [].slice.call(arguments), n = a.shift();
n.classList.toggle(...a);
return tC;
}
shuffle = array=>{
let a = array.slice(), i = a.length, n, h;
while(i){
n = Math.floor(Math.random()*i--); h = a[i]; a[i] = a[n]; a[n] = h;
}
return a;
}
rand = (min, max)=>{
let mn = min, mx = max;
if(mx === undefined){
mx = mn; mn = 0;
}
return mn+Math.floor(Math.random()*(mx-mn+1));
}
RockPaperScissors = function(displayFunc){
const a = ['rock', 'paper', 'scissors'];
this.wins = this.losses = this.ties = 0; this.text;
this.play = (you)=>{
let c = a[rand(2)], r;
switch(you){
case 'rock':
switch(c){
case 'rock':
r = 'You and the Computer chose "rock". IT\'S A TIE!'; this.ties++;
break;
case 'paper':
r = 'You chose "rock". The Computer chose "paper". YOU LOSE!'; this.losses++;
break;
case 'scissors':
r = 'You chose "rock". The Computer chose "scissors". YOU WIN!'; this.wins++;
break;
}
break;
case 'paper':
switch(c){
case 'rock':
r = 'You chose "paper". The Computer chose "rock". YOU WIN!'; this.wins++;
break;
case 'paper':
r = 'You and the Computer chose "paper". IT\'S A TIE!'; this.ties++;
break;
case 'scissors':
r = 'You chose "paper". The Computer chose "scissors". YOU LOSE!'; this.losses++;
break;
}
break;
case 'scissors':
switch(c){
case 'rock':
r = 'You chose "scissors". The Computer chose "rock". YOU LOSE!'; this.losses++;
break;
case 'paper':
r = 'You chose "scissors". The Computer chose "paper". YOU WIN!'; this.wins++;
break;
case 'scissors':
r = 'You and the Computer chose "scissors". IT\'S A TIE!'; this.ties++;
break;
}
break;
}
this.text = r;
if(displayFunc)displayFunc(this);
return this;
}
this.reset = ()=>{
this.wins = this.losses = this.ties = 0;
if(displayFunc)displayFunc(this);
return this;
}
}
// magic under here
const game = I('game'), rock = I('rock'), paper = I('paper'), scissors = I('scissors');
const again = I('again'), res = I('res'), replay = I('replay'), reset = I('reset');
const you = I('you'), comp = I('comp'), ties = I('ties');
setTimeout(()=>{
rC(game, 'played');
}, 0);
const rps = new RockPaperScissors(t=>{
you.textContent = t.wins; comp.textContent = t.losses; ties.textContent = t.ties;
res.textContent = t.text; aC(game, 'played'); rC(again, 'played');
});
rock.onclick = paper.onclick = scissors.onclick = function(){
rps.play(this.id);
}
function playAgain(){
res.textContent = ''; aC(again, 'played'); rC(game, 'played');
}
replay.onclick = playAgain;
reset.onclick = function(){
rps.reset(); playAgain();
}
}); // end load
//]]>
*{
box-sizing:border-box; color:#000; font:bold 22px Tahoma, Geneva, sans-serif; padding:0; margin:0; overflow:hidden;
}
html,body,.main{
width:100%; height:100%;
}
.main{
background:#999; overflow-y:auto;
}
.bar{
width:100%; height:39px; border-bottom:1px solid #777; background:#ccc; padding:2px
}
h1{
display:inline-block; font-size:27px; margin-left:7px;
}
#score{
display:flex; justify-content:space-around;
}
#score>div{
color:#555;
}
#y>span{
color:#070;
}
#c>span{
color:#700;
}
#t>span{
color:#777;
}
#game{
display:flex; transition:margin-top 0.25s ease-in-out;
}
.played{
margin-top:-38px;
}
#again{
display:flex; flex-wrap:wrap; margin-top:0;
}
#again.played{
margin-top:-76px;
}
#res{
width:100vw; font-size:18px; padding:0 10px; text-align:center;
}
input[type=button]{
flex:1; height:38px; background:linear-gradient(#1b7bbb,#147); color:#fff; border:1px solid #007; border-radius:5px; cursor:pointer;
}
#paper,#replay{
background:linear-gradient(#679467,#235023); border-color:#070;
}
#scissors,#reset{
background:linear-gradient(#b75757,#502323); border-color:#700;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1, user-scalable=no' />
<title>Rock, Paper, Scissors</title>
<link type='text/css' rel='stylesheet' href='css/external.css' />
<script src='js/external.js'></script>
</head>
<body>
<div class='bar'><h1>Rock, Paper, Scissors</h1></div>
<div id='score'>
<div id='y'>You: <span id='you'>0</span></div>
<div id='c'>Computer: <span id='comp'>0</span></div>
<div id='t'>Ties: <span id='ties'>0</span></div>
</div>
<div class='main'>
<div class='played' id='game'>
<input id='rock' type='button' value='rock' />
<input id='paper' type='button' value='paper' />
<input id='scissors' type='button' value='scissors' />
</div>
<div class='played' id='again'>
<input id='replay' type='button' value='replay' />
<input id='reset' type='button' value='reset' />
<div id='res'></div>
</div>
</div>
</body>
</html>

Event listener in my button doesn't work properly, the function runs normally outside the click event, but it doesn't work when I click the button

I am making a rock,paper and scissors game.
This is my whole code, I am only posting it full because I can't figure out why it isn't working, when I use playRound('paper','scissors'); the function runs just fine, but when I use it inside a click event such as (see the end of the code) :
var paperButton = document.querySelector("#paper");
paperButton.addEventListener("click", playRound('paper',computerPlay()));
it just doesn't work, I click the paper button but it doesn't do anything. Why?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Rock, Paper and Scissors Game</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="container">
<button id="rock">Rock</button>
<button id="paper">Paper</button>
<button id="scissors">Scissors</button>
</div>
<div class="results">
<div id="result">No result</div>
</div>
// HTML ENDS HERE
//START OF THE JAVASCRIPT
<script>
var computerScore = 0;
var playerScore = 0;
function computerPlay(){
let randomNum = Math.floor((Math.random() * 3) + 1);
if (randomNum == 1) {
var compChoice = 'rock';
} else if (randomNum == 2){
var compChoice = 'paper';
} else {
var compChoice = 'scissors';
}
return compChoice;
}
function playerPlay() {
var playerChoice = prompt("Enter rock, paper or scissors");
return playerChoice;
}
function playRound(playerSelection, computerMove ) {
var result = document.querySelector("#result");
switch(playerSelection) {
case 'rock':
if (computerMove === 'paper') {
computerScore++;
result.textContent = 'Paper beats rock! You lose that round.';
}
else if (computerMove === 'scissors') {
playerScore++;
result.textContent = 'Rock beats scissors! You win that round.';
}
else {
result.textContent = 'It\'s a draw!';
}
break;
case 'paper':
if (computerMove === 'scissors') {
computerScore++;
result.textContent = 'Scissors beats paper! You lose that round.';
}
else if (computerMove === 'rock') {
playerScore++;
result.textContent = 'Paper beats rock! You win that round.';
}
else {
result.textContent = 'It\'s a draw!';
}
break;
case 'scissors':
if (computerMove === 'rock') {
computerScore++;
result.textContent = 'Rock beats scissors! You lose that round.';
}
else if (computerMove === 'paper') {
playerScore++;
result.textContent = 'Scissors beats paper! You win that round.';
}
else {
result.textContent = 'It\'s a draw!';
}
}
}
playRound('paper','scissors'); //this works
var rockButton = document.querySelector('#rock');
rockButton.addEventListener("click", playRound('rock',computerPlay())); // doesn't work
var paperButton = document.querySelector("#paper");
paperButton.addEventListener("click", playRound('paper',computerPlay())); // doesn't work
var scissorsButton = document.querySelector("#scissors");
scissorsButton.addEventListener("click", playRound('scissors', computerPlay())); // doesn't work**
</script>
</body>
</html>
You are actually executing the function when you pass like this:
rockButton.addEventListener("click", playRound('rock',computerPlay()));
You need to pass a function as a argument, like this:
rockButton.addEventListener("click", () => {
playRound('rock',computerPlay());
}
);

Rock Paper Scissors Javascript Game Add Choice Limit

I've created a Javascript-based Rock Paper Scissors game and it's pretty good so far. However, I want to create an option for "best out of 3" or "best out of 5". Please could some of you awesome JS people have a look at my code and see how I could implement the best of "x" scenario. Basically, I guess it comes down to the number of clicks.
Anyway, the code speaks for itself and here is a live example of the code:
Rock Paper Scissors Live Github Example
And the code:
(function(){
/*
* Rock, paper, scissors
*
* The classic game recreated in Javascript for playing in the browser.
*
*/
// create the choices
var choices = [
'rock',
'paper',
'scissors'
];
var CHOICES_LENGTH = choices.length;
// create the text for winning or drawing
var USER_WINS = "You win!";
var COMP_WINS = "Computer wins";
var DRAW = "Draw"
var MEH = '<i class="fa fa-meh-o" aria-hidden="true"></i>';
var SMILE = '<i class="fa fa-smile-o" aria-hidden="true"></i>';
var FROWN = '<i class="fa fa-frown-o" aria-hidden="true"></i>';
var score = 0;
var computer_score = 0;
var gameType;
var clicks = 0;
// score elements
var userScore = getById('score');
var compScore = getById('computerScore');
userScore.textContent = score;
compScore.textContent = computer_score;
// get the game area and get access to all the buttons
var game = getById('game');
var userChoices = game.getElementsByTagName('button');
var comp = getById('computer');
var compChoices = comp.getElementsByTagName('div');
// get the results element and hide it initially
var results = getById('results');
hide(results);
var gameOver = getById('gameOver');
hide(gameOver);
// get the intro element and the buttons for choosing a game type
var intro = getById('intro');
var bestOf3 = getById('bestOf3');
var bestOf5 = getById('bestOf5');
// start the best of 3 game
bestOf3.onclick = function() {
enableGame();
gameType = 3;
}
bestOf5.onclick = function() {
enableGame();
gameType = 5;
}
function enableGame() {
enable(userChoices);
hide(intro);
}
// add an onclick event to each button and disable them initially
for(var i = 0; i < userChoices.length; i++) {
userChoices[i].onclick = selection;
userChoices[i].disabled = true;
}
function computerSelection() {
var randomIndex = Math.floor(Math.random() * CHOICES_LENGTH);
var compChoice = choices[randomIndex];
return compChoice;
}
function selection() {
// get the user and computer choice
var chosen = this.id;
var comp = computerSelection();
// get the users chosen item
var chosenItem = getById(chosen);
// prepare the chosenCompItem so we can assign it to a dynamic id
var chosenCompItem;
if(comp === 'rock') {
chosenCompItem = getById('computerRock');
}
else if(comp === 'paper') {
chosenCompItem = getById('computerPaper');
}
else if(comp === 'scissors') {
chosenCompItem = getById('computerScissors');
}
// show results and disable all choices so no more can
// be made while waiting for the pop up to fade out
show(results);
reappear(results);
disable(userChoices);
disable(compChoices);
// make the selected item stand out from the rest
chosenItem.classList.add('selected');
chosenCompItem.classList.add('selected');
// decide who wins
if(chosen === comp) {
results.textContent = DRAW;
// ugly repetive code. what can I do???
timeout();
results.innerHTML += MEH;
}
else if(chosen === 'rock' && comp === 'scissors') {
results.textContent = USER_WINS;
score += 1;
userScore.textContent = score;
timeout();
results.innerHTML += SMILE;
}
else if(chosen === 'paper' && comp === 'rock') {
results.textContent = USER_WINS;
score += 1;
userScore.textContent = score;
timeout();
results.innerHTML += SMILE;
}
else if(chosen === 'scissors' && comp === 'paper') {
results.textContent = USER_WINS;
score += 1;
userScore.textContent = score;
timeout();
results.innerHTML += SMILE;
}
else {
results.textContent = COMP_WINS;
computer_score +=1;
compScore.textContent = computer_score;
timeout();
results.innerHTML += FROWN;
}
console.log(clicks);
}
// utilities
function getById(id) {
return document.getElementById(id);
}
function hide(element) {
element.style.display = 'none';
}
function show(element) {
element.style.display = 'block';
}
function disappear(element) {
element.className = 'disappear';
}
function reappear(element) {
element.className = 'reappear';
}
function disable(elements) {
for(var i = 0; i < elements.length; i++) {
elements[i].disabled = true;
elements[i].classList.add('unselected');
}
}
function enable(elements) {
for(var i = 0; i < elements.length; i++) {
elements[i].disabled = false;
elements[i].classList.add('default');
elements[i].classList.remove('selected', 'unselected');
}
}
function timeout() {
setTimeout(function(){
disappear(results);
enable(userChoices);
enable(compChoices);
}, 2000)
}
})();
The code has massive room for improvement but the main thing here is, how do I make it so the user gets only 3 or 5 plays??
Hope this all makes sense.
Thanks
Assuming your definition of best of "N" is the same as mine, my code should work.
My definition of "best of N" is:
To win, one person must win N/2 rounds, with N/2 being rounded up to the nearest whole number.
You could use this code:
if(userScore + compScore === gameType) { gameOver(); }
And use a simple if statement to see who won.
Hope this helped!

Categories

Resources