이전 포스팅에서 구현했던
틱택토 게임에서 업그레이드된 심화 과정입니다.
틱택토 게임에서 업그레이드된 심화 과정입니다.
예제는 인프런의 제로초, "조현영"님의 강의를 들으면서 공부한 내용입니다.
틱택토 구현 BEFORE 버전은 아래 포스트로 이동하세요.
https://goddino.tistory.com/102
추가 구현 기능:
· 컴퓨터의 턴(나의 턴: X/컴퓨터의 턴: O)
· 무승부일 경우
자바스크립트 코드
컴퓨터의 턴
순수자바스크립트 코드(컴퓨터의 턴)
let table = document.createElement('table');
let row = [];
let col = [];
let turn = 'X';
let clickFn = function(e) {
e.target;
let rowNo = row.indexOf(e.target.parentNode);
console.log('줄번호', rowNo);
let colNo = col[rowNo].indexOf(e.target);
console.log('칸번호', colNo);
if (col[rowNo][colNo].textContent !== "") { //빈칸이 아닐 경우
console.log('다른 칸을 클릭하세요.');
} else { //빈칸이면
col[rowNo][colNo].textContent = turn; //턴 체크
//위치 중요(턴 패스하기 전)
//3줄 빙고 확인
let bingo = false;
//가로줄 검사
if (col[rowNo][0].textContent === turn &&
col[rowNo][1].textContent === turn &&
col[rowNo][2].textContent === turn) {
bingo = true;
}
//세로줄 검사
if (col[0][colNo].textContent === turn &&
col[1][colNo].textContent === turn &&
col[2][colNo].textContent === turn) {
bingo = true;
}
//대각선 검사 //좌상->우하 대각선 검사
if (col[0][0].textContent === turn &&
col[1][1].textContent === turn &&
col[2][2].textContent === turn) {
bingo = true;
}
if (col[0][2].textContent === turn &&
col[1][1].textContent === turn &&
col[2][0].textContent === turn) {
bingo = true;
}
//빙고일 경우 //bingo = true
if (bingo) {
result.textContent = `WINNER는 ${turn}님 축하드립니다`;
//초기화
turn = 'X';
//배열의 반복문 forEach - 아처원 배열이므로 forEach 2번 필요
col.forEach(function(row) {
row.forEach(function(td) {
td.textContent = '';
});
});
} else { //빙고가 안되었으면
if (turn === 'X') {
turn = 'O';
}
//1초 후 컴퓨터 턴 표시
setTimeout(function() {
console.log('컴퓨터의 턴입니다.');
//빈칸 중 하나를 고름
let candidates = [];
//모든 칸들을 candidates으로 넣은 후, 그 중에서 filter()로 빈칸만 고름
col.forEach(function(row) {
row.forEach(function(td) {
candidates.push(td);
})
});
//filter()로 return값이 true인 것(빈칸)만 추출하여 새 배열을 반환
candidates = candidates.filter(function(el) {
return el.textContent == "" //빈값 = "", false, null, NaN, 0, return !el.textContent 와 같은 의미
});
//candidates중 랜덤으로 한개 추출
let computerChoice = candidates[Math.floor(Math.random() * candidates.length)];
computerChoice.textContent = 'O';
//컴퓨터가 승리했는지 체크
//3줄 빙고 확인
let bingo = false;
//가로줄 검사
if (col[rowNo][0].textContent === turn &&
col[rowNo][1].textContent === turn &&
col[rowNo][2].textContent === turn) {
bingo = true;
}
//세로줄 검사
if (col[0][colNo].textContent === turn &&
col[1][colNo].textContent === turn &&
col[2][colNo].textContent === turn) {
bingo = true;
}
//대각선 검사 //좌상->우하 대각선 검사
if (col[0][0].textContent === turn &&
col[1][1].textContent === turn &&
col[2][2].textContent === turn) {
bingo = true;
}
if (col[0][2].textContent === turn &&
col[1][1].textContent === turn &&
col[2][0].textContent === turn) {
bingo = true;
}
//빙고일 경우 //bingo = true
if (bingo) {
result.textContent = `WINNER는 ${turn}님 축하드립니다`;
//초기화
turn = 'X';
col.forEach(function(row) {
row.forEach(function(td) {
td.textContent = '';
});
});
}
//턴을 나한테 넘김
turn = 'X';
}, 1000)
}
}
}
코드 리팩토링
· 중복되는 부분 함수로 설정
· 함수로 설정하면서 생기는 스코프 에러 문제 변수 위로 위치 설정
· 컴퓨터의 턴일 경우, 클릭 방지
· 초기화 1초 뒤로 설정
· 무승부 결과 출력
· 함수로 설정하면서 생기는 스코프 에러 문제 변수 위로 위치 설정
· 컴퓨터의 턴일 경우, 클릭 방지
· 초기화 1초 뒤로 설정
· 무승부 결과 출력
전체 코드
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>틱택토 심화</title>
<style>
table {
border-collapse: collapse;
}
td {
width: 60px;
height: 60px;
border: 1px solid #666;
font-size: 30px;
text-align: center;
}
</style>
</head>
<body>
<script>
let table = document.createElement('table');
let row = [];
let col = [];
let turn = 'X';
let result = document.createElement('div');
//리팩토링: 스코프 문제 변수 위치 수정
let bingo = '';
let rowNo = '';
let colNo = '';
//리팩토링: 함수 설정
function bingoCheck() {
bingo = false;
//가로줄 검사
if (col[rowNo][0].textContent === turn &&
col[rowNo][1].textContent === turn &&
col[rowNo][2].textContent === turn) {
bingo = true;
}
//세로줄 검사
if (col[0][colNo].textContent === turn &&
col[1][colNo].textContent === turn &&
col[2][colNo].textContent === turn) {
bingo = true;
}
//대각선 검사 //좌상->우하 대각선 검사
if (col[0][0].textContent === turn &&
col[1][1].textContent === turn &&
col[2][2].textContent === turn) {
bingo = true;
}
if (col[0][2].textContent === turn &&
col[1][1].textContent === turn &&
col[2][0].textContent === turn) {
bingo = true;
}
}
//리팩토링: 함수 설정
function reset(tie) { //매개변수로 무승부/승부 처리
if (tie) { //if = true 일 경우
result.textContent = `무승부 입니다`;
} else { //if = false 일 경우
result.textContent = `WINNER는 ${turn}님 축하드립니다`;
}
//리팩토링: 1초 후 초기화
turn = 'X';
setTimeout(function() {
result.textContent = '';
col.forEach(function(row) {
row.forEach(function(td) {
td.textContent = '';
});
});
}, 1000);
}
let clickFn = function(e) {
//리팩토링: 컴퓨터의 턴일때 클릭 방지
if (turn === 'O') {
return;
}
e.target;
rowNo = row.indexOf(e.target.parentNode);
console.log('줄번호', rowNo);
colNo = col[rowNo].indexOf(e.target);
console.log('칸번호', colNo);
if (col[rowNo][colNo].textContent !== "") { //빈칸이 아닐 경우
console.log('다른 칸을 클릭하세요.');
} else { //빈칸이면
col[rowNo][colNo].textContent = turn; //턴 체크
bingoCheck(); //리팩토링 함수 콜
//리팩토링 무승부
//모든 칸이 다 찼는지 검사
let candidates = [];
//모든 칸들을 candidates으로 넣은 후, 그 중에서 filter()로 빈칸만 고름
col.forEach(function(row) {
row.forEach(function(td) {
candidates.push(td);
})
});
candidates = candidates.filter(function(el) {
//빈값 = "", false, null, NaN, 0, return !el.textContent 와 같은 의미
return el.textContent == "";
});
if (bingo) {
reset(false); //리팩토링 함수 콜 = reset(); undefined 가 if문 안에 있으면 false와 같음
} else if (candidates.length === 0) { //빈칸이 없을 때
reset(true); //무승부일 경우
} else { //빙고가 안되었으면
if (turn === 'X') {
turn = 'O';
}
//1초 후 컴퓨터 턴 표시
setTimeout(function() {
console.log('컴퓨터의 턴입니다.');
//빈칸 중 하나를 고름
//filter()로 return값이 true인 것(빈칸)만 추출하여 새 배열을 반환
//candidates중 랜덤으로 한개 추출
let computerChoice = candidates[Math.floor(Math.random() * candidates.length)];
computerChoice.textContent = turn;
//컴퓨터가 승리했는지 체크
//중요! 컴퓨터의 위치 재정의
rowNo = row.indexOf(computerChoice.parentNode);
//console.log('컴퓨터 줄번호', rowNo);
colNo = col[rowNo].indexOf(computerChoice);
//console.log('컴퓨터 칸번호', colNo);
bingoCheck(); //리팩토링 함수 콜
if (bingo) { //빙고일 경우 //bingo = true
reset(); //리팩토링 함수 콜
}
turn = 'X'; //턴을 나한테 넘김
}, 1000)
}
}
}
for (let i = 0; i < 3; i += 1) {
let tr = document.createElement('tr');
row.push(tr);
col.push([]);
for (let j = 0; j < 3; j += 1) {
let td = document.createElement('td');
td.addEventListener('click', clickFn);
tr.appendChild(td);
col[i].push(td);
}
table.appendChild(tr);
}
document.body.append(table);
document.body.append(result);
</script>
</body>
</html>
화면 결과(Result 클릭)
반응형
'개발 > Javascript' 카테고리의 다른 글
[js] 자바스크립트로 카드 뒤집기 게임 구현하기(카드 세팅 ver.1) (0) | 2021.02.13 |
---|---|
[js] 자바스크립트 toggle 적용하기(ft. add, remove) (0) | 2021.02.13 |
[js]자바스크립트 스코프, 클로저(ft. 지역/글로벌/렉시컬 scope) (0) | 2021.01.08 |
[js] 자바스크립트로 반응속도 테스트 구현 (0) | 2021.01.03 |
[js] 자바스크립트로 지뢰찾기 게임 구현하기 (0) | 2021.01.02 |
댓글