rps function not working (javascript) - javascript

Rps game code isn't working. My battle function is supposed to set win to a 1,2, or 3 but it always stays at the default 0. I've checked the other values through the console, and they all seem to be working. here is my code.
function Player(number) {
this.number = number;
this.choice = 0;
}
var player1 = new Player(1);
var player2 = new Player(2);
var win = 0;
var battle = function() {
if (player1.choice === player2.choice) {
win = 3;
} else if (player1.choice + 2 === player2.choice && player1.choice === 1){
win = 2;
} else if (player1.choice + 1 === player2.choice && player1.choice === 1) {
win = 1;
} else if (player1.choice + 1 === player2.choice && player1.choice === 2) {
win = 1;
} else if (player1.choice - 1 === player2.choice && player1.choice === 2) {
win = 2;
} else if (player1.choice - 1 === player2.choice && player1.choice === 3) {
win = 2;
} else if (player1.choice - 2 === player2.choice && player1.choice === 3) {
win = 1;
} else {
alert ('someone pressed the wrong button')
}
}
var Reset = function () {
win = 0;
player1.choice = 0;
player2.choice = 0;
}
$(document).ready(function() {
$(document).keydown(function(event) {
if (event.which === 81) {
player1.choice = 1;
} else if (event.which === 87){
player1.choice = 2;
} else if (event.which === 69){
player1.choice = 3;
} else if (event.which === 37){
player2.choice = 1;
} else if (event.which === 40){
player2.choice = 2;
} else if (event.which === 39){
player2.choice = 3;
}
})
if (player1.choice > 0 && player2.choice > 0) {
battle();
if (win === 1) {
$('.winner').append('<p>player1 wins!</p>')
} else if (win === 2) {
$('.winner').append('<p>player2 wins!</p>')
} else if (win === 3) {
$('.winner').append('<p>It is a draw!</p>')
}
}
})
My html has the div with class 'winner' in it.
Additional question
How do I cancel the keydown function after both players have chosen their options.

Are you giving your player a choice in the Player class you created? It should look like this:
function Player(number, choice) {
this.number = number;
this.choice = choice;
}

Related

Uncaught TypeError: this.initTimer is not a function

Modular refactoring of javascript is in progress. When executing the codes below in the game class start method, an error like this.initTimer is not a function is output. Not only initTimer but also the code below shows an error like is not a function. How can I solve this?
game.js
'use strict';
import * as sound from './sound.js';
import Field from './field.js';
export default class Game{
constructor(gameDuration){
this.gameDuration = gameDuration;
this.gameTimer = document.querySelector('.game__timer');
this.gameField = new Field();
this.gameField.setClickListener(this.onFieldClick);
this.startBtn = document.querySelector('.game__startBtn');
this.startBtn.addEventListener('click', this.start);
this.started = false;
this.timer = undefined;
this.level = 0;
}
onFieldClick = (stage, win) => {
if(!this.started){
return;
}
if(this.level == 0){
if(stage == 'first' && win == 'win'){
this.finish('win');
}else if(stage == 'first' && win == 'lose'){
this.finish('lose');
}
}
if(this.level == 1){
if(stage == 'second' && win == 'win'){
this.finish('win');
}else if(stage == 'second' && win == 'lose'){
this.finish('lose');
}
}
if(this.level == 2){
if(stage == 'third' && win == 'win'){
this.finish('finish');
}else if(stage == 'third' && win == 'lose'){
this.finish('lose');
}
}
}
onItemClick(button) {
if(button == 'next'){
++this.level;
}
if(button == 'finish'){
this.level = 0;
}
start();
}
setGameStopListener(onGameStop){
this.onGameStop = onGameStop;
}
start() {
this.started = true;
this.initTimer();
this.gameField.hideStartContent;
this.setBackgroundImg();
this.showTimer();
sound.playBackground();
this.startTimer();
}
finish(win){
this.started = false;
this.stopTimer();
sound.stopBackground();
if(win == 'win' || win == 'finish'){
sound.playWin();
}
if(win == 'lose') {
sound.playAlert();
}
this.onGameStop && this.onGameStop(win);
}
initTimer(){
this.timer = undefined;
}
setBackgroundImg(){
let imgPath = `url(img/game__field/stage${this.level}.jpg)`;
this.gameField.setBackgroundImage(imgPath);
}
showTimer() {
this.gameTimer.style.visibility = 'visible';
}
startTimer() {
let remainingTimeSec = this.gameDuration;
this.updateTimerText(remainingTimeSec);
this.timer = setInterval(() => {
if(remainingTimeSec <= 0) {
clearInterval(timer);
sound.stopBackground();
this.finish('lose');
return;
}
this.updateTimerText(--remainingTimeSec);
}, 1000);
}
updateTimerText(time) {
const minutes = Math.floor(time / 60);
const seconds = time % 60;
this.gameTimer.innerHTML = `${minutes}:${seconds}`;
}
stopTimer() {
clearInterval(this.timer);
}
}
OutPut
game.js:60 Uncaught TypeError: this.initTimer is not a function
at HTMLImageElement.start (game.js:60)
Expected
Sequencing of code inside start
I believe a problem is in event 'click' handler. Without binding, 'this' is prebound to clicked element, in your case to some img inside button.
this.startBtn.addEventListener('click', this.start.bind(this));

