visit
A few months ago, I watched a video (in Spanish) about creating a Wordle using AI.
How to Develop a Wordle Game using TDD in 25 Minutes
/* create a table with 6 rows and 5 columns */
/* create a table with 6 rows and 5 columns */
var table = document.createElement('table');
table.setAttribute('border','1');
for (var i = 0; i < 6; i++) {
var row = document.createElement('tr');
for (var j = 0; j < 5; j++) {
var cell = document.createElement('td');
cell.innerHTML = '<b>' + (i * 5 + j) + '</b>';
row.appendChild(cell);
}
table.appendChild(row);
}
document.body.appendChild(table);
This was unexpected.
A table is not an HTML Table.
Both the author and Javascript code generator think about visual elements.
What is more, variables have very bad names like i and j
We started with an abbreviation code smell.
/* Cells are grey, squared of 80px 80px */
/* Cells are grey, squared of 80px 80px */
var cells = table.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
cells[i].style.backgroundColor = '#ccc';
cells[i].style.width = '80px';
cells[i].style.height = '80px';
}
Moving on with accidental UI style definition, the generator stylized the cells
/* cells are half size */
/* cells are half size */
for (var i = 0; i < cells.length; i++) {
cells[i].style.width = '40px';
cells[i].style.height = '40px';
}
Impressive. It has context and is aware meaning of halving.
/* there are no borders */
/* there are no borders */
table.style.border = 'none';
/* Cells have no border */
/* Cells have no border */
for (var i = 0; i < cells.length; i++) {
cells[i].style.border = 'none';
}
Notice we have 5 steps and we have no idea what is a Wordle, we are just playing around with the User Interface.
/* text is centered */
/* Text is centered */
for (var i = 0; i < cells.length; i++) {
cells[i].style.textAlign = 'center';
}
/* text is white*/
/* text is white */
for (var i = 0; i < cells.length; i++) {
cells[i].style.color = 'white';
}
/* text is font Helvetica and bold */
/* text is font Helvetica and bold */
for (var i = 0; i < cells.length; i++) {
cells[i].style.fontFamily = 'Helvetica';
cells[i].style.fontWeight = 'bold';
}
Seriously? No actual game yet?
/* Cells have no padding */
/* cells have no padding */
for (var i = 0; i < cells.length; i++) {
cells[i].style.padding = '0px';
}
/* cells are empty */
/* cells are empty */
for (var i = 0; i < cells.length; i++) {
cells[i].innerHTML = '';
}
Following Carlos's Instructions, we arrived at a ready-to-use User Interface.
No tests, no business rules. yet.
/* add an input text field under the table */
/* add an input text field under the table */
var input = document.createElement('input');
input.setAttribute('type','text');
input.setAttribute('placeholder','Write Something');
document.body.appendChild(input);
/* add margin reduce text field width to 100px */
/* add margin reduce text field width to 100px */
input.style.margin = '10px';
input.style.width = '100px';
/* add a button by the field with the 'tick' character. The button must have an id named 'validate' */
/*add a button by the field with the 'tick' character. The Button must have un id named 'validate' */
var button = document.createElement('button');
button.innerHTML = '✓';
button.id = 'validate';
document.body.appendChild(button);
We think ahead knowing we will need an accidental and implementation id.
It is fine. As Carlos comments in his video, we need to
We are creating a button with a special identifier since we guess it might be useful later.
/* add another button with id 'remove' and the 'x' character as label */
/* add another button with id 'remove' and the 'x' character as label */
var button = document.createElement('button');
button.innerHTML = '✗';
button.id = 'remove';
document.body.appendChild(button);
/* Center box text */
/* center box text */
input.style.textAlign = 'center';
/* we cannot write more than 5 characters in the input field */
/* we cannot write more than 5 characters in the input field */
input.setAttribute('maxlength','5');
/* create variable named 'rowIndex' starting at 0 */
/* create variable named 'rowIndex' starting at 0 */
var rowIndex = 0;
This is when black magic comes in.
We need to think ahead.
There's surely a better place to program a wordle. Stay tuned!
/* when entering text in the box, convert it to uppercase */
/* when entering text in the box, convert it to uppercase */
input.addEventListener('keyup', function(event) {
event.target.value = event.target.value.toUpperCase();
});
We need to rephrase the following instruction several times until we get the desired behavior.
We have immediate feedback, so we are happy.
/* after writing on the text field, the value from every character will be written on each cell of the selected row */
/* after writing on the text field,
the value from every character will be writen
on each cell of the selected row */
input.addEventListener('keyup', function(event) {
var text = event.target.value;
var cells = document.querySelectorAll('td');
for (var i = 0; i < cells.length; i++) {
if (i >= rowIndex * 5 && i < (rowIndex + 1) * 5) {
cells[i].innerHTML = text.charAt(i - rowIndex * 5);
}
}
});
/* store in a variable the secret word 'PAPER' */
/* store in a variable the secret word 'PAPER' */
var secretWord = 'PAPER';
/* When clicking the 'validate' button, we need to check if the characters of the chosen row are included in the secret word. If they are, the cell should be marked as yellow */
/* When clicking validate button,
we need to check if the characters of the chosen row
are included in the secret word.
If they are, the cell should be marked as yellow (#edc953) */
document.getElementById('validate').addEventListener('click', function(event) {
var cells = document.querySelectorAll('td');
for (var i = 0; i < cells.length; i++) {
if (i >= rowIndex * 5 && i < (rowIndex + 1) * 5) {
if (secretWord.indexOf(cells[i].innerHTML) >= 0) {
cells[i].style.backgroundColor = '#edc953';
}
}
}
});
/* if character is in right position, cell should be in green (#a9e54e) */
// Step 23
// if character is in right position, cell should be in green (#aedb95)
document.getElementById('validate').addEventListener('click', function(event) {
for (var i = 0; i < cells.length; i++) {
if (i >= rowIndex * 5 && i < (rowIndex + 1) * 5) {
if (secretWord.charAt(i - rowIndex * 5) === cells[i].innerHTML) {
cells[i].style.backgroundColor = '#aedb95';
}
}
}
});
/*when clicking validate button, rowIndex variable increases */
/* when clicking validate button, rowIndex variable increases */
document.getElementById('validate').addEventListener('click', function(event) {
rowIndex++;
});
/* when clicking validate button, rowIndex variable increases */
// Step 25
// when pushing remove button, every letter is erased, rowIndex goes to 0 and all cells turn gray
document.getElementById('remove').addEventListener('click', function(event) {
var cells = document.querySelectorAll('td');
for (var i = 0; i < cells.length; i++) {
cells[i].innerHTML = '';
cells[i].style.backgroundColor = '#ccc';
}
rowIndex = 0;
});
/* save a collection of the following words: tools, super, faker, catch, cried in uppercase */
// Step 26
/* save a collection of the following words: tools, super, faker, catch, cried in uppercase */
var words = ['TOOLS', 'SUPER', 'FAKER', 'CATCH', 'CRIED'];
/* when pressing remove, chose randomly the secret word from the words collection */
// Step 27
/* when pressing remove, chose randomly the secret word from the words collection */
document.getElementById('remove').addEventListener('click', function(event) {
var randomIndex = Math.floor(Math.random() * words.length);
secretWord = words[randomIndex];
});
The model might not survive many business changes.
Maybe the TDD version does.
The technology is amazing. We can build an entire User Interface providing natural language commands. Stay tuned for Wordle evolution on the following articles.
Also published .