How to end my RPS game after someone wins 10 times - javascript

New to JavaScript and Vue.js I'm building a rock paper scissors game and I'm struggling to get it to end after either the player or the computer wins. Right now the game will continue and the progress bar does as well but I need to get it to stop after 10 wins. Not sure how to do this in Vue.js. I would appreciate any pointers.
new Vue({
el: '#app',
data: {
playerWins: 0,
cpuWins: 0,
gameIsRunning: false,
turns: [],
rock: 1,
paper: 2,
scissors: 3
},
methods: {
startGame: function () {
this.gameIsRunning = true;
},
rockUser: function () {
let cpuChoice = this.calculateCpuChoice();
if (cpuChoice === this.paper) {
this.cpuWins += 1;
this.turns.unshift({
isPlayer: false,
text: 'Computer Chose Paper | Paper Beats Rock | Computer Wins!'
})
} else if (cpuChoice === this.scissors) {
this.playerWins += 1;
this.turns.unshift({
isPlayer: true,
text: 'Computer Chose Scissors | Rock Beats Scissors | Player Wins!'
})
} else {
this.turns.unshift({
tie: true,
text: 'Computer Chose Rock | You Have Tied!'
})
}
console.log(this.playerWins);
console.log(this.cpuWins);
},
paperUser: function () {
let cpuChoice = this.calculateCpuChoice();
if (cpuChoice === this.scissors) {
this.cpuWins += 1;
this.turns.unshift({
isPlayer: false,
text: 'Computer Chose Scissors | Scissors Beats Paper | Computer Wins!'
})
} else if (cpuChoice === this.rock) {
this.playerWins += 1;
this.turns.unshift({
isPlayer: true,
text: 'Computer Chose Rock | Paper Beats Rock | Player Wins!'
})
} else {
this.turns.unshift({
tie: true,
text: 'Computer Chose Paper | You Have Tied!'
})
}
console.log(this.playerWins);
console.log(this.cpuWins);
},
scissorsUser: function () {
let cpuChoice = this.calculateCpuChoice();
if (cpuChoice === this.rock) {
this.cpuWins += 1;
this.turns.unshift({
isPlayer: false,
text: 'Computer Chose Rock | Rock Beats Scissors | Computer Wins!'
})
} else if (cpuChoice === this.paper) {
this.playerWins += 1;
this.turns.unshift({
isPlayer: true,
text: 'Computer Chose Paper | Scissors Beats Paper | Player Wins!'
})
} else {
this.turns.unshift({
tie: true,
text: 'Computer Chose Scissors | You Have Tied!'
})
}
console.log(this.playerWins);
console.log(this.cpuWins);
},
restart: function () {
this.gameIsRunning = false;
this.cpuWins = 0;
this.playerWins = 0;
this.turns = [];
},
whoWins: function (playerWins, cpuWins) {
if(cpuWins === 10) {
prompt ("The computer has won!");
this.gameIsRunning = false;
}
if(playerWins === 10) {
prompt ("The player has won!");
this.gameIsRunning = false;
}
},
calculateCpuChoice: function () {
let max = 3;
let min = 0;
return Math.max(Math.floor(Math.random() * max) + 1, min);
}
}
});
.text-center {
text-align: center;
}
.wins {
width: 80%;
color: black;
height: 40px;
background-color: #eee;
margin: auto;
transition: width 1000ms;
}
.controls, .log {
margin-top: 30px;
text-align: center;
padding: 10px;
border: 1px solid #ccc;
box-shadow: 0px 3px 6px #ccc;
}
.turn {
margin-top: 20px;
margin-bottom: 20px;
font-weight: bold;
font-size: 22px;
}
.log ul {
list-style: none;
font-weight: bold;
text-transform: uppercase;
}
.log ul li {
margin: 5px;
}
.log ul .player-turn {
color: green;
background-color: #aaffb0;
}
.log ul .computer-turn {
color: red;
background-color: #ffc0c1;
}
.log ul .tie-turn {
color: blue;
background-color: #e4e8ff;
}
button {
font-size: 20px;
background-color: #eee;
padding: 12px;
box-shadow: 0 1px 1px black;
margin: 10px;
}
#start-game {
background-color: #e4e8ff;
}
#start-game:hover {
background-color: #687eff;
}
#rock {
background-color: #ff7367;
}
#rock:hover {
background-color: #ff3f43;
}
#paper {
background-color: #ffaf4f;
}
#paper:hover {
background-color: #ff9a2b;
}
#scissors {
background-color: #aaffb0;
}
#scissors:hover {
background-color: #76ff7e;
}
#restart {
background-color: #ffffff;
}
#restart:hover {
background-color: #c7c7c7;
}
<!DOCTYPE html>
<html>
<head>
<title>RPS with VueJS</title>
<script src="https://npmcdn.com/vue/dist/vue.js"></script>
<link rel="stylesheet" href="css/foundation.min.css">
<link rel="stylesheet" href="css/app.css">
</head>
<body>
<div id="app">
<section class="row">
<div class="small-6 columns">
<h1 class="text-center">PLAYER</h1>
<div class="wins">
<div class="wins text-center" style="background-color: green; margin: 0; color: white;"
:style="{ width: playerWins + '0%' }">
{{ playerWins }}
</div>
</div>
</div>
<div class="small-6 columns">
<h1 class="text-center">COMPUTER</h1>
<div class="wins">
<div class="wins text-center" style="background-color: green; margin: 0; color: white;"
:style="{ width: cpuWins + '0%' }">
{{ cpuWins }}
</div>
</div>
</div>
</section>
<section class="row controls" v-if="!gameIsRunning">
<div class="small-12 columns">
<button id="start-game" #click="startGame">START NEW GAME</button>
</div>
</section>
<section class="row controls" v-else>
<div class="small-12 columns">
<button id="rock" #click="rockUser">ROCK</button>
<button id="paper" #click="paperUser">PAPER</button>
<button id="scissors" #click="scissorsUser">SCISSORS</button>
<button id="restart" #click="restart">RESTART</button>
</div>
</section>
<section class="row log" v-if="turns.length > 0">
<div class="small-12 columns">
<ul>
<li v-for="turn in turns"
:class="{'player-turn': turn.isPlayer, 'computer-turn': !turn.isPlayer, 'tie-turn': turn.tie}">
{{ turn.text }}
</li>
</ul>
</div>
</section>
</div>
<script src="app.js"></script>
</body>
</html>

