Scramble per letter using javascript - javascript

How can I scramble the words per letter?
My code scramble the whole words...
I can't seem to change it per letter. Since I'm new to Vue.js
I'm using Vue.js in here.
const sampleText1 = 'インバウント'
const characters =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
const charactersLength = characters.length
export default {
data() {
return {
sam01: sampleText1,
}
},
setup() {
const texts = reactive({
text1: sampleText1,
})
const scrambleText = (text, name) => ({ progress }) => {
if (progress === 100) {
texts[name] = text
} else if (Math.floor(progress) % 20 === 0) {
texts[name] = text.replace(
/./g,
characters.charAt(Math.floor(Math.random() * charactersLength))
)
}
}
}
current output
expected output

You can pass the replacement as a function instead of single string which will invoke for each match.
...
texts[name] = text.replace(
/./g,
() => characters.charAt(Math.floor(Math.random() * charactersLength))
)
...

Related

React, Uncaught RangeError: Maximum call stack size exceeded

I have an array of objects containing details about players (name, skill(number 0-10)),
I'm trying to split that array into two arrays Team1 and Team2 while making sure that the sum of skill in both teams is equal or close at least.
This is the way I came up with but it seems like I have some kind of recursion error and I can't see where the problem is.
const [team1, setTeam1] = useState([]);
const [team2, setTeam2] = useState([]);
const [team1Skill, setTeam1Skill] = useState(0);
const [team2Skill, setTeam2Skill] = useState(0);
const [skillGap, setSkillGap] = useState(0);
const randomize = () => {
let randomNum1 = Math.floor(Math.random() * playersList.length);
let randomNum2 = Math.floor(Math.random() * playersList.length);
const pickedPlayer1 = playersList[randomNum1];
const pickedPlayer2 = playersList[randomNum2];
if (!team2.includes(pickedPlayer1) && !team1.includes(pickedPlayer1)) {
team1.push(pickedPlayer1);
}
if (!team1.includes(pickedPlayer2) && !team2.includes(pickedPlayer2)) {
team2.push(pickedPlayer2);
}
checkNumberEquality();
if (team1.length + team2.length === playersList.length) {
checkSkillSum();
}
};
const checkNumberEquality = () => {
if (team1.length + team2.length !== playersList.length) {
randomize();
}
};
const checkSkillSum = () => {
team1.map((player) => {
setTeam1Skill((value) => value + player.skill);
});
team2.map((player) => {
setTeam2Skill((value) => value + player.skill);
});
if (team1Skill === team2Skill) {
console.log("The teams are perfectly balanced.");
} else if (
team1Skill + 1 == team2Skill ||
team1Skill + 2 == team2Skill
) {
console.log(
"The teams have been balanced as much as possible, but team 2 is slightly better than team 2"
);
} else if (
team1Skill - 1 == team2Skill ||
team1Skill - 2 == team2Skill
) {
console.log(
"The teams have been balanced as much as possible, but team 1 is slightly better than team 2"
);
} else if (team1Skill !== team2Skill) {
setTeam1([]);
setTeam2([]);
randomize();
}
};
Here's a better and clearer image of the code
Also, in the app I have an input field (in another component) and whenever I type something there I notice that it keeps executing the commands and repeating things ( I kinda know how onChange and re-rendering work in react but it just seemed weird )

Store value in a variable

I am new in Javascript. I develop a program that store the score of humun and computer guess number. I want the human score and computer score will update when I call the updateScore() functions. However, it works but the score unable to increase by last score.
Here is the code:
let humanScore = 0;
let computerScore = 0;
let currentRoundNumber = 1;
// Write your code below:
const generateTarget = () => {
return Math.floor(Math.random()*10);
};
const compareGuesses = () => {
// Humun & Computer guess a number
const humunGuess = 1;
const computerGuess = 2;
// Call the generateTarget functions
const secretTargetNumber = generateTarget();
// Compare the difference between Target number and humun guess number
const humunTarget = Math.abs(humunGuess - secretTargetNumber);
// Compare the difference between Target number and computer guess number
const computerTarget = Math.abs(computerGuess - secretTargetNumber);
// Return true if humun won, false if computer won
if (humunTarget < computerTarget || humunTarget == computerTarget) {
return true;
}
else {
return false;
}
};
let updateScore = () => {
switch (compareGuesses()) {
case true:
return humanScore+=1;
case false:
computerScore+=1;
}
};
updateScore()
console.log(humanScore)
console.log(computerScore)
It is a programming language based on javascript event/trigger features. all variables are reset when you call the file again.
The variables seem to be reset every time you call the javascript file
let humanScore = 0,
computerScore = 0,
currentRoundNumber = 1;
// Write your code below:
const generateTarget = () => {
return Math.floor(Math.random() * 10);
};
const compareGuesses = () => {
// Humun & Computer guess a number
const humanGuess = 1;
const computerGuess = 2;
// Call the generateTarget functions
const secretTargetNumber = generateTarget();
// Compare the difference between Target number and humun guess number
const humanTarget = Math.abs(humanGuess - secretTargetNumber);
// Compare the difference between Target number and computer guess number
const computerTarget = Math.abs(computerGuess - secretTargetNumber);
// Return true if humun won, false if computer won
if (humanTarget < computerTarget) {
return true;
} else {
return false;
}
};
let updateScore = () => {
switch (compareGuesses()) {
case true:
return humanScore += 1;
case false:
computerScore += 1;
}
};
let showScore = () => {
updateScore();
console.log(humanScore)
console.log(computerScore)
}
<button onclick="showScore()">Click</button>
Woking Demo : https://jsfiddle.net/6v25y9qd/
Push click and show console
Because you're new, and I think #Onur Özkır is on to something, I will give some guidelines instead.
I understand that you mostly trying out to see if things works, and will refactor afterwards, but I recommend that you create methods that does only one thing. You already done that with generateTarget(), but if I look at compareGuesses(), that method doesn't just compare guesses. It also reads and generates numbers. I would instead read the values in updateScore() and then add them as parameters in compareGuesses.
By restricting your methods to only do one thing will make your code more readable, your methods will be smaller so they are easier to grasp, and the code is easier to debug.
I would also like to suggest that you only return a value at the end of the method, and always return (unless you can fit everything on one row) using a variable.
I also don't like switches in javascript, because the forced use of return. Would rather use ifs statement or a shorthand if statements, using conditional/ternary operator.
Use method names and variables to explain the code (ex. the constant HUMAN_WON in the code below). Try to avoid comments as far as possible. Comments should, IMHO, only be used if you generate a documentation. I suggest that you get your hands on Clean Code, which was a revelation for me to read, even as an experienced programmer.
I will refactor your code as a suggestion of how it can look like:
let humanScore = 0;
let computerScore = 0;
let currentRoundNumber = 1;
const HUMAN_WON = 1, COMPUTER_WON = -1, EQUAL = 0;
const generateTarget = () => {
return Math.floor(Math.random() * 10);
};
const readHumanGuess = () => {
return 1; // replace with appropriate code
}
const generateComputerGuess = () => {
return 2; // replace with generateTarget();
}
const compareGuesses = (humanGuess, computerGuess, secretTargetNumber) => {
let result = EQUAL;
const humanTarget = Math.abs(humanGuess - secretTargetNumber);
const computerTarget = Math.abs(computerGuess - secretTargetNumber);
if (humanTarget < computerTarget) {
result = HUMAN_WON;
} else if (computerTarget < humanTarget) {
result = COMPUTER_WON;
}
return result;
};
let updateScore = () => {
let humanGuess = readHumanGuess();
let computerGuess = generateComputerGuess();
let secretTargetNumber = generateTarget();
let whoWon = compareGuesses(humanGuess, computerGuess, secretTargetNumber);
if (whoWon == HUMAN_WON) {
humanScore++;
} else if (whoWon == COMPUTER_WON) {
computerScore++;
}
};
let displayCurrentScore = () => {
updateScore();
console.log(`${humanScore} vs ${computerScore}`);
}
<input type="button" onclick="displayCurrentScore()" value="Display Score">
You can even go one step further refactoring readGuesses() from updateScore() and separate updating UI—displayCurrentScore()—from handling logic in updateScore().
let humanScore = 0;
let computerScore = 0;
let currentRoundNumber = 1;
const HUMAN_WON = 1, COMPUTER_WON = -1, EQUAL = 0;
const generateTarget = () => {
return Math.floor(Math.random() * 10);
};
const readHumanGuess = () => {
return 1; // replace with appropriate code
}
const generateComputerGuess = () => {
return 2; // replace with generateTarget();
}
const readGuesses = () => {
let humanGuess = readHumanGuess();
let computerGuess = generateComputerGuess();
let secretTargetNumber = generateTarget();
return [humanGuess, computerGuess, secretTargetNumber]; // returning array
}
const compareGuesses = (humanGuess, computerGuess, secretTargetNumber) => {
let result = EQUAL;
const humanTarget = Math.abs(humanGuess - secretTargetNumber);
const computerTarget = Math.abs(computerGuess - secretTargetNumber);
if (humanTarget < computerTarget) {
result = HUMAN_WON;
} else if (computerTarget < humanTarget) {
result = COMPUTER_WON;
}
return result;
};
let updateScore = (humanGuess, computerGuess, secretTargetNumber) => {
let whoWon = compareGuesses(humanGuess, computerGuess, secretTargetNumber);
if (whoWon == HUMAN_WON) {
humanScore++;
} else if (whoWon == COMPUTER_WON) {
computerScore++;
}
return {'human': humanScore, 'computer': computerScore};
};
let displayCurrentScore = () => {
let [humanGuess, computerGuess, secretTargetNumber] = readGuesses();
let score = updateScore(humanGuess, computerGuess, secretTargetNumber);
console.log(`${score.human} vs ${score.computer}`);
}
<input type="button" onclick="displayCurrentScore()" value="Display Score">

Problem with Animating Number Counter on Javascript

I was hoping to create a counter which would increment to the eventual number of followers. I have other code, but I just included the part that would affect the incrementation. Currently, when I run the program the HTML file only displays the final number of followers, and the word "Followers" showing it is able to get the proper number, but it isn't able to have an incrementation animation as I would like. How would I go about fixing this?
var text_field = document.getElementById('followers');
fetch(api)
.then((response) => {
return response.json();
})
.then((data) => {
var number = data['Count'][0][0];
const updateCount = () => {
const target = number;
const count = text_field.innerText;
const increment = target / speed;
if (count < target) {
text_field.innerText = count + increment;
setTimeout(updateCount, 5);
} else {
text_field.innerText = target + ' Followers';
}
};
updateCount();
});
The innerText property returns a string value. Use the parseInt function before any calculations.
var text_field = document.getElementById("followers");
function counter(){
var number = 100;
const updateCount = () => {
const target = number;
const count = parseInt(text_field.innerText); //parsing
const speed=number;
const increment = target / speed;
if (count < target) {
text_field.innerText = count + increment;
setTimeout(updateCount, 5);
} else {
text_field.innerText = target;
}
};
updateCount();
}
counter();
<div id="followers">1</div> Followers!!!

Logical NaN Error in my React Typescript counter for win percentage

I am making a simple Typescript counter to track my win percentage in my Legends of Runeterra games I play. I can't figure out why when I increment a win or a loss I get NaN as my win percentage. The logic seems fine (obviously you can't decrement right now, that's a problem for later), I just want to focus on fixing the NaN error for now.
Here's my counter component:
import React, { useState } from 'react'
// add a ? after the type name if you want any one of these to be optional, ex: wins?
const Counter: React.FC<{
initialGamesPlayed: number
initialWins: number
initialLosses: number
initialWinPercentage: number
initialDeckName: string
}> = ({
initialDeckName,
initialWinPercentage,
initialWins,
initialLosses,
initialGamesPlayed,
}) => {
const [deckName, setDeckName] = useState(initialDeckName)
const [wins, setWins] = useState(initialWins)
const [losses, setLosses] = useState(initialLosses)
const [totalGames, setTotalGames] = useState(initialGamesPlayed)
const [winPercentage, setWinPercentage] = useState(initialWinPercentage)
const incrementWins = () => {
setWins(wins + 1)
winPercentageCalc()
console.log(winPercentage)
}
const decrementWins = () => {
if (wins > 0) setWins(wins - 1)
winPercentageCalc()
}
const incrementLosses = () => {
setLosses(losses + 1)
winPercentageCalc()
console.log(winPercentage)
}
const decrementLosses = () => {
if (losses > 0) setLosses(losses - 1)
winPercentageCalc()
}
const winPercentageCalc = () => {
setTotalGames(wins + losses)
setWinPercentage((wins / totalGames) * 100)
}
return (
<div>
<p>Deck Name: </p>
<p>wins: {wins} </p>
<button onClick={incrementWins}>+</button>
<button onClick={decrementWins}>-</button>
<p>losses: {losses}</p>
<button onClick={incrementLosses}>+</button>
<button onClick={decrementLosses}>-</button>
<p>Win Percentage: {winPercentage} % </p>
</div>
)
}
export default Counter
Thanks for taking a look!
The setWins, setLosses, setTotalGames and setWinPercentage are all asynchronous functions. So the first time your call winPercentageCalc, this is what happens:
const winPercentageCalc = () => {
setTotalGames(wins + losses) // This is asynchronous, so...
setWinPercentage((wins / totalGames) * 100) // totalGames = 0 => NaN
}
When you divide wins by totalGames, totalGames has not been updated so you divide by 0 which gives NaN (Not a Number) as a result

Simplify semver version compare logic

There's the standard npm semver version comparison library, but I have some simple logic to compare semver versions here:
const versionA = '14.8.3';
const versionB = '15.1.1';
const versionC = '15.1.2';
const semver = require('semver');
const assert = require('assert');
const isGreater = (a, b) => {
const [majorA, minorA, patchA] = String(a).split('.').map(v => Number.parseInt(v));
const [majorB, minorB, patchB] = String(b).split('.').map(v => Number.parseInt(v));
if (majorA > majorB) {
return true;
}
if (majorB > minorA) {
return false;
}
if (minorA > minorB) {
return true;
}
if (minorB > minorA) {
return false;
}
if (patchA > patchB) {
return true;
}
if (patchB > patchA) {
return false;
}
return false;
};
assert(isGreater(versionB, versionA), 'version b should be greater.');
assert(isGreater(versionA, versionB), 'version b should be greater.');
my question is - is there a way to simplify the logic in the greaterThan function? This function is supposed to replicate the logic in semver.gt().
You can use localeCompare instead, with the numeric option (with numeric, comparison is such that "1" < "2" < "10"), which is exactly the logic you're looking for:
const versionA = '14.8.3';
const versionB = '15.1.1';
const versionC = '15.1.2';
const versionD = '15.1.10';
const versionE = '15.2.1';
const versionF = '15.11.1';
const isGreater = (a, b) => {
return a.localeCompare(b, undefined, { numeric: true }) === 1;
};
// first argument version comes later than second argument:
console.log(isGreater(versionB, versionA));
console.log(isGreater(versionC, versionB));
console.log(isGreater(versionD, versionC));
console.log(isGreater(versionE, versionD));
console.log(isGreater(versionF, versionE));
console.log('---');
// second comes before first:
console.log(isGreater(versionA, versionB));
// same, return value should be false:
console.log(isGreater(versionA, versionA));
Or, equivalently, you can pass the locale string
en-US-u-kn-true
as the second parameter instead of { numeric: true }.
I believe this is logically the same and shorter, but not exactly stunning in it's simplicity
const parseInt = (v: string) : number => {
const num = Number.parseInt(v);
if(!(Number.isInteger(num) && num > 0)){
throw new Error('Could not parse positive integer from string')
}
return num;
};
const isGreater = (a: string, b: string) : boolean => {
const [majorA, minorA, patchA] = String(a).split('.').map(parseInt);
const [majorB, minorB, patchB] = String(b).split('.').map(parseInt);
if (majorA !== majorB) {
return majorA > majorB;
}
if (minorA !== minorB) {
return minorA > minorB;
}
return patchA > patchB;
};

Categories

Resources