This commit is contained in:
40
.gitea/workflows/mail.yaml
Normal file
40
.gitea/workflows/mail.yaml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
name: Build'n'Push
|
||||||
|
run-name: ${{ gitea.actor }} building and deploying images
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: catthehacker/ubuntu:act-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # all history for all branches and tags
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
|
- name: Login to registry
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: git.arrowlab.ru
|
||||||
|
username: ${{ secrets.USER }}
|
||||||
|
password: ${{ secrets.PASSWORD }}
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v4
|
||||||
|
env:
|
||||||
|
ACTIONS_RUNTIME_TOKEN: '' # See https://gitea.com/gitea/act_runner/issues/119
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ./Dockerfile
|
||||||
|
platforms: |
|
||||||
|
linux/amd64
|
||||||
|
push: true
|
||||||
|
# tags: git.arrowlab.ru/${{ gitea.repository }}:${{ gitea.ref_name }}
|
||||||
|
tags: git.arrowlab.ru/ratelok/5letters:latest
|
||||||
10
Dockerfile
Normal file
10
Dockerfile
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Базовый образ Nginx для хостинга статических файлов
|
||||||
|
FROM nginx:alpine
|
||||||
|
|
||||||
|
# Копируем содержимое текущей директории в папку Nginx
|
||||||
|
COPY . /usr/share/nginx/html
|
||||||
|
|
||||||
|
# Открываем порт 80 для доступа
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
|
||||||
346
Empty File
Normal file
346
Empty File
Normal file
@@ -0,0 +1,346 @@
|
|||||||
|
Привет. Есть игра 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();
|
||||||
|
|
||||||
74
index.html
Normal file
74
index.html
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<!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="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>
|
||||||
|
|
||||||
104
script.js
Normal file
104
script.js
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
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, excluded) {
|
||||||
|
const maskRegex = new RegExp(`^${mask.replace(/_/g, ".")}$`, "i");
|
||||||
|
const excludedLetters = excluded
|
||||||
|
.split("")
|
||||||
|
.map((l) => l.trim())
|
||||||
|
.filter(Boolean); // Убираем пустые символы
|
||||||
|
|
||||||
|
// Преобразуем неправильные маски в формат [ "_", "_", "_" ]
|
||||||
|
const forbiddenPositions = Array(5).fill(null).map(() => new Set());
|
||||||
|
const requiredLetters = new Set();
|
||||||
|
|
||||||
|
incorrectMasks.forEach((mask) => {
|
||||||
|
for (let i = 0; i < mask.length; i++) {
|
||||||
|
const letter = mask[i];
|
||||||
|
if (letter && letter !== "_") {
|
||||||
|
forbiddenPositions[i].add(letter); // Запрещённая буква на конкретной позиции
|
||||||
|
requiredLetters.add(letter); // Эти буквы должны присутствовать в слове
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return dictionary.filter(word => {
|
||||||
|
// Проверяем соответствие маске (буквы на своих местах)
|
||||||
|
if (!maskRegex.test(word)) return false;
|
||||||
|
|
||||||
|
// Проверяем отсутствие букв из исключённого списка
|
||||||
|
if (excludedLetters.some(letter => word.includes(letter))) return false;
|
||||||
|
|
||||||
|
// Проверяем присутствие всех обязательных букв
|
||||||
|
if (!Array.from(requiredLetters).every(letter => word.includes(letter))) return false;
|
||||||
|
|
||||||
|
// Проверяем, что буквы из неправильных масок не находятся на запрещённых позициях
|
||||||
|
for (let i = 0; i < word.length; i++) {
|
||||||
|
if (forbiddenPositions[i].has(word[i])) {
|
||||||
|
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 excluded = document.getElementById("excluded-letters").value.toLowerCase();
|
||||||
|
|
||||||
|
console.log("Введенные данные:");
|
||||||
|
console.log("Маска:", mask);
|
||||||
|
console.log("Неправильные маски:", incorrectMasks);
|
||||||
|
console.log("Исключенные буквы:", excluded);
|
||||||
|
|
||||||
|
const possibleWords = calculatePossibleWords(mask, incorrectMasks, 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();
|
||||||
148
styles.css
Normal file
148
styles.css
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
/* Базовые стили для страницы */
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user