Related

Is there some kind of implementation or DOM I need?

I'm taking a beginner javascript/html/css course and don't have a super strong background in these. I'm trying to make a page that simulates a simple card game for a user versus the computer. The game takes digits that correspond to a card's suit and value and then displays them on the screen. Whoever has the higher card wins and a message is displayed.
This involves some things I'm not clear on, such as simple formatting or making the functions work together. I'm especially confused on where to put DOMs and how to even get a startbutton to work.
I'm using four functions:
randomizer
getcard
startgame
comparecard
In what ways can I make these interact with eachother? Are there any formatting issues in the css, html, etc.? Below is my initial code, I've tried too many variations and I'm just missing something I can't spot.
function randomizer(x) {
var y = x * Math.random();
var randNum = Math.round(y);
return randNum;
}
function getcard() {
var suit = randomizer(3);
var card = randomizer(13);
var wholeCard = suit + " " + card;
return wholeCard;
}
function startgame() {
var usercard;
var computercard;
usercard.getcard();
document.getElementByID("yourcard").innerHTML = usercard;
computercard.getcard();
document.getElementByID("computercard").innerHTML = computercard;
}
function comparecard() {
var usercard;
var computercard;
var winnermessage;
var usernum;
var computernum;
if (usernum > computernum) {
winnermessage = "You Win!";
} else if (usernum < computernum) {
winnermessage = "The Computer Wins!";
} else {
winnermessage = "It's a Tie!";
}
}
body {
font-family: Helvetica, Arial, sans-serif;
}
.cardcontain {
width: 80%;
margin: auto;
}
[class*="cardgrid"] {
float: left;
width: 45%;
text-align: center;
}
.cardgrid {
color: #aa4444;
}
.cardgrid2 {
display: block;
vertical-align: top;
color: #651e1e;
height: 110px;
font-size: 2em;
border: 2px solid #000000;
border-radius: 5px;
}
.cardgrid3 {
text-align: left;
color: #888888;
}
button {
background-color: #57ac75;
}
.winner::before {
display: block;
content: " ";
height: 400px;
}
.winner {
font-size: 24px;
font-weight: bolder;
color: #3f7a3b;
text-align: center;
}
<div class="cardcontain">
<h2 class="cardgrid">Computer Card</h2>
<h2 class="cardgrid">Your Card</h2>
</div>
<div class="cardcontain">
<div class="cardgrid2" id="computercard"></div>
<div class="cardgrid2" id="yourcard"></div>
</div>
<div class="cardcontain">
<div class="cardgrid">
<p> </p>
</div>
<div class="cardgrid"><button onclick="startgame()">Click here for your card</button></div>
</div>
<div class="cardcontain">
<div class="cardgrid3">
<h3>Key: first digit</h3>
<ul>
<li>0 = Spade</li>
<li>1 = Club</li>
<li>2 = Heart</li>
<li>3 = Diamond</li>
</ul>
</div>
<div class="cardgrid3">
<h3>Key: second digit</h3>
<ul>
<li>11 = Jack</li>
<li>12 = Queen</li>
<li>13 = King</li>
<li>14 = Ace</li>
</ul>
</div>
</div>
<p class="winner" id="winner"></p>
A few points
getcard probably needs to return the suit & value separately, as you need just the value to compare later on
Javascript is case sensitive so getElementByID is wrong (it is getElementById)
Where you had code like var usercard; and usercard.getcard(); makes no sense. getcard() is a standalone function which just returns a value so you probably wanted var usercard = getcard();
There are a bunch of other things which you will learn as you get better at javascript too broad for this answer
The below works along the lines I expect you thought
function randomizer(x) {
var y = x * Math.random();
var randNum = Math.round(y);
return randNum;
}
function getcard() {
var suit = randomizer(3);
var card = randomizer(13);
return {suit, card};
}
function startgame() {
var usercard = getcard();
var computercard = getcard();
document.getElementById("yourcard").innerHTML = usercard.suit + " " + usercard.card;
document.getElementById("computercard").innerHTML = computercard.suit + " " + computercard.card;
comparecard(usercard.card, computercard.card)
}
function comparecard(usernum, computernum) {
if (usernum > computernum) {
winnermessage = "You Win!";
} else if (usernum < computernum) {
winnermessage = "The Computer Wins!";
} else {
winnermessage = "It's a Tie!";
}
document.getElementById("winner").innerHTML = winnermessage;
}
body {
font-family: Helvetica, Arial, sans-serif;
}
.cardcontain {
width: 80%;
margin: auto;
}
[class*="cardgrid"] {
float: left;
width: 45%;
text-align: center;
}
.cardgrid {
color: #aa4444;
}
.cardgrid2 {
display: block;
vertical-align: top;
color: #651e1e;
height: 110px;
font-size: 2em;
border: 2px solid #000000;
border-radius: 5px;
}
.cardgrid3 {
text-align: left;
color: #888888;
}
button {
background-color: #57ac75;
}
.winner::before {
display: block;
content: " ";
height: 400px;
}
.winner {
font-size: 24px;
font-weight: bolder;
color: #3f7a3b;
text-align: center;
}
<div class="cardcontain">
<h2 class="cardgrid">Computer Card</h2>
<h2 class="cardgrid">Your Card</h2>
</div>
<div class="cardcontain">
<div class="cardgrid2" id="computercard"></div>
<div class="cardgrid2" id="yourcard"></div>
</div>
<div class="cardcontain">
<div class="cardgrid">
<p> </p>
</div>
<div class="cardgrid"><button onclick="startgame()">Click here for your card</button></div>
</div>
<div class="cardcontain">
<div class="cardgrid3">
<h3>Key: first digit</h3>
<ul>
<li>0 = Spade</li>
<li>1 = Club</li>
<li>2 = Heart</li>
<li>3 = Diamond</li>
</ul>
</div>
<div class="cardgrid3">
<h3>Key: second digit</h3>
<ul>
<li>11 = Jack</li>
<li>12 = Queen</li>
<li>13 = King</li>
<li>14 = Ace</li>
</ul>
</div>
</div>
<p class="winner" id="winner"></p>
Note: I have not fixed your randomizer but if you're generating playing cards I dont think you want to generate zeros... also if were going for realism you need to ensure the computer and player cant randomly pick the same card.

