Stuck on my first program/game, Hangman - javascript

I'm working on a hangman game in jQuery. This is my first time working with writing my own code/program from scratch with no references to other peoples code (GitHub).
I created a "Start Game" button that starts the Hangman game. It will then grab a random word from an array I created, 'wordBank' and store it into a variable, 'word'. I use word.length and assign it to variable, 'wordLength'. I was not sure how to convert the wordLength (ex: 6 characters in the word) to 6 blank underscores: _ _ _ _ _ _
I was not sure if that should be part of a separate function either. I'm pretty good with HTML/CSS, but now I'm trying to learn to program and have been stuck the past day on this (I started it yesterday). I appreciate anyone who gives me advice. My code is below. Thanks.
var wordBank = ['apple', 'orange', 'peanut'];
// grab random word from array when user clicks start
function startGame() {
("#start").click(function(){
var word = wordBank[Math.floor(Math.random()*wordBank.length)];
var wordLength = word.length;
// convert wordLength into an underscore for each character
});
}
startGame();

You have several ways. (For each letter you get underscore and white space)
One is to use replace with regexp:
// Regex way.
var word = "abcd123456";
var userscores = word.replace(/.{1}/g, "_ ");
Other is to build underscores from word length:
// Build way.
var word = "abcd123456";
var wordLength = word.length;
var underscores = "";
for(i=0; i<wordLength; i++) {
underscores = underscores + "_ "
}
// now variable underscores has the underscores.
Happy gaming :)

First: I would keep it within the same function.
Second: I would just do a for loop and print a div with a class that has a
.underscore{
border-bottom: 2px solid black;
width:30px;
}
Like this:
var underscores ="";
for(var i=0;i<wordLength;i++){
underscores+= "<div class='underscore'></div>";
}
Hope this helps!

I think you are looking for a basic for loop, such as the following:
for (i=0;i<(word.length);i++) {
document.write("_ "); //or similar function
}
The above will output a number of underscores equal to your word length. Adjust this if you want to store them as a variable or other such function. I would consider assigning each letter in the string to an array with the value equalling "_ " by default, then changing the value to the actual letter when they guess correctly, or some other similar means, but abstract stabs at your game logic are beyond the scope of your question as it were posed.

Why don't you just store an underscore for each letter inside an array? That way you could access each underscore by it's index and decide how to display them later.
var result = [];
for(var i = 0; i < wordLength; i++){
result.push('_');
}
result.toString(); //returns _,_,_,_,_,_
result[0] //returns the first underscore
result[5] //returns the last underscore
result[2] = 'A'; // Replaces the third underscore with the letter 'A' (zero based)
result.toString(); //returns "_,_,A,_,_,_"
Later on, when you want to display the contents of the array you could just iterate it again. Something like this:
for(var i = 0; i < wordLength; i++) {
document.write(result[i] + ' ');
}

Related

Randomize words in a sentence / string with Javascript and list all the variations

i've searched a lot but havent found exactly what i am trying to do. But here goes:
I want to input a sentence / string in javascript and output all randomized variations of that sentence.
Example
input: 'my test sentence 123'
output: 'test my sentence 123', 'my sentence 123 test', '123 sentence my test', and so on, and stop when theres no variations left.
I've split the sentence into words in an array, but im a bit stuck on how to proceed to randomize the words and join them to new sentences in a list or new array.
code so far:
let str = "my test sentence 123";
let words = str.split(" ");
for (let i = 0; i < words.length - 1; i++) {
words[i] += " ";
}
A bit stuck on how to proceed. My thought process is: I have the words variable / array, but i need to randomize each word, output new strings but also check the existing ones so i don't duplicate any of them.
Thanks for all help i can get to learn more :)
Check this code
var phrase = "my test sentence 123";
var words = phrase.toLowerCase().match(/\w+/g);
var wordsCopy = phrase.toLowerCase().match(/\w+/g);
// First of all I loop each word
words.forEach(function(word, index){
// Random word going to contain my randomized word
var randomWord = word;
// Copy the entire phrase
var wordsMissing = wordsCopy.slice();
// Remove the current word
wordsMissing.splice(wordsCopy.indexOf(word), 1);
// Loop tru my missing words
for (var i = 0; i < wordsMissing.length; i++) {
// Set my random word with the rest of the words
randomWord += " " + wordsMissing.join(" ");
// get the first word and send to the final of my original phrase
var firstWord = wordsMissing.splice(0,1)[0];
wordsMissing.push(firstWord);
// Log my random word
console.log(randomWord);
// Reset random word to the initial word
randomWord = word;
}
});
As you are on Javascript, using .join(' ') will be easier to create a string from an array.
Then, there is a lot of solutions to achieve what you want to do, the easier way would be a foreach on foreach, where you simply test if the string you created already exists in the array.
It would be the easy way, but the more you put items, the more you will need power, so use this solution wisely.
Something like this can work :
var stringToSplit = 'I want to split this'
var stringSplitted = stringToSplit.split(' ')
var arrayOfNewStrings = []
stringSplitted.forEach(word => {
var arrayOfString = []
arrayOfString.push(word)
stringSplitted.forEach(otherWord => {
if(word !== otherWord)
arrayOfString.push(otherWord)
})
arrayOfNewStrings.push(arrayOfString)
});
console.log(arrayOfNewStrings)
You then need to add a layer of for/foreach to make it for every words (this will work only for the first one), and to test if the array already exists in ArrayOfNewStrings to prevent duplication.