refactoring: How can I improve this as a clean code

I am currently studying JS myself.And make the pig-game which is project of the course that I watched. I'm always curious how can I improve my code but I got no idea where do I begin.
Is there some principle that I can improve any code?
If there's a way, Could you let me know? Thanks!
https://github.com/wonkooklee/pig-game
result : https://wonkooklee.github.io/pig-game/
below is main functions
document.querySelector('.btn-roll').addEventListener('click', function() {
if (gamePlaying) {
dice = Math.floor(Math.random() * 6) + 1;
diceDOM.style.display = 'block';
diceDOM.src = `dice-${dice}.png`;
if (dice === 6 && lastDice === 6) {
// Player looses score
scores[activePlayer] = 0;
document.getElementById(`score-${activePlayer}`).textContent = '0';
nextPlayer();
} else if (dice !== 1 && dice !== 6) {
roundScore += dice;
document.getElementById(`current-${activePlayer}`).textContent = roundScore;
lastDice = 0;
} else if (dice === 6) {
roundScore += dice;
document.getElementById(`current-${activePlayer}`).textContent = roundScore;
lastDice = dice;
} else {
nextPlayer();
}
}
});
document.querySelector('.btn-hold').addEventListener('click', function() {
if (gamePlaying) {
scores[activePlayer] += roundScore;
document.getElementById(`score-${activePlayer}`).textContent = scores[activePlayer];
let input = document.getElementById('scoreSet').value;
let winningScore;
if (isNaN(input) === false) {
winningScore = input;
} else {
document.getElementById('scoreSet').value = '100';
}
if (scores[activePlayer] >= winningScore) {
document.getElementById(`name-${activePlayer}`).textContent = 'WINNER!';
document.querySelector(`.player-${activePlayer}-panel`).classList.add('winner');
document.querySelector(`.player-${activePlayer}-panel`).classList.remove('active');
diceDOM.style.display = 'none';
gamePlaying = false;
} else {
nextPlayer();
}
}
});
Martin Fowler wrote a great book "Refactoring". Besides, Fowler has a great blog Refactoring.com, where you can find a lot of information about refactoring with examples in Javascript.
I'm not strong in Javascript, but can let you some advices about your code.
1.Simplify Conditional Logic
For example like this:
if (dice === 6 && lastDice === 6) {
// Player looses score
scores[activePlayer] = 0;
document.getElementById(`score-${activePlayer}`).textContent = '0';
nextPlayer();
return;
}
if (dice !== 1 && dice !== 6) {
roundScore += dice;
document.getElementById(`current-${activePlayer}`).textContent = roundScore;
lastDice = 0;
return;
}
if (dice === 6) {
roundScore += dice;
document.getElementById(`current-${activePlayer}`).textContent = roundScore;
lastDice = dice;
return;
}
nextPlayer();
2.Delete duplicated code and extract function
For example
function someFunctionName(diffRoundScore, lastDiceValue){
roundScore += diffRoundScore;
document.getElementById(`current-${activePlayer}`).textContent = roundScore;
lastDice = lastDiceValue;
}
if (dice !== 1 && dice !== 6) {
someFunctionName(dice, 0);
return;
}
if (dice === 6) {
someFunctionName(dice, dice);
return;
}
3.Change check "dice for 6" to function
function isDiceEqualsSix { return dice === 6};
if (isDiceEqualsSix && lastDice === 6) {
// Player looses score
scores[activePlayer] = 0;
document.getElementById(`score-${activePlayer}`).textContent = '0';
nextPlayer();
return;
}
if (dice !== 1 && !isDiceEqualsSix) {
someFunctionName(dice, 0);
return;
}
if (isDiceEqualsSix) {
someFunctionName(dice, dice);
return;
}
4.Change "6" to a constant variable or a function
const LIMIT_SCORE = 6;
function isDiceEqualsSix { return dice === LIMIT_SCORE};
if (isDiceEqualsSix && lastDice === LIMIT_SCORE) {
// Player looses score
scores[activePlayer] = 0;
document.getElementById(`score-${activePlayer}`).textContent = '0';
nextPlayer();
return;
}
I hope I helped you.

