각종 후기/우아한테크코스

[우아한 테크코스 3기] LEVEL 1 회고 (53일차)

제이온 (Jayon) 2021. 3. 26.

안녕하세요? 제이온입니다.

 

오늘은 어제 배운 JS 지식으로 체스 게임을 리팩토링해 보았습니다.

 

 

데일리 미팅

어제에 이어서 크수타를 진행하였습니다. 저부터 시작하여 남은 크루들이 각자 올라온 질문에 답변을 하였습니다. 여러 가지 답변 중에서 백엔드 막내로서의 포부에 대해 궁금해하는 내용이 있었습니다. 그래서 현재는 51명의 크루 중에서 제가 제일 못한다고 생각을 하지만, 나중에 수료하고나서 사람들이 입에서 잘하는 3기 크루 중에 제 이름이 오르내렸으면 한다고 말했습니다. 그리고 지금처럼 악착같이 꾸준하게 공부한다면 할 수 있지 않을까 기대해 봅니다. 그 외에 재미난 질문들이 많았는데, 크루들의 프라이버시를 지켜주겠습니다.

 

 

체스 미션 리팩토링

처음에 체스 4단계를 수행할 때는 JS를 아예 몰랐습니다. 그래서 체스판에 말을 띄울 때, 64줄의 HTML 코드를 하나 하나 하드 코딩했습니다. 결국 원하는 기능이 나왔지만, 제 스스로도 이게 개발자인지 코더인지 헷갈릴 정도였습니다. 그래서 대학교 동기의 말대로 JS를 공부하여 이 부분은 리팩토링하겠다고 다짐했습니다. 이 다짐을 그저께하였고, 어제 정말 열심히 바닐라 JS를 이용한 투두 리스트를 완성하였습니다.

 

그리고 오늘 체스판을 띄우기 위한 제 코드가 이렇게 변했습니다.

 

 

<index.html>

<!DOCTYPE html>
<html>

<head>
  <title>체스 게임</title>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="css/style.css">
</head>

<body>
<h1>체스 게임</h1>
<table id="chess-board"></table>
<script src="js/main.js"></script>
</body>
</html>

 

 

<main.js>

createChessBoard();

function createChessBoard() {
  const pieces = [
    ["BR", "BN", "BB", "BQ", "BK", "BB", "BN", "BR"],
    new Array(8).fill("BP"),
    new Array(8),
    new Array(8),
    new Array(8),
    new Array(8),
    new Array(8).fill("WP"),
    ["WR", "WN", "WB", "WQ", "WK", "WB", "WN", "WR"]
  ]
  makeTable(pieces);
}

function makeTable(pieces) {
  const table = document.getElementById("chess-board");
  for (let i = 0; i < 8; i++) {
    table.appendChild(makeTr(pieces, i));
  }
}

function makeTr(pieces, row) {
  const newTr = document.createElement("tr");
  for (let j = 0; j < 8; j++) {
    newTr.appendChild(makeTd(pieces, row, j));
  }
  return newTr;
}

function makeTd(pieces, row, col) {
  const newTd = document.createElement("td");
  newTd.id = String.fromCharCode('a'.charCodeAt(0) + col) + String(8 - row);
  if (pieces[row][col]) {
    const piece = document.createElement("img");
    piece.src = "img/" + pieces[row][col] + ".png";
    newTd.appendChild(piece);
  }
  decideCellStyle(newTd, row, col)
  return newTd;
}

function decideCellStyle(td, row, col) {
  if ((row % 2 === 0 && col % 2 === 0) || (row % 2 === 1 && col % 2 === 1)) {
    td.setAttribute("style",
        "background-color: rgb(204, 204, 204); width: 80px; height: 82px;");
    return;
  }
  td.setAttribute("style",
      "background-color: rgb(000, 102, 051); width: 80px; height: 82px;");
}

 

 

