Player 2명이 번갈아 끝말잇기를 하는 게임이다. 추가적으로 input 유효성검사와 승부 판별, 플레이어 전환, 모달창 구현을 하였다. 목업 툴을 통해 대략적으로 구상해본 화면이다.
1️⃣ word
: 끝말잇기에 사용되는 단어 state.(초기값을 수박으로 설정)
2️⃣ value
: 플레이어가 입력할 단어의 값을 저장할 state.
3️⃣ wordlist
: 입력되었던 단어들의 list.
4️⃣ 만약 제시된 단어(word)와 입력한 단어(value)가 같다면?
setWord(value)
: 제시되는 단어가 입력한 단어로 교체 setValue('')
: 입력창값은 다시 빈값으로.setWordList([...wordList, value])
: 단어리스트에 단어 추가. const [word, setWord] = useState('수박'); // 1️⃣ 번
const [value, setValue] = useState(''); // 2️⃣ 번
const [wordList, setWordList] = useState<string[]>(['']); // 3️⃣ 번
const onSubmitForm = useCallback<(e: React.FormEvent) => void>(
e => {
e.preventDefault();
...
if (value.length === 1) {
...
} else {
if (word[word.length - 1] === value[0]) { // 4️⃣ 번
...
setWord(value);
setValue('');
setWordList([...wordList, value]);
...
} else {
setValue('');
...
}
}
},
[word, value]
1️⃣ onlyKorean
: 입력된 단어가 한글이어야 한다는 정규식을 가진 replace된 문자열
2️⃣ setWarning
: onlyKorean의 조건을 만족 못할 경우 경고 문자 출력.
3️⃣ disabled
: 빈값 제출을 막기 위해 value값이 존재할 경우 제출되게 설정.
const [warning, setWarning] = useState('');
...
const onChangeValue = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const onlyKorean = e.target.value.replace(/[^ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/g, '');
if (onlyKorean.length === 1) {
setWarning('1글자 이상을 입력하세요');
}
if (!onlyKorean) {
setWarning('한글을 입력해주세요');
}
setValue(onlyKorean);
},
[]
);
...
<button type="submit" disabled={!value}></button>
wordlist
배열을 map
을 통해 출력만 해주면 끝! 이때 플레이어에 따라 단어 색깔을 구별해주고, ul태그
에 flex
flex-wrap
을 사용하여 단어가 일정한 간격으로 가로로 출력되게 설정.
<ul className="flex flex-wrap text-center font-semibold text-[#124753]">
{wordList.map((text, i) => (
<div key={`${i + 1}번째 : ${text}`}>
<li className="mx-auto my-3 rounded-2xl px-3 py-2 text-lg">
{i % 2 !== 0 ? (
<div className="text-blue-700"> {text}</div>
) : (
<div className="text-red-700"> {text}</div>
)}
</li>
</div>
))}
</ul>
wordlist
배열의 길이가 짝수,홀수에 따라 플레리어가 1
인지 2
인지를 판별한다.
if (wordList.length % 2 === 0) {
setWinner(1);
} else {
setWinner(2);
}
...
{winner === 1 ? (
<div className="text-blue-700">Player 1's Turn!</div>
) : (
<div className="text-red-700">Player 2's Turn!</div>
)}
제시된 단어가 입력된 단어와 다르면 result는 땡
이라는 값이 저장되고, 땡이 되는 순간 모달창이 출력되며 게임은 종료. 모달창에는 winner
값을 props
로 전달하여 1
또는 2
를 승자로 출력한다.
const [result, setResult] = useState('');
...
if (word[word.length - 1] === value[0]) {
setResult('딩동댕');
...
} else {
setResult('땡');
...
}
...
{result === '땡' && (
<Modal wordRelay={'끝말잇기'} wordRelayWinner={winner} />
)}
💡 모달창
: 모달창 하나를 재사용하기 위하여 게임마다 보여줘야할 결과를 props로 Modal컴포넌트에 전달한다.
자세히 👉 모달창 기능 구현