JavaScript Hangman, place the Letters - replace

so I have come quiet far in my Hangman Game, but apparently im stuck with placing the Letters when a letter gets clicked.
I made 2 Variables, one of them is "word" which saves the word that has to be guessed.
And the other one is "hiddenword" which is basically the same length as "word" but the letters are replaced with underscores as you can see here:
function checkLetter(buchstabe) {
if(word.includes(buchstabe)) {
hiddenWord = hiddenWord.replace(/_/g, buchstabe);
console.log("right");
document.getElementById("response").innerHTML = "Great guess!";
}
else {
console.log("wrong")
lives = lives -1;
document.getElementById("response").innerHTML = "Sorry, the letter you chose is not part of the hidden word.";
}
}
Now my 2 Variables I told you about:
let word = "hallo123";//I set the variable to something random, because it randomly changes on start
let lives = 8; //Ignore this one, its just how many tries the user has left.
let hiddenWord;//and I didnt declare this one yet, because it will be only underscores
Example of what my Hangman looks like
So my plan is, if someone clicks a letter (here a example of my clickable letters aka divs) and its actually part of the word, it will replace the specific underscore with that letter.
<div class="layout" onclick="checkLetter('a');">a</div>
<div class="layout" onclick="checkLetter('b');">b</div>
<div class="layout" onclick="checkLetter('c');">c</div>
<div class="layout" onclick="checkLetter('d');">d</div>
<div class="layout" onclick="checkLetter('e');">e</div>
<div class="layout" onclick="checkLetter('b');">b</div>
<div class="layout" onclick="checkLetter('c');">c</div>
<div class="layout" onclick="checkLetter('d');">d</div>
<div class="layout" onclick="checkLetter('e');">e</div>

Okay! So after looking at your PasteBin I can see it looks like the #wordToGuess div at the bottom of the image you posted is a div containing x amount of underscores with a preceding space (" _") depending on the length of the word the user needs to guess.
When the checkLetter(buchstabe) function is fired and meets the if(word.includes(buchstabe)) condition why don't you do:
// HTML
<div id="wordToGuess"> _ _ _</div>
// JS
var buchstabe = 'a';
var currentHiddenWord = document.getElementById('wordToGuess').textContent;
var newHiddenWord = currentHiddenWord.replace(' _', buchstabe);
document.getElementById('wordToGuess').textContent = newHiddenWord;
So your function would become:
function checkLetter(buchstabe) {
if(word.includes(buchstabe)) {
hiddenWord = hiddenWord.replace(/_/g, buchstabe);
console.log("right");
document.getElementById("response").innerHTML = "Great guess!";
// Update underscores
var currentHiddenWord = document.getElementById('wordToGuess').textContent;
var newHiddenWord = currentHiddenWord.replace(' _', buchstabe);
document.getElementById('wordToGuess').textContent = newHiddenWord;
}
else {
console.log("wrong")
lives = lives -1;
document.getElementById("response").innerHTML = "Sorry, the letter you chose is not part of the hidden word.";
}
}
The code, upon successful guess, now sets the current text from wordToGuess div as a variable called currentHiddenWord, replaces the first instance of " _" with the correctly guessed letter (buchstabe) and sets that as a variable called newHiddenWord, and then replaces the text inside the wordToGuess div the value of the newHiddenWord variable.
Does that achieve what you need?

Related

Is it possible to match a nested pair with regex?

