거의 마무리가 되었으나
이 Rematch!(재대결!) 버튼이 게임을 실제로 재시작한다면 더 좋을 것입니다
그리고 그것은 감사하게도 만들기 쉽습니다
이제 우리는 여기에 button을 갖고 있습니다
그러나 게임을 재시작 한다는 것은 어떤 의미일까요?
끝에서
우리의 게임은 이 gameTurns 상태로 제어됩니다
이것이 전체 게임에서 true/false를 도출할 수 있는 하나뿐인 출처입니다
이 gameTurns 상태가
우리가 gameBoard를 도출하기 위해 사용하는 것입니다
그리고 activePlayer와
우승자를 확인하는 데도 사용됩니다
따라서 이것이 우리의 true/false 여부를 확인할 수 있는 유일한 출처입니다
따라서 이 게임을 다시 시작한다는 것은
간단히 gameTurns를 빈 배열로 재설정하고
이 로그를 지우는 것이라고 할 수 있습니다
그리고 나머지는 모두 이 상태에서 파생되기에
자동적으로 조정될 것입니다
따라서 우리가 App 컴포넌트 내에서 해야할 것은
예를 들어 handleRematch라는 새로운 함수를 추가하는 것입니다
혹은 더 명확하게 handleRestart 입니다
그리고 이 안에서 setgameTurns를
다음과 같이 빈 배열로 만듭니다
이게 전부입니다
이제 우리는 단지
GameOver 컴포넌트 내에서 이 함수가
촉진되도록 하는 것입니다
따라서 이 button으로부터
GameOver 컴포넌트 내에
onRestart라 부를 수 있는 속성을 수락할 수 있습니다
그리고 우리는 이 buttond의 onClick 속성에 이 값을 설정하고자 합니다
다시 말해서 우리는 이 프로젝트에서 전에 여러 번 한 것처럼
이 컴포넌트의 외부에서
이 button으로 함수를 전달하려고 합니다
그리고 이제 이 App 컴포넌트에서, 우리는 handleRestart를
우리가 방금 사용한 onRestart 속성을 위한 값으로 사용하고자 합니다
그리고 GameOver 컴포넌트에 다음과 같이 추가합니다
그러면 그것이 전부입니다
이 상태로부터 모든 것을 얻기 때문에
이것이 우리가 수행해야 할 전부입니다
이로써, 만약 다시 로딩하고 이겨서 Rematch!(재대결!)을 클릭한다면
마치 제대로 실행된 것처럼 보입니다
왜냐하면 플레이어 섹션이 변경되었기 때문입니다
그러나 게임 오버 화면은 아직 이곳에 있고
게임판는 조정되지 않았습니다
이런 경우는 이 게임에 버그가 있기 때문입니다
실제로, 이는 잡기 어려울 수 있는 버그이지만,
우리가 gameBoard를 어떻게 업데이트 하는지에 따라
발생할 수 있는 버그입니다.
현재 여기서는 우리의 gameTurns를 기반으로
gameBoard 를 동적으로 도출하고 있습니다
하지만 이 줄을 확인해 봅시다
이 줄에서 우리는 무엇을 하고 있습니까
사실 우리는 배열 내의 중첩된 배열에서
특정 차례를 한 플레이어의 기호(player)로
내부의 요소를 덮어쓰고 있습니다
문제는 우리가 이 값을 덮어쓰거나
값을 정하는 gameBoard가
이 initialGameBoard를
기반으로 한다는 점입니다
그리고 그것은 배열로 채워진 배열입니다
이 섹션의 초반에 언급했듯이,
자바스크립트 내의 객체와 같은 배열은 참조 값입니다
이 말은 즉 그들은 메모리에 보관됩니다
우리가 그것들을 사용한다면
비록 다른 변수들에 보관되었더라도
우리는 항상 메모리의 같은 객체 혹은 배열을 편집하는 것입니다
그렇기에, 여기 특정 행-열 조합을
플레이어 기호 (player)로 설정할 때
그 원래 배열의 메모리 내에서 그것을 수행하고 있는 것입니다
따라서, 게임을 재시작한 후
여기 배열은 초기화되지 않고
여전히 편집된 이전 배열입니다
그래서 지금은 이렇게 업데이트되기 때문에
gameBoard를 gameTurns로부터 분리하였습니다
감사하게도 해결 방안은 간단합니다
우리는 단지 여기 initialGameBoard의 복사본을 생성합니다
이것은 반드시 깊은 복사여야 합니다
즉 바깥 배열만이 아니라
안쪽 배열의 복사도 필요한 것입니다
그리고 우리는 이것을 다음과 같은 방식으로 할 수 있습니다
이미 여러분에게 이전에 보여주었는데 여기서 map을 불러오고
이후 안쪽 배열을 모두 작성합니다
그리고 모든 안쪽 배열마다, 우리는 기존 배열 요소가
그대로 펼쳐진 복사본을 만듭니다
이로써 우리는
gameBoard를 도출할 때 우리가 메모리의 기존의 배열이 아닌
새로운 배열을 추가했도록 합니다
따라서 이제
우리가 저장을 하고 여기서 다시 로드를 하고 다음과 같이 이겼다면
Rematch!(재대결!)를 클릭한다면 이렇게 정상적으로 작동합니다
이제 우리는 재시작하고 다시 이길 수 있습니다
그리고 우리가 Rematch!(재대결!)을 누를 때
로그 또한 없어진 것을 볼 수 있습니다
콘솔에서도 에러가 뜨지 않았습니다
이로써 우리는 마침내 게임을 재시작 할 수 있습니다