Я расшифровываю инструкции по созданию рабочего слова, используя естественный язык

TL;DR: Как создать Wordle без программирования

Несколько месяцев назад я посмотрел видео (на испанском языке) о создании Wordle с использованием ИИ.


В видео использовался OpenAI Codex для создания Wordle.

Он был разработан его удивительным хозяином Карлос Сантана.

Если вы понимаете испанский, я предлагаю вам подписываться научиться удивительным вещам.

Ранее я написал статью о том, как написать Wordle с использованием TDD в январе.

Решил повторить и сделать выводы.

Поэтому я следовал тем же инструкциям хозяина (перевел их на английский и добавил свои комментарии).

Вы можете следовать этому пошаговому руководству на сайте Codex Playground.

Жаль, что замечательный учебник Карлоса написан на испанском языке, и англоговорящие люди его пропускают.

Я переведу его шаги на английский.


0. Настройка

Перейти к Сайт Open AI

Создайте учетную запись, если вы еще этого не сделали.

Перейти к Песочница Codex Javascript

Песочница


1. Первая инструкция (UI?)


/* 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);
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 1

Это было неожиданно.

Таблица не является таблицей HTML.

И автор, и генератор кода Javascript думают о визуальных элементах.

Более того, переменные имеют очень плохие имена, такие как i и j.

Мы начали с аббревиатуры кода запах.


2. Стиль ячеек (пользовательский интерфейс)


/* 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';
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 2

Переходя к случайному определению стиля пользовательского интерфейса, генератор стилизовал ячейки.


3. Ячейки половинного размера (UI)


/* 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';
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 3

Впечатляющий. Он имеет контекст и осознает значение деление пополам.


4. Нет границ таблицы (пользовательский интерфейс)


/* there are no borders */

/* there are no borders */

table.style.border = 'none';
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 4


5. Ячейки не имеют границ (UI)


/* Cells have no border */

/* Cells have no border */

