본문 바로가기
Projects/Socket Omok

[Socket Omok] 7. 플레이어 턴 진행

by DevJaewoo 2022. 6. 13.
반응형

플레이어 턴 진행

이제 플레이어가 팀도 선택할 수 있고, 착수도 할 수 있으니 언제 착수시킬건지만 정하면 된다.

클라이언트에서 착수 신호를 보내도, 응답을 받기 전까지는 착수한 돌을 화면에 표시하지 않도록 해야된다.

또한 착수가 잘못되었으면 착수 메시지를 무시하고, 다시 해당 플레이어에게 턴을 넘겨줘야 한다.

 

플레이어가 착수하면 서버에 "player_selected" 신호를 주고, 만약 정상적인 착수라면 해당 방에 참가한 모든 플레이어들에게 "player_selected" 신호를 돌려주어 오목판을 업데이트 하도록 했다.

  socket.on("player_selected", (coord) => {
    const name = getJoinedRoomName(socket);
    const room = getPublicRoom(name);

    if (room === undefined) {
      console.log(`Room ${name} is not existing.`);
      return;
    }

    const isBlackTurn = room.takes.length % 2 == 0;

    if (isBlackTurn) {
      //흑돌
      if (room.blackPlayer !== socket.id) {
        socket.emit("error", "흑돌 플레이어가 아닙니다.");
        return;
      }
    } else {
      //백돌
      if (room.whitePlayer !== socket.id) {
        socket.emit("error", "백돌 플레이어가 아닙니다.");
        return;
      }
    }

    if (
      findSocketByID(room.blackPlayer) === undefined ||
      findSocketByID(room.whitePlayer) === undefined
    ) {
      socket.emit("error", "상대가 존재하지 않습니다.");
      return;
    }

    if (
      room.takes.find((c) => c.x === coord.x && c.y === coord.y) !== undefined
    ) {
      socket.emit("error", "이미 다른 돌이 위치하고 있습니다.");
      socket.emit("player_select");
      return;
    }

    room.takes.push(coord);
    wsServer.in(name).emit("player_selected", coord);

    if (isBlackTurn) {
      findSocketByID(room.whitePlayer).emit("player_select");
    } else {
      findSocketByID(room.blackPlayer).emit("player_select");
    }
  });

 

또한 현재 선택해야하는 플레이어한테만 "player_select" 신호를 주도록 했고, 클라이언트에선 이 신호가 오지 않으면 이벤트를 감지하지 않도록 했다.

const OmokBoard = ({ takes }) => {
  const [inBoard, setInBoard] = React.useState(false);
  const [myTurn, setMyTurn] = React.useState(false);
  const [coord, setCoord] = React.useState({});

  React.useState(() => {
    socket.on("player_select", () => {
      setMyTurn(true);
    });

    socket.on("player_change", () => {
      setMyTurn(false);
    });
  }, []);
  
  ...

  return (
    <div className="omokboard">
      {myTurn ? (
        <CoordSelectArea
          onBoardEnter={handleBoardEnter}
          onBoardMove={handleBoardMove}
          onBoardLeave={handleBoardLeave}
          onBoardSelect={handleBoardSelect}
        />
      ) : null}
      
      ...
      
      {myTurn && inBoard ? (
        <MemoriedStone
          type={[takes.length % 2 == 0 ? "black" : "white", "hint"]}
          x={coord.x}
          y={coord.y}
        />
      ) : null}
    </div>
  );
};

 

현재 시나리오는 다음과 같다.

  • 서버에서 상대 플레이어에게 턴 지정 (player_select)
  • 플레이어가 착수 (player_selected)
  • 서버에서 같은 방의 플레이어들에게 착수 알림 (player_selected)

 

실행 결과
잘 된다.

 

반응형