JS DOM: How to stop click event from firing? - javascript
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>
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.
Why does my function always return the same value?
Newly learning Javascript, so I'm learning to store functions in objects. Currently creating a simple rock,paper, scissors game. I'm stuck, where I need the getWinner function to determine the winner and added 3 conditions to the function = draw, win or lose. Now the problem is, it always returns draw to me. Can anyone help? const startGameBtn = document.getElementById('start-game-btn'); let ROCK = "ROCK"; let PAPER = "PAPER"; let SCISSORS = "SCISSORS"; let RESULT_DRAW = "It's a draw"; let RESULT_PLAYER_WINS = "Player Wins"; let RESULT_COMPUTER_WINS = "Player Wins"; let GAME_IS_RUNNING = false; let getPlayerChoice = function () { let selection = prompt(`${ROCK},${PAPER}, or ${SCISSORS}? `, '').toUpperCase(); if (selection !== ROCK && selection !== PAPER && selection !== SCISSORS) { alert ("Invalid choice, defaulted to Rock"); selection = ROCK; } return selection } const getComputerChoice = function() { const randomValue = Math.floor(Math.random() * 2); if (randomValue === 0) { return ROCK; } else if (randomValue === 1) { return PAPER; } else if (randomValue === 2) { return SCISSORS; }; } const getWinner = function (cChoice, pChoice) { if (cChoice === pChoice) { return RESULT_DRAW; } else if (cChoice === ROCK && pChoice === PAPER || cChoice === PAPER && pChoice === SCISSORS || cChoice === SCISSORS && pChoice === ROCK ) { return RESULT_PLAYER_WINS; } else { return RESULT_COMPUTER_WINS; } } startGameBtn.addEventListener('click', function () { if (GAME_IS_RUNNING) { return } GAME_IS_RUNNING = true; console.log("Game is starting...."); let playerChoice = getPlayerChoice(); console.log(playerChoice); let computerChoice = getComputerChoice(); console.log(computerChoice); let winner = getWinner(computerChoice, playerChoice); console.log(winner); }); <button id="start-game-btn">Start</button>
Fixing only the problem that the computer can never choose SCISSORS, it runs and works. Maybe you just had a lucky run of draws. const startGameBtn = document.getElementById('start-game-btn'); let ROCK = "ROCK"; let PAPER = "PAPER"; let SCISSORS = "SCISSORS"; let RESULT_DRAW = "It's a draw"; let RESULT_PLAYER_WINS = "Player Wins"; let RESULT_COMPUTER_WINS = "Player Wins"; let GAME_IS_RUNNING = false; let getPlayerChoice = function() { let selection = prompt(`${ROCK},${PAPER}, or ${SCISSORS}? `, '').toUpperCase(); if (selection !== ROCK && selection !== PAPER && selection !== SCISSORS) { alert("Invalid choice, defaulted to Rock"); selection = ROCK; } return selection } const getComputerChoice = function() { const randomValue = Math.floor(Math.random() * 3); // <---- if (randomValue === 0) { return ROCK; } else if (randomValue === 1) { return PAPER; } else if (randomValue === 2) { return SCISSORS; }; } const getWinner = function(cChoice, pChoice) { if (cChoice === pChoice) { return RESULT_DRAW; } else if (cChoice === ROCK && pChoice === PAPER || cChoice === PAPER && pChoice === SCISSORS || cChoice === SCISSORS && pChoice === ROCK ) { return RESULT_PLAYER_WINS; } else { return RESULT_COMPUTER_WINS; } } startGameBtn.addEventListener('click', function() { if (GAME_IS_RUNNING) { return } GAME_IS_RUNNING = true; console.log("Game is starting...."); let playerChoice = getPlayerChoice(); console.log(playerChoice); let computerChoice = getComputerChoice(); console.log(computerChoice); let winner = getWinner(computerChoice, playerChoice); console.log(winner); }); <button id="start-game-btn">START-STOP</button>
my html script tags aren't linking to my external javascript
I've been trying to write a small rock, paper scissors machine but there seems to be something wrong with the script tags in my HTML. it works when I put the script between the script tags but I've been told that doing so is confusing.` var selector = document.getElementById('selectors'); var title = document.getElementById('title'); var userInput = ''; var choices = ['rock', 'paper', 'scissors']; var computerChoice = ''; var outcome = ''; function getUserInput() { if (class = 'rock') { userInput = 'rock'; return userInput; } else if (class = 'paper') { userInput = 'paper'; return userInput; } else if (class = 'scissors') { userInput = 'scissors'; return userInput; } } function change() { document.getElementById("title").innerHTML = 'it has worked' } <head> <title>scissors, paper, rock engine</title> <script type="text/javascript" src="./rockPaperScissors.js"></script> </head> strong text`
If all files are in same folder then try by removing the dot and slash <script type="text/javascript" src="rockPaperScissors.js"></script>
Or add two dots before / if your script is located one level up. <script type="text/javascript" src="../rockPaperScissors.js">
I realised that it didn't work because of the getUserInput function it is working now
In function getUserInput, you have two errors, First, you can't use the class as it's a reserved keyword. Second, I hope you are trying to compare the class name with the string, you need to place === or!== to check. To check if the file loaded successfully or not... Right click on your site and choose Inspect. It will open a new window of chrome developer tools. In that go to network and refresh(F5). It shows every document, image and supporting files required for that web page. and If you click on any file, it gives the details about headers, preview, response and timing details of that.
Hi first of all kindly solve this error in your code i.e. function getUserInput() { if (class == 'rock') { //here = should be == userInput = 'rock'; return userInput; } else if (class == 'paper') { //here = should be == userInput = 'paper'; return userInput; } else if (class == 'scissors') { //here = should be == userInput = 'scissors'; return userInput; } } as you are comparing the values in condition and as for script tag simply specify in src if have file in same directory simply use file name e.g.: <script type="text/javascript" src="file.js"></script>
Just wanted to include an example of what your code might end up looking like. var doc, bod, M, I, S, Q, aC, rC, tC; // for use on other loads addEventListener('load', function(){ // load wrapper doc = document; bod = doc.body; M = function(tag){ // make element return doc.createElement(tag); } I = function(id){ // document.getElementById(id) return doc.getElementById(id); } S = function(selector, within){ // .querySelector var w = within || doc; return w.querySelector(selector); } Q = function(selector, within){ // .querySelectorAll var w = within || doc; return w.querySelectorAll(selector); } aC = function(element, className, text){ // addClass var s = element.className.split(/\s+/), n = s.indexOf(className); if(n === -1){ s.push(className); element.className = s.join(' '); } if(text !== undefined){ if(element.value === undefined){ element.innerHTML = text; } else{ element.value = text; } } return function(className, text){ return aC(element, className, text); } } rC = function(element, className, text){ // remove class var s = element.className.split(/\s+/), n = s.indexOf(className); if(n !== -1){ s.splice(n, 1); element.className = s.join(' '); } if(text !== undefined){ if(typeof element.innerHTML === 'undefined'){ element.value = text; } else{ element.innerHTML = text; } } return function(className, text){ return rC(element, className, text); } } tC = function(element, className, onText, offText){ // toggle class var s = element.className.split(/\s+/), n = s.indexOf(className); if(n === -1){ s.push(className); element.className = s.join(' '); if(onText !== undefined){ if(element.value === undefined){ element.innerHTML = onText; } else{ element.value = onText; } } } else{ s.splice(n, 1); element.className = s.join(' '); if(offText !== undefined){ if(element.value === undefined){ element.innerHTML = offText; } else{ element.value = offText; } } } return function(className, onText, offText){ return tC(element, className, onText, offText); } } var players = I('players'), playerCount = +players.value, comp = I('computer'), player2 = I('player2'), res = I('res'), play1, play2; function randPSR(){ var a = ['paper', 'scissors', 'rock']; return a[Math.floor(Math.random()*3)]; } function psr(p1, p2){ var yp, op; if(p1 === p2){ return "It's a tie. Play again!"; } if(playerCount === 1){ yp = 'You Win'; op = 'Computer'; } else{ yp = 'Player 1 Wins'; op = 'Player 2'; } switch(p1){ case 'paper': switch(p2){ case 'scissors': return op+' Wins - Scissors Beats Paper'; case 'rock': return yp+' - Paper Beats Rock'; } break; case 'scissors': switch(p2){ case 'paper': return yp+' - Scissors Beats Paper'; case 'rock': return op+' Wins - Rock Beats Scissors'; } break; case 'rock': switch(p2){ case 'paper': return op+' Wins - Paper Beats Rock'; case 'scissors': return yp+' - Rock Beats Scissors'; } break; } } function paperScissorsRock(){ aC(comp, 'hide'); comp.innerHTML = res.innerHTML = ''; for(var i=0,p1buttons=Q('#player1>input[type=button]'),p2buttons=Q('#player2>input[type=button]'),l=p1buttons.length; i<l; i++){ p1buttons[i].onclick = function(){ play1 = this.value; if(playerCount === 1){ play2 = randPSR(); comp.innerHTML = 'Computer Picks "'+play2+'"'; rC(comp, 'hide'); } else if(!play1 || !play2){ res.innerHTML = ''; } if(play1 && play2){ res.innerHTML = psr(play1, play2); play1 = play2 = false; } } p2buttons[i].onclick = function(){ play2 = this.value; if(!play1 || !play2)res.innerHTML = ''; if(play1 && play2){ res.innerHTML = psr(play1, play2); play1 = play2 = false; } } } } paperScissorsRock(); players.addEventListener('change', function(){ aC(comp, 'hide'); comp.innerHTML = res.innerHTML = ''; play1 = play2 = false; playerCount = +this.value; playerCount === 1 ? aC(player2, 'hide') : rC(player2, 'hide'); }); }); // end load wrapper *{ padding:0; margin:0; } html,body{ width:100%; height:100%; background:#aaa; color:#000; overflow-x:hidden; } body{ overflow-y:scroll; } .main{ width:940px; padding:20px; margin:0 auto; } select,#computer{ border:0; margin-bottom:15px; } select,input{ cursor:pointer; } label,select,input[type=button]{ font:22px Tahoma, Geneva, sans-serif; padding:5px 10px; border-radius:5px; } input[type=button]{ background:#ccc; border:3px solid #000; margin-bottom:15px; } .hide{ display:none; } <!DOCTYPE html> <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'> <head> <meta http-equiv='content-type' content='text/html;charset=utf-8' /> <meta name='viewport' content='width=device-width, height=device-height, initial-scale:1' /> <title>Same Page Paper Scissors Rock</title> </head> <body> <div class='main'> <label id='players_label' for='players'>Players</label> <select name='players' id='players'> <option value='1' selected='selected'>1</option> <option value='2'>2</option> </select> <div class='hide' id='computer'></div> <div id='player1'> <input type='button' value='paper' /> <input type='button' value='scissors' /> <input type='button' value='rock' /> </div> <div class='hide' id='player2'> <input type='button' value='paper' /> <input type='button' value='scissors' /> <input type='button' value='rock' /> </div> <div id='res'></div> </div> </body> </html>
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!
How to decide a winner in rock, paper, scissors?
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(); }); });