반응형
게임 승리 조건 만들기
게임 승리 조건도 별거 없다. 그냥 알고리즘만 짜면 되기 때문에 별로 어렵지 않다.
우선 코드부터 보자.
function checkOmokCompleted(coord, takes) {
//(0, 1), (1, 1), (1, 0), (1, -1)
const offset = [
{ x: 1, y: 0 }, //가로
{ x: 1, y: 1 }, //대각선1
{ x: 0, y: 1 }, //세로
{ x: -1, y: 1 }, //대각선2
];
return offset.some((dir) => {
let streak = 1;
const type = (takes.length - 1) % 2;
//정방향
for (
let x = coord.x + dir.x, y = coord.y + dir.y;
x > 0 && x < 19 && y > 0 && y < 19;
x += dir.x, y += dir.y
) {
if (takes.some((t, index) => t.x == x && t.y == y && index % 2 == type))
streak++;
else break;
}
//반대방향
for (
let x = coord.x - dir.x, y = coord.y - dir.y;
x > 0 && x < 19 && y > 0 && y < 19;
x -= dir.x, y -= dir.y
) {
if (takes.some((t, index) => t.x == x && t.y == y && index % 2 == type))
streak++;
else break;
}
if (streak === 5) {
return true;
}
});
}
wsServer.on("connection", (socket) => {
...
socket.on("player_selected", (coord) => {
...
if (checkOmokCompleted(coord, room.takes)) {
console.log("Omok completed!");
wsServer.in(name).emit("game_end", isBlackTurn ? "black" : "white");
wsServer.in(name).emit("message", `${socket.id}님이 승리하셨습니다!`);
room.blackPlayer = "";
room.whitePlayer = "";
emitPlayerChange(room);
return;
}
...
});
});
주석을 보면 알 수 있겠지만 오목은 고려해야 할 방향이 가로, 세로, 양쪽 대각선 총 4개이다.
그 방향에 대한 X, Y 좌표 변동을 미리 배열로 만들어놓고, 현재 착수 위치를 기준으로 해당 방향으로 이동하며 같은 색의 돌을 더하고, 반대 방향으로 이동하며 같은 색의 돌을 더한다.
만약 다 더한 값이 정확히 5가 되면, 오목이 완성되었다는 뜻이고, 만약 아니라면 5개가 되지 않았거나 육목 이상이 되었다는 뜻이다.
오목이 완성되면 true를 반환할거고, 그럼 서버에서 해당 방의 플레이어들에게 "game_end" 메시지를 전송한다.
게임이 종료되고 팀을 바꿔서 플레이하고 싶을수도 있기 때문에 검은돌, 흰돌 플레이어를 초기화했다.
클라이언트에선 "game_end" 메시지가 수신되면 승리한 플레이어를 GameEndScreen에 표시하도록 했다.
const GamingRoom = ({ publicRoom }) => {
const [roomName, setRoomName] = React.useState(publicRoom.name);
const [blackPlayer, setBlackPlayer] = React.useState(publicRoom.blackPlayer);
const [whitePlayer, setWhitePlayer] = React.useState(publicRoom.whitePlayer);
const [takes, setTakes] = React.useState(publicRoom.takes);
const [winner, setWinner] = React.useState("");
console.log(publicRoom);
document.title = `공개방: ${roomName}`;
const onGameEnd = () => {
setWinner("");
};
const GameEndScreen = ({ winner }) => {
const text = `${winner === "black" ? "흑돌" : "백돌"} 승리!`;
return (
<div className="endscreen">
<div className="endscreen__main">
<h3 className="endscreen__text">{text}</h3>
<button className="endscreen__button" onClick={onGameEnd}>
확인
</button>
</div>
</div>
);
};
React.useEffect(() => {
...
socket.on("game_end", (winner) => {
setWinner(winner);
});
}, []);
return (
<div className="gaming-room">
...
{winner !== "" ? <GameEndScreen winner={winner} /> : null}
</div>
);
};
승리 버튼은 지금은 화면 아래쪽에 뜬다.
반응형
'Projects > Socket Omok' 카테고리의 다른 글
[Socket Omok] 11. 프로젝트 종료 (0) | 2022.06.14 |
---|---|
[Socket Omok] 10. 메세지 창 만들기 (0) | 2022.06.14 |
[Socket Omok] 8. 마지막 착수 위치 보여주기 (0) | 2022.06.13 |
[Socket Omok] 7. 플레이어 턴 진행 (0) | 2022.06.13 |
[Socket Omok] 6. 착수 위치 미리보기 및 선택하기 (0) | 2022.06.13 |