Skip to content

Commit 4885ae9

Browse files
committed
✨ feat : 방 게임 시작 구현
1 parent a1d6dc6 commit 4885ae9

File tree

9 files changed

+59
-27
lines changed

9 files changed

+59
-27
lines changed

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

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010
import static io.f1.backend.global.util.SecurityUtils.getCurrentUserId;
1111
import static io.f1.backend.global.util.SecurityUtils.getCurrentUserNickname;
1212

13+
import io.f1.backend.domain.game.dto.GameStartData;
1314
import io.f1.backend.domain.game.dto.RoomEventType;
1415
import io.f1.backend.domain.game.dto.RoomExitData;
1516
import io.f1.backend.domain.game.dto.RoomInitialData;
1617
import io.f1.backend.domain.game.dto.request.RoomCreateRequest;
1718
import io.f1.backend.domain.game.dto.request.RoomValidationRequest;
1819
import io.f1.backend.domain.game.dto.response.GameSettingResponse;
20+
import io.f1.backend.domain.game.dto.response.GameStartResponse;
1921
import io.f1.backend.domain.game.dto.response.PlayerListResponse;
2022
import io.f1.backend.domain.game.dto.response.RoomCreateResponse;
2123
import io.f1.backend.domain.game.dto.response.RoomListResponse;
@@ -192,32 +194,51 @@ private static Player createPlayer() {
192194
return new Player(getCurrentUserId(), getCurrentUserNickname());
193195
}
194196

