Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
import static io.f1.backend.global.util.SecurityUtils.getCurrentUserId;
import static io.f1.backend.global.util.SecurityUtils.getCurrentUserNickname;

import io.f1.backend.domain.game.dto.GameStartData;
import io.f1.backend.domain.game.dto.RoomEventType;
import io.f1.backend.domain.game.dto.RoomExitData;
import io.f1.backend.domain.game.dto.RoomInitialData;
import io.f1.backend.domain.game.dto.request.RoomCreateRequest;
import io.f1.backend.domain.game.dto.request.RoomValidationRequest;
import io.f1.backend.domain.game.dto.response.GameSettingResponse;
import io.f1.backend.domain.game.dto.response.GameStartResponse;
import io.f1.backend.domain.game.dto.response.PlayerListResponse;
import io.f1.backend.domain.game.dto.response.RoomCreateResponse;
import io.f1.backend.domain.game.dto.response.RoomListResponse;
Expand Down Expand Up @@ -190,4 +192,52 @@ private static String getDestination(Long roomId) {
private static Player createPlayer() {
return new Player(getCurrentUserId(), getCurrentUserNickname());
}

private Integer checkGameSetting(Room room, Long quizId) {

GameSetting gameSetting = room.getGameSetting();

Long roomQuizId = gameSetting.getQuizId();

if (!roomQuizId.equals(quizId)) {
throw new IllegalArgumentException("E409002 : 게임 설정이 다릅니다. (게임을 시작할 수 없습니다.)");
}

return gameSetting.getRound();
}

public GameStartData gameStart(Long roomId, Long quizId) {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 gameService로 분리하면 좋을 것 같습니다! 🧚‍♀️

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 확인했습니다 ! 🪄

Room room =
roomRepository
.findRoom(roomId)
.orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다."));

if (!validateReadyStatus(room)) {
throw new IllegalArgumentException("E403004 : 레디 상태가 아닙니다.");
}

// 방의 gameSetting에 설정된 퀴즈랑 요청 퀴즈랑 같은지 체크 후 GameSetting에서 라운드 가져오기
Integer round = checkGameSetting(room, quizId);

// 라운드 수만큼 랜덤 Question 추출
GameStartResponse questions = quizService.getRandomQuestionsWithoutAnswer(quizId, round);

// 방 정보 게임 중으로 변경
room.updateRoomState(RoomState.PLAYING);

return new GameStartData(getDestination(roomId), questions);
}

private boolean validateReadyStatus(Room room) {

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

for (Player player : playerSessionMap.values()) {
if (!player.isReady()) {
return false;
}
}
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.f1.backend.domain.game.dto;

import io.f1.backend.domain.game.dto.response.GameStartResponse;

public record GameStartData(String destination, GameStartResponse gameStartResponse) {}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ public enum MessageType {
GAME_SETTING,
PLAYER_LIST,
SYSTEM_NOTICE,
GAME_START,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package io.f1.backend.domain.game.dto.request;

public record GameStartRequest(Long quizId) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.f1.backend.domain.game.dto.response;

import io.f1.backend.domain.quiz.dto.GameQuestionResponse;

import java.util.List;

public record GameStartResponse(List<GameQuestionResponse> questions) {}
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,8 @@ public Room(Long id, RoomSetting roomSetting, GameSetting gameSetting, Player ho
public void updateHost(Player nextHost) {
this.host = nextHost;
}

public void updateRoomState(RoomState newState) {
this.state = newState;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package io.f1.backend.domain.game.websocket;

import io.f1.backend.domain.game.app.RoomService;
import io.f1.backend.domain.game.dto.GameStartData;
import io.f1.backend.domain.game.dto.MessageType;
import io.f1.backend.domain.game.dto.RoomExitData;
import io.f1.backend.domain.game.dto.RoomInitialData;
import io.f1.backend.domain.game.dto.request.GameStartRequest;
import io.f1.backend.domain.quiz.app.QuizService;

import lombok.RequiredArgsConstructor;

Expand All @@ -19,6 +22,7 @@ public class GameSocketController {

private final MessageSender messageSender;
private final RoomService roomService;
private final QuizService quizService;

@MessageMapping("/room/enter/{roomId}")
public void roomEnter(@DestinationVariable Long roomId, Message<?> message) {
Expand Down Expand Up @@ -55,6 +59,18 @@ public void exitRoom(@DestinationVariable Long roomId, Message<?> message) {
}
}

@MessageMapping("/room/start/{roomId}")
public void gameStart(@DestinationVariable Long roomId, Message<GameStartRequest> message) {

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

GameStartData gameStartData = roomService.gameStart(roomId, quizId);

String destination = gameStartData.destination();

messageSender.send(destination, MessageType.GAME_START, gameStartData.gameStartResponse());
}

private static String getSessionId(Message<?> message) {
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
return accessor.getSessionId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

import static java.nio.file.Files.deleteIfExists;

import io.f1.backend.domain.game.dto.response.GameStartResponse;
import io.f1.backend.domain.question.app.QuestionService;
import io.f1.backend.domain.question.dto.QuestionRequest;
import io.f1.backend.domain.question.entity.Question;
import io.f1.backend.domain.quiz.dao.QuizRepository;
import io.f1.backend.domain.quiz.dto.QuizCreateRequest;
import io.f1.backend.domain.quiz.dto.QuizCreateResponse;
Expand Down Expand Up @@ -205,6 +207,7 @@ public Long getQuizMinId() {
return quizRepository.getQuizMinId();
}

@Transactional(readOnly = true)
public QuizQuestionListResponse getQuizWithQuestions(Long quizId) {
Quiz quiz =
quizRepository
Expand All @@ -213,4 +216,15 @@ public QuizQuestionListResponse getQuizWithQuestions(Long quizId) {

return quizToQuizQuestionListResponse(quiz);
}

@Transactional(readOnly = true)
public GameStartResponse getRandomQuestionsWithoutAnswer(Long quizId, Integer round) {
quizRepository
.findById(quizId)
.orElseThrow(() -> new NoSuchElementException("존재하지 않는 퀴즈입니다."));

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

return toGameStartResponse(randomQuestions);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package io.f1.backend.domain.quiz.dao;

import io.f1.backend.domain.question.entity.Question;
import io.f1.backend.domain.quiz.entity.Quiz;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

public interface QuizRepository extends JpaRepository<Quiz, Long> {

Page<Quiz> findQuizzesByTitleContaining(String title, Pageable pageable);
Expand All @@ -15,4 +18,9 @@ public interface QuizRepository extends JpaRepository<Quiz, Long> {

@Query("SELECT MIN(q.id) FROM Quiz q")
Long getQuizMinId();

@Query(
value = "SELECT * FROM question WHERE quiz_id = :quizId ORDER BY RAND() LIMIT :round",
nativeQuery = true)
List<Question> findRandQuestionsByQuizId(Long quizId, Integer round);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package io.f1.backend.domain.quiz.dto;

public record GameQuestionResponse(Long id, String question) {}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package io.f1.backend.domain.quiz.mapper;

import io.f1.backend.domain.game.dto.response.GameStartResponse;
import io.f1.backend.domain.question.dto.QuestionResponse;
import io.f1.backend.domain.question.entity.Question;
import io.f1.backend.domain.quiz.dto.GameQuestionResponse;
import io.f1.backend.domain.quiz.dto.QuizCreateRequest;
import io.f1.backend.domain.quiz.dto.QuizCreateResponse;
import io.f1.backend.domain.quiz.dto.QuizListPageResponse;
Expand Down Expand Up @@ -83,4 +85,16 @@ public static QuizQuestionListResponse quizToQuizQuestionListResponse(Quiz quiz)
quiz.getQuestions().size(),
questionsToQuestionResponses(quiz.getQuestions()));
}

public static List<GameQuestionResponse> toGameQuestionResponseList(List<Question> questions) {
return questions.stream().map(QuizMapper::toGameQuestionResponse).toList();
}

public static GameQuestionResponse toGameQuestionResponse(Question question) {
return new GameQuestionResponse(question.getId(), question.getTextQuestion().getContent());
}

public static GameStartResponse toGameStartResponse(List<Question> questions) {
return new GameStartResponse(toGameQuestionResponseList(questions));
}
}