Function used for calculating not functioning, and a snake that can't be longer than 2?

I'm making a snake clone, and I've got the head to the second segment working. The rest of the body checks should run through automatically, but it cuts off the body at the second segment without going through the rest of the segments, despite the fact that it should. My code is as follows:
var pixels = document.getElementsByClassName('pixel'); // 0 to 95
var dir = 'right';
var foodEat = true;
var dead = true;
var snakeLong = 1;
var headPos;
var foodPix;
var foodMake = function(){ // Create Food pixel (Not On Snake)
var tempnum = Math.ceil(Math.random() * (95 - 5) + 5);
var pixstate = window.getComputedStyle(pixels[tempnum]).getPropertyValue('--state');
if (pixstate == 'snake' || pixstate == 'snakeHead' || pixstate == 'snakeEnd'){
console.log('Repeating');
foodMake();
} else {
console.log('Food Made!');
$(pixels[tempnum]).css('--state','food');
}
}
var directSend = function(reference,direction){
if (direction == 'left'){
reference -=1;
return reference;
} else if (direction == 'up'){
reference -=12;
return reference;
} else if (direction == 'right'){
reference +=1;
return reference;
} else if (direction == 'down'){
reference +=12;
return reference;
}
}
var snakeMake = function(refer,tsnakel){ // Continue To Form Snake
if (tsnakel > 0){
var tempdir = $(pixels[refer]).css('--goFrom');
console.log(directSend(refer,tempdir));
if (tsnakel = 1){
$(pixels[directSend(refer,tempdir)]).css('--state','empty');
} else {
refer = directSend(refer,tempdir);
}
tsnakel -= 1;
snakeMake(refer,tsnakel);
}
}
var snakeHEF = function(){ // Form First Sections of Snake
var Pheadpos;
var tdir;
if (dir == 'left'){ // Previous Segment Position
Pheadpos = 1;
tdir = 'right';
} else if (dir == 'up'){
Pheadpos = 12;
tdir = 'down';
} else if (dir == 'right'){
Pheadpos = -1;
tdir = 'left';
} else if (dir == 'down'){
Pheadpos = -12;
tdir = 'up';
}
$(pixels[headPos]).css('--state','snakeHead');
$(pixels[headPos]).css('--snakePos','1');
$(pixels[headPos]).css('--goFrom',tdir);
if (snakeLong == 1){ // No Food Eaten
$(pixels[headPos+Pheadpos]).css('--state','empty');
}
if (snakeLong >= 2){ // One Food Eaten
var send;
$(pixels[headPos+Pheadpos]).css('--state','snake');
$(pixels[headPos+Pheadpos]).css('--snakePos','2');
var temppos = $(pixels[headPos+Pheadpos]).css('--goFrom');
if (temppos == 'left'){
$(pixels[headPos+Pheadpos-1]).css('--state','empty');
send = headPos+Pheadpos-1;
} else if (temppos == 'up'){
$(pixels[headPos+Pheadpos-12]).css('--state','empty');
send = headPos+Pheadpos-12;
} else if (temppos == 'right'){
$(pixels[headPos+Pheadpos+1]).css('--state','empty');
send = headPos+Pheadpos+1;
} else if (temppos == 'down'){
$(pixels[headPos+Pheadpos+12]).css('--state','empty');
send = headPos+Pheadpos+12;
}
if (snakeLong > 2){ // More Than 1 Food Eaten
snakeMake(send,snakeLong-2);
}
}
}
var Game = setInterval(function(){
$(document).keydown(function(keyPressed){
if (keyPressed.keyCode == 88){ // Reset Game [x]
for (s = 0; s < 96; s++){
var pixstate = $(pixels[s]).css('--state');
if (pixstate == 'food'){
$(pixels[s]).css('--state','empty');
}
if (pixstate == 'snake' || pixstate == 'snakeHead' || pixstate == 'snakeEnd'){
$(pixels[s]).css('--state','empty');
$(pixels[s]).css('--snakePos','not');
$(pixels[s]).css('--goFrom','none');
}
}
foodEat = true;
$(pixels[0]).css('--state','snakeHead');
$(pixels[0]).css('--snakePos','1');
$(pixels[0]).css('--goFrom','left');
dead = false;
snakeLong = 1;
headPos = 0;
dir = 'right';
} // Movement Set
if (keyPressed.keyCode == 37 && dir !== 'right'){ // [<-]
dir = 'left';
} else if (keyPressed.keyCode == 38 && dir !== 'down'){ // [^^]
dir = 'up';
} else if (keyPressed.keyCode == 39 && dir !== 'left'){ // [->]
dir = 'right';
} else if (keyPressed.keyCode == 40 && dir !== 'up'){ // [vv]
dir = 'down';
}
});
if (dead == false){ //Dead Check Then Do Game Calculations
if (dir == 'left'){ // Move Head
for (s = 0; s < 8; s++){
if (headPos == 0+(12*s)){
dead = true;
}
}
if (dead == false){
headPos -= 1;
if (foodPix == headPos){
snakeLong += 1;
foodEat = true;
}
snakeHEF();
}
} else if (dir == 'up'){
if (headPos < 12){
dead = true;
}
if (dead == false){
headPos -= 12;
if (foodPix == headPos){
snakeLong += 1;
foodEat = true;
}
snakeHEF();
}
} else if (dir == 'right'){
for (s = 0; s < 8; s++){
if (headPos == 11+(12*s)){
dead = true;
}
}
if (dead == false){
headPos += 1;
if (foodPix == headPos){
snakeLong += 1;
foodEat = true;
}
snakeHEF();
}
} else if (dir == 'down'){
if (headPos > 83){
dead = true;
}
if (dead == false){
headPos += 12;
if (foodPix == headPos){
snakeLong += 1;
foodEat = true;
}
snakeHEF();
}
}
if (foodEat == true){ // Food generator
foodMake();
foodEat = false;
}
for (s = 0; s < 96; s++){
var tpixstate = $(pixels[s]).css('--state');
if (tpixstate == 'food'){
foodPix = s;
}
}
}
for (s = 0; s < 96; s++){ // Pixel Update
var pixstate = $(pixels[s]).css('--state');
if (pixstate == 'snake' || pixstate == 'snakeHead' || pixstate == 'snakeEnd'){
$(pixels[s]).css('background-color','rgb(0,170,0)');
} else if (pixstate == 'food'){
$(pixels[s]).css('background-color','rgb(270,0,0)');
} else if (pixstate == 'empty'){
$(pixels[s]).css('background-color','rgb(68,68,68)');
}
}
},750);
Edit: To reduce confusion, I have now given the entire code.
As it turns out, I was calling the code to remove the third body segment every time, (lines 76 thru 88) even when the body was supposed to be longer.(I changed it to one '--state' changer, in an if statement checking for a body length of 2) Additionally, an if statement (line 40) was using = instead of ==, causing it to count as true each time, cutting off the fourth body segment.