How do I use a for loop to manage increments of an object property in JavaScript?

I’m doing a rockPaperScissors project. Here’s the published link: https://george-swift.github.io/rockPaperScissors/. I want to add a first to 5 feature to put an end score to the game. If either the player or computer reaches 5, I'll have a message declare a winner (I know how to manipulate the message). Attached is a snippet for clarity.
//computer will randomly pick from this array
const RPS = ['rock','paper','scissors']
//object defines the rules of the game for each player selection
const rulesRPS = {
rock: {
beats: "scissors"
},
paper: {
beats: "rock"
},
scissors: {
beats: "paper"
}
};
//cached elements for scores
const pScore = document.getElementById("player-score");
const tScore = document.getElementById("tie-score");
const cScore = document.getElementById("computer-score");
//declared variables for helper functions
let winner, results, scores;
//for event listeners
document.getElementById("rock-btn").addEventListener('click', pSelectedR);
document.getElementById("paper-btn").addEventListener("click", pSelectedP);
document.getElementById("scissors-btn").addEventListener("click", pSelectedS);
// updates the scores after each game round
function render() {
pScore.innerHTML = scores.player;
tScore.innerHTML = scores.tie;
cScore.innerHTML = scores.computer;
}
function pickRandom () {
const selection = RPS[Math.floor(Math.random() * 3)];
return selection;
}
//handle results after player selection
function manageResults () {
results.computer = pickRandom();
winner = findWinner();
scores[winner]++;
render();
}
//player selections and subsequent action
function pSelectedR () {
results.player = "rock";
manageResults();
}
function pSelectedP () {
results.player = "paper";
manageResults();
}
function pSelectedS () {
results.player = "scissors";
manageResults();
}
//compare selections to find winner
function findWinner() {
results.computer = pickRandom();
if (results.player === results.computer) {
return 'tie';
}
if (rulesRPS[results.player].beats === results.computer) {
return 'player';
}
return 'computer';
}
//instantiates the state of the game
function init() {
scores = {
player: 0,
tie: 0,
computer: 0,
};
results = {
player: 'rock',
computer: 'rock'
};
winner = null;
}
init();
* {
box-sizing: border-box;
}
body {
font-family: 'Judson', serif;
text-align: center;
height: 100vh;
margin: 40px 0px;
}
h1, h2 {
font-family: 'Archivo Black', sans-serif;
}
body,
main,
aside {
display: flex;
justify-content: space-evenly;
align-items: center;
}
body,
main {
flex-direction: column;
}
table {
width: 100%;
}
td {
width: 33.3%;
font-size: 2.5rem;
}
img {
width: 50vh;
height: 50vh;
}
aside {
width: 75vw;
padding: 0.5em 0 0 0;
}
button {
width: 30vw;
margin: 2vw;
background-color: rgb(38,39,39);
color: whitesmoke;
border: rgb(113, 125, 126) solid 2px;
border-radius: 3px;
padding: 5px;
cursor: pointer;
}
button:hover {
background-color: rgb(112, 123, 124);
color: black;
transition: 0.5s;
}
button,
#link {
font-size: 20px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rock Paper Scissors</title>
<link rel="stylesheet" href="styles.css">
<link href="https://fonts.googleapis.com/css?family=Archivo+Black|Judson:400,700" rel="stylesheet">
<script defer src="main.js"></script>
</head>
<body>
<header>
<h1>ROCK PAPER SCISSORS- FOR PASTIME</h1>
</header>
<main>
<table>
<caption>
<h2>Scores</h2>
<p>Best of 5?</p>
</caption>
<tbody>
<tr>
<th>Player</th>
<th>Tie</th>
<th>Computer</th>
</tr>
<tr>
<td id="player-score">0</td>
<td id="tie-score">0</td>
<td id="computer-score">0</td>
</tr>
</tbody>
</table>
<figure>
<img src="https://res.cloudinary.com/george-swift/image/upload/v1603381143/9d966b99b233a6768b6981b83e43e0f0_hobh0x.jpg"
alt="rock paper scissors illustrated"/>
</figure>
</main>
<aside>
<button id="rock-btn">Rock</button>
<button id="paper-btn">Paper</button>
<button id="scissors-btn">Scissors</button>
</aside>
<nav>
GitHub
</nav>
</body>
</html>
From what I see, the incrementing is working as expected. You only need to put in a condition to check for 5 after the winner score has been incremented.
And then add the check to your current code.
function manageResults () {
results.computer = pickRandom();
winner = findWinner();
scores[winner]++;
render();
if (scores[winner] === 5) {
renderEndGame();
init(); // To reset the scores to 0 for a new game.
}
}
Then you can add the extra function to the js file:
function renderEndGame () {
// Display end game message and score
// maybe an alert message
}

