틱택토 컴퓨터랑 게임하기
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>틱택토</title>
<style>
table {
border-collapse: collapse;
}
td {
border: 1px solid black;
width: 40px;
height: 40px;
text-align: center;
}
</style>
</head>
<body>
</body>
<script>
const { body } = document;
const $table = document.createElement('table');
const $result = document.createElement('div');
const rows = [];
let turn = 'O';
let clickable = true;
const callback = (event) => {
if(!clickable) return;
if (event.target.textContent !== '') {
console.log('빈칸이 아닙니다.');
return;
}
console.log('빈칸입니다');
event.target.textContent = turn;
checkWinnerAndDraw(event.target)
if (turn === 'X') {
const emptyCells = rows.flat().filter((v) => !v.textContent);
const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
clickable = false;
setTimeout(()=>{
randomCell.textContent = 'X';
checkWinnerAndDraw(randomCell);
clickable = true;
},1000);
}
};
const checkWinnerAndDraw = (target) => {
let hasWinner = checkWinner(target);
if (hasWinner) {
$result.textContent = `${turn}님이 승리!`;
$table.removeEventListener('click', callback);
return;
}
let draw = rows.flat().every((cell) => cell.textContent);
if (draw) {
$result.textContent = `무승부`;
return;
}
turn = turn === 'X' ? 'O' : 'X';
}
const checkWinner = (target) => {
let rowIndex = target.parentNode.rowIndex;
let cellIndex = target.cellIndex;
console.log(target.parentNode.children);
let hasWinner = false;
rows.forEach((row, ri) => {
row.forEach((cell, ci) => {
if (cell === target) {
rowIndex = ri;
cellIndex = ci;
}
})
});
if (
rows[rowIndex][0].textContent === turn &&
rows[rowIndex][1].textContent === turn &&
rows[rowIndex][2].textContent === turn
) {
hasWinner = true;
}
if (
rows[0][cellIndex].textContent === turn &&
rows[1][cellIndex].textContent === turn &&
rows[2][cellIndex].textContent === turn
) {
hasWinner = true;
}
if (
rows[0][0].textContent === turn &&
rows[1][1].textContent === turn &&
rows[2][2].textContent === turn
) {
hasWinner = true;
}
if (
rows[0][2].textContent === turn &&
rows[1][1].textContent === turn &&
rows[2][0].textContent === turn
) {
hasWinner = true;
}
return hasWinner;
}
for (let i = 1; i <= 3; i++) {
const $tr = document.createElement('tr');
const cells = [];
for (let j = 1; j <= 3; j++) {
const $td = document.createElement('td');
cells.push($td);
$tr.appendChild($td);
}
rows.push(cells);
$table.appendChild($tr);
$table.addEventListener('click', callback);
}
body.appendChild($table);
body.appendChild($result);
</script>
</html>
RPG게임
기억사항
- 깊은 복사
parse메서드는 문자열을 객체로
stringfy 메자열로 만듬
JSON.parse(JSON.stringify(monsterList[Math.floor(Math.random() * monsterList.length)]));
- 얕은 복사
가장 바깥 객체만 복사되고. 내부 객체는 참조 관계를 유지하는 복사
스프레드 문법은 기존 객체의 속성을 새 객체에 할당할 때 사용
배열은 [ ...배열 ] , 객체라면 { ...객체 }
<html lang="en">
<head>
<meta charset="UTF-8">
<title>텍스트 RPG</title>
</head>
<body>
<form id="start-screen">
<input id="name-input" placeholder="주인공 이름을 입력하세요!" />
<button id="start">시작</button>
</form>
<div id="screen">
<div id="hero-stat">
<span id="hero-name"></span>
<span id="hero-level"></span>
<span id="hero-hp"></span>
<span id="hero-xp"></span>
<span id="hero-att"> </span>
</div>
<form id="game-menu" style="display: none;">
<div id="menu-1">1.모험</div>
<div id="menu-2">2.휴식</div>
<div id="menu-3">3.종료</div>
<input id="menu-input" />
<button id="menu-button">입력</button>
</form>
<form id="battle-menu" style="display: none;">
<div id="battle-1">1.공격</div>
<div id="battle-2">2.회복</div>
<div id="battle-3">3.도망</div>
<input id="battle-input" />
<button id="battle-button">입력</button>
</form>
<div id="message"></div>
<div id="monster-stat">
<span id="monster-name"></span>
<span id="monster-hp"></span>
<span id="monster-att"></span>
</div>
</div>
<script>
const $startScreen = document.querySelector('#start-screen');
const $gameMenu = document.querySelector('#game-menu');
const $battleMenu = document.querySelector('#battle-menu');
const $heroName = document.querySelector('#hero-name');
const $heroLevel = document.querySelector('#hero-level');
const $heroHp = document.querySelector('#hero-hp');
const $heroXp = document.querySelector('#hero-xp');
const $heroAtt = document.querySelector('#hero-att');
const $monsterName = document.querySelector('#monster-name');
const $monsterHp = document.querySelector('#monster-hp');
const $monsterAtt = document.querySelector('#monster-att');
const $message = document.querySelector('#message');
const hero = {
name: '',
lev: 1,
maxHp: 100,
hp: 100,
xp: 0,
att: 10,
};
let monster = null;
const monsterList = [
{ name: '슬라임', hp: 25, att: 10, xp: 10 },
{ name: '스켈레톤', hp: 50, att: 15, xp: 20 },
{ name: '마왕', hp: 150, att: 35, xp: 50 },
];
$startScreen.addEventListener('submit', (event) => {
event.preventDefault();
const name = event.target['name-input'].value;
$startScreen.style.display = 'none';
$gameMenu.style.display = 'block';
$heroName.textContent = name;
$heroLevel.textContent = `${hero.lev}Lev`;
$heroHp.textContent = `HP: ${hero.hp}/${hero.maxHp}`;
$heroXp.textContent = `XP: ${hero.xp}/${15 * hero.lev}`;
$heroAtt.textContent = `ATT: ${hero.att}`;
hero.name = name;
});
$gameMenu.addEventListener('submit', (event) => {
event.preventDefault();
const input = event.target['menu-input'].value;
if (input === '1') {
$gameMenu.style.display = 'none';
$battleMenu.style.display = 'block';
monster = JSON.parse(
JSON.stringify(monsterList[Math.floor(Math.random() * monsterList.length)])
);
monster.maxHp = monster.hp;
$monsterName.textContent = monster.name;
$monsterHp.textContent = `HP: ${monster.hp}/${monster.maxHp}`;
$monsterAtt.textContent = `ATT: ${monster.att}`;
} else if (input === '2') {
} else if (input === '3') {
}
});
</script>
</body>
</html>