Skip to content

Commit

Permalink
feat: 결과 조회 기능 구현 (#46)
Browse files Browse the repository at this point in the history
* feat: 게임이 끝나지않았을때 예외 추가

* feat: 게임 결과 반환 기능 구현
  • Loading branch information
thdwoqor authored May 20, 2024
1 parent 5b1e231 commit 238c4f5
Show file tree
Hide file tree
Showing 10 changed files with 206 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public enum ExceptionCode {
INVALID_CONTENT(106, "내용이 누락 되었습니다."),
NOT_ALIVE_PLAYER(107, "이미 사망한 사람입니다."),
INVALID_PLAYER(108, "존재 하지 않는 사람입니다."),
GAME_IS_NOT_FINISHED(108, "현재 게임이 진행 중입니다."),

NOT_PARTICIPATING_GAME(200, "게임에 참가해 주십시오."),
INVALID_JOB(201, "마피아만 지목 대상을 볼 수 있습니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import mafia.mafiatogether.service.dto.RoomCreateRequest;
import mafia.mafiatogether.service.dto.RoomInfoResponse;
import mafia.mafiatogether.service.dto.RoomModifyRequest;
import mafia.mafiatogether.service.dto.RoomResultResponse;
import mafia.mafiatogether.service.dto.RoomStatusResponse;
import mafia.mafiatogether.service.dto.RoomValidateResponse;
import org.springframework.http.ResponseEntity;
Expand Down Expand Up @@ -79,4 +80,11 @@ public ResponseEntity<RoomInfoResponse> findRoomInfo(
) {
return ResponseEntity.ok(roomService.findRoomInfo(playerInfoDto.code(), playerInfoDto.name()));
}

@GetMapping("/result")
public ResponseEntity<RoomResultResponse> findResult(
@PlayerInfo final PlayerInfoDto playerInfoDto
) {
return ResponseEntity.ok(roomService.findResult(playerInfoDto.code()));
}
}
18 changes: 15 additions & 3 deletions src/main/java/mafia/mafiatogether/domain/Room.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public StatusType getStatusType(final Long now) {
return status.getType();
}

// statusType 제거
public void modifyStatus(final StatusType statusType, final Long now) {
this.status = status.getNextStatus(this, now);
}
Expand Down Expand Up @@ -114,11 +115,22 @@ public Long getPlayerCount() {
}

public boolean isEnd() {
final long playerCount = getPlayerCount();
final long mafia = players.values().stream()
long aliveMafia = getAliveMafia();
return getAliveCitizen() / 2 < aliveMafia || aliveMafia == 0;
}

public long getAliveMafia(){
return players.values().stream()
.filter(player -> player.getJobType().equals(JobType.MAFIA))
.filter(player -> player.isAlive() == true)
.count();
}

public long getAliveCitizen(){
return players.values().stream()
.filter(player -> !player.getJobType().equals(JobType.MAFIA))
.filter(player -> player.isAlive() == true)
.count();
return playerCount / 2 < mafia || mafia == 0;
}

public void executeVote() {
Expand Down
52 changes: 49 additions & 3 deletions src/main/java/mafia/mafiatogether/domain/status/EndStatus.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,63 @@
package mafia.mafiatogether.domain.status;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import mafia.mafiatogether.domain.Player;
import mafia.mafiatogether.domain.Room;
import mafia.mafiatogether.domain.job.JobType;

public class EndStatus extends Status {

private final List<Player> players;

public static final Long ONE_MINUTE = 60_000L;

private EndStatus(final Long start, final Long end) {
private EndStatus(final List<Player> players, final Long start, final Long end) {
super(start, end);
this.players = players;
}

public static EndStatus create(final List<Player> players, final Long now) {
return new EndStatus(players, now, now + ONE_MINUTE);
}

public JobType getWinnerJob() {
if(getAliveMafia()==0){
return JobType.CITIZEN;
}
return JobType.MAFIA;
}

private Map<Boolean, List<Player>> partitionPlayersByRole() {
return players
.stream()
.collect(Collectors.partitioningBy(Player::isMafia));
}

public List<Player> getWinner() {
Map<Boolean, List<Player>> players = partitionPlayersByRole();

if (getAliveMafia() == 0) {
return players.get(Boolean.FALSE);
}
return players.get(Boolean.TRUE);
}

public List<Player> getLoser() {
Map<Boolean, List<Player>> players = partitionPlayersByRole();

if (getAliveMafia() == 0) {
return players.get(Boolean.TRUE);
}
return players.get(Boolean.FALSE);
}

public static EndStatus create(final Long now) {
return new EndStatus(now, now + ONE_MINUTE);
private long getAliveMafia(){
return players.stream()
.filter(player -> player.getJobType().equals(JobType.MAFIA))
.filter(player -> player.isAlive() == true)
.count();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package mafia.mafiatogether.domain.status;

import java.util.List;
import mafia.mafiatogether.domain.Player;
import mafia.mafiatogether.domain.Room;

public class NightStatus extends Status {
Expand All @@ -17,8 +19,12 @@ public static NightStatus create(final Long now) {
@Override
public Status getNextStatus(final Room room, final Long now) {
room.executeJobTarget();
final List<Player> players = room.getPlayers()
.values()
.stream()
.toList();
if (room.isEnd()) {
return EndStatus.create(now);
return EndStatus.create(players, now);
}
return DayIntroStatus.create(now);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package mafia.mafiatogether.domain.status;

import java.util.List;
import mafia.mafiatogether.domain.Player;
import mafia.mafiatogether.domain.Room;

public class VoteResultStatus extends Status {
Expand All @@ -17,7 +19,11 @@ protected static VoteResultStatus create(final Long now) {
@Override
public Status getNextStatus(final Room room, final Long now) {
if (room.isEnd()) {
return EndStatus.create(now);
final List<Player> players = room.getPlayers()
.values()
.stream()
.toList();
return EndStatus.create(players, now);
}
return NightIntroStatus.create(now);
}
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/mafia/mafiatogether/service/RoomService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@

import java.time.Clock;
import lombok.RequiredArgsConstructor;
import mafia.mafiatogether.config.exception.ExceptionCode;
import mafia.mafiatogether.config.exception.RoomException;
import mafia.mafiatogether.domain.Player;
import mafia.mafiatogether.domain.Room;
import mafia.mafiatogether.domain.RoomManager;
import mafia.mafiatogether.domain.status.EndStatus;
import mafia.mafiatogether.service.dto.RoomCodeResponse;
import mafia.mafiatogether.service.dto.RoomCreateRequest;
import mafia.mafiatogether.service.dto.RoomInfoResponse;
import mafia.mafiatogether.service.dto.RoomModifyRequest;
import mafia.mafiatogether.service.dto.RoomResultResponse;
import mafia.mafiatogether.service.dto.RoomStatusResponse;
import mafia.mafiatogether.service.dto.RoomValidateResponse;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -50,4 +54,12 @@ public RoomInfoResponse findRoomInfo(final String code, final String name) {
public RoomValidateResponse validateCode(final String code) {
return new RoomValidateResponse(roomManager.validateCode(code));
}

public RoomResultResponse findResult(final String code) {
final Room room = roomManager.findByCode(code);
if(!room.isEnd()){
throw new RoomException(ExceptionCode.GAME_IS_NOT_FINISHED);
}
return RoomResultResponse.of((EndStatus) room.getStatus());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package mafia.mafiatogether.service.dto;

import mafia.mafiatogether.domain.Player;

public record RoomResultPlayerDto(
String name,
Boolean isAlive,
String job
) {
public static RoomResultPlayerDto of(
final Player player
) {
return new RoomResultPlayerDto(
player.getName(),
player.isAlive(),
player.getJobType().name()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package mafia.mafiatogether.service.dto;

import java.sql.Timestamp;
import java.util.List;
import mafia.mafiatogether.domain.status.EndStatus;

public record RoomResultResponse(
String winnerJob,
Timestamp endTime,
List<RoomResultPlayerDto> winner,
List<RoomResultPlayerDto> loser
) {
public static RoomResultResponse of(
final EndStatus endStatus
) {
final List<RoomResultPlayerDto> winner = endStatus.getWinner()
.stream()
.map(RoomResultPlayerDto::of)
.toList();

final List<RoomResultPlayerDto> loser = endStatus.getLoser()
.stream()
.map(RoomResultPlayerDto::of)
.toList();

return new RoomResultResponse(
endStatus.getWinnerJob().name(),
endStatus.getEndTime(),
winner,
loser
);
}
}
55 changes: 55 additions & 0 deletions src/test/java/mafia/mafiatogether/domain/status/EndStatusTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package mafia.mafiatogether.domain.status;

import java.time.Clock;
import java.util.List;
import mafia.mafiatogether.domain.Player;
import mafia.mafiatogether.domain.job.JobType;
import mafia.mafiatogether.domain.job.Mafia;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

class EndStatusTest {

@Test
void 시민_승리_결과_반환() {
Mafia mafia = new Mafia();
Player A = Player.create("A");
A.modifyJob(mafia);
A.kill();
Player B = Player.create("B");
B.modifyJob(mafia);
B.kill();
Player C = Player.create("C");
Player D = Player.create("D");
Player E = Player.create("E");

List<Player> players = List.of(A, B, C, D, E);

EndStatus endStatus = EndStatus.create(players, Clock.systemUTC().millis());

Assertions.assertThat(endStatus.getWinnerJob()).isEqualTo(JobType.CITIZEN);
Assertions.assertThat(endStatus.getWinner()).containsAll(List.of(C, D, E));
Assertions.assertThat(endStatus.getLoser()).containsAll(List.of(A, B));
}

@Test
void 마피아_승리_결과_반환() {
Mafia mafia = new Mafia();
Player A = Player.create("A");
A.modifyJob(mafia);
Player B = Player.create("B");
B.modifyJob(mafia);
Player C = Player.create("C");
C.kill();
Player D = Player.create("D");
Player E = Player.create("E");

List<Player> players = List.of(A, B, C, D, E);

EndStatus endStatus = EndStatus.create(players, Clock.systemUTC().millis());

Assertions.assertThat(endStatus.getWinnerJob()).isEqualTo(JobType.MAFIA);
Assertions.assertThat(endStatus.getLoser()).containsAll(List.of(C, D, E));
Assertions.assertThat(endStatus.getWinner()).containsAll(List.of(A, B));
}
}

0 comments on commit 238c4f5

Please sign in to comment.