195-
@Transactional(readOnly = true)
196-
public Integer checkGameSetting(Long roomId, Long quizId) {
197-
Room room =
198-
roomRepository
199-
.findRoom(roomId)
200-
.orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다."));
197+
private Integer checkGameSetting(Room room, Long quizId) {
201198

202199
GameSetting gameSetting = room.getGameSetting();
203200

204201
Long roomQuizId = gameSetting.getQuizId();
205202

206-
// TODO : 에러 코드 추가하기
207203
if(!roomQuizId.equals(quizId)) {
208-
throw new IllegalArgumentException("게임 설정이 다릅니다. (게임을 시작할 수 없습니다.)");
204+
throw new IllegalArgumentException("E409002 : 게임 설정이 다릅니다. (게임을 시작할 수 없습니다.)");
209205
}
210206

211207
return gameSetting.getRound();
212208
}
213209

214-
@Transactional
215-
public void gameStart(Long roomId) {
210+
public GameStartData gameStart(Long roomId, Long quizId) {
211+
216212
Room room =
217213
roomRepository
218214
.findRoom(roomId)
219215
.orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다."));
220216

221-
room.gameStart();
217+
if(!validateReadyStatus(room)){
218+
throw new IllegalArgumentException("E403004 : 레디 상태가 아닙니다.");
219+
}
220+
221+
// 방의 gameSetting에 설정된 퀴즈랑 요청 퀴즈랑 같은지 체크 후 GameSetting에서 라운드 가져오기
222+
Integer round = checkGameSetting(room, quizId);
223+
224+
// 라운드 수만큼 랜덤 Question 추출
225+
GameStartResponse questions = quizService.getRandomQuestionsWithoutAnswer(quizId, round);
226+
227+
// 방 정보 게임 중으로 변경
228+
room.updateRoomState(RoomState.PLAYING);
229+
230+
return new GameStartData(getDestination(roomId), questions);
231+
}
232+
233+
private boolean validateReadyStatus(Room room) {
234+
235+
Map<String, Player> playerSessionMap = room.getPlayerSessionMap();
236+
237+
for(Player player : playerSessionMap.values()) {
238+
if(!player.isReady()) {
239+
return false;
240+
}
241+
}
242+
return true;
222243
}
223244
}
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;
2+
3+
import io.f1.backend.domain.game.dto.response.GameStartResponse;
4+
5+
public record GameStartData(String destination, GameStartResponse gameStartResponse) {
6+
7+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ public enum MessageType {
55
GAME_SETTING,
66
PLAYER_LIST,
77
SYSTEM_NOTICE,
8+
GAME_START,
89
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public void updateHost(Player nextHost) {
4040
this.host = nextHost;
4141
}
4242

43-
public void gameStart() {
44-
this.state = RoomState.PLAYING;
43+
public void updateRoomState(RoomState newState) {
44+
this.state = newState;
4545
}
4646
}

backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.f1.backend.domain.game.websocket;
22

33
import io.f1.backend.domain.game.app.RoomService;
4+
import io.f1.backend.domain.game.dto.GameStartData;
45
import io.f1.backend.domain.game.dto.MessageType;
56
import io.f1.backend.domain.game.dto.RoomExitData;
67
import io.f1.backend.domain.game.dto.RoomInitialData;
@@ -64,12 +65,11 @@ public void gameStart(@DestinationVariable Long roomId, Message<GameStartRequest
6465

6566
Long quizId = message.getPayload().quizId();
6667

67-
Integer round = roomService.checkGameSetting(roomId, quizId);
68+
GameStartData gameStartData = roomService.gameStart(roomId, quizId);
6869

69-
// TODO : 라운드 수만큼 랜덤하게 문제 주기..!
70-
GameStartResponse questions = quizService.getQuestionsWithoutAnswer(quizId, round);
70+
String destination = gameStartData.destination();
7171

72-
roomService.gameStart(roomId);
72+
messageSender.send(destination, MessageType.GAME_START, gameStartData.gameStartResponse());
7373

7474
}
7575

backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
import io.f1.backend.domain.game.dto.response.GameStartResponse;
88
import io.f1.backend.domain.question.app.QuestionService;
99
import io.f1.backend.domain.question.dto.QuestionRequest;
10+
import io.f1.backend.domain.question.entity.Question;
1011
import io.f1.backend.domain.quiz.dao.QuizRepository;
11-
import io.f1.backend.domain.quiz.dto.GameQuestionResponse;
1212
import io.f1.backend.domain.quiz.dto.QuizCreateRequest;
1313
import io.f1.backend.domain.quiz.dto.QuizCreateResponse;
1414
import io.f1.backend.domain.quiz.dto.QuizListPageResponse;
@@ -218,15 +218,13 @@ public QuizQuestionListResponse getQuizWithQuestions(Long quizId) {
218218
}
219219

220220
@Transactional(readOnly = true)
221-
public GameStartResponse getQuestionsWithoutAnswer(Long quizId, Integer round) {
222-
Quiz quiz =
223-
quizRepository
224-
.findById(quizId)
221+
public GameStartResponse getRandomQuestionsWithoutAnswer(Long quizId, Integer round) {
222+
quizRepository.findById(quizId)
225223
.orElseThrow(() -> new NoSuchElementException("존재하지 않는 퀴즈입니다."));
226224

225+
List<Question> randomQuestions = quizRepository.findRandQuestionsByQuizId(quizId, round);
227226

228-
229-
return toGameStartResponse(quiz);
227+
return toGameStartResponse(randomQuestions);
230228
}
231229

232230
}

backend/src/main/java/io/f1/backend/domain/quiz/dao/QuizRepository.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package io.f1.backend.domain.quiz.dao;
22

3+
import io.f1.backend.domain.question.entity.Question;
34
import io.f1.backend.domain.quiz.entity.Quiz;
45

6+
import java.util.List;
57
import org.springframework.data.domain.Page;
68
import org.springframework.data.domain.Pageable;
79
import org.springframework.data.jpa.repository.JpaRepository;
@@ -15,4 +17,7 @@ public interface QuizRepository extends JpaRepository<Quiz, Long> {
1517

1618
@Query("SELECT MIN(q.id) FROM Quiz q")
1719
Long getQuizMinId();
20+
21+
@Query(value="SELECT * FROM question WHERE quiz_id = :quizId ORDER BY RAND() LIMIT :round", nativeQuery = true)
22+
List<Question> findRandQuestionsByQuizId(Long quizId, Integer round);
1823
}

backend/src/main/java/io/f1/backend/domain/quiz/mapper/QuizMapper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public static GameQuestionResponse toGameQuestionResponse(Question question) {
9595
return new GameQuestionResponse(question.getId(), question.getTextQuestion().getContent());
9696
}
9797

98-
public static GameStartResponse toGameStartResponse(Quiz quiz) {
99-
return new GameStartResponse(toGameQuestionResponseList(quiz.getQuestions()));
98+
public static GameStartResponse toGameStartResponse(List<Question> questions) {
99+
return new GameStartResponse(toGameQuestionResponseList(questions));
100100
}
101101
}

backend/src/main/java/io/f1/backend/global/config/SecurityConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public SecurityFilterChain userFilterChain(HttpSecurity http) throws Exception {
3838
"/oauth2/**",
3939
"/signup",
4040
"/css/**",
41-
"/js/**")
41+
"/js/**","/**")
4242
.permitAll()
4343
.requestMatchers("/ws/**")
4444
.authenticated()

0 commit comments

Comments
 (0)