want to show both correct and incorrect answer when the choosen answer is incorrect

Need to get the green background on the correct answer with the red background on the incorrect answer when we choose a wrong answer in the quiz. I need to show a pop-up that congratulate the user to complete this quiz. How is this possible ? I am new to JavaScript . Help me to find solution
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Quick Quiz - Play</title>
<link rel="stylesheet" href="/Main/main.css" />
<link rel="stylesheet" href="game.css" />
</head>
<body>
<div class="container">
<div id="game" class="justify-center flex-column">
<div id="hud">
<div id="hud-item">
<p id="progressText" class="hud-prefix">
Question
</p>
<div id="progressBar">
<div id="progressBarFull"></div>
</div>
</div>
<div id="hud-item">
<p class="hud-prefix">
Score
</p>
<h1 class="hud-main-text" id="score">
0
</h1>
</div>
</div>
<h2 id="question">What is the answer to this questions?</h2>
<div class="choice-container">
<p class="choice-prefix">A</p>
<p class="choice-text" data-number="1">Choice 1</p>
</div>
<div class="choice-container">
<p class="choice-prefix">B</p>
<p class="choice-text" data-number="2">Choice 2</p>
</div>
<div class="choice-container">
<p class="choice-prefix">C</p>
<p class="choice-text" data-number="3">Choice 3</p>
</div>
<div class="choice-container">
<p class="choice-prefix">D</p>
<p class="choice-text" data-number="4">Choice 4</p>
</div>
<div class="timer-quiz">Time left : <span id="timer"></span>
</div>
</div>
<audio id="crctmusic" src="/Assets/win31.mp3" preload="auto"></audio>
<audio id="wrngmusic" src="/Assets/computerError.mp3" preload="auto"></audio>
<script src="game.js"></script>
</body>
</html>
CSS
.choice-container {
display: flex;
margin-bottom: 0.5rem;
width: 100%;
font-size: 6vw;
border: 0.1rem solid rgb(86, 165, 235, 0.25);
background-color: white;
text-align: justify;
}
.choice-container:hover {
cursor: pointer;
box-shadow: 0 0.4rem 1.4rem 0 rgba(86, 185, 235, 0.5);
transform: translateY(-0.1rem);
transition: transform 150ms;
}
.choice-prefix {
padding: 1.5rem 2.5rem;
background-color: #56a5eb;
color: white;
}
.choice-text {
padding: 1.5rem;
width: 100%;
}
.correct {
background-color: #28a745;
}
.incorrect {
background-color: #dc3545;
}
/* HUD */
#hud {
display: flex;
justify-content: space-between;
}
.hud-prefix {
text-align: center;
font-size: 8vw;
}
.hud-main-text {
text-align: center;
}
#progressBar {
width: 15rem;
height: 3rem;
border: 0.3rem solid #56a5eb;
margin-top: 1.5rem;
}
#progressBarFull {
height: 3rem;
background-color: #56a5eb;
width: 0%;
}
/*TIMER*/
.timer-quiz {
color: #efd0ca;
text-align: center;
font-size: 10vw;
background-color: #56a5eb;
width: 100%;
}
Javascript
const question = document.getElementById("question");
const choices = Array.from(document.getElementsByClassName("choice-text"));
const progressText = document.getElementById("progressText");
const scoreText = document.getElementById("score");
const progressBarFull = document.getElementById("progressBarFull");
let currentQuestion = {};
let acceptingAnswers = false;
let score = 0;
let questionCounter = 0;
let availableQuesions = [];
let questions = [{
question: "Inside which HTML element do we put the JavaScript??",
choice1: "<script>",
choice2: "<javascript>",
choice3: "<js>",
choice4: "<scripting>",
answer: 1
},
{
question: "What is the correct syntax for referring to an external script called 'xxx.js'?",
choice1: "<script href='xxx.js'>",
choice2: "<script name='xxx.js'>",
choice3: "<script src='xxx.js'>",
choice4: "<script file='xxx.js'>",
answer: 3
},
{
question: " How do you write 'Hello World' in an alert box?",
choice1: "msgBox('Hello World');",
choice2: "alertBox('Hello World');",
choice3: "msg('Hello World');",
choice4: "alert('Hello World');",
answer: 4
}
];
//CONSTANTS
const CORRECT_BONUS = 1;
const MAX_QUESTIONS = 50;
startGame = () => {
questionCounter = 0;
score = 0;
availableQuesions = [...questions];
getNewQuestion();
};
getNewQuestion = () => {
if (availableQuesions.length === 0 || questionCounter >= MAX_QUESTIONS) {
localStorage.setItem("mostRecentScore", score);
//go to the end page
return window.location.assign("/End/end.html");
}
questionCounter++;
progressText.innerText = `Question ${questionCounter}/${MAX_QUESTIONS}`;
//Update the progress bar
progressBarFull.style.width = `${(questionCounter / MAX_QUESTIONS) * 100}%`;
const questionIndex = Math.floor(Math.random() * availableQuesions.length);
currentQuestion = availableQuesions[questionIndex];
question.innerText = currentQuestion.question;
choices.forEach(choice => {
const number = choice.dataset["number"];
choice.innerText = currentQuestion["choice" + number];
});
availableQuesions.splice(questionIndex, 1);
acceptingAnswers = true;
};
choices.forEach(choice => {
choice.addEventListener("click", e => {
if (!acceptingAnswers) return;
acceptingAnswers = false;
const selectedChoice = e.target;
const selectedAnswer = selectedChoice.dataset["number"];
const classToApply =
selectedAnswer == currentQuestion.answer ? "correct" : "incorrect";
if (classToApply === "correct") {
incrementScore(CORRECT_BONUS);
}
if (classToApply === "correct") {
document.getElementById('crctmusic').play();
} else {
document.getElementById('wrngmusic').play();
}
selectedChoice.parentElement.classList.add(classToApply);
setTimeout(() => {
selectedChoice.parentElement.classList.remove(classToApply);
getNewQuestion();
}, 1000);
});
});
incrementScore = num => {
score += num;
scoreText.innerText = score;
};
startGame();

