I'm trying to make a Rock Paper Scissors coding challenge for myself, and I got a simple version with a text box, so no I'm trying to make it with buttons, I have made it very far through, I'm just on the last step.
So what I want to do is take the info from the rock(), paper(), and scissors() functions and go further
This is what I have so far
var playerInput = "blank"
function rock(playerInput) {
this.playerInput = playerInput;
playerInput = "rock";
}
function paper(playerInput) {
this.playerInput = playerInput;
playerInput = "paper";
}
function scissors() {
this.playerInput = playerInput;
playerInput = "scissors";
}
and what I want to do from there is take it into another function where I have already created the game itself.
I've tried
var rock = rock();
console.log(rock.playerInput);
and it didn't work please help.
[Here's a super useful example][1] on how to tackle the Rock, Paper, Scissors game logic using buttons.
Besides that, you don't need multiple functions, programming is not about copy/pasting code around a file, but to determine the characteristics we can reuse.
Use data-* attributes to store the figure index:
function play() {
const player = Number(this.dataset.player); // Get 0, 1, 2 from button data-player
const computer = Math.floor(Math.random() * 3); // Generate random 0, 1, 2 integer
console.log(`PLAYER: ${player} COMPUTER:${computer}`);
// Game logic goes here
}
const buttons = document.querySelectorAll("[data-player]");
buttons.forEach(function(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>
Given the above, you got pretty much all the needed data.
Both player and computer values are an integer 0 (rock), 1 (paper), 2 (scissors)
Example of Rock Paper Scissors game with result
const fig = ["Rock", "Paper", "Scissors"];
const msg = ["You won!", "You lost :(", "It's a draw"];
function play() {
const player = Number(this.dataset.player); // Get 0, 1, 2 from button data-player
const computer = Math.floor(Math.random() * 3); // Generate random 0, 1, 2 integer
// Game logic goes here
// See: https://stackoverflow.com/a/53983473/383904
let result;
if (player === computer) {
result = 2; // Draw
} else if ((computer + 1) % 3 === player) {
result = 0; // Player wins
} else {
result = 1; // Computer wins
}
console.log(`PLAYER:${fig[player]} COMPUTER:${fig[computer]} ${msg[result]}`);
}
const buttons = document.querySelectorAll("[data-player]");
buttons.forEach(function(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>
Another resource that explains the logic is here
[1]: https://stackoverflow.com/a/53983473/383904
function rock(playerInput) {
this.playerInput = playerInput;
}
var playerInput = 'blank'
var myRock = new rock(playerInput);
console.log(myRock.playerInput) // Should output "Blank"
If you want to make an object with function notation, you need to use the new keyword:
var myRock = new rock();
And you should be passing the info to the object when you create it, not before. Try something like this.
function rock(playerInput) {
this.playerInput = playerInput;
}
var myRock = new rock("Blank");
console.log(myRock.playerInput) // Should output "Blank"
Related
I am just beginning with JS and am having trouble with scope and executing code in similar style as I would with Python. I have started learning JS on Codecademy and have just begun my first project.
My code for the project is below:
//////////////////////////
// R U Hungry Console App
/////////////////////////
// Step 1: Load in Necessary Modules
////////////////////////////////////
// add in the prompt-sync module
// allows to take in and display users name
const prompt = require('prompt-sync')();
// load in fs module
// allows reading in from text files
const fs = require("fs");
// load open module
//allows the opening of webpages
const open = require('open');
// Step 2: Create a menu object
///////////////////////////////
const menu = {
starters: [],
mains: [],
desserts: []
}
// Step 3 Create a factory function to update the Menu object
/////////////////////////////////////////////////////////////
const menuUpdate = (course,dishName,dishLink) => {
if (course.toLowerCase() === 'starter'){
let newItem = {dish: dishName, link: dishLink};
menu.starters.push(newItem);
} else if (course.toLowerCase() === 'main'){
let newItem = {dish: dishName, link: dishLink};
menu.mains.push(newItem);
} else if (course.toLowerCase() === 'dessert'){
let newItem = {dish: dishName, link: dishLink};
menu.desserts.push(newItem);
} else {
console.log('You did not enter a valid course.\nCould not update menu');
}
}
// Step 4: Read in text files of scraped web data
/////////////////////////////////////////////////
const dishes = [menu.starters,menu.mains,menu.desserts];
const filesToRead = ['starters.txt','mains.txt','desserts.txt'];
function addFiles(course,file){
const text = fs.readFileSync(`./menu_files/${file}`);
const textByLine = text.toString().split("\n");
for (const line of textByLine){
course.push(line);
}
}
addFiles(dishes[0],filesToRead[0]);
addFiles(dishes[1],filesToRead[1]);
addFiles(dishes[2],filesToRead[2]);
// Step 5: Put it all together
//////////////////////////////
console.log('\n\nFeeling hungry and can\'t decide what to eat? You have come to the right place.')
const name = prompt('What is your name? ');
console.log(`\nWelcome, ${name}!\nWould you like to be:\n1.Presented With a Menu\n2.Add a Dish to the Menu`);
let userChoice;
while (true){
userChoice = prompt('\nEnter 1 to get a Menu\nEnter 2 to add a Menu Item\nEnter 3 to exit R U Hungry ');
if (userChoice.trim() === 1){
const starterSelector = Math.floor(Math.random() * menu.starters.length);
const mainSelector = Math.floor(Math.random() * menu.mains.length);
const dessertSelector = Math.floor(Math.random() * menu.desserts.length);
let starterDish = menu.starters[starterSelector][0];
let starterRecipe = menu.starters[starterSelector][1];
let mainDish = menu.mains[mainsSelector][0];
let mainRecipe = menu.mains[mainsSelector][1];
let dessertDish = menu.desserts[dessertSelector][0];
let dessertRecipe = menu.desserts[dessertSelector][1];
console.log(`${name}, your Menu is as follows:\n`);
console.log(`Starter: ${starterDish}`);
console.log(`Main: ${mainDish}`);
console.log(`Dessert: ${dessertDish}`);
console.log('\nWe will direct you to recipes for your selected dishes');
// opens the url in the default browser
open(starterRecipe);
open(mainRecipe);
open(dessertRecipe);
} else if (userChoice.trim() === 2){
let userCourse = prompt('Is your dish a Starter, Main or Dessert? ');
let userDishName = prompt('Great! Please tell me the name of your dish ');
let userDishLink = prompt('Please provide the link to the dish recipe ');
menuUpdate = (userCourse,userDishName,userDishLink);
console.log('Menu updated with your dish!');
} else {
console.log(`Goodbye, ${name}.`);
break;
}
console.log('Would you like to perform another function?');
}
// End
I am having trouble with the while loop at the end.
This part specifically:
let userChoice;
while (true){
userChoice = prompt('\nEnter 1 to get a Menu\nEnter 2 to add a Menu Item\nEnter 3 to exit R U Hungry ');
if (userChoice.trim() === 1){
const starterSelector = Math.floor(Math.random() * menu.starters.length);
const mainSelector = Math.floor(Math.random() * menu.mains.length);
const dessertSelector = Math.floor(Math.random() * menu.desserts.length);
let starterDish = menu.starters[starterSelector][0];
let starterRecipe = menu.starters[starterSelector][1];
let mainDish = menu.mains[mainsSelector][0];
let mainRecipe = menu.mains[mainsSelector][1];
let dessertDish = menu.desserts[dessertSelector][0];
let dessertRecipe = menu.desserts[dessertSelector][1];
console.log(`${name}, your Menu is as follows:\n`);
console.log(`Starter: ${starterDish}`);
console.log(`Main: ${mainDish}`);
console.log(`Dessert: ${dessertDish}`);
console.log('\nWe will direct you to recipes for your selected dishes');
// opens the url in the default browser
open(starterRecipe);
open(mainRecipe);
open(dessertRecipe);
} else if (userChoice.trim() === 2){
let userCourse = prompt('Is your dish a Starter, Main or Dessert? ');
let userDishName = prompt('Great! Please tell me the name of your dish ');
let userDishLink = prompt('Please provide the link to the dish recipe ');
menuUpdate = (userCourse,userDishName,userDishLink);
console.log('Menu updated with your dish!');
} else {
console.log(`Goodbye, ${name}.`);
break;
}
console.log('Would you like to perform another function?');
}
It keeps executing the code in the else block and then exiting the program.
In python I would have used something like this:
while (True):
choice = input("What is your name? ")
if choice.strip().lower() != 'john':
print("Who are you?")
break;
elif choice choice.strip().lower() != 'shaun':
print("Who are you?")
break;
else:
print("Hi there, glad you aren't John or Shaun")
continue
Stupid example but I just wanted to show how I could normally have achieved something like this before.
Would anyone be able to explain what is incorrect?
I also struggle to understand the scope in JS. Is that perhaps the problem here?
I am finding it difficult in some cases to apply my thinking from Python to JS.
Any help would be appreciated. I am really wanting to learn.
Thanks!
Maybe as a starter you can you == rather than === as it would not match the type, also in your else if it seems you are calling function incorrectly, remove =.
I'm currently working through a prep course for a bootcamp and the last assignment is to put some basic JavaScript functions into a rock, paper, scissors game. I'm stuck trying to finish this onclick function.
What is the best way to populate the users choice when they click the buttons?
I've currently got my choices defined and set-up in an array. So, I guess I'm trying to get the defined choices to equal the buttons pushed. If I'm thinking correctly I want ex: choices[1] to also be my "Papyrus" button. I've attempted const () =, but I get a no "initializer" warning.
UPDATED ONCLICK FUNCTION. Everywhere I looked and on my lessons it had function(e) with e.target.id and I changed the querySelector to querySelectorAll to grab all the buttons. But still not seeing the console.log output nor seeing the compareChoice results on the screen.
const firstChoice = "Lapis";
const secondChoice = "Papyrus";
const thirdChoice = "Scalpellus";
const choices = ['Lapis', 'Payrus', 'Scalpellus'];
player.currentChoice = document.querySelectorAll('button').onclick = function(e) {
console.log(e.target.id);
}
//Example of on of the choice outcomes
else if(computer.currentChoice === choices[0]){
if(player.currentChoice === choices[1]){
displayResults("The player wins! The computer chose " + computer.currentChoice + " and the player chose " + player.currentChoice);
}else{
displayResults("The computer loses! The computer chose " + computer.currentChoice + " and the player chose " + player.currentChoice);
I assume you have player Obj and multiple buttons where user can pick from
let player = {
currentChoice: ''
},
computer = {
computerSelection: ['Lapis', 'Payrus', 'Scalpellus'],
currentChoice: ''
};
const allButtons = document.querySelectorAll('button')
for (var i = 0; i < allButtons.length; i++) {
allButtons[i].addEventListener('click', getUserSelection);
}
function compare() {
let playerChoice = player.currentChoice,
computerChoice = computer.currentChoice,
outcome = '';
if (playerChoice === computerChoice) {
outcome = 'draw';
} else if (playerChoice === 'Lapis' && computerChoice === 'Scalpellus' || (playerChoice === 'Papyrus' && computerChoice === 'Lapis') || (playerChoice === 'Scalpellus' && computerChoice === 'Papyrus')) {
outcome = 'You win';
} else {
outcome = 'You lose'
}
displayResults(outcome)
displayResults(`You picked ${playerChoice}`)
displayResults(`Computer picked ${computerChoice}`)
}
function getUserSelection(e) {
player.currentChoice = this.id;
// From here trigger a function that compares
// User slection against computers random selection
startTheFight();
}
function setComputerChoice() {
let random = Math.floor(Math.random() * (computer.computerSelection.length - 1)) + 1;
computer.currentChoice = computer.computerSelection[random];
}
function startTheFight() {
// Get a random selection
setComputerChoice();
compare();
}
function displayResults(result) {
const resultText = document.createElement('p');
resultText.innerText = result;
document.body.appendChild(resultText);
}
<button id="Lapis">
Lapis
</button>
<button id="Papyrus">
Papyrus
</button>
<button id="Scalpellus">
Scalpellus
</button>
Edit:In your case, can show the result ultimatium like in the example
The first thing I can see from your code is that you are not defining your onclick callback correctly.
You should use the addEventListener function instead, with the first parameter being the event you want to listen to ( "click" in your case ) and the second being your callback.
Note that the callback can take a parameter, which is the event.
document.querySelectorAll('button').addEventListener("click", function(event) {
// do something once the button is clicked.
});
A callback is just a function that will be executed at some point. And since you seams to be using the "Return value" of the callback in the rest of the code, it is not going to be executed properly. Take the example bellow.
const myButton = document.querySelector('#button');
let myVariable;
// proper way to define an event listener.
myButton.addEventListener('click', function(event) {
myVariable = "Some string";
});
console.log(myVariable); // will always be undefined.
<button id="button">Click me !</button>
Notice how the console always output undefined when you run the code ?
This is because, the callback and the rest of the code are not executed at the same time. Even though the console.log part comes after the callback, it is run at with the rest of the code, not when the callback is trigger. Only the code in the callback will be run when the event we listen to is triggered.
That being said, you can define variable outside the callback and use it inside. This could be useful to keep track of what each player has chosed.
With that in mind, you need to move the logic that check whether or not the player has won, in your callback.
document.querySelectorAll('button').addEventListener("click", function(event) {
if(player.currentChoice === choices[1]){
// player wins
} else {
// computer wins.
}
});
As for the populate the users choice part, you don't really need an external variable. You can simply listen to the click and get the player's choice using the event.target.id like you did previously. Then compare that with a predefined computer move.
Here is a somewhat working example.
const choices = ['Lapis', 'Payrus', 'Scalpellus'];
const allButtons = document.querySelectorAll('button');
// we register the listener on the `click` event, for each buttons.
for(let i = 0; i < allButtons.length; i ++) {
allButtons[i].addEventListener('click', function(event){
// we retrieve the player's choice from the id of the clicked button.
const playerChoice = event.target.id;
// we get a random id for the computer's move.
const randomChoiceId = Math.floor(Math.random() * choices.length);
const computerChoice = choices[randomChoiceId];
// we check if the player wins.
// I don't know the logic and comparing each element might
// not be the more efficient way to achieve this. But it works for now.
if(playerChoice === "Lapis" && computerChoice === "Payrus") {
console.log('Player Wins ! ');
} else {
console.log('Computer wins... ');
}
});
}
<button id="Lapis">Lapis</button>
<button id="Payrus">Payrus</button>
<button id="Scalpellus">Scalpellus</button>
Hopefully, this brief overview of callback was clear enough to help you go forward in your project. Good luck !
I am trying a very simple version of the game "rock, paper or scissors" with javascript. (Mostly to learn functions and although i think my code makes sense and it should print in the console the outputs on each If Else statement it doesnt print anything.
Any hint?
Code below
const startGame = document.getElementById('start-game-btn');
const choicePlayer = ["Rock" , "Scissor", "Paper"];
const defaultChoise = "Rock";
function startTheGame(choicePlayer,defaultChoise) {
alert("Choose Rock , Scissor or Paper");
prompt(choicePlayer[0], choicePlayer[1]);
for (var i=0; i<choicePlayer.length; i++) {
if(choicePlayer[i]===choicePlayer[0] || choicePlayer[i] === choicePlayer[1] || choicePlayer[i] === choicePlayer[2]) {
console.log("asdf");
return choicePlayer[i];
}
else {
console.log("we choose for you");
return defaultChoise;
}
}
}
startGame.addEventListener('click' , startTheGame);
prompt works by returning a value, meaning you should use it like this:
choicePlayer[0] = prompt("Player 1 - Choose Rock , Scissor or Paper", choicePlayer[0]);
choicePlayer[1] = prompt("Player 2 - Choose Rock , Scissor or Paper", choicePlayer[1]);
Plus - having a function argument called choicePlayer will override your global variable choicePlayer, meaning that the choicePlayer inside the function holds the event argument.
in order to save the user input from the prompt function, you should save it in a variable like so: const result = prompt("text that will show in the prompt");
you can check the snippet I added for a solution for a few other fixes.
const startGame = document.getElementById('start-game-btn');
const choices = ["rock" , "scissor", "paper"];
const defaultChoice = "rock";
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
}
function gameInit() {
const playerChoice = prompt("Choose Rock , Scissor or Paper");
if(choices.includes(playerChoice.toLowerCase())) {
//return playerChoice;
console.log(capitalizeFirstLetter(playerChoice));
} else {
console.log("we choose for you");
//return defaultChoice;
console.log(capitalizeFirstLetter(defaultChoice));
}
}
startGame.addEventListener('click' , gameInit);
<button id="start-game-btn">Start</button>
why does my variable pc_score and my_score not increase? The output is 0.
I have two more functions of the eventListener format that I omitted from the code, but it should not affect the results. .
I edited the post for runnable code. Thank you.
Thanks for looking at my question.
<script>
var options = ['rock','paper','scissors']
let my_score = 0;
var pc_score = 0;
let computerChoice ;
function computerSelection() {
computerChoice = options[Math.floor(Math.random()*options.length)]
return computerChoice;
}
var results = document.getElementById("result")
document.getElementById("rock").addEventListener("click", ()=> {
playerChoice=rock;
computerSelection();
if (computerChoice=='rock'){
results.innerHTML="It is a tie";
} else if (computerChoice=='paper'){
results.innerHTML="It is a loss";
pc_score += 1;
}else if (computerChoice=='scissors'){
results.innerHTML="It is a win";
my_score+= 1
}
})
const you = document.getElementById("You")
you.innerHTML= my_score
const computer = document.getElementById("Computer")
computer.innerHTML=pc_score
</script>
Since you are assigning the value outside the event handler function that code does not get executed when click happens (instead those code is executed on page load with the initial value). You have to update the HTML inside the event handler function.
Also I will suggest you to use innerText or textContent if the text is plain text (not htmlString).
Try the following:
var my_score = 0;
var pc_score = 0;
const you = document.getElementById("You");
const computer = document.getElementById("Computer");
document.getElementById("scissors").addEventListener("click", ()=> {
playerChoice=scissors;
computerSelection();
if (computerChoice == "rock"){
results.textContent = "It is a loss";
pc_score++;
} else if (computerChoice == "paper"){
results.textContent = "It is a win";
my_score++;
}else if (computerChoice=="scissors"){
results.textContent = "It is a tie";
}
you.textContent = my_score;
computer.textContent = pc_score;
});
You are updating the score variables, but not the innerHTML's of the elements showing that score. There surely is a better/cleaner way to do this, but just call computer.innerHTML=pc_score and you.innerHTML= my_score again after changing the value
I am a new Developer and am working on a Tic Tac Toe SPA. I have a working game, but I want to customize the game tokens. I have tried creating a DOM element a few different ways, which were all successful. Here is the problem:
Every time I go to make a second move for a player, the DOM image disappears and reappears in the new square selected. Obviously this is not the desired action. Is there something I don't know about creating a DOM element. I have googled this and read countless articles and watched countless videos.
const stark = document.createElement('img')
stark.src = 'https://i.imgur.com/d70XlET.png'
stark.height = 80
stark.width = 80
const lanister = document.createElement('img')
lanister.src = 'https://i.imgur.com/d70XlET.png'
lanister.height = 80
lanister.width = 80
const play = (event) => {
if (gameOver === false) {
if (event.target.innerHTML === '') {
$('#' + event.target.id).append(turn)
}
}
}
'turn' is a variable that works with a toggle function to switch between players and stores whichever players turn it is(i.e. 'stark')
I would be really grateful if someone could point me in the direction of a resource where I could learn more about this.
const player1 = stark
const player2 = lanister
let turn = player1
let prevTurn = player2
const togglePrevTurn = () => {
if (!gameOver) {
if (prevTurn === player1) {
prevTurn = player2
} else {
prevTurn = player1
}
}
}
const toggleTurn = () => {
if (!gameOver) {
if (turn === player1) {
turn = player2
} else {
turn = player1
}
$('#message').text(turn + " 's turn")
}
}
Whenever you use Javascript's appendChild or jQuery's append, when you pass it an element, that element gets removed from its previous location in the DOM (if it's in the DOM), and then gets inserted at the new position. It sounds like what you need to do is explicitly create a new element each time, which you might do with cloneNode().
Also, probably best to name your variables precisely - if turn is an image, name it to make it clear that it's an image, perhaps currentPlayerImage.
In addition, because you already have a reference to the event.target, there's no need to reselect it with $('#' + event.target.id) - just select event.target:
const play = (event) => {
if (gameOver === false) {
if (event.target.innerHTML === '') {
$(event.target).append(currentPlayerImage.cloneNode());
}
}
}