오늘 틱택토 게임 만들기를 해봤다.
게임을 만드는 과정 중 어려웠던 부분을 기록하려한다.
내가 생각했던 로직
1. 9개의 숫자 중 3개로 빙고가 될 수 있을 만한 배열들을 추려놓는다.
2. 9개의 버튼 중에 철수(X)와 영희(O)가 차례대로 누른다.
3. 철수가 누르는 버튼의 숫자(X가 배정된 숫자 = xList)와 영희가 누른 버튼의 숫자(O가 배정된 숫자 = oList)를 각각 다른 배열에 따로 담아둔다.
4. xList와 oList 중에서 3개를 골라서 나올 수 있는 모든 경우의 수를 구한다.
5. 만약 xList(또는 oList)에서 무작위로 3개를 고른 배열들 중 1번의 빙고가 될 수 있는 배열을 포함하면 X(철수) 또는 O(영희)가 이긴다.
나의 코드
특히 내 코드에서 이 부분을 쓸 때 매우 오래 걸렸다
combilist.some((arr) => arr.every((num) => dapList[i].includes(num)))
의도했던 바는 "xList나 oList 중에서 무작위로 3개를 뽑은 배열들 중 빙고가 될 수 있는 배열을 포함하면~" 이었고,
처음에는
combilist.includes(dapList[i])
이렇게 썼었다. 그랬더니 절대 false가 되는 것이다.
객체형 데이터는 각자 메모리의 주소값을 가지기 때문에 두 배열이 같아보여도 사실은 다른 주소값을 가진다.
즉, 두 배열은 같다고 할 수 없다 = includes로 찾을 수 없다....
따라서 두 배열이 같은지를 따져보려면 객체형 데이터 안에 있는 단순 데이터들끼리를 비교해 봐야한다.
결국에는 xList에서 무작위로 세 개를 뽑은 배열들(= combilist) 중에서, 빙고가 될 수 있는 배열(= dapList[i])이 combilist의 배열 하나의(arr), 각 요소들을 모두(every)포함(그래야 똑같은거니까)하는 combi가 하나라도 있으면(some) 승자를 알리는 alert가 뜨는 것이다.
A배열(combilist) 안의 요소와 B배열(dapList) 안의 요소가 같은지를 비교할 때는 이중 반복문을 써야하는데 그 안의 요소들이 또 배열이라면, 배열과 배열의 직접 비교는 불가능
=> A배열 안의 각 요소들을 다시 돌리면서 다른 배열이 그 요소들을 다 포함하는지를 봐야한다.
답 코드를 봤다.
const WINNING_LINES = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
initialState: {
board: Array(9).fill(null),
currentPlayer: "X",
winner: null,
histories: [],
}
>>
...
state.board[index] = state.currentPlayer;
state.currentPlayer = state.currentPlayer === "X" ? "O" : "X";
...
>>
const winningLine = WINNING_LINES.find((line) => {
const [a, b, c] = line;
if (board[a] && board[a] === board[b] && board[a] === board[c]) {
return board[a];
}
이건 마치 애기한테 빙고라는 게임을 알려주는 것과 같다고 생각했다.
1. 우리는 X랑 O중에 누가 이기는지를 알아볼거야
2. board(9개의 칸)에는 O 또는 X가 들어갈거야
state.board[index] = state.currentPlayer;
3. 그리고 이거, 이거, 이거 다 O이거나 X면 우린 그걸 "one 빙고"라고 할겨
4. 여기서 이렇게, 이렇게, 이렇게는 board의 순서고, 그 경우는 WINNING_LINES에 다 들어있어.
5. 근데 WINNING_LINES 을 보니 될 수 있는 경우들이 많지?
매번 board의 0번째, 3번째, 6번째 그러고 또 board의 2번째, 5번째, 8번째 이렇게 모든 경우를 비교하기엔 너무 많으니 이 경우들을 통틀어서 우리는 [a, b, c]라고 할거야.
const [a, b, c] = line;
6. 그럼 board의 a번째랑, b번째랑, c번째가 모두 같으면 "one 빙고!"라는 말이랑 같은 말이지?
if (board[a] && board[a] === board[b] && board[a] === board[c])
7. 그때 board의 a번째에 들어가 있는 값이 O면 O가 이기는 거고 X면 X가 이기는 거야
return board[a];
이미 답이 될 수 있는 경우들은 정해져있고 결국 누가 이기는지가 중요한 것이고
철수와 영희가 매번 뭘 고르는지는 몰라도 되는 것이었다.
결국 난 눌린 버튼 숫자 간의 직접비교를 했던 것이고
답은 버튼의 숫자가 몇이든 어차피 그 숫자에는 O 또는 X가 들어갈 것이니,
세 개에 모두 같은 게 들어갈 경우 그게 O인지 X인지로 풀이를 했다.
'TIL' 카테고리의 다른 글
2024.02.26 TIL #Map() #flex-grow, flex-shrink, flex-basis (0) | 2024.02.27 |
---|---|
2024.02.23 TIL #객체의 구조분해 할당 (0) | 2024.02.26 |
2024.02.21 TIL #spread연산자의 무서운 점 (0) | 2024.02.21 |
2024.02.16 TIL #exportVSexportDefault #inputType="number" #substring()VSslice() (0) | 2024.02.19 |
2024.02.06 TIL #useRef로 ref가 부여되는 시점 #payload의 데이터형 (0) | 2024.02.06 |