Vue.js Battle - confirm box overrides reset function

i'm currently working through Udemy's Vue.js tutorial. I've reached the section where you are building a battle web app game. After finishing it, I decided to practice my refactoring and came across this bug.
When you click the attack buttons and then the confirm box comes up to ask if you want to play again, it seems to add one extra item in my log array instead of resetting the game fully.
I'm suspecting it is to do with pressing the attack buttons too quickly, and then the confirm box comes up before running an addToLog() and then it runs it afterwards.
Or it could be my bad code. lol
Note that I know that clicking cancel on the confirm box also comes up with bugs too.
index.html
<!DOCTYPE html>
<html>
<head>
<title>Monster Slayer</title>
<script src="https://npmcdn.com/vue/dist/vue.js"></script>
<link rel="stylesheet" href="css/foundation.min.css">
<link rel="stylesheet" href="css/app.css">
</head>
<body>
<div id="app">
<section class="row">
<div class="small-6 columns">
<h1 class="text-center">YOU</h1>
<div class="healthbar">
<div class="healthbar text-center" style="background-color: green; margin: 0; color: white;" :style="{width: playerHealth + '%'}">
{{ playerHealth }}
</div>
</div>
</div>
<div class="small-6 columns">
<h1 class="text-center">BADDY</h1>
<div class="healthbar">
<div class="healthbar text-center" style="background-color: green; margin: 0; color: white;" :style="{width: computerHealth + '%'}">
{{ computerHealth }}
</div>
</div>
</div>
</section>
<section class="row controls" v-if="!isRunning">
<div class="small-12 columns">
<button id="start-game" #click="startGame">START GAME</button>
</div>
</section>
<section class="row controls" v-else>
<div class="small-12 columns">
<button id="attack" #click="attack">ATTACK</button>
<button id="special-attack" #click="specialAttack">SPECIAL ATTACK</button>
<button id="heal" #click="heal">HEAL</button>
<button id="restart" #click="restart">RESTART</button>
</div>
</section>
<section class="row log" v-if="turns.length > 0">
<div class="small-12 columns">
<ul>
<li v-for="turn in turns" :class="{'player-turn': turn.isPlayer, 'monster-turn': !turn.isPlayer}">
{{ turn.text }}
</li>
</ul>
</div>
</section>
</div>
<script src="app.js"></script>
</body>
</html>
css/app.css
.text-center {
text-align: center;
}
.healthbar {
width: 80%;
height: 40px;
background-color: #eee;
margin: auto;
transition: width 500ms;
}
.controls,
.log {
margin-top: 30px;
text-align: center;
padding: 10px;
border: 1px solid #ccc;
box-shadow: 0px 3px 6px #ccc;
}
.turn {
margin-top: 20px;
margin-bottom: 20px;
font-weight: bold;
font-size: 22px;
}
.log ul {
list-style: none;
font-weight: bold;
text-transform: uppercase;
}
.log ul li {
margin: 5px;
}
.log ul .player-turn {
color: blue;
background-color: #e4e8ff;
}
.log ul .monster-turn {
color: red;
background-color: #ffc0c1;
}
button {
font-size: 20px;
background-color: #eee;
padding: 12px;
box-shadow: 0 1px 1px black;
margin: 10px;
}
#start-game {
background-color: #aaffb0;
}
#start-game:hover {
background-color: #76ff7e;
}
#attack {
background-color: #ff7367;
}
#attack:hover {
background-color: #ff3f43;
}
#special-attack {
background-color: #ffaf4f;
}
#special-attack:hover {
background-color: #ff9a2b;
}
#heal {
background-color: #aaffb0;
}
#heal:hover {
background-color: #76ff7e;
}
#restart {
background-color: #ffffff;
}
#restart:hover {
background-color: #c7c7c7;
}
app.js
new Vue({
el: app,
data: {
playerHealth: 100,
computerHealth: 100,
isRunning: false,
turns: [],
},
methods: {
startGame: function() {
this.isRunning = true;
this.playerHealth = 100;
this.computerHealth = 100;
this.clearLog();
},
attackController: function(attacker, maxRange, minRange) {
let receiver = this.setReceiver(attacker);
let damage = 0;
if (attacker === 'player') {
damage = this.randomDamage(maxRange, minRange);
this.computerHealth -= damage;
}
if (attacker === 'computer') {
damage = this.randomDamage(maxRange, minRange);
this.playerHealth -= damage;
}
this.addToLog(attacker, receiver, damage);
if (this.checkWin()) {
return;
}
},
attack: function() {
this.attackController('player', 10, 3);
this.attackController('computer', 10, 3);
},
specialAttack: function() {
this.attackController('player', 30, 5);
this.attackController('computer', 30, 5);
},
heal: function() {
if (this.playerHealth <= 90) {
this.playerHealth += 10;
} else {
this.playerHealth = 100;
}
this.turns.unshift({
isPlayer: true,
text: 'Player heals for ' + 10,
});
},
randomDamage: function(max, min) {
return Math.floor(Math.random() * max, min);
},
checkWin: function() {
if (this.computerHealth <= 0) {
this.alertBox('YOU WIN! New Game?');
} else if (this.playerHealth <= 0) {
this.alertBox('LOSER!!! New Game?');
}
return false;
},
alertBox: function(message) {
if (confirm(message)) {
this.isRunning = false;
this.startGame();
} else {
this.isRunning = false;
}
return true;
},
restart: function() {
this.isRunning = false;
this.startGame();
},
addToLog: function(attacker, receiver, damage) {
this.turns.unshift({
isPlayer: attacker === 'player',
text: attacker + ' hits ' + receiver + ' for ' + damage,
});
},
clearLog: function() {
this.turns = [];
},
setReceiver: function(attacker) {
if (attacker === 'player') {
return 'computer';
} else {
return 'player';
}
},
damageOutput: function(attacker, health) {
if (attacker === 'player') {
damage = this.randomDamage(maxRange, minRange);
this.computerHealth -= damage;
}
},
},
});
Github repo is here if you prefer that. Thanks!
Your attack (and specialAttack) function attacks for both players:
attack: function() {
this.attackController('player', 10, 3);
this.attackController('computer', 10, 3);
},
Currently, it is checking for win at every attackController call. So when the first attacker (player) wins, the game resets AND the second player attacks.
So, my suggestion, move the checkWin out of the attackController into the attack functions:
attack: function() {
this.attackController('player', 10, 3);
this.attackController('computer', 10, 3);
this.checkWin();
},
The same to specialAttack.
Code/JSFiddle: https://jsfiddle.net/acdcjunior/wwc1xnyc/10/
Note, when the player wins, in the code above, the computer will still "strike back", even though the game is over. If you want to halt that, make checkWin return if the game is over:
checkWin: function() {
if (this.computerHealth <= 0) {
this.alertBox('YOU WIN! New Game?');
return true;
} else if (this.playerHealth <= 0) {
this.alertBox('LOSER!!! New Game?');
return true;
}
return false;
},
And add an if to attack (and specialAttack):
attack: function() {
this.attackController('player', 10, 3);
if (this.checkWin()) return;
this.attackController('computer', 10, 3);
this.checkWin();
},
Updated fiddle: https://jsfiddle.net/acdcjunior/wwc1xnyc/13/