How to compare two variables in javascript

I want to match two variables.
var this_roll;
and
var last_roll;
I have this code, that i want the output of "win" or "losse". The output should be "win" if last_roll and this_roll have the same value and "lose" if not
"use strict";
var x;
var win_losse = 'losse';
var last_roll;
var last_bet;
var this_roll = $('#past')[0].childNodes[9].textContent;
var bet_input = document.getElementById('betAmount').value=x;
var roll_time = $('#banner')[0].childNodes[0].textContent;
var base_bet = 5;
function thisRoll() {
console.log(this_roll);
if (this_roll == 0) {
this_roll = 'green';
} else if ((this_roll >= 1) && (this_roll <= 7)) {
this_roll = 'red';
} else if ((this_roll >= 8) && (this_roll <= 14)) {
this_roll = 'black';
}
}
function compare() {
if (this_roll == last_roll) {
win_losse = 'win';
} else {
win_losse = 'losse';
}
console.log(win_lose);
}
function lastRoll() {
console.log(this_roll);
if (this_roll == 0) {
last_roll = 'green';
} else if ((this_roll >= 1) && (this_roll <= 7)) {
last_roll = 'red';
} else if ((this_roll >= 8) && (this_roll <= 14)) {
last_roll = 'black';
}
}
function bet() {
if (win_losse == 'win') {
x = base_bet;
} else if (win_losse == 'losse') {
x = last_bet * 2;
}
}
console.log(x);
This works for sure
"use strict";
//Removed the global x variable
//Removed the global win_lose variable
var last_roll = $('#past')[0].childNodes[8].textContent;
var last_bet;
var this_roll = $('#past')[0].childNodes[9].textContent;
var bet_input = document.getElementById('betAmount').value=x;
//Removede the Roll_time variable because it wasn't used
var base_bet = 5;
function ThisRoll(this_roll) {
var rollhisThis; //Added a local variable
if (this_roll === 0) {
rollhisThis = 'green';
} else if ((this_roll >= 1) && (this_roll <= 7)) {
rollhisThis = 'red';
} else if ((this_roll >= 8) && (this_roll <= 14)) {
rollhisThis = 'black';
}
return rollhisThis; //Added return
}
var thisRoll = ThisRoll(this_roll); //Added a new global variable
console.log(thisRoll);
function LastRoll(last_roll) {
var rollhisLast; //Added a local variable
if (last_roll === 0) {
rollhisLast = 'green';
} else if ((last_roll >= 1) && (last_roll <= 7)) {
rollhisLast = 'red';
} else if ((last_roll >= 8) && (last_roll <= 14)) {
rollhisLast = 'black';
}
return rollhisLast; //Added return
}
var lastRoll = LastRoll(last_roll); //Added a new global variable
console.log(LastRoll);
function compare(thisRoll, lastRoll) {
var win_lose; //Added a local win_lose variable
if (thisRoll !== lastRoll) {
win_lose = 'lose';
} else {
win_lose = 'win';
}
return win_lose; //Added return
}
var winLose = compare(thisRoll, lastRoll); //Added a gloabl variable
console.log(winLose);
function bet() {
if (win_losse == 'win') {
x = base_bet;
} else if (win_losse == 'losse') {
x = last_bet * 2;
}
}
console.log(x);

