I'm trying to write a very simple rock-paper-scissors game and I'm running into a problem where the final button only works if you haven't clicked the rock, paper, or scissors buttons.
Once any of the other buttons are clicked the final button will no longer work.
the compareChoices
function seems to work when I manually change the player and computer variables but not if the button functions change them.
If I set the var's to choices[0] the button works but will output the wrong answer.
Here is my Web application and associated scripts:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Rock, Paper, Scissors</title>
<link rel="stylesheet" href="styles.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fredoka One&display=swap" rel="stylesheet">
</head>
<body>
<h1 >Lapis, Papyrus, Scalpellus</h1>
<p >Fiat Fatum Decernere</p>
<p ></p>
<br/>
<button id="btn"></button>
<button id="btn"></button>
<button id="btn"></button>
<br/>
<button id="btn">Final Answer</button>
<div ></div>
</body>
</html>
function playRPS() {
const choices = ["Lapis", "Papyrus", "Scalpellus"]
var player = null;
var computer = null;
function computerChooses() {
let computer = choices[Math.floor(Math.random() * choices.length)];
console.log(computer);
}
document.querySelector(".rock").addEventListener("click", computerChooses);
document.querySelector(".paper").addEventListener("click", computerChooses);
document.querySelector(".scissors").addEventListener("click", computerChooses);
function rockBtn(){
player = choices[0];
console.log(player);
}
document.querySelector(".rock").addEventListener("click", rockBtn);
function paperBtn(){
player = choices[1];
console.log(player);
}
document.querySelector(".paper").addEventListener("click", paperBtn);
function scissorBtn() {
player = choices[2];
console.log(player);
}
document.querySelector(".scissors").addEventListener("click", scissorBtn);
function compareChoices() {
if(computer === player) {
console.log("Tie!");
} else
if(computer == choices[0]) {
if(player == choices[1]) {
console.log("You Won!");
} else {
console.log("Computer Won!");
}
} else
if(computer == choices[1]) {
if(player == choices[2]) {
console.log("You Won!");
} else {
console.log("Computer Won!");
}
} else
if(computer == choices[2]) {
if(player == choices[0]) {
console.log("You Won!");
} else {
console.log("Computer Won!");
}
}
}
document.querySelector(".final").addEventListener("click", compareChoices);
}
playRPS();
CodePudding user response:
You cannot approach this binding your elements twice, one for "player choice" and the other for "computer choice".
As a matter of fact, there is no need to imagine the computer choice as event-driven, there is no need for a "Final answer" button either: computer choice has to be performed automatically after the user choice, and lead to the display of results.
You should perform compareChoices()
right after the user clicked one of the three buttons. Inside that function, you can call computerChooses()
and check the results.
function playRPS() {
const choices = ["Lapis", "Papyrus", "Scalpellus"]
const resultsDiv = document.querySelector('.results')
var player = null;
var computer = null;
function computerChooses() {
computer = choices[Math.floor(Math.random() * choices.length)];
}
function rockBtn() {
player = choices[0];
compareChoices()
}
document.querySelector(".rock").addEventListener("click", rockBtn);
function paperBtn() {
player = choices[1];
compareChoices()
}
document.querySelector(".paper").addEventListener("click", paperBtn);
function scissorBtn() {
player = choices[2];
compareChoices()
}
document.querySelector(".scissors").addEventListener("click", scissorBtn);
function compareChoices() {
computerChooses()
resultsDiv.innerHTML = ''
resultsDiv.innerHTML = "<br>You: " player
resultsDiv.innerHTML = "<br>Computer: " computer
let results = ''
if (computer === player) {
results = "Tie!";
} else if (computer == choices[0]) {
if (player == choices[1]) {
results = "You Won!";
} else {
results = "Computer Won!";
}
} else if (computer == choices[1]) {
if (player == choices[2]) {
results = "You Won!";
} else {
results = "Computer Won!";
}
} else if (computer == choices[2]) {
if (player == choices[0]) {
results = "You Won!";
} else {
results = "Computer Won!";
}
}
resultsDiv.innerHTML = "<br>" results
}
}
playRPS();
<h1 >Lapis, Papyrus, Scalpellus</h1>
<p >Fiat Fatum Decernere</p>
<p ></p>
<br/>
<button id="btn">Lapis</button>
<button id="btn">Papyrus</button>
<button id="btn">Scalpellus</button>
<br/>
<div >
</div>
CodePudding user response:
You can use a nested switch statement to determine winning conditions.
Note: Avoid class names and use data attributes instead.
const results = document.querySelector('.results');
const choices = ['rock', 'paper', 'scissors'];
const dictionary = {
paper: 'Papyrus',
rock: 'Lapis',
scissors: 'Scalpellus'
}
const playRPS = () => {
document.querySelectorAll('[data-choice]')
.forEach(choice =>
choice.addEventListener('click', handleChoice));
};
const handleChoice = (e) => {
const player = e.target.getAttribute('data-choice');
const computer = randChoice();
results.innerHTML = JSON.stringify({
player: dictionary[player],
computer: dictionary[computer],
result: compareChoices(player, computer),
})
};
const compareChoices = (player, computer) => {
switch (didWin(player, computer)) {
case -1 : return "Computer Won!";
case 0 : return "Tie!";
case 1 : return "You Won!";
}
};
const didWin = (attacker, defender) => {
switch (attacker) {
case 'rock':
switch (defender) {
case 'rock' : return 0;
case 'paper' : return -1;
case 'scissors' : return 1;
}
case 'paper':
switch (defender) {
case 'rock' : return 1;
case 'paper' : return 0;
case 'scissors' : return -1;
}
case 'scissors':
switch (defender) {
case 'rock' : return -1;
case 'paper' : return 1;
case 'scissors' : return 0;
}
}
throw new Error('Illegal input');
};
const randChoice = () =>
choices[Math.floor(Math.random() * choices.length)];
playRPS();
body {
font-family: "Fredoka One";
}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fredoka One&display=swap" rel="stylesheet">
<h1 >Lapis, Papyrus, Scalpellus</h1>
<p >Fiat Fatum Decernere</p>
<p ></p>
<br />
<button data-choice="rock">Lapis</button>
<button data-choice="paper">Papyrus</button>
<button data-choice="scissors">Scalpellus</button>
<br /><br />
<div ></div>
CodePudding user response:
Taking out the let in the computerChooses function worked! thankyou!
also I'm pretty new to this so best practices aren't there yet. I think I fixed the binding elements problem? how's this look?
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Rock, Paper, Scissors</title>
<link rel="stylesheet" href="styles.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fredoka One&display=swap" rel="stylesheet">
</head>
<body>
<h1 >Lapis, Papyrus, Scalpellus</h1>
<p >Fiat Fatum Decernere</p>
<p ></p>
<br/>
<button ></button>
<button ></button>
<button ></button>
</body>
</html>
function playRPS() {
const choices = ["Lapis", "Papyrus", "Scalpellus"]
var player = null;
var computer = null;
function compareChoices (){
if(computer === player){
console.log("Tie!");
document.querySelector(".decission").innerText = "Tie!";
}else if(computer == choices[0]){
if(player == choices[1]){
console.log("You Won!");
document.querySelector(".decission").innerText = "You Win!";
}else{
console.log("Computer Won!");
document.querySelector(".decission").innerText = "Computer Wins!";
}
}
else if(computer == choices[1]){
if(player == choices[2]){
console.log("You Won!");
document.querySelector(".decission").innerText = "You Win!";
}else{
console.log("Computer Won!");
document.querySelector(".decission").innerText = "Computer Wins!";
}
}
else if(computer == choices[2]){
if(player == choices[0]){
console.log("You Won!");
document.querySelector(".decission").innerText = "You Win!";
}else{
console.log("Computer Won!");
document.querySelector(".decission").innerText = "Computer Wins!";
}
}
}
function computerChooses(){
computer = choices[Math.floor(Math.random() * choices.length)];
console.log(computer);
}
function rockBtn(){
player = choices[0];
console.log(player);
}
document.querySelector(".rock").addEventListener("click", () => {
rockBtn();
computerChooses();
compareChoices();
});
function paperBtn(){
player = choices[1];
console.log(player);
}
document.querySelector(".paper").addEventListener("click", () => {
paperBtn();
computerChooses();
compareChoices();
});
function scissorBtn(){
player = choices[2];
console.log(player);
}
document.querySelector(".scissors").addEventListener("click", () => {
scissorBtn();
computerChooses();
compareChoices();
});
}
playRPS();