How to prevent page refresh on button click

I need help with my coin flip. Basically what I wanted to do is to create two buttons. By pressing one of them, the player would pick a side, for example Global or Fortune.
I can't figure out how to do it so when the player presses the button it will actually pick a side without refreshing the site.
var result, userchoice;
function resetAll() {
var resetHTML = '<div class="tail"><img src="coin_F.png" /></div><div class="head"><img src="coin_G.png" /></div>';
setTimeout(function() {
$('.coinBox').fadeOut('slow', function() {
$(this).html(resetHTML)
}).fadeIn('slow', function() {
$('#btnFlip').removeAttr('disabled');
});
}, 2500);
}
// Checking User Input
$(document).on('change', '#userChoice', function() {
userchoice = $(this).val();
if (userchoice == "") {
$(this).parent('p').prepend("<span class='text text-danger'>Please select a coin side to play the game</span>")
$('#btnFlip').attr('disabled', 'disabled');
} else {
/**/
$('#btnFlip').removeAttr('disabled');
$(this).siblings('span').empty();
}
return userchoice;
});
// Final result declaration
function finalResult(result, userchoice) {
var resFormat = '<h3>';
resFormat += '<span class="text text-primary">You choose : <u>' + userchoice + '</u></span> |';
resFormat += '<span class="text text-danger"> Result : <u>' + result + '</u></span>';
resFormat += '</h3>';
var winr = '<h2 class="text text-success" style="color: #49DF3E;">You Won!!</h2>';
var losr = '<h2 class="text text-danger" style="color: #c34f4f;">You Lost...</h2>';
if (result == userchoice) {
$('.coinBox').append(resFormat + winr)
} else {
$('.coinBox').append(resFormat + losr)
}
}
// Button Click Actions
$(document).on('click', '#btnFlip', function() {
if ($('#userChoice').val() == "") return;
var flipr = $('.coinBox>div').addClass('flip');
var number = Math.floor(Math.random() * 2);
$(this).attr('disabled', 'disabled');
setTimeout(function() {
flipr.removeClass('flip');
//result time
if (number) {
result = 'Global';
//alert('Head = '+number);
$('.coinBox').html('<img src="coin_G.png" /><h3 class="text-primary">Global</h3>');
finalResult(result, userchoice);
resetAll();
} else {
result = 'Fortune';
//alert('Tail = '+number);
$('.coinBox').html('<img src="coin_F.png" /><h3 class="text-primary">Fortune</h3>');
finalResult(result, userchoice);
resetAll();
}
}, 2000);
return false;
});
#wrapper
{
width: 100%;
height: auto;
min-height: 500px;
}
.btn
{
width: 12%;
background-color: #c34f4f;
color: white;
padding: 14px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 22px;
}
.btn:hover
{
background-color: #A64242;
}
input[type=submit]:hover {
background-color: #A64242;
}
.container
{
padding: 50px 0;
text-align: center;
}
h1
{
margin-bottom: 100px;
}
.head
{
margin-top: -205px;
}
.flip img{animation: flipIt 0.5s linear infinite;}
.head img
{
animation-delay: 0.25s;
}
#keyframes flipIt
{
0%{width: 0px;
height: 200px;}
25%{width: 200px;
height: 200px;}
50%{width: 0px;
height: 200px;}
100%{width: 0px;
height: 200px;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<div class="container">
<div class="row">
<div class="col-lg-12">
<h1>Coin Flip | <span>Global or Fortune</span></h1>
</div>
<div class="col-lg-12">
<!--blank-->
<div class="col-lg-4"></div>
<!--coin-->
<div class="col-lg-4">
<div class="coinBox">
<div class="tail">
<img src="coin_F.png" />
</div>
<div class="head">
<img src="coin_G.png" />
</div>
</div>
</div>
<!--user form elements-->
<div class="col-lg-4 text-left">
<p>
<div class="form-control">
<button name="Global" id="userChoice">Global</button>
<button name="Fortune" id="userChoice">Fortune</button>
</div>
<p>
<button class="btn btn-lg btn-primary" id="btnFlip" disabled>Flip It</button>
</p>
</div>
</div>
</div>
</div>
</div>
Try something like this:
HTML
<div class="choices">
<button name="Heads">Heads</button>
<button name="Tails">Tails</button>
<p>You have chosen: <span class="choice"></span></p>
</div>
<div class="flip">
<button class="disabled">Flip Coin</button>
<p></p>
</div>
CSS
.flip button {
background: #cc0000;
color: #fff;
padding: 5px;
}
.flip button.disabled {
cursor: not-allowed;
background: #ccc;
color: #eee;
}
JS
$(function() {
$(".choices button").on("click", function() {
var choice = $(this).attr("name");
//show selected choice
$(".choice").text(choice);
//enable flip button
$(".flip button").removeClass("disabled");
});
$(".flip button").on("click", function() {
//flip coin if a choice has been made
if(!$(this).hasClass("disabled")) {
//get random number
var flip = Math.floor(Math.random() * 2) + 1;
//determine side of coin and result of guess (ternary)
var flipSide = flip == 1 ? "Heads" : "Tails";
var result = flipSide == $(".choice").text() ? "correct" : "wrong";
//show flip result
$(".flip p").text(flipSide + ", you chose " + result);
}
});
});
You can also view it working here: https://jsfiddle.net/8jw1ogLd/

Categories