Is it possible to replace two opposite and different functions with a single one?

I want to optimise and reduce my code to increase performance and correct-ability of it. With those two different functions below I can successfuly move a Google Map Marker on a map forward and backward using a pathIndex, calcuted on an array of GPS coordinates [I didn't include this section of code since I think it's not releated to this question but I can and will post it if needed].
This is my code:
1st function:
function animate() {
if (pathIndex < coord.length && mapAnimationStatus != PLAY_PAUSED) {
googleMapsMarker.setPosition(coord[pathIndex]);
googleMap.panTo(coord[pathIndex]);
pathIndex += 1;
if (pathIndex == coord.length) {
pause();
pathIndex = 0;
mapAnimationStatus = NOT_PLAY;
return;
}
timerHandler = setTimeout("animate(" + pathIndex + ")", 1000);
}
}
2nd function:
function animateRewind() {
if (pathIndex >= 0 && mapAnimationStatus != PLAY_PAUSED) {
googleMap.panTo(coord[pathIndex]);
googleMapsMarker.setPosition(coord[pathIndex]);
if (pathIndex == 0) {
pause();
mapAnimationStatus = NOT_PLAY;
return;
}
pathIndex -= 1;
timerHandler = setTimeout("animateRewind(" + pathIndex + ")", 1000);
}
}
As you can see those two functions shares a lot of portions of code and it think that they can be replaced with a single one for this reason but I can't figure out how to do this.
So, is it possible to create a single function to manage those two different animations?
I hope I didnt miss something...
function animate(pathIndex, dir) {
var animateDir = (pathIndex < coord.length
&& mapAnimationStatus != PLAY_PAUSED && dir == 'f')
? dir
: (pathIndex >= 0
&& mapAnimationStatus != PLAY_PAUSED && dir == 'r')
? dir : "error";
if (animateDir === "r") { googleMap.panTo(coord[pathIndex]); }
if (animateDir !== 'error') { googleMapsMarker.setPosition(coord[pathIndex]); }
if (animateDir === "f") {
googleMap.panTo(coord[pathIndex]);
pathIndex += 1;
}
if (animateDir !== 'error') {
if (pathIndex == coord.length || pathIndex == 0) {
pause();
pathIndex = animateDir === "f" ? 0 : pathIndex;
mapAnimationStatus = NOT_PLAY;
return;
}
pathIndex = animateDir === "f" ? pathIndex - 1 : pathIndex;
timerHandler = setTimeout("animate(" + pathIndex + "," + animateDir + ")", 1000);
}
}
You can try this :
function ConcatenateFunctions() {
if(mapAnimationStatus != PLAY_PAUSED){
googleMap.panTo(coord[pathIndex]);
googleMapsMarker.setPosition(coord[pathIndex]);
if (pathIndex < coord.length) {
pathIndex += 1;
if (pathIndex == coord.length) {
pause();
pathIndex = 0;
mapAnimationStatus = NOT_PLAY;
return;
}
}else if (pathIndex >= 0) {
if (pathIndex == 0) {
pause();
mapAnimationStatus = NOT_PLAY;
return;
}
pathIndex -= 1;
}
timerHandler = setTimeout("ConcatenateFunctions(" + pathIndex + ")", 1000);
}
}
Hope it will help !

Categories