Im attempting to parse some BBCode with regex, but the nested structures are giving me a headache
What I'm trying to parse is the following:
[COLOR="Red"]Red [COLOR="Green"]Green[/COLOR][/COLOR]
I've come up with the following pattern, which I need to deal with the quotation marks around the color attribute, but it only matches the first leading COLOR and the first closing COLOR. Its not matching in a proper nested arrangement
\[COLOR=(\"?)(.*?)(\"?)]([\s\S]*?)\[\/COLOR\]\
Its being done in dart, as follows, but really I believe the problem might be with my regex pattern rather then the dart implementation
text = text.replaceAllMapped(RegExp(r'\[COLOR=(\"?)(.*?)(\"?)]([\s\S]*?)\[\/COLOR\]', caseSensitive: false, multiLine: true), (match) {
return '<font style="color: ${match.group(2)}">${match.group(4)}</font>';
});
Matching braces (of any kind) are not regular. It's known to be a problem which is context free (can be solved by a stack machine or specified by a context free grammar), but not regular (can be solved by a finite state machine or specified by a regular expression).
While the commonly implemented "regular expressions" can do some non-regular things (due to backreferences), this is not one of those things.
In general, I'd recommend using a RegExp to tokenize the input, then build the stack based machine yourself on top.
Here, because it's simple enough, I'd just match the start and end markers and replace them individually, and not try to match the text between.
var re = RegExp(r'\[COLOR="(\w+)"\]|\[/COLOR\]');
text = text.replaceAllMapped(re, (m) {
var color = m[1]; // The color of a start tag, null if not start tag.
return color == null ? "</span>" : ​"<span style='color:$color'>";
});
If you want to check that the tags are balanced, we're back to having a stack (in this case so simple it's just a counter):
var re = RegExp(r'\[COLOR="(\w+)"\]|\[/COLOR\]');
var nesting = 0;
text = text.replaceAllMapped(re, (m) {
var color = m[1];
if (color == null) {
if (nesting == 0) {
throw ArgumentError.value(text, "text", "Bad nesting");
}
nesting--; // Decrement on close tag.
return "</span>";
}
nesting++; // Increment on open-tag.
return ​"<span style='color:$color'>";
});
if (nesting != 0) {
throw ArgumentError.value(text, "text", "Bad nesting");
}

Using java script In a string `,"'/\{}[]() this character presents i need to show validation message. otherwise I need to allow next process [duplicate]

This question already has answers here:
Is there a RegExp.escape function in JavaScript?
(18 answers)
Check for special characters in string
(12 answers)
Closed 2 years ago.
In my application is one of the fields I want to validate some special characters like `,"'/{}
If User-provided string in case character `,"'/{} matches I want to throw a validation message to the user. For that, I am trying to add validation to the input using regex. But I did get exact regex expression for selected special characters.
Please let me know anyone how to make our own regex or how to validate selected special characters.
function validateSpecialChars() {
var address = document.getElementById('address');
if (address.value == "") {
alert("Address must be filled out");
return false;
} else if (document.getElementById('address').value.length > 150) {
alert("Address cannot be more than 150 characters");
return false;
} else {
var regex = /[-\/\\^$*+?.()|[\]{}]/;
var isValid = regex.test(address);
if (!isValid) {
alert("Contains Special Characters.");
}
}
}
Address: <input type="text" id="address"/>
<br/>
<br/>
<input type="button" value="Submit" onclick="validateSpecialChars()"/>

How can I replace a character in an OnChanging event using Regex and keeping the caret at the end of the EditText in ExtendScript?

I need to type in a TextBox and see instantly the result in a StaticText. In order to avoid " " (space character), I'm replacing it using Regex.
It is working but the cursor moves to the left every time when a space key is pressed. It is being replaced by "_" but because the cursor moves to the first position in my EditText box, it makes impossible to proceed typing fluently.
editText.onChanging = function(){
if (this.text.match(/\s*$/i)) {
this.text = this.text.replace(/ /g, "_");
}
staticText.text = this.text;
}
How can I type in that edittext, replacing every space character and keeping the cursor at the end of the line?
I have found the solution.
To replace a character using Regex and keep the caret at the end of the line, you should save the result from the replacement in a variable, clear the text box and use a textselection to bring it back to your edittext box.
editText.onChanging = function(){
if (this.text.match(/\s*$/i)) {
var text = this.text.replace(/ /g, "_");
this.text = "";
this.textselection = text;
}
staticText.text = this.text;
}

filtering string to keep a-z and space marks c++?

I'm using QT to design a dictionary to sort a word/string of words entered by a user.
In 'silent mode' I want the user to only enter a single word (a-z) or a string of words (a-z, separated by a space).
I'm really having trouble trying to filter out non-alphabetical while keeping whitespaces!
if(ui->silentButton->isChecked())
{
if(userWord == " ") // if user enters just a space
{
QMessageBox messageBox;
messageBox.critical(0,"Error!","Please enter a valid word to continue...");
messageBox.setFixedSize(500,200);
}
else if(userWord == "") // if user enters nothing
{
QMessageBox messageBox;
messageBox.critical(0,"Error!","Please enter a valid word to continue...");
messageBox.setFixedSize(500,200);
}
else if (userWord.contains(" ")) // if user enters a string that contains a space
{
QStringList Splitstring = userWord.split(QRegExp("\\W"), QString::SkipEmptyParts);
for(int i = 0; i < Splitstring.size(); ++i)
{
MyTree->insert(MyTree->getRoot(), Splitstring.at(i).toLocal8Bit().constData());
}
}
else
{
MyTree->insert(MyTree->getRoot(),userWord);
}
Unfortunately this does not work as it still allows the user to enter a non-alphabetical or a string containing a non-alphabetical i.e. } a} a b c}
I want it to bring up an error when they enter anything at all that is non alphabetical. I have tried using if(userWord.contains(QRegExp("\\w"))) however this also filters out spaces too.
Can anyone point me in the right direction?
if(ui->silentButton->isChecked())
{
if(userWord.trimmed() == "") // if user enters just a space or nothing
{
QMessageBox messageBox;
messageBox.critical(0,"Error!","Please enter a valid word to continue...");
messageBox.setFixedSize(500,200);
}
else if (userWord.contains(" ")) // if user enters a string that contains a space
{
QStringList splitString { userWord.split(QRegularExpression("[^a-z]"), QString::SkipEmptyParts) };
for(int i = 0; i < splitString.size(); ++i)
{
MyTree->insert(MyTree->getRoot(), splitString.at(i).toLocal8Bit().constData());
}
}
else
{
MyTree->insert(MyTree->getRoot(),userWord);
}
}
This should do the trick for you.
I've made some improvements like adding trimmed() because that will make it work for both input errors, as well as specifying more than one space and adjusted the regular expression to exclude what you don't need.
I've replaced QRegExp, because QRegularExpression should be used instead as it is faster (new).
Variables should start with lowercase, therefore the splitString renaming.
Now the result for this input:
"test } awa} fa baad cdda c}"
is:
test
awa
fa
baad
cdda
c
As #deW1 pointed out you should be using QRegularExpression for performance issues and try using this for regular expression
/^([a-zA-Z]+( )?[a-zA-Z]+)*$/
This will allow blank spaces separated values.

Remove tabs with more than 5 in a line

I am trying to extract a snippet out of a sourcecode from a website and now I want to delete all the spaces and tabs before the tags in each line. So I copied the string to a char and now I am checking each character with isspace (also tried '\t' and ' ') each line till there are some other chars like '<' doesn't matter which one while counting how much spaces and tabs there are. Subsequently I create another char and write the separator(line) to it but there I just skip the spaces (with [chars+i]). This method works pretty good but the problem is if there are more than 5 tabs then it just don't work properly. I have absolutely no idea where the fault is.
for(int i = 0;i < lines;i++){
getline(codefile, buf);
char *separator = new char[buf.size()+1];
separator[buf.size()] = 0;
memcpy(separator,buf.c_str(),buf.size());
int chars = 0;
for(int j = 0; j <= sizeof(separator); j++){
if(isspace(separator[j])){
chars++;
}
else{
break;
}
}
char *newbuf= new char[buf.size()-chars+1];
newbuf[buf.size()-chars] = 0;
for(int k = 0; k <= buf.size()-chars+1; k++){
newbuf[k] = separator[chars+k];
}
if(i > lcounter){
cout << newbuf << i << endl;
}
}
Here is the snippet of the sourcecode from the website. You can see it at the image tag, at the closing figure tag and the p tag. They have more than 5 tabs (sorry I had to censor it).
<div class="xxx">
<article class="xxx" data-id="0">
<a href="link" class="tile" style="background-image:url('x.jpg');background-position:left center" data-more="<a href=x" data-clicks="<i class="fa fa-eye"></i>" data-teaserimg="x.jpg">
<time datetime="2015">
<span>2015</span>
</time>
<h1 class="title">
<span>x</span>
</h1>
<div class="x">x</div>
<div class="x">x</div>
<div class="x">
<figure class="x">
<img src="x.jpg" width="1" height="1" alt="">
</figure>
<p>
<strong>x</strong>xxx
</p>
</div>
</a>
Sorry I can't post a picture and I hope it is understandable.
sizeof(separator) should be strlen(separator)
sizeof is the size of the separator variable, not the length of the string. Since separator is a char* this is four bytes. Now do you see why your code doesn't work when you have more than five tabs?
And as others have pointed out there really is no reason to copy the string to the separator array. Why not just examine the characters where they are? isspace(buf[j]) works just as well as isspace(separator[j]).