Храните состояние игры и индекс крота. После запуска или попадания планируйте появление через случайную задержку; при остановке очищайте таймер.
Разработка простой игры «Убей крота» на TypeScript
Храните состояние игры и индекс крота. После запуска или попадания планируйте появление через случайную задержку; при остановке очищайте таймер.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
На квадратном поле размером 4 × 4 клетки через случайные промежутки времени появляется крот в произвольной ячейке. Пользователь должен кликнуть по нему левой кнопкой мыши, после чего крот исчезает и появляется снова в другой случайной клетке. Игра должна поддерживать запуск и остановку через одну кнопку (можно использовать одну кнопку для переключения состояния). Для визуализации крота можно выбрать любой удобный символ, например "@" или любой другой. Для получения случайных координат используйте функцию Math.random(), возвращающую число в диапазоне [0, 1).
import React, { useState, useEffect } from "react";
import "./styles.css";
const App: React.FC = () => {
return (
<div className="App">
<h1>⭐️ Crush the mole ⭐️</h1>
</div>
);
};
export default App;
Ответ
Храните состояние игры и индекс крота. После запуска или попадания планируйте появление через случайную задержку; при остановке очищайте таймер.
const App: React.FC = () => {
const [running, setRunning] = useState(false);
const [mole, setMole] = useState<number | null>(null);
const [round, setRound] = useState(0);
const previous = React.useRef<number | null>(null);
useEffect(() => {
if (!running) return;
const timer = setTimeout(() => {
let next = Math.floor(Math.random() * (previous.current === null ? 16 : 15));
if (previous.current !== null && next >= previous.current) next++;
previous.current = next; setMole(next);
}, 300 + Math.random() * 900);
return () => clearTimeout(timer);
}, [running, round]);
function toggle() { setMole(null); setRunning(value => !value); }
function hit(index: number) {
if (!running || mole !== index) return;
setMole(null); setRound(value => value + 1);
}
return <div><h1>Crush the mole</h1>
<button onClick={toggle}>{running ? 'Stop' : 'Start'}</button>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 3rem)', gap: '.25rem' }}>
{Array.from({ length: 16 }, (_, index) => <button key={index} style={{ height: '3rem' }} aria-label={'Клетка ' + (index + 1)} onClick={() => hit(index)}>{mole === index ? '@' : ''}</button>)}
</div>
</div>;
};
Крот остаётся до попадания; новое место отличается от предыдущего. Обычный click поддерживает основную кнопку мыши и клавиатуру, правый клик не засчитывается.