Logic of hangman game with javascript - javascript

I am trying to build a hangman game and I need help with the logic. I am in a beginners class so I want to try and build this using beginners syntax. What I am trying to figure out
2) My issue is I need to display dashes (-) that represent blank lines and they need to be the same length of the randomly chosen word. In addition, every time a letter is correctly guessed, I need to replace the dashes with the correctly chosen letter. A solution I have thought of is making an empty array and then assigning it the dash signs in a for loop that is the length of the string and then replacing the indexes of specific dashes with matched letters, but I am not sure if this will work.
var randomWords = ['rock', 'paper', 'scissors'];
var numWins = 0;
var chosenWord = randomWords[Math.floor(Math.random() * randomWords.length)];
document.onkeyup = function(event) {
// var userGuess = String.fromCharCode(event.keyCode).toLowerCase();
var dashes = "";
for (var x = 0; x < chosenWord.length; x++) {
dashes += " - ";
// document.getElementById("word").innerHTML = blankLines;
// document.getElementById("word").innerHTML = ;
}
document.getElementById("word").innerHTML = dashes;
Trying to replace a dash with a letter in lines below. But both commented out code and non commented out codes work. That is why I am thinking of using an empty array but not sure if I can fill it with data using a foor loop
// for (x = 0; x < chosenWord.length; x++)
// {
// dashes[x] = "a";
// dahes.charAt(x) = 'a';
// }
dashes.charAt(0) = "a";
document.getElementById("test2").innerHTML = dashes;

This one should work. In the first case (if there's a white space in the word) it will display a whitespace. In the second case, it will replace every letter of the word with a dash.
var dashes = "";
for (i = 0; i < chosenWord.length; i++) {
if (chosenWord.charAt(i) == " ") {
dashes += " ";
} else {
dashes += "-";
}
}

Related

How to find the first incorrect word in a document attempting to use Standard Pilish?

I am creating a GDocs Apps Script to check my document to see if it is in Standard Pilish. I'd like to have the checker return both the position of the first error and the word that is incorrect. I can get the position of the first error in pi, but since the word list does not necessarily perfectly reflect that positioning.
For example, I used a modified quote from Peter Walder: "Two mathematicians accommodatingly promenade to tavern, quest everything". The error lies in the 8th word in the list, but the 10th position in pi.
This is the script I've landed at, and I originally tried to just words[positionOne] before realizing my counting error.
function pilishTranslate() {
var doc = DocumentApp.getActiveDocument();
var text = doc.getBody().getText();
// Remove quotation marks from the text
text = text.replace(/\"/g, "");
// Replace all non-letter characters with white space
text = text.replace(/[^a-zA-Z\s]/g, " ");
// Split the text into an array of words
var words = text.split(/\s+/);
// Count word length
var wordLengths = words.map(function(word) {
return word.length;
});
// Change 10 character counts to 0
wordLengths = wordLengths.map(function(length) {
return length === 10 ? 0 : length;
});
// Join character counts into single string
var wordLengthsString = wordLengths.join('');
// Create variable for pi
var decimal15 = '314159265358979'
// Find common prefix of strings a and b.
var prefix = function(a,b){
return a && a[0] === b[0] ? a[0] + prefix(a.slice(1), b.slice(1)) : '';
};
// Find index of first difference.
var diff = function(a,b){
return a===b ? -1 : prefix(a,b).length;
};
// actual test case
var tests = [
[wordLengthsString,decimal15],
];
// find first position of error
var positionOne = tests.map(test => diff(test[0], test[1]))
console.log(positionOne);
}
function checkPilish(text) {
// Remove quotation marks from the text
text = text.replace(/\"/g, "");
// Replace all non-letter characters with white space
text = text.replace(/[^a-zA-Z\s]/g, " ");
// Split the text into an array of words
var words = text.split(/\s+/);
// Create variable for pi
var decimal15 = '314159265358979'
let pi_index = 0;
// Loop over words
for (let i = 0; i < words.length; i++) {
// convert word length to Standard Pilish digits
let length_str = String(words[i].length);
if (length_str == '10') {
word_length = '0';
}
// check if this matches the current position in pi
if (decimal15.substr(pi_index, length_str.length) != length_str) {
return [i+1, words[i]];
}
pi_index += length_str.length;
}
return [];
}
console.log(checkPilish("Two mathematicians accommodatingly promenade to tavern, quest everything"));
console.log(checkPilish("Two mathematicians accommodatingly promenade to tavern, quest all"));

To lower case using if else/ for

I am the very begginer (only if/else, for, while, slice etc) and i ve got a problem: so i wrote Hangman game. I need to put in there code saying ‘’let’s player upper case guess letter transform to lowercase one every time he puts uppercase letter”
Did i choose the right place for this new code in existing code?
Were my thoughts about appropriate code more or less right?
If not: what s wrong then?
var words = ["fish", "monkey", "pioni", "agreable"];
var randomWord = words[Math.floor(Math.random() * words.length)];
var answerArray = [];
for (var i = 0; i < randomWord.length; i++) {
answerArray[i] = "_";
}
var ramainingLetters = randomWord.length;
//Game circle
while (ramainingLetters > 0) {
alert(answerArray.join(" "));
var guess = prompt("Guess a letter or press cancel to exit game");
if (guess === null) {
break;
} else if (guess.length !== 1) {
alert("Enter only one letter");
} else if (guess == guess.toUpperCase()) {
guess = guess.toLowerCase();
} else {
//renew game cycle
for (var j = 0; j < randomWord.length; j++) {
if (randomWord[j] === guess) {
answerArray[j] = guess;
ramainingLetters--;
}
}
}
// stop game
}
alert(answerArray.join(" "));
alert(" Cool! this word was " + randomWord);
You could easily solve your problem by converting the chosen word to uppercase and everytime the user puts in a letter, make that uppercase too.
var randomWord = words[Math.floor(Math.random() * words.length)].toUpperCase();
And convert your quess always to uppercase
guess = guess.toUpperCase();
This way everything is consistent.
If they type in a letter in lowercase its getting converted to uppercase and compared with the word also in uppercase.

How to retain spaces in input strings of Caesar Cipher for javascript?

This project is in javascript. I need to make sure the output retains spaces found in the string that is inputted into the function. The test I am trying to pass is calling the function for the term "hello world" with a shift of 13 letters. From this code, the result is "uryybjbeyq" and "uryyb jbeyq" is expected. I have identified I need an if statement which I have included already, but not sure what command I should include before the continue keyword that will insert the space needed. I am a beginner and this is only my 3rd project so any assistance would be appreciated. Please find the corresponding code below.
function caesarCypher(string, num){
// line below is the encrypted string we will return from the function
const letters = 'abcdefghijklmnopqrstuvwxyz';
let encryptStr = ""
// loop through every character in the inputted string
for(let i = 0; i < string.length; i++){
// line below will look up index of char in alphabet
let char = string[i];
/* if statement below is attempting to identify the space in the original string and then add a command that will add a space to the encrypted string then continue to work through the rest of the input */
if (char === " ") {
//need something to put on this line to insert space;
continue;
}
let index = letters.indexOf(char);
// index + num below will give us the letter 7 spots over
let newIndex = index + num;
// if statement below makes the function loop back around
if (newIndex > 26) {
newIndex = newIndex - 26;
}
let newChar = letters[newIndex];
encryptStr += newChar;
}
return encryptStr;
}
/* invoke the function with these parameters to pass the test-- expected result is 'uryyb jbeyq'*/
caesarCypher("hello world", 13)
You can add the white space like this:
encryptStr += " ";
I tried your code and I ran into an error... All letters were the same. Here is how I did it:
function caesarCypher(string, num){
let encryptStr = "";
for(let i = 0; i < string.length; i++){
let char = string[i];
if (char === " ") {
encryptStr += " "; //This adds a white space.
continue;
}
// If you want to keep the case of a letter, skip the
// "toLowerCase()" and extend the condition below.
let asciiCode = string.toLowerCase().charCodeAt(i) + num;
if(asciiCode > 122) {
asciiCode -= 26;
}
encryptStr += String.fromCharCode(asciiCode);
}
return encryptStr;
}

Function to capitalize first and last letter of each word not working

I created a function that given any string will return the string with the first and last letter of each word capitalized. So far it works in some words, not on others, can someone help me figure out why?
function Capitalize(str) {
var spl = str.split(" ");
var words = [];
for (let i = 0; i < spl.length; i++) {
//For every word
for (let j = 0; j < spl[i].length; j++) {
//For every letter in each word
var word = spl[i];
var size = spl[i].length;
var firstLetterCapital = word.replace(word[0], word[0].toUpperCase()); //Creates new array
var LastLetterCapital = firstLetterCapital.replace(
word[size - 1],
word[size - 1].toUpperCase()
);
}
words.push(LastLetterCapital);
}
console.log(words.join(" "));
}
Capitalize("hello there");
It works when I type : Capitalize("my name is john smith"), but not with Capitalize("hello there")
I know it's a complete mess and probably a very bad way to do it, but I started programming a month ago so give me a break :)
#symlink has already explained why it is "HellO ThEre" instead of "Hello TherE". He also has given a solution to explicitly target first and last character of the string. I have accomplished not much different than already posted by members, except for .. "may be" a little more explanation.
You can break the entire problem in these four steps.
Get all the words into an array.
Create a function, that takes each word and targets first and last character, changes it and returns the changed word.
Apply a mapping step using the function created above (in step 2) to the entire array of words (obtained in step 1).
Join the transformed array, obtained in step 3, using a blank space as a separator.
I have written two functions that accomplish this task. I am sorry for long name of functions. It helps me keep track of things in a complex program (especially when I am in a hurry!).
Step 2 function
function Capitalize_FirstAndLast_One_Word(word){
// Split the string in array for easy access/manipulation by indexing
Split_String = word.split("")
// Target the first word
Split_String[0] = Split_String[0].toUpperCase();
// Target the last word
Split_String[Split_String.length - 1] = Split_String[Split_String.length - 1].toUpperCase();
// Join the array into a single word
Joined_Back = Split_String.join("")
return Joined_Back;
}
Step 1, 3 and 4 function
function Capitalize_Entire_String(str){
Regular_Exp = new RegExp(/\w+/g);
//Below is step 1
MatchedArray = str.match(Regular_Exp);
//Below is step 3
ConvertedArray = MatchedArray.map(Capitalize_FirstAndLast_One_Word);
// Below is step 4
ReturnedString = ConvertedArray.join(" ");
console.log(ReturnedString);
return ReturnedString;
}
Now you have everything. You can use the function like below.
Capitalize_Entire_String("hello there");
Capitalize_Entire_String("hello there this is a test");
Hope this helps. I am sorry if this turned out to be a redundant answer for you.
Reason your code don't work is the use of replace(). replace() will always replace the first character found.
There is absolutely no reason to run a nested loop. You can achieve this using a single loop.
function cap(str){
let spl = str.split(' ');
for(let i = 0; i < spl.length; i++){
let temp = spl[i];
temp = temp[0].toUpperCase() + temp.slice(1)
temp = temp.slice(0,-1) + temp[temp.length - 1].toUpperCase();
spl[i] = temp;
}
return spl.join(' ');
}
console.log(cap("a quick brown fox"))
An easier way is to use map() and template strings.
const cap = str => str
.split(' ')
.map(x => (
x.length === 1 ?
x.toUpperCase() :
`${x[0].toUpperCase()}${x.slice(1,-1)}${x[x.length -1].toUpperCase()}`)
)
.join(' ')
console.log(cap("a quick brown fox"))
To simplify the function, you could split the string into an array, map each word to the desired format, and join it together into a string again.
function Capitalize(str){
return str.split(" ").map((word) => word.charAt(0).toUpperCase() +
(word.length > 2 ? word.substring(1, word.length - 1) : "") +
(word.length > 1 ? word.charAt(word.length - 1).toUpperCase() : "")).join(" ");
}
console.log(Capitalize("i want to capitalize first and last letters"));
Congrats on starting out programming...
You can use this to achieve what you want to do
function capitalizeFirstAndLastLetters (str) {
const words = str.split(" "); // Split the string into words
const modified = [];
for (const word of words) {
if (word.length <= 2) {
modified.push(word.toUpperCase()); // If the word less than 3 characters, the whole word is capitalized
continue;
}
var firstCapital = word[0].toUpperCase(); // word[0] gets the first index of the string (I.e. the first letter of the word)
var lastCapital = word.slice(-1).toUpperCase(); // The slice function slices a portion of the word. slice(-1) gets the last letter
var middlePart = word.slice(1, -1); // slice(1, -1) means start slicing from the second index (I.e. 1) and ignore the last index
modified.push(firstCapital + middlePart + lastCapital);
}
return modified.join(" "); // Join each element in the modified array with a space to get the final string with each words first and last letters capitalized
}
capitalizeFirstAndLastLetters("hello there I am a boy"); // "HellO TherE I AM A BoY"
Try this, it worked for hello world because I guess you want the outcome to be HellO TherE right?:
function capitalize(str) {
var spl = str.split(" ");
var words = [];
for (let i = 0; i < spl.length; i++) {
//For every word
let changedWord = "";
for (let j = 0; j < spl[i].length; j++) {
//For every letter in each word
if(j == 0 || j == spl[i].length - 1) {
changedWord += spl[i][j].toUpperCase();
} else {
changedWord += spl[i][j].toLowerCase();
}
}
words.push(changedWord);
console.log(words);
}
console.log(words.join(" "));
}
capitalize("hello there");
ALSO: Make your functions name start with lowercase letter. Thats just how it is. Starting with uppercase letters usually are Classes. Just a quick tip
Maybe this does what you want, don't want to change much from your code:
function Capitalize(str) {
var spl = str.split(" ");
var words = [];
for (let i = 0; i < spl.length; i++) {
var word = spl[i];
var firstCapital = word[0].toUpperCase(); // get first character after capitalizing
var lastCapital = word.slice(-1).toUpperCase(); // get last character after capitalizing
var midOriginal = word.slice(1, -1);
words.push(firstCapital + midOriginal + lastCapital) // concat 3 parts
}
console.log(words.join(" "));
}
Capitalize("hello there");
This expression:
var LastLetterCapital = firstLetterCapital.replace(
word[size - 1],
word[size - 1].toUpperCase()
);
Is replacing the first occurrence of the character "e" in "There" with an uppercase "E".
Explanation
The replace() function first translates the first param: word[size - 1] to the literal character "e", then replaces the first occurrence of that character with the uppercase "E", resulting in the string "ThEre".
Solution
Use a regular expression as your first parameter instead, to ensure that the last character is targeted, regardless of whether or not that same character shows up anywhere else in the word:
var LastLetterCapital = firstLetterCapital.replace(/.$/, word[size - 1].toUpperCase());
function Capitalize(str) {
var spl = str.split(" ");
var words = [];
for (let i = 0; i < spl.length; i++) {
//For every word
var word = spl[i];
var size = spl[i].length;
for (let j = 0; j < size; j++) {
//For every letter in each word
var firstLetterCapital = word.replace(word[0], word[0].toUpperCase()); //Creates new array
var LastLetterCapital = firstLetterCapital.replace(/.$/, word[size - 1].toUpperCase());
}
words.push(LastLetterCapital);
}
console.log(words.join(" "));
}
Capitalize("hello there");
This should do the trick:
function Capitalize(str) {
return str.replace(/(\b\w|\w\b)/g, l => l.toUpperCase())
}
console.log(Capitalize('i want to be capitalized in a rather strange way'))
Explanation:
In the regular expression /(\b\w|\w\b)/g, \b means "word boundary" and \w means "word character", so (\b\w|\w\b) matches a word boundary followed by a word character OR a word character followed by a word boundary (i.e. the first and last character of words).
The matches of this expression are then passed to the inline function l => l.toUpperCase() (which itself is the second argument to replace) that capitalizes the passed letter.
the string type is immutable, so why don't you try to convert the string to an array like y = word.split('') and do y[0] = word.charAt(0).toUpperCase() and then convert back to string with y.join('')

How to make a .replace loop in javascript?

I am currently trying to make a .replace function loop in javascript. What I am trying to do is replace a random character with a hyphen, but the part that I am struggling with is how to make it loop the replacing of the character to hyphen. Here is the code that I have so far:
var randHold;
var randomWord;
var randLetHold;
var dispWord;
var repLetHold;
var myWords = new Array("Spectrometer", "Bandwagonjghvyjh", "jvjyvyvilvyjlvyv",
"fruitjjyvtyvjv", "seventctcvtv", "weathertfhtcthc",
"undercfxdtfv"); // random letters to make words that have more than 10 letters
function level() {
randHold = parseInt((Math.random() * 6) + 1);//code to randomly pick a word from the above array
randomWord = myWords[randHold]; //code to call the random word from the array
randLetHold = (Math.random() * randomWord.length);//code to randomly pick a character from the random word chosen
repLetHold = randomWord.charAt(randLetHold);//code to call the random character
for (i = 1; i <= 3; i++) //loop to replace three random characters with a hyphen
{
dispWord = randomWord.replace(repLetHold," - ");//code to replace a random character with a hyphen
document.write(dispWord);//But all this does is display the word(with ONE hypenated character)three times.
}
}
Your code actually seems fine, the main issue is that you're declaring your random variables outside of your for loop. Doing this will only generate them once for the entire loop. Try this instead:
var dispWord;
var myWords = new Array("Spectrometer", "Bandwagonjghvyjh", "jvjyvyvilvyjlvyv",
"fruitjjyvtyvjv", "seventctcvtv", "weathertfhtcthc",
"undercfxdtfv"); // random letters to make words that have more than 10 letters
function level() {
for (i = 1; i <= 3; i++) //loop to replace three random characters with a hyphen
{
var randHold = parseInt((Math.random() * 6) + 1);//code to randomly pick a word from the above array
var randomWord = myWords[randHold]; //code to call the random word from the array
var randLetHold = (Math.random() * randomWord.length);//code to randomly pick a character from the random word chosen
var repLetHold = randomWord.charAt(randLetHold);//code to call the random character
dispWord = randomWord.replace(repLetHold," - ");//code to replace a random character with a hyphen
document.write(dispWord);//But all this does is display the word(with ONE hypenated character)three times.
}
}
For 3 random characters to be hyphenated in the word, you want something like this.
<div id="result"></div>
var myWords = ["Spectrometer", "Bandwagonjghvyjh", "jvjyvyvilvyjlvyv",
"fruitjjyvtyvjv", "seventctcvtv", "weathertfhtcthc",
"undercfxdtfv"]; // random letters to make words that have more than 10 letters
var randomWord;
var dispWord;
var repLetHold = [];
function uniqueCount(str) {
var unique = [];
Array.prototype.forEach.call(str, function (value) {
if (unique.indexOf(value) === -1) {
unique.push(value);
}
});
return unique.length;
}
function level() {
var randHold = Math.floor(Math.random() * myWords.length);
dispWord = randomWord = myWords[randHold];
if (uniqueCount(randomWord) > 2) {
var count = 0,
temp1,
temp2;
while (count < 3) {
temp1 = Math.floor(Math.random() * dispWord.length);
temp2 = dispWord.charAt(temp1);
if (temp2 !== "-" && repLetHold.indexOf(temp2) === -1) {
dispWord = dispWord.replace(new RegExp(temp2, "g"), "-");
repLetHold[count] = temp2;
count += 1;
}
}
}
document.getElementById("result").textContent = dispWord;
}
level();
console.log(randomWord, repLetHold);
on jsfiddle
If you use a regular expression, you can replace all instances at once with the g (global) flag. For example:
var str = "this is a mass Spectrometer, which is a Spectrometer to detect the spectra of different masses";
var replaced = str.replace(/Spectometer/g, 'something');
// "this is a mass something, which is a something to detect the spectra of different masses";
Just keep in mind that some characters must be escaped inside regular expressions.
http://jsfiddle.net/zt8mp/
If i got the question right:
randomWord.replace(new RegExp(repLetHold,'g')," - ")
replaces all occurences of repLetHold (as long as it is not made of special regex characters)

Categories