Splitting sentence string into array of words, then array of words into arrays of characters within the array of words

I'm working through a problem on freecodecamp.com, and I want to see whether my code so far is doing what I think it is doing...
function titleCase(str) {
var wordArr = str.split(' '); // now the sentences is an array of words
for (var i = 0; i < wordArr.length; i++) { //looping through the words now...
charArr = wordArr[i].split(''); //charArr is a 2D array of characters within words?
return charArr[1][1];
}
}
titleCase("a little tea pot"); // this should give me 'i', right?
Again, this is just the beginning of the code. My goal is to capitalize the first letter of each word in the parameter of titleCase();. Perhaps I'm not even going about this right at all.
But... is charArr on line 4 a multidimensional array. Did that create [['a'],['l','i','t','t','l','e'],['t','e','a','p','o','t']]?
In addition to ABR answer (I can't comment yet) :
charArr is a one-dimensional array, if you want it to be a 2d array you need to push the result of wordArr[i].split(''); instead of assigning it.
charArr.push(wordArr[i].split(''));
And don't forget to initialize charArr as an empty array
Few issues :
1. Your return statement will stop this after one iteration.
2. If one of the words have fewer then 2 letters (like the first one in your example, which is 'a') - you will get an exception at charArr[1][1].
Other then that, it is mostly ok.
It would probably help you to download a tool like firebug and test your code live...
You can do the following:
function titleCase(str) {
var newString = "";
var wordArr = str.split(' ');
for (var i = 0; i < wordArr.length; i++) { //looping through the words now...
var firstLetter = wordArr[i].slice(0,1); // get the first letter
//capitalize the first letter and attach the rest of the word
newString += firstLetter.toUpperCase() + wordArr[i].substring(1) + " ";
}
return newString;
}
Also you need to remove the return statement in your for loop because the first time the for loop goes over the return statement, it will end the function and you will not be able to loop through all the words
Here you can learn more about string.slice() : http://www.w3schools.com/jsref/jsref_slice_string.asp

Advice on using word count javascript

I created a function that should generate a random paragraph, but I would like to get some advice on how can I display the number of times each word in the paragraph is used, once the button is clicked.... do you use something like a counter variable?
<html>
<head>
<title></title>
<script type="text/javascript">
<!--
var article = ["the", "be", "let", "done", "any"];
var noun = ["boy", "girl", "dog", "town", "car"];
var verb = ["drove","jumped", "ran", "walked", "skipped"];
Use regular expression match, and get the length of the result for each searched word.
For example:
var countThe = sentence.match(/the/g).length;
update: More generally:
function countOccurances(sentence, word){
var reg = RegExp(word,'g');
return sentence.match(reg).length
}
With a test:
var sentence = "This is the sentence that we are going to look in for testing -- not the real thing." ;
alert(countOccurances(sentence, "the"))
This will count the frequency of all words in a string.
function countWords(s) {
var a = s.match(/\w+/g);
var counts = {};
for(var i = 0; i < a.length; i++) {
var elem = a[i];
if(!counts[elem]) counts[elem] = 1;
else counts[elem]++;
}
return counts;
}
You can use javascript string.match is probably the easiest method.
function checkFor(wordsArray,inString){
returnObject={};
for(var i=0;i<wordsArray.length;i++){
returnObject[wordsArray[i]]=inString.match(new RegExp("([^A-Za-z]|^)"+wordsArray[i]+"([^A-Za-z]|$)","gi")).length
}
return returnObject;
}
checkFor(["hi","peter"],"I would like to say to you Peter, hi howdy hello, I think hi is the best of these greetings for you");
Returns Object {hi: 2, peter: 1};
Then just run this on each of the arrays with the sentance as the inString argument
EDIT:
To explain what this does,
It is a function where you can pass in an array of words to look for and it will output an associative array or object (JavaScript doesn't distinguish between the two) of the counts of those values
The function loops through each element in the words array
It then runs the regular expression /([^A-Za-z]|^)wordGoesHere([^A-Za-z]|$)/gi which is a bit complicated I admit
the regular expression checks for "WordGoesHere" and makes sure that is is a word not just part of another word, the ([^A-Za-z]|^) checks that the character before the word is not in the set A-Z or is the start of the string so basically allows spaces, commas, full stops and any other punctual thing you can imagine. ([^A-Za-z]|$) does the same except it checks for the end of the string
the gi is a flag stating a global search (don't just stop after the first match) and case insensitive
This site I find is invaluable for testing regular expressions

Count number of words in string using JavaScript

I am trying to count the number of words in a given string using the following code:
var t = document.getElementById('MSO_ContentTable').textContent;
if (t == undefined) {
var total = document.getElementById('MSO_ContentTable').innerText;
} else {
var total = document.getElementById('MSO_ContentTable').textContent;
}
countTotal = cword(total);
function cword(w) {
var count = 0;
var words = w.split(" ");
for (i = 0; i < words.length; i++) {
// inner loop -- do the count
if (words[i] != "") {
count += 1;
}
}
return (count);
}
In that code I am getting data from a div tag and sending it to the cword() function for counting. Though the return value is different in IE and Firefox. Is there any change required in the regular expression? One thing that I show that both browser send same string there is a problem inside the cword() function.
[edit 2022, based on comment] Nowadays, one would not extend the native prototype this way. A way to extend the native protype without the danger of naming conflicts is to use the es20xx symbol. Here is an example of a wordcounter using that.
Old answer: you can use split and add a wordcounter to the String prototype:
if (!String.prototype.countWords) {
String.prototype.countWords = function() {
return this.length && this.split(/\s+\b/).length || 0;
};
}
console.log(`'this string has five words'.countWords() => ${
'this string has five words'.countWords()}`);
console.log(`'this string has five words ... and counting'.countWords() => ${
'this string has five words ... and counting'.countWords()}`);
console.log(`''.countWords() => ${''.countWords()}`);
I would prefer a RegEx only solution:
var str = "your long string with many words.";
var wordCount = str.match(/(\w+)/g).length;
alert(wordCount); //6
The regex is
\w+ between one and unlimited word characters
/g greedy - don't stop after the first match
The brackets create a group around every match. So the length of all matched groups should match the word count.
This is the best solution I've found:
function wordCount(str) {
var m = str.match(/[^\s]+/g)
return m ? m.length : 0;
}
This inverts whitespace selection, which is better than \w+ because it only matches the latin alphabet and _ (see http://www.ecma-international.org/ecma-262/5.1/#sec-15.10.2.6)
If you're not careful with whitespace matching you'll count empty strings, strings with leading and trailing whitespace, and all whitespace strings as matches while this solution handles strings like ' ', ' a\t\t!\r\n#$%() d ' correctly (if you define 'correct' as 0 and 4).
You can make a clever use of the replace() method although you are not replacing anything.
var str = "the very long text you have...";
var counter = 0;
// lets loop through the string and count the words
str.replace(/(\b+)/g,function (a) {
// for each word found increase the counter value by 1
counter++;
})
alert(counter);
the regex can be improved to exclude html tags for example
//Count words in a string or what appears as words :-)
function countWordsString(string){
var counter = 1;
// Change multiple spaces for one space
string=string.replace(/[\s]+/gim, ' ');
// Lets loop through the string and count the words
string.replace(/(\s+)/g, function (a) {
// For each word found increase the counter value by 1
counter++;
});
return counter;
}
var numberWords = countWordsString(string);

Splitting a String by an Array of Words in Javascript

I'm taking some text and want to split it into an array. My goal is to be able to split it into phrases delimited by stopwords (words ignored by search engines, like 'a' 'the' etc), so that I can then search each individual phrase in my API. So for example: 'The cow's hat was really funny' would result in arr[0] = cow's hat and arr[1] = funny. I have an array of stopwords already but I can't really think of how to actually split by each/any of the words in it, without writing a very slow function to loop through each one.
Use split(). It takes a regular expression. The following is a simple example:
search_string.split(/\b(?:a|the|was|\s)+\b/i);
If you already have the array of stop words, you could use join() to build the regular expression. Try the following:
regex = new RegExp("\\b(?:" + stop_words.join('|') + "|\\s)+\\b", "i");
A working example http://jsfiddle.net/NEnR8/. NOTE: it may be best to replace these values than to split on them as there are empty array elements from this result.
This does a case insensitive .split() on your keywords, surrounded by word boundries.
var str = "The cow's hat was really funny";
var arr = str.split(/\ba\b|\bthe\b|\bwas\b/i);
You may end up with some empty items in the Array. To compact it, you could do this:
var len = arr.length;
while( len-- ) {
if( !arr[len] )
arr.splice( len, 1);
}
Quick and dirty way would be to replace the "stop word" strings with some unique characters (e.g. &&&), and then split based on that unique character.
For example.
var the_text = "..............",
stop_words = ['foo', 'bar', 'etc'],
unique_str = '&&&';
for (var i = 0; i < stop_words.length; i += 1) {
the_text.replace(stop_words[i], unique_str);
}
the_text.split(unique_str);

Categories