prepare.ts 4.11 KB
import { Game } from "../../game/Game";
import { Room } from "../../room/Room";
import { RoomManager } from "../../room/RoomManager";
import { User } from "../../user/User";
import { SocketTester } from "./SocketTester";

/**
 * 유저들을 만듭니다.
 * @param userCount 만들어지는 유저 수입니다.
 * @returns 만들어진 유저들을 반환합니다.
 */
export function prepareUsers(userCount: number): {
  sockets: SocketTester[];
  users: User[];
  roomManager: RoomManager;
} {
  const roomManager = new RoomManager();
  let sockets = [];
  let users = [];
  for (let i = 0; i < userCount; i++) {
    const socket = new SocketTester(roomManager);
    sockets.push(socket);

    socket.login(`guest${i + 1}`);
    if (!socket.connection.user) {
      throw new Error("User is not initialized.");
    }
    users.push(socket.connection.user);
  }
  return { sockets, users, roomManager };
}

/**
 * 유저들과 빈 방들을 만듭니다.
 * @param userCount 만들어지는 유저 수입니다.
 * @param roomCount 만들어지는 방 수입니다.
 * @param roomMaxConnections 각 방의 최대 접속 인원 수 입니다.
 * @returns 생성된 소켓, 유저, 방을 반환합니다.
 */
export function prepareUsersEmptyRooms(
  userCount: number,
  roomCount: number,
  roomMaxConnections: number = 2
): {
  sockets: SocketTester[];
  users: User[];
  rooms: Room[];
  roomManager: RoomManager;
} {
  const { sockets, users, roomManager } = prepareUsers(userCount);

  let rooms = [];
  for (let i = 0; i < roomCount; i++) {
    rooms.push(roomManager.create(`room${i + 1}`, roomMaxConnections));
  }
  return { sockets, users, rooms, roomManager };
}

/**
 * 방 하나를 만들고 유저들을 접속시킵니다. 이때 첫번째 유저가 방장이 됩니다.
 * @param userCount 방에 접속하는 유저 수 입니다.
 * @param roomMaxConnections 방에 최대 접속할 수 있는 인원 수 입니다.만약 userCount보다 작다면 userCount값으로 변경됩니다.
 * @param emptyAdmin 참이면 방장이 없는 상태로 방이 생성됩니다.
 * @returns 생성된 소켓, 유저, 방을 반환합니다.
 */
export function prepareJoinedRoom(
  userCount: number,
  roomMaxConnections: number = 2,
  emptyAdmin: boolean = false
): { sockets: SocketTester[]; users: User[]; room: Room } {
  roomMaxConnections = Math.max(roomMaxConnections, userCount);
  const roomManager = new RoomManager();
  let sockets = [];
  let users = [];
  for (let i = 0; i < userCount; i++) {
    const socket = new SocketTester(roomManager);
    sockets.push(socket);

    socket.login(`guest${i + 1}`);
    if (!socket.connection.user) {
      throw new Error("User is not initialized.");
    }
    users.push(socket.connection.user);
  }

  const room = roomManager.create(
    "room1",
    roomMaxConnections,
    emptyAdmin ? undefined : users[0]
  );
  for (let i = emptyAdmin ? 0 : 1; i < userCount; i++) {
    sockets[i].testOk("joinRoom", { uuid: room.uuid });
  }
  return { sockets, users, room };
}

export function prepareGame(
  userCount: number,
  maxRound: number = 5,
  roundDuration: number = 60,
  roundTerm: number = 5,
  roomMaxConnections: number = 2
): {
  sockets: SocketTester[];
  users: User[];
  room: Room;
  game: Game;
  drawerSocket: SocketTester;
  guesserSockets: SocketTester[];
} {
  const { sockets, users, room } = prepareJoinedRoom(
    userCount,
    roomMaxConnections
  );

  for (let i = 1; i < userCount; i++) {
    sockets[i].testOk("ready", { ready: true });
  }
  sockets[0].testOk("startGame", { maxRound, roundDuration, roundTerm });

  if (!room.game) {
    throw new Error("Game is not initialized.");
  }

  let drawerSocket = undefined;
  let guesserSockets: SocketTester[] = [];
  sockets.forEach((socket) => {
    if (socket.connection.user === room.game?.drawer) {
      drawerSocket = socket;
    } else {
      guesserSockets.push(socket);
    }
  });

  if (!drawerSocket) {
    throw new Error("There is no drawer!");
  }
  if (guesserSockets.length == 0) {
    throw new Error("There is no guesser!");
  }

  return {
    sockets,
    users,
    room,
    game: room.game,
    drawerSocket,
    guesserSockets,
  };
}