처음부터 이미지 이름에 해당하는 값들을 배열로 관리하고, 반복문을 통하여 테이블을 만들어 주었습니다. 또한, 블록의 색깔을 회색과 초록색으로 구분해 주었는데, 이 부분도 css에서 노가다하였던 것을 td에 속성값을 설정하도록 수정하였습니다. 이 코드도 다른 잘하시는 분이 보았을 때는 바람직하지 않을 수 있지만, 제 스스로는 상당히 만족합니다. 왜냐하면, 개발하면서 재미있었고 현타가 오지 않았기 때문이죠.

 

또한, Javascript는 Number와 String의 연산에서 String을 우선시하며, Charcter 타입이 없다는 것을 알게 되었습니다. 그래서 아스키 코드 연산에 애를 먹는 과정에서 charCodeAt()과 fromCharCode() 함수를 알게 되었습니다. charCodeAt()은 Number 타입의 아스키 코드 값을 반환하는 역할을 하고, fromCharCode()는 특정 아스키 코드에 맞는 문자를 반환하는 역할을 합니다.

 

 

이후에는 특정 체스판 블록을 눌렀을 때, 클릭 이펙트를 주고 싶어졌습니다. 예를 들면 아래와 같은 것이죠.

 

 

 

 

위와 같이 이동시킬 말을 클릭하였을 때, 노란색 이펙트를 주는 것입니다.

 

 

function addClickEventListener() {
  const table = document.getElementById("chess-board");
  table.addEventListener("click", onSelectPiece);
}

function onSelectPiece(event) {
  const clickPiece = event.target.closest("td");
  if (clickPiece.childElementCount === 0) {
    alert("빈 공간은 선택할 수 없습니다!");
    return;
  }

  if (clickPiece.className !== "clicked") {
    clickPiece.classList.toggle("clicked");
    return;
  }
  clickPiece.classList.toggle("clicked");
}

 

 

이렇게 click 이벤트 리스너를 설정하였고, 빈 공간은 클릭할 수 없다는 창도 띄우게 하였습니다. 이로써, 이동시킬 말을 클릭하고 빈 공간 관련 예외 처리 기능을 구현하였습니다. 그리고 아래와 같이 선택된 체스말을 어디로 보낼지 알림창을 띄우도록 코드를 작성하였습니다.

 

 

const table = document.getElementById("chess-board");
  const children = table.children;
  for (let i = 0; i < children.length; i++) {
    const tr = children[i];
    for (let j = 0; j < tr.children.length; j++) {
      if (tr.children[j].classList.contains("clicked")) {
        alert(tr.children[j].id + "에서 " + clickPiece.id + "로 이동하시는 군요!");
        return;
      }
    }
  }

 

 

생각나는 대로 짰던 거라 가독성이 좋지는 않은데, 이런 방식으로 어디서 어디로 이동하였는지 위치 정보를 얻어올 수 있습니다. 물론, 당연히 리팩토링할 코드가 맞습니다.

 

여기서 난관에 부딪히게 되었습니다. 바로, 해당 좌표로 이동할 수 있는지 여부는 서버에게 물어보아야 하는 것이죠. 현재 알고 있는 DOM이나 BOM, EVENT 지식으로는 해결할 수 없었기에 제리에게 물어보았습니다. 제리는 ajax와 json을 이용하여 서버와 통신하였다고 말해주었습니다.

 

그제서야 투두리스트 2단계 미션이 ajax를 사용한다는 것을 알게 되었고, 우테코 코치님들은 다 계획이 있었다는 사실을 깨달았습니다. 네.. 결국 또다시 새로운 지식을 익혀야 한다는 것이죠.

 

그래서 내일부터는 ajax를 익히면서 투두리스트 2단계를 주말동안 어떻게든 끝내려고 합니다.

 

 

정리

배운 개념을 미션에 적용하고, 실제로 기능이 구현되는 것을 제 눈으로 봐서 매우 뿌듯했습니다. 이번에 새롭게 익혀야할 ajax도 처음에는 쉽지 않겠지만, 제가 열심히 하면 이 또한 잘 헤쳐나갈 것이라고 믿습니다.

 

부디 주말에는 투두 리스트 2단계를 끝내서 제가 웃고 있으면 좋겠습니다.

댓글

추천 글