Skip to content

Commit 6f3b0e7

Browse files
committed
✨ feat : 게임 종료 로직 구현
1 parent 4c2cd3a commit 6f3b0e7

File tree

9 files changed

+95
-7
lines changed

9 files changed

+95
-7
lines changed

backend/src/main/java/io/f1/backend/domain/game/app/GameService.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
package io.f1.backend.domain.game.app;
22

3+
import static io.f1.backend.domain.game.mapper.RoomMapper.toGameResultListResponse;
4+
import static io.f1.backend.domain.game.mapper.RoomMapper.toGameSettingResponse;
5+
import static io.f1.backend.domain.game.mapper.RoomMapper.toPlayerListResponse;
36
import static io.f1.backend.domain.game.mapper.RoomMapper.toQuestionStartResponse;
7+
import static io.f1.backend.domain.game.mapper.RoomMapper.toRoomSetting;
8+
import static io.f1.backend.domain.game.mapper.RoomMapper.toRoomSettingResponse;
49
import static io.f1.backend.domain.game.websocket.WebSocketUtils.getDestination;
510
import static io.f1.backend.domain.quiz.mapper.QuizMapper.toGameStartResponse;
611

712
import io.f1.backend.domain.game.dto.MessageType;
13+
import io.f1.backend.domain.game.dto.response.GameResultResponse;
814
import io.f1.backend.domain.game.event.RoomUpdatedEvent;
915
import io.f1.backend.domain.game.model.Player;
1016
import io.f1.backend.domain.game.model.Room;
@@ -19,6 +25,7 @@
1925
import io.f1.backend.global.exception.errorcode.GameErrorCode;
2026
import io.f1.backend.global.exception.errorcode.RoomErrorCode;
2127

28+
import java.util.ArrayList;
2229
import lombok.RequiredArgsConstructor;
2330

2431
import org.springframework.context.ApplicationEventPublisher;
@@ -70,6 +77,28 @@ public void gameStart(Long roomId, UserPrincipal principal) {
7077
toQuestionStartResponse(room, START_DELAY));
7178
}
7279

