Char Codes

by Станислав Некрасов

HTML

<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap" rel="stylesheet">
<div class="centered">
  <div class="calc">
    <div class="display">Баг</div>
    <div class="preview"></div>
    <div class="btn btn-space"></div>
    <div class="btn btn-space"></div>
    <div class="btn btn-space btn-off"></div>
    <div class="btn btn-act">CE</div>
    <div class="btn btn-space"></div>
    <div class="btn btn-space"></div>
    <div class="btn btn-space btn-off"></div>
    <div class="btn btn-act">RU</div>
    <div class="btn btn-space btn-off"></div>
    <div class="btn btn-space btn-off"></div>
    <div class="btn btn-space btn-off"></div>
    <div class="btn btn-act">EN</div>
    <div class="btn btn-oper">+</div>
    <div class="btn btn-oper">-</div>
    <div class="btn btn-oper">x</div>
    <div class="btn btn-oper">/</div>
    <div class="reload">Сбросить всё</div>
    <div class="restart">Перезапустить уровень</div>
  </div>
</div>

CSS

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: Montserrat, sans-serif;
}

.calc {
	display: grid;
  grid-template-rows: 50px 16px 50px 50px 50px 50px 32px;
  grid-template-columns: 50px 50px 50px 50px;
  grid-gap: 5px;
}

.display {
  grid-column: 1 / span 4;
  background: #e6e6ff;
  border-radius: 10px;
  line-height: 50px;
  padding: 0 10px;
  font-size: 18px;
  box-shadow: 1px 1px 2px 0 #0004;
}

.word-letter.correct {
  font-weight: bold;
  color: #4bd351;
}

.word-letter.incorrect {
  font-weight: bold;
  color: #d3514b;
}

.preview {
  grid-column: 1 / span 4;
  text-align: center;
  color: #444;
  font-size: 16px;
  line-height: 16px;
  padding: 0 5px;
}

.btn {
  display: block;
  text-align: center;
  background: #8a8eff;
  border-radius: 10px;
  color: #ffffff;
  font-weight: bold;
  font-size: 20px;
  line-height: 50px;
  box-shadow: 1px 1px 2px 0 #0004;
}

.btn:not(.btn-off):hover {
  cursor: pointer;
  background: #999cff;
}

.btn:not(.btn-off):active {
  background: #8084ff;
  /* margin: 2px -2px -2px 2px; */
}

.btn-off {
  background: #d3514b;
}

.btn-oper {
  font-size: 32px;
}

.centered {
  display: flex;
  width: 100vw;
  height: 100vh;
  justify-content: center;
  align-items: center;
}

.reload {
  grid-column: 1 / span 2;
  font-size: 12px;
}

.restart {
  grid-column: 3 / span 2;
  text-align: right;
  font-size: 12px;
}

.reload:hover, .restart:hover {
  cursor: pointer;
  text-decoration: underline;
}

JavaScript

/* 
Баг
Нос
Аист
Морс
Мопс
*/

const alphRU = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя',
	alphEN = 'abcdefghjklmnopqrstuvwxyz';

const calc = document.querySelector('.calc');
const display = document.querySelector('.display');
const preview = document.querySelector('.preview');

let btn1 = null, btn2 = null, btnOper = null, calcResult = null;
let wordI = 0;

let words = [
	'Баг', 'Бит', 'Нос', 'Аист', 'Морс', 'Мопс',
  'Слово', 'Калькулятор', 'Компьютер', 
  'Python', 'JavaScript', 'Девятиклассник'
];
let wordN = 0, word = 'Баг';

function updatePreview() {
	preview.textContent = (btn1 ? btn1.textContent : '') 
  	+ (btnOper ? btnOper.textContent : '') 
    + (btn2 ? btn2.textContent : '') 
    + (calcResult != null ? '='+calcResult : '');
}

function displayWord() {
	display.innerHTML = '';
	for (let i = 0; i < word.length; i++) {
    let l = word[i], e = document.createElement('span'), ll = l.toLowerCase();
    e.classList.add('word-letter');
    e.classList.add('wl'+i);
    e.title = (alphRU.indexOf(ll) + 1) || (alphEN.indexOf(ll) + 1);
    e.textContent = l;
    display.append(e);
	}
}

function clearBoard() {
	document.querySelectorAll('.btn-space').forEach((elem, idx) => {
  	elem.textContent = idx > 1 ? '' : '1';
  });
}

function btnSpaceOnClick(event) {
	if (this.matches('.btn-off')) return;
  
  if (calcResult != null) {
    this.textContent = calcResult;
    btn1 = btn2 = btnOper = calcResult = null;
    return;
  }
  
  let value = this.textContent.trim();
  if (value == '') {
  	return;
  }
  
  if (isNaN(+value)) {
  	let elem = document.querySelector('.wl'+wordI);
  	if (value.toLowerCase() == word[wordI].toLowerCase()) {
    	elem.classList.add('correct');
      elem.classList.remove('incorrect');
      wordI += 1;
      if (wordI >= word.length) {
      	alert('Молодец ;)');
        wordN += 1;
        wordI = 0;
        word = words[wordN];
        displayWord();
        clearBoard();
        if (wordN == 6) {
       ...