I'm working on a simple rock, paper, scissors game of HTML + JS.
Here are the full codes (CSS, JS, HTML): http://jsfiddle.net/fJw4R/
(too long to past here I thought). Here you can see it with pictures: http://shinebrightmedia.se/rps/rockpaperscissors.html
As you can see, the .math-module works, and when you choose rock, paper or scissor the computer randomizes a choice.
However, I now would like to have a textstring underneath the computer/monitor, and I'm wondering what the easiest way to do that. I want it to either say YOU WIN! or YOU LOSE!
I started on a function looking like this:
function theWinnerIs(userChoice, computerChoice) {
if (userChoice === computerChoice ) {
return 'No winner, it is a draw';
}
if ((userChoice === 'rock') && (computerChoice === 'scissor')) {
return 'human';
}
if ((userChoice === 'rock') && (computerChoice === 'paper')) {
return 'computer';
}
if ((userChoice === 'paper') && (computerChoice === 'scissor')) {
return 'computer';
}
if ((userChoice === 'paper') && (computerChoice === 'rock')) {
return 'human';
}
if ((userChoice === 'scissor') && (computerChoice === 'rock')) {
return 'computer';
}
if ((userChoice === 'scissor') && (computerChoice === 'paper')) {
return 'human';
}
}
What is the easiest way to send the return to the index-file? ie. YOU WIN! or YOU LOSE!
Thanks for any help.
No need to use this block of ifs - here's very compact alternative:
var choices = { rock: -1, paper: 0, scissors: 1 };
var score = choices[userChoice] - choices[computerChoice];
score = score - (score/2|0) * 3;
... which will give you -1 if user loses the round, 1 if they win, 0 in case of draw.
Now you can just send the output to any prepared container by filling its innerHTML property:
var results = {
'-1': 'YOU LOSE',
'1': 'YOU WIN',
'0': 'IT\'S A DRAW'
};
var resultContainer = document.getElementById('result');
resultContainer.innerHTML = results[score];
Here's a small demo to illustrate both those concepts.
From what I understand, you would like to display some text depending on the outcome of your "theWinnerIs" method. I would suggest you create a div on your page and set its content with JavaScript. There are numerous ways to accomplish your goal, however.
So you want to add a div to your page, something like <div id="output"></div>. You can then update the text here with the following
var outputElement = document.getElementById("output");
outputElement.innerHTML = theWinnerIs(userChoice, computerChoice);
Here's an updated version of your code for perspective, though raina77ow's solution is much nicer.
Related
I'm doing my first JS project which is a simple Rock, Paper, Scissor game that should work in the console.
I think my code is quite correct, but when I "console.log" my function (playRound) I get the following snippet in the "console": "You both played undefined It's a Draw!". I'm not sure what I'm missing so if someone could take a look then that would be very much appreciated!
Here is my script:
function computerPlay (){
const choices = ["Rock", "Paper", "Scissor"];
const randomChoice = choices[Math.floor(Math.random() * choices.length)];
return(randomChoice);
}
console.log(computerPlay()) //just to show "computerPlay" works
function playRound(playerSelection, computerPlay) { //This is the actual round
if (playerSelection == computerPlay) {
result = `You both played ${computerPlay} It's a Draw!`;
} else if ((playerSelection == "Paper" && computerPlay == "Rock") ||
(playerSelection == "Rock" && computerPlay == "Scissor") ||
(playerSelection == "Scissor" && computerPlay == "Paper")) {
result = `${playerSelection} beats ${computerSelection} You Win!`;
} else {
result = `${computerPlay} beats ${playerSelection} You Loose!`;
}
return (result);
}
let playerSelection = 'rock'
console.log(playRound()) // to test if "playRound" works
Thanks for checking!
Kind regards,
A coding newbie
Once you define the function, you should call it with parameters to see the result.
The playRound function has 2 parameters, so please replace console.log(playRound) with console.log(playRound(playerSelection, computerPlay())).
You have not called the function you are just printing the content inside your function using console.log.
Try like below :
function computerPlay() {
const choices = ["Rock", "Paper", "Scissor"];
const randomChoice = choices[Math.floor(Math.random() * choices.length)];
return (randomChoice);
}
computerPlay();//call it
function playRound(playerSelection, computerPlay) { //This is the actual round
if (playerSelection == computerPlay) {
result = `You both played ${computerPlay} It's a Draw!`;
} else if ((playerSelection == "Paper" && computerPlay == "Rock") ||
(playerSelection == "Rock" && computerPlay == "Scissor") ||
(playerSelection == "Scissor" && computerPlay == "Paper")) {
result = `${playerSelection} beats ${computerSelection} You Win!`;
} else {
result = `${computerPlay} beats ${playerSelection} You Loose!`;
}
return (result);
}
let playerSelection = 'rock'
playRound(playerSelection, playerSelection);//pass parameter in calling funciton
console.log(result) // to test if "result" is accurate
I am pretty new to coding still, so I apologize in advance if this seems super basic. I've been doing The Odin Project and have made it to the RPS assignment. Now, I've kind of been playing with different iterations of the code just to get a better idea as to how things could work.
Right now I am just putting script tags in an html file to get the desired result and running the function through a console.log() in my browser. The issue I am having is that even when I run the function with the right inputs - I sometimes get the final else statement. I'll post the code below and then try to explain in greater detail what I mean.
<script>
function game(playerSelection) {
playerSelection = playerSelection.toLowerCase();
function computerSelection() {
let cAnswer = Math.floor(Math.random() * 3 + 1);
if (cAnswer == 1) {
return 'rock';
} else if (cAnswer == 2) {
return 'paper';
} else {
return 'scissors';
}
}
if (playerSelection == computerSelection()) {
return 'It\'s a tie! Try again.'
} else if (playerSelection == 'rock' && computerSelection() == 'scissors') {
return 'Rock beats scissors, you win!'
} else if (playerSelection == 'rock' && computerSelection() == 'paper') {
return 'Paper beats rock, you lose!'
} else if (playerSelection == 'paper' && computerSelection() == 'scissors') {
return 'Scissors beats scissors, you lose!'
} else if (playerSelection == 'paper' && computerSelection() == 'rock') {
return 'Paper beats rock, you win!'
} else if (playerSelection == 'scissors' && computerSelection() == 'paper') {
return 'Scissors beats paper, you win!'
} else if (playerSelection == 'scissors' && computerSelection() == 'rock') {
return 'Rock beats scissors, you lose!'
} else {
return 'It doesn\'t seem like you typed a valid option. Please type \'Rock\', \'Paper\', or \'Scissors\''
}
}
</script>
Whenever I run console.log(game('scissors')) for instance, I still occasionally get the final else statement from my if ... else block. Shouldn't that be impossible? When I go through it - as long as I type rock, paper, or scissors, I thought I should be hitting one of the other if statements before reaching the final else in the block. But still, sometimes the output I get in my console is 'It doesn't seem like you typed a valid option. Please type 'Rock', 'Paper', or 'Scissors
I imagine I didn't explain this very well so please let me know if I can help clarify.
Thank you!
You're running computerSelection every time in the if checks - every time the interpreter comes across the function call computerSelection(), a new computer answer is generated.
Generate the computer's answer just once instead:
const computerSelection = (() => {
let cAnswer = Math.floor(Math.random() * 3 + 1);
if (cAnswer == 1) {
return 'rock';
} else if (cAnswer == 2) {
return 'paper';
} else {
return 'scissors';
}
})();
if (playerSelection == computerSelection) {
return 'It\'s a tie! Try again.'
} else if (playerSelection == 'rock' && computerSelection == 'scissors') {
// etc
Or, less repetitively:
const computerSelection = ['rock', 'paper', 'scissors'][Math.floor(Math.random() * 3));
I want the user to input his answer in a rock-paper-scissors game in the following line of code.
userChoice = prompt("Do you choose rock, paper or scissors?");
However, in case the user writes something other than exactly "rock", "paper" or "scissors", he is supposed to choose again, which I tried to do with this piece of code:
while (userChoice !== "rock" || "paper" || "scissors") {
userChoice = prompt("Invalid choice. Please change your answer.");
};
The problem I have is that the program keeps recognizing the given input as invalid, even if it is "rock", "paper" or "scissors".
While typing this, I managed to find a solution on my own.
while (userChoice !== "rock" && userChoice !== "paper" && userChoice !== "scissors") {
userChoice = prompt("Invalid choice. Please change your answer.");
};
That way does make sense and the first condition probably didn't work because even if you type a correct answer (e.g. "paper"), it still doesn't equal the other two answers (in this case "rock" and "scissors"), which is why the program kept saying the answer has been invalid, right? Or is it a syntax error?
Now (with the working condition), the choice of the user has to be neither "rock" nor "paper" nor "scissors" and thus it works properly.
Also, is there possibly an easier and shorter way of writing that condition?
Note: I hope it's fine that parts of the solution are already included as they could help other coders.
Two examples
One with an array and Array.prototype.indexOf():
var userChoice;
while (!~['rock', 'paper', 'scissors'].indexOf(userChoice)) {
userChoice = prompt("Invalid choice. Please change your answer.");
};
And another with an object and the in operator:
The in operator returns true if the specified property is in the specified object.
var userChoice;
while (!(userChoice in {rock: 1, paper: 1, scissors: 1})) {
userChoice = prompt("Invalid choice. Please change your answer.");
};
Use indexOf
while (["rock", "paper", "scissors"].indexOf(userChoice) > -1) {
Your first attempt
while (userChoice !== "rock" || "paper" || "scissors") {
is technically an infinite loop because
|| "paper"
for example, technically evaluates to true or a truthy value
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Rock Papper Scissors Game</title>
</head>
<body>
<h1>Play Rock Papper Scissors?</h1>
<button id="start">Play?</button>
<script>
function rpsGame() {
var computerChoice = Math.random(),
userChoice = prompt('Do you choose rock, paper, or scissors');
function getComputerChoice() {
if (computerChoice <= 0.33) {
computerChoice = 'rock';
} else if (computerChoice <= 0.66 && computerChoice >= 0.33) {
computerChoice = 'paper';
} else {
computerChoice = 'scissors';
}
}
function playAgain() {
var restart = prompt('Would you like to play again, yes or no?').toLowerCase();
switch(restart) {
case 'yes':
rpsGame();
break;
default:
alert('Okay, see you later!');
}
}
function compare() {
var choice1 = userChoice.toLowerCase(),
choice2 = computerChoice,
tie = "The computer chose " + choice2 + ", and you chose " + choice1 + ". The result is a tie!",
win = "The computer chose " + choice2 + ", and you chose " + choice1 + ". You win!",
lose = "The computer chose " + choice2 + ", and you chose " + choice1 + ". The computer wins!";
switch (choice1) {
case "":
alert("You didn't enter anything. Maybe we can play later!");
break;
case 'rock':
if (choice2 === 'scissors') {
alert(win);
} else if (choice2 === 'rock') {
alert(tie);
} else {
alert(lose);
}
playAgain();
break;
case 'paper':
if (choice2 === 'rock') {
alert(win);
} else if (choice2 === 'paper') {
alert(tie);
} else {
alert(lose);
}
playAgain();
break;
case 'scissors':
if (choice2 === 'paper') {
alert(win);
} else if (choice2 === 'scissors') {
alert(tie);
} else {
alert(lose);
}
playAgain();
break;
default:
alert(choice1.substring(0,1).toUpperCase() + choice1.substring(1, choice1.length).toLowerCase() + " is an invalid choice. Please change your answer.");
rpsGame();
}
}
getComputerChoice();
compare();
}
document.getElementById('start').addEventListener('click', rpsGame);
</script>
</body>
</html>
I just started learning JavaScript (Today actually) and I'd really appreciate some help with nested if-else statements. I thought I'd write a simple program to practice, and it seems that every if-else statement in my if blocks executes regardless of which parameter I put in. Any pointers or even things you notice that aren't germane to the problem at hand are appreciated. Thanks again. My code is below.
EDIT: I've gotten it now, and learned the error of my ways. Thanks to everyone who commented and gave advice so quickly.
var playerOne = prompt('Choose rock, paper, or scissors');
var playerTwo = prompt('Choose rock, paper, or scissors');
var fight = function (playerOne, playerTwo)
{
if( playerOne == 'rock' || 'Rock')
{
if (playerTwo == 'paper' || 'Paper')
{
alert('Player Two Wins!');
}
else if (playerTwo == 'rock' || 'Rock')
{
alert('Tie!');
}
else
{
alert('Player One wins!');
}
}
if(playerOne == 'paper' || 'Paper')
{
if (playerTwo == 'paper' || 'Paper')
{
alert('Tie!');
}
else if (playerTwo == 'rock' || 'Rock')
{
alert('Player One Wins!');
}
else
{
alert('Player Two wins!');
}
}
if (playerOne == 'scissors' || 'Scissors')
{
if (playerTwo == 'paper' || 'Paper')
{
alert('Player One Wins!');
}
else if (playerTwo == 'rock' || 'Rock')
{
alert('Player Two Wins!');
}
else
{
alert('Tie!');
}
}
};
fight(playerOne, playerTwo);
As several people have pointed out, your if statements need to be in the form of:
if (playerOne == 'paper' || playerOne == 'Paper')
or the more succinct:
if (playerOne.toLowerCase() == 'paper')
The problem is that playerOne == 'paper' || 'Paper' will always return a "Truthy" value (see http://11heavens.com/falsy-and-truthy-in-javascript for more detail on Truthy and Falsy values).
As an aside, while there's absolutely nothing wrong with multiple if statements, if I were coding this exercise my way would involve less if statements (and look a little like this:
var playerOne = prompt('Choose rock, paper, or scissors');
var playerTwo = prompt('Choose rock, paper, or scissors');
var fists = {
"rock": {
"beats": "scissors",
"loses": "paper"
},
"paper": {
"beats": "rock",
"loses": "scissors"
},
"scissors": {
"beats": "paper",
"loses": "rock"
}
}
var fight = function (playerOne, playerTwo) {
playerOne = playerOne.toLowerCase();
playerTwo = playerTwo.toLowerCase();
if (fists[playerOne] === undefined || fists[playerTwo] === undefined) {
alert('Someone threw an unknown fist!');
} else if (fists[playerOne].beats === playerTwo) {
alert('Player One wins!');
} else if (fists[playerTwo].beats === playerOne) {
alert('Player Two Wins!');
} else {
alert('Tie!');
}
};
fight(playerOne, playerTwo);
By objectifying the rock/paper/scissors combinations, the code is IMO significantly easier to read.
The other comments and answer are great, so I won't repeat what they said. But you asked for advice, and mine is to not use so many if statements to begin with. A big part of programming is learning how to cut down on unnecessary or repeated code. Data structures like objects and arrays are good for this:
var win_conditions = { //simple object showing which hands beat which
'rock': 'scissors',
'paper': 'rock',
'scissors': 'paper'
}
var fight = function(p1, p2) {
var result;
if (!win_conditions.hasOwnProperty(p1) || !win_conditions.hasOwnProperty(p2)) {
result = false; //error! user typed something invalid
} else {
if (win_conditions[p1] == p2) {
result = 'Player One wins!';
} else if (win_conditions[p2] == p1) {
result = 'Player Two wins!';
} else {
result = 'Tie!';
}
}
return result;
}
var fight_result = false;
var prompt_text = 'Choose rock, paper, or scissors';
var playerOne = prompt(prompt_text);
var playerTwo = prompt(prompt_text);
//keep asking until the user types a valid option
while (!fight_result) {
fight_result = fight(playerOne.toLowerCase(), playerTwo.toLowerCase());
}
alert(fight_result);
I recommend you to use FireBug to debug your JavaScript Code. When you debug your code change the alert() to console.log() and probably playerOne/playerTwo to simple strings.
(Doesn't fit your question perfectly, but if you continue learning it's a good advice overall.)
So, I'm making a rock,paper,scissors game using Javascript and I'm having some trouble starting. I need to have a text box and submit button, then the user input of "rock", "paper", "scissors" will be played against the computer's random choice. How would I have the computer take what's entered into the text field and run it against the computers choice? I'm a novice and in need of a nudge in the right direction, because I'm not sure how to start this problem.
Thanks
Edit:
So, a friend sent me some code and I added onto some of it and it looks like it would work(at least to me), but I'm not sure what to set the variable "player" equal to in order to equal the textbox information.
var player =
var choices = ["rock","paper","scissors"];
var computer = choices[Math.floor(Math.random()*3)];
var win = "Your "+player+" beats "+computer+". You win.";
var lose = "Your "+player+" loses to "+computer+". You lose.";
var draw = "A draw: "+player+" on "+computer+".";
if(player === "rock"){
if(computer === "scissors"){
result = win;
alert="win";
}
else if(computer === "paper"){
result = lose;
alert="lose";
}
else if(computer === "rock"){
result = draw;
alert="draw";
}
}
else if(player === "paper"){
if(computer === "rock"){
result = win;
alert="win";
}
else if(computer === "scissors"){
result = lose;
alert="lose";
}
else if(computer === "paper"){
result = draw;
alert="draw";
}
}
else if(player === "scissors"){
if(computer === "paper"){
result = win;
alert="win";
}
else if(computer === "rock"){
result = lose;
alert="lose";
}
else if(computer === "scissors"){
result = draw;
alert="draw";
}
}
</script>
</head>
<body>
<form>
<input type="text" id="rockTextInput" size="100" placeholder="Rock, Paper, or Scissors" >
<input type="button" id="Button" value="Play Hand">
</form>
</body>
</html>
The computer's choice could be generated like this:
...
var plays = ["rock", "paper", "scissors"];
var rand = Math.round(Math.random() * 2);
alert("Computer played: " + plays[rand]);
//Check to see the winner
...
Hope that helps give you a start.
Due to the limited number of possibilities, a way to do it is with a look-up table. You'd have to use further JavaScript to link it to your HTML. For that you'll probably want to use document.getElementById with an <input>'s value and output to some other Element.
/*
Usage:
play(player_choice)
player_choice String, 'rock', 'paper' or 'scissors'
returns Object with properties
player String, player's choice
ai String, ai's choice
result Integer, 0 - lose, 1 - draw, 2 - win
resultText String, description of result
*/
var play = (function () {
var options = ['rock', 'paper', 'scissors'],
result_table = {
'rock': {
'rock': 1,
'paper': 0,
'scissors': 2
},
'paper': {
'rock': 2,
'paper': 1,
'scissors': 0
},
'scissors': {
'rock': 0,
'paper': 2,
'scissors': 1
}
},
result_text = ['AI wins', 'Draw', 'Player wins'];
return function (player_choice) {
var ai_choice;
player_choice = player_choice.toLowerCase();
if (!result_table.hasOwnProperty(player_choice)) {
throw '[' + player_choice + '] not a valid choice.';
}
ai_choice = options[Math.floor(Math.random() * options.length)];
return {
'player': player_choice,
'ai': ai_choice,
'result': result_table[player_choice][ai_choice],
'resultText': result_text[result_table[player_choice][ai_choice]]
};
};
}());