80+
public void gameEnd(Room room) {
81+
room.updateRoomState(RoomState.FINISHED);
82+
83+
Long roomId = room.getId();
84+
String destination = getDestination(roomId);
85+
86+
Map<String, Player> playerSessionMap = room.getPlayerSessionMap();
87+
88+
messageSender.send(destination, MessageType.GAME_SETTING, toGameSettingResponse(room.getGameSetting(), room.getCurrentQuestion()
89+
.getQuiz()));
90+
messageSender.send(destination, MessageType.PLAYER_LIST, toPlayerListResponse(room));
91+
messageSender.send(destination, MessageType.ROOM_SETTING, toRoomSettingResponse(room));
92+
messageSender.send(destination, MessageType.GAME_RESULT, toGameResultListResponse(playerSessionMap, room.getGameSetting().getRound()));
93+
94+
room.initializeRound();
95+
for (Player player : playerSessionMap.values()) {
96+
player.initializeCorrectCount();
97+
player.toggleReady();
98+
}
99+
room.updateRoomState(RoomState.WAITING);
100+
}
101+
73102
private boolean validateReadyStatus(Room room) {
74103

75104
Map<String, Player> playerSessionMap = room.getPlayerSessionMap();

backend/src/main/java/io/f1/backend/domain/game/app/RoomService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
@RequiredArgsConstructor
6060
public class RoomService {
6161

62+
private final GameService gameService;
6263
private final TimerService timerService;
6364
private final QuizService quizService;
6465
private final RoomRepository roomRepository;
@@ -263,9 +264,8 @@ public void chat(Long roomId, String sessionId, ChatMessage chatMessage) {
263264

264265
timerService.cancelTimer(room);
265266

266-
// TODO : 게임 종료 로직 추가
267267
if (!timerService.validateCurrentRound(room)) {
268-
// 게임 종료 로직
268+
gameService.gameEnd(room);
269269
return;
270270
}
271271

backend/src/main/java/io/f1/backend/domain/game/app/TimerService.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public class TimerService {
2626
private static final String NONE_CORRECT_USER = "";
2727
private static final int CONTINUE_DELAY = 3;
2828

29+
private final GameService gameService;
30+
2931
public void startTimer(Room room, int delaySec) {
3032
cancelTimer(room);
3133

@@ -53,14 +55,11 @@ private void handleTimeout(Room room) {
5355
MessageType.SYSTEM_NOTICE,
5456
ofPlayerEvent(NONE_CORRECT_USER, RoomEventType.TIMEOUT));
5557

56-
// TODO : 게임 종료 로직
5758
if (!validateCurrentRound(room)) {
58-
// 게임 종료 로직
59-
// GAME_SETTING, PLAYER_LIST, GAME_RESULT, ROOM_SETTING
59+
gameService.gameEnd(room);
6060
return;
6161
}
6262

63-
// 다음 문제 출제
6463
room.increaseCurrentRound();
6564

6665
startTimer(room, CONTINUE_DELAY);

backend/src/main/java/io/f1/backend/domain/game/dto/MessageType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ public enum MessageType {
99
CHAT,
1010
QUESTION_RESULT,
1111
RANK_UPDATE,
12-
QUESTION_START
12+
QUESTION_START,
13+
GAME_RESULT
1314
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.f1.backend.domain.game.dto.response;
2+
3+
import java.util.List;
4+
5+
public record GameResultListResponse(List<GameResultResponse> result) {
6+
7+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package io.f1.backend.domain.game.dto.response;
2+
3+
public record GameResultResponse(String nickname, int score, int totalCorrectCount, int rank) {
4+
}

backend/src/main/java/io/f1/backend/domain/game/mapper/RoomMapper.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import io.f1.backend.domain.game.dto.Rank;
44
import io.f1.backend.domain.game.dto.RoomEventType;
55
import io.f1.backend.domain.game.dto.request.RoomCreateRequest;
6+
import io.f1.backend.domain.game.dto.response.GameResultListResponse;
7+
import io.f1.backend.domain.game.dto.response.GameResultResponse;
68
import io.f1.backend.domain.game.dto.response.GameSettingResponse;
79
import io.f1.backend.domain.game.dto.response.PlayerListResponse;
810
import io.f1.backend.domain.game.dto.response.PlayerResponse;
@@ -21,8 +23,10 @@
2123
import io.f1.backend.domain.quiz.entity.Quiz;
2224

2325
import java.time.Instant;
26+
import java.util.ArrayList;
2427
import java.util.Comparator;
2528
import java.util.List;
29+
import java.util.Map;
2630

2731
public class RoomMapper {
2832

@@ -109,4 +113,40 @@ public static QuestionStartResponse toQuestionStartResponse(Room room, int delay
109113
room.getCurrentRound(),
110114
Instant.now().plusSeconds(delay));
111115
}
116+
117+
public static GameResultResponse toGameResultResponse(Player player, int round, int rank, int totalPlayers) {
118+
double correctRate = (double) player.getCorrectCount() / round;
119+
int score = (int) (correctRate * 100) + (totalPlayers - rank) * 5;
120+
121+
return new GameResultResponse(player.nickname, score, player.getCorrectCount(), rank);
122+
}
123+
124+
public static GameResultListResponse toGameResultListResponse(Map<String, Player> playerSessionMap, int round) {
125+
126+
List<Player> rankedPlayers = playerSessionMap.values().stream()
127+
.sorted(Comparator.comparingInt(Player::getCorrectCount).reversed())
128+
.toList();
129+
130+
int totalPlayers = rankedPlayers.size();
131+
132+
int prevCorrectCnt = -1;
133+
int rank = 0;
134+
135+
List<GameResultResponse> gameResults = new ArrayList<>();
136+
for(int i=0; i<totalPlayers; i++) {
137+
Player player = rankedPlayers.get(i);
138+
139+
int correctCnt = player.getCorrectCount();
140+
141+
if(prevCorrectCnt != correctCnt) {
142+
rank = i + 1;
143+
}
144+
145+
gameResults.add(toGameResultResponse(player, round, rank, totalPlayers));
146+
prevCorrectCnt = correctCnt;
147+
}
148+
149+
return new GameResultListResponse(gameResults);
150+
}
112151
}
152+

backend/src/main/java/io/f1/backend/domain/game/model/Player.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,8 @@ public void toggleReady() {
2727
public void increaseCorrectCount() {
2828
correctCount++;
2929
}
30+
31+
public void initializeCorrectCount() {
32+
correctCount = 0;
33+
}
3034
}

backend/src/main/java/io/f1/backend/domain/game/model/Room.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,8 @@ public Boolean isPlaying() {
9090
public void increaseCurrentRound() {
9191
currentRound++;
9292
}
93+
94+
public void initializeRound() {
95+
currentRound = 0;
96+
}
9397
}

0 commit comments

Comments
 (0)