347 lines
13 KiB
Plaintext
347 lines
13 KiB
Plaintext
Привет. Есть игра 5 букв. Правила - нужно угадать загаданное слово, оно состоит из 5 букв. есть 6 попыток, в каждую попытку можно вставить существующее слово из русского языка. если слово не верное показывается каких букв нет в слове, какие есть буквы, и какие стоят на своем месте. Я написал калькулятор для этой игры, которая помогает отгадать слово. Но он работает не корректно. Я приложу код ниже. Проблема в том, что если вставлять в маску буквы, которые есть в слове, но не в своем месте, то он предлагает не правильные слова. Например, если в это маске ввести на 3, 4, 5 место буквы бор, то он будет предлагать слова по типу забор, хотя именно такие слова по логике работы он не должен предлагать.
|
||
html
|
||
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Калькулятор 5 букв</title>
|
||
<link rel="stylesheet" href="styles.css">
|
||
</head>
|
||
<body>
|
||
<div class="calculator-container">
|
||
<h1>Калькулятор для игры 5 букв</h1>
|
||
<div class="inputs">
|
||
<label for="correct-mask">Маска (буквы на своем месте):</label>
|
||
<div id="mask-container">
|
||
<input type="text" maxlength="1" class="mask-letter">
|
||
<input type="text" maxlength="1" class="mask-letter">
|
||
<input type="text" maxlength="1" class="mask-letter">
|
||
<input type="text" maxlength="1" class="mask-letter">
|
||
<input type="text" maxlength="1" class="mask-letter">
|
||
</div>
|
||
|
||
<label>Маски (буквы не на своих местах, для каждой попытки):</label>
|
||
<div id="incorrect-masks">
|
||
<div class="incorrect-mask-container">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
</div>
|
||
<div class="incorrect-mask-container">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
</div>
|
||
<div class="incorrect-mask-container">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
</div>
|
||
<div class="incorrect-mask-container">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
</div>
|
||
<div class="incorrect-mask-container">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
<input type="text" maxlength="1" class="incorrect-mask-letter">
|
||
</div>
|
||
</div>
|
||
|
||
<label for="included-letters">Присутствующие буквы:</label>
|
||
<input type="text" id="included-letters" placeholder="Например, а, б, в">
|
||
|
||
<label for="excluded-letters">Отсутствующие буквы:</label>
|
||
<input type="text" id="excluded-letters" placeholder="Например, г, д, е">
|
||
|
||
<button id="calculate-btn">Рассчитать</button>
|
||
</div>
|
||
<div class="results">
|
||
<h2>Возможные слова:</h2>
|
||
<ul id="results-list"></ul>
|
||
</div>
|
||
</div>
|
||
<script src="script.js"></script>
|
||
</body>
|
||
</html>
|
||
|
||
css
|
||
/* Базовые стили для страницы */
|
||
body {
|
||
font-family: Arial, sans-serif;
|
||
background-color: #f4f4f4;
|
||
margin: 0;
|
||
padding: 0;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: flex-start;
|
||
height: 100vh;
|
||
overflow: auto;
|
||
}
|
||
|
||
/* Контейнер для приложения */
|
||
.calculator-container {
|
||
background: white;
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||
text-align: center;
|
||
width: 400px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: auto;
|
||
}
|
||
|
||
/* Стили для ввода данных */
|
||
.inputs {
|
||
margin-bottom: 20px;
|
||
text-align: left;
|
||
position: sticky;
|
||
top: 0;
|
||
background: white;
|
||
z-index: 10;
|
||
padding-bottom: 10px;
|
||
border-bottom: 1px solid #ddd;
|
||
}
|
||
|
||
/* Метки (label) */
|
||
label {
|
||
display: block;
|
||
margin: 10px 0 5px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
/* Поля ввода */
|
||
input {
|
||
width: calc(100% - 20px);
|
||
padding: 10px;
|
||
margin-bottom: 10px;
|
||
border: 1px solid #ccc;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
/* Стили для маски букв на своем месте */
|
||
#mask-container {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.mask-letter {
|
||
width: 50px;
|
||
text-align: center;
|
||
font-size: 16px;
|
||
padding: 5px;
|
||
border: 1px solid #ccc;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
/* Стили для масок букв не на своих местах */
|
||
#incorrect-masks {
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.incorrect-mask-container {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.incorrect-mask-letter {
|
||
width: 50px;
|
||
text-align: center;
|
||
font-size: 16px;
|
||
padding: 5px;
|
||
border: 1px solid #ccc;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
/* Кнопка "Рассчитать" */
|
||
#calculate-btn {
|
||
padding: 10px 20px;
|
||
background-color: #007bff;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
width: 100%;
|
||
}
|
||
|
||
#calculate-btn:hover {
|
||
background-color: #0056b3;
|
||
}
|
||
|
||
/* Стили для блока результатов */
|
||
.results {
|
||
text-align: left;
|
||
overflow-y: auto; /* Прокрутка по вертикали */
|
||
max-height: 50vh; /* Ограничение высоты списка */
|
||
padding-right: 10px; /* Добавляем отступ для скроллбара */
|
||
border-top: 1px solid #ddd; /* Разделение от ввода */
|
||
}
|
||
|
||
/* Стили для списка результатов */
|
||
ul {
|
||
list-style: none;
|
||
padding: 0;
|
||
margin: 0;
|
||
}
|
||
|
||
li {
|
||
padding: 5px 0;
|
||
border-bottom: 1px solid #ddd;
|
||
}
|
||
|
||
li:hover {
|
||
background-color: #f0f0f0;
|
||
}
|
||
|
||
/* Медиазапросы для мобильных устройств */
|
||
@media (max-width: 480px) {
|
||
.calculator-container {
|
||
width: 90%;
|
||
padding: 15px;
|
||
}
|
||
|
||
.mask-letter,
|
||
.incorrect-mask-letter {
|
||
width: 40px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
#calculate-btn {
|
||
padding: 8px 16px;
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
|
||
js
|
||
let dictionary = []; // Словарь будет загружен из файла
|
||
|
||
// Функция для загрузки слов из файла
|
||
async function loadDictionary() {
|
||
try {
|
||
const response = await fetch("words.txt");
|
||
if (!response.ok) {
|
||
console.error("Ошибка загрузки файла:", response.statusText);
|
||
return;
|
||
}
|
||
const text = await response.text();
|
||
dictionary = text
|
||
.split(/\s+/)
|
||
.map(word => word.trim())
|
||
.filter(word => word.length === 5);
|
||
|
||
console.log("Словарь успешно загружен. Количество слов:", dictionary.length);
|
||
} catch (error) {
|
||
console.error("Ошибка при загрузке словаря:", error);
|
||
}
|
||
}
|
||
|
||
// Основная функция для фильтрации слов
|
||
function calculatePossibleWords(mask, incorrectMasks, included, excluded) {
|
||
const maskRegex = new RegExp(`^${mask.replace(/_/g, ".")}$`, "i");
|
||
const includedLetters = included
|
||
.split("")
|
||
.map((l) => l.trim())
|
||
.filter(Boolean); // Убираем пустые символы
|
||
const excludedLetters = excluded
|
||
.split("")
|
||
.map((l) => l.trim())
|
||
.filter(Boolean); // Убираем пустые символы
|
||
|
||
// Составляем списки запрещенных позиций и обязательных букв
|
||
const forbiddenPositions = [];
|
||
const requiredLetters = new Set();
|
||
|
||
incorrectMasks.forEach((mask) => {
|
||
Array.from(mask).forEach((letter, position) => {
|
||
if (letter.trim()) {
|
||
forbiddenPositions.push({ letter: letter.trim(), position });
|
||
requiredLetters.add(letter.trim());
|
||
}
|
||
});
|
||
});
|
||
|
||
return dictionary.filter((word) => {
|
||
// Проверяем соответствие маске (буквы на своих местах)
|
||
if (!maskRegex.test(word)) return false;
|
||
|
||
// Проверяем наличие всех включенных букв
|
||
if (!includedLetters.every((letter) => word.includes(letter))) return false;
|
||
|
||
// Проверяем отсутствие исключенных букв
|
||
if (excludedLetters.some((letter) => word.includes(letter))) return false;
|
||
|
||
// Проверяем, что все буквы из масок "не на своих местах" присутствуют
|
||
const requiredArray = Array.from(requiredLetters);
|
||
if (!requiredArray.every((letter) => word.includes(letter))) {
|
||
return false;
|
||
}
|
||
|
||
// Проверяем, что буквы из неправильных масок не находятся на запрещенных позициях
|
||
for (const { letter, position } of forbiddenPositions) {
|
||
if (word[position] === letter) {
|
||
return false; // Буква находится на запрещенной позиции
|
||
}
|
||
}
|
||
|
||
return true; // Слово проходит все проверки
|
||
});
|
||
}
|
||
|
||
// Обработчик для кнопки "Рассчитать"
|
||
document.getElementById("calculate-btn").addEventListener("click", () => {
|
||
const maskInputs = document.querySelectorAll(".mask-letter");
|
||
const incorrectMaskContainers = document.querySelectorAll(".incorrect-mask-container");
|
||
|
||
let mask = Array.from(maskInputs).map((input) => input.value || "_").join("");
|
||
let incorrectMasks = Array.from(incorrectMaskContainers).map(container =>
|
||
Array.from(container.querySelectorAll(".incorrect-mask-letter"))
|
||
.map(input => input.value || "")
|
||
.join("")
|
||
);
|
||
|
||
const included = document.getElementById("included-letters").value.toLowerCase();
|
||
const excluded = document.getElementById("excluded-letters").value.toLowerCase();
|
||
|
||
console.log("Введенные данные:");
|
||
console.log("Маска:", mask);
|
||
console.log("Неправильные маски:", incorrectMasks);
|
||
console.log("Присутствующие буквы:", included);
|
||
console.log("Исключенные буквы:", excluded);
|
||
|
||
const possibleWords = calculatePossibleWords(mask, incorrectMasks, included, excluded);
|
||
|
||
const resultsList = document.getElementById("results-list");
|
||
resultsList.innerHTML = "";
|
||
|
||
if (possibleWords.length === 0) {
|
||
console.log("Слов не найдено.");
|
||
resultsList.innerHTML = "<li>Подходящих слов не найдено</li>";
|
||
} else {
|
||
console.log("Найденные слова:", possibleWords);
|
||
possibleWords.forEach((word) => {
|
||
const listItem = document.createElement("li");
|
||
listItem.textContent = word;
|
||
resultsList.appendChild(listItem);
|
||
});
|
||
}
|
||
});
|
||
|
||
// Загружаем словарь при старте
|
||
loadDictionary();
|
||
|