for (var i = 0; i < cells.length; i++) {
  cells[i].style.border = 'none';
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 5

Обратите внимание, что у нас есть 5 шагов, и мы понятия не имеем, что такое Wordle, мы просто играем с пользовательским интерфейсом.


6. Текст выравнивается по центру (пользовательский интерфейс)


/* text is centered */

/* Text is centered */

for (var i = 0; i < cells.length; i++) {
  cells[i].style.textAlign = 'center';
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 6


7. Текст белый (UI)


/* text is white*/

/* text is white */

for (var i = 0; i < cells.length; i++) {
  cells[i].style.color = 'white';
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 7


8. Стиль текста (пользовательский интерфейс)


/* 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';
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

Серьезно? Еще нет настоящей игры?

шаг 8


9. Ячейки не имеют заполнения (пользовательский интерфейс)


/* Cells have no padding */

/* cells have no padding */

for (var i = 0; i < cells.length; i++) {
  cells[i].style.padding = '0px';
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 9


10. Ячейки пусты (пользовательский интерфейс/модель)


/* cells are empty */

/* cells are empty */

for (var i = 0; i < cells.length; i++) {
  cells[i].innerHTML = '';
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 10

Следуя инструкциям Карлоса, мы получили готовый к использованию пользовательский интерфейс.

Никаких тестов, никаких бизнес-правил. пока что.


11. Добавьте поле ввода (пользовательский интерфейс/модель)


/* 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);
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 11


12. Стиль поля ввода (UI)


/* add margin reduce text field width to 100px */

/* add margin reduce text field width to 100px */

input.style.margin = '10px';
input.style.width = '100px';
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 12


13. Добавить валидатор с идентификатором (модель)


/* 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 = '&#10003;';
button.id = 'validate';
document.body.appendChild(button);
Войти в полноэкранный режим

Выйти из полноэкранного режима

Мы думаем заранее, зная, что нам понадобится случайный идентификатор и идентификатор реализации.

Это нормально. Как комментирует Карлос в своем видео, нам нужно немного подумать как программистам.

шаг 13

Мы создаем кнопку со специальным идентификатором, так как мы предполагать это может быть полезно позже.


14. Добавить кнопку удаления с другим идентификатором (Модель)


/* 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 = '&#10007;';
button.id = 'remove';
document.body.appendChild(button);
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 14


15. Текст в центре поля (пользовательский интерфейс)


/* Center box text */

/* center box text */

input.style.textAlign = 'center';
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 15


16. Ограничьте размер текста (пользовательский интерфейс/модель)


/* 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');
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 16


17. Нам нужно сохранить текущую попытку (Модель)


/* create variable named 'rowIndex' starting at 0 */

/* create variable named 'rowIndex' starting at 0 */

var rowIndex = 0;
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 17

В это время в дело вступает черная магия.

Нам нужно думать наперед.

Наверняка есть лучшее место для программирования wordle. Следите за обновлениями!


18. Текст в верхнем регистре (Модель)


/* 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();
});
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 18


19. Мы пошли раньше времени (…)

Нам нужно несколько раз перефразировать следующую инструкцию, пока мы не получим желаемое поведение.

У нас есть мгновенная обратная связь, поэтому мы счастливы.


20. Вводимый текст должен отображаться в ячейках (Модель/UI)


/* 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);
    }
  }
});
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 20


21. Выбираем наше секретное слово (Модель)


/* store in a variable the secret word 'PAPER' */

/* store in a variable the secret word 'PAPER' */

var secretWord = 'PAPER';
Войти в полноэкранный режим

Выйти из полноэкранного режима


22. Если персонаж совпадает, ставим желтый (Модель/UI)


/* 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';
      }
    }
  }
});
Войти в полноэкранный режим

Выйти из полноэкранного режима


23. Если персонаж совпадает, то ставим зеленый (Модель/UI)


/* 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';
      }
    }
  }
});
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 23


24. Переход к следующему ряду (модель)


/*when clicking validate button, rowIndex variable increases */

/* when clicking validate button, rowIndex variable increases */

document.getElementById('validate').addEventListener('click', function(event) {
  rowIndex++;
});
Войти в полноэкранный режим

Выйти из полноэкранного режима

шаг 24


25. Игра «Стирание» (Модель)


/* 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;
});
Войти в полноэкранный режим

Выйти из полноэкранного режима


26. Сохранение допустимых слов (Модель)


/* 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'];
Войти в полноэкранный режим

Выйти из полноэкранного режима


27. Выбор секретного слова (Модель)


/* 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];
});
Войти в полноэкранный режим

Выйти из полноэкранного режима

До сих пор я придерживался демонстрации Карлоса.

Не хватает некоторых функций:

— Бизнес правила:

  • Игра должна начинаться со случайного слова.

  • Слова вне словаря должны быть недействительными. Поэтому слова с длиной, отличной от 5, будут недоступны.

  • Конец игры, когда мы выигрываем или проигрываем.

  • Нам нужен настоящий словарь.

— Пользовательский интерфейс/UX:

— Дополнительный:

  • Символы обмена Wordle

⬛⬛⬛🟩🟩

🟨⬛⬛⬛⬛

⬛⬛⬛🟩🟩

⬛🟨🟨🟨⬛

🟩🟩🟩🟩🟩

  • …многое еще впереди…

Из 27 вышеперечисленных шагов 22 связаны с пользовательским интерфейсом.

Модель может не пережить многих бизнес-изменений.

Возможно, версия TDD делает.

Технология потрясающая.

Мы можем создать весь пользовательский интерфейс, предоставляющий команды на естественном языке.

Следите за развитием Wordle в следующих статьях.


Автор изображения ДАТЬ ЕЙ

Оригинальное видео здесь

Полный исходный код на GitHub здесь.

Рабочая версия (не полностью функциональна, как указано выше) здесь


В следующих статьях я повторю эту и версию TDD.

Подпишитесь, чтобы получать следующие статьи, чтобы не пропустить их.