[TIL] 24.11.18 MON

GDORI·2024년 11월 19일
0

TIL

목록 보기
106/143
post-thumbnail

아직 패킷 전송 부분에 대해서 생각하지 못해 TODO로 냅두고 클래스 만들어서 테스트 해보았다.

임시로 만든 테스트 코드 흐름에는 문제가 없는데... 패킷 전송부 구현 후 테스트가 두렵다

CheckPoint 클래스

import Timer from '../utils/Timer.class.js';

class CheckPoint {
  #users;
  #status;
  currentStatus;

  constructor(name) {
    this.name = name;
    this.#users = [[], []]; // 0: 팀 A, 1: 팀 B
    this.#status = 'waiting';
    this.currentStatus = this.#status;
    this.timer = new Timer(5000, this.completeOccupation.bind(this)); // 5초 타이머
  }
  // 유닛 추가/제거
  modifyUnit(team, unit, action) {
    const array = this.#users[team];

    switch (action) {
      case 'add':
        array.push(unit);
        this.checkStatus(team);// 상태 확인 (waiting, occupied(0,1), attempting(0,1))
        break;
      case 'remove':
        array.splice(array.indexOf(unit), 1);
        this.checkStatus(team);
        break;
      default:
        break;
    }
  }

  checkStatus(team) {
    const myUnits = this.getUsersCount(team);// 내 유닛 수
    const opponentUnits = this.getUsersCount(1 - team); // 상대 유닛 수
    const timerStatus = this.timer.status; // 타이머 상태

    /*
    상태에 따른 행동
    waiting - 내 유닛이 있으면 점령 시도 (동시에 적팀도 들어갈 확률은 없음, 패킷도착순)
    occupied(0,1) - 점령 상태 기준에서 상대방 유닛만 있을 경우 점령시도
    attempting(0,1) - 점령 시도 중 상대방 유닛이 들어올 경우 일시정지

    handleAttempt 함수에서 상태에 따른 행동 처리
    */
    const actions = {
      waiting: () => {
        if (myUnits) this.attemptedOccupation(team);
      },
      [`occupied${team}`]: () => {
        if (!myUnits && opponentUnits) this.attemptedOccupation(1 - team);
      },
      [`occupied${1 - team}`]: () => {
        if (myUnits && !opponentUnits) this.attemptedOccupation(team);
      },
      [`attempting${team}`]: () => {
        this.handleAttempt(opponentUnits, myUnits, timerStatus);
      },
      [`attempting${1 - team}`]: () => {
        this.handleAttempt(myUnits, opponentUnits, timerStatus);
      },
    };

    const action = actions[this.#status];
    if (action) action();
  }

  handleAttempt(opponentUnits, myUnits, timerStatus) {
    if (opponentUnits && timerStatus) {
      this.pauseOccupation();
    } else if (!opponentUnits && !timerStatus) {
      this.resumeOccupation();
    } else if (!myUnits) {
      this.clearOccupation();
      this.#status = this.currentStatus;
    }
  }

  getUsersCount(team) {
    return this.#users[team].length;
  }

  attemptedOccupation(team) {
    this.#status = `attempting${team}`;
    console.log(`${team}${this.name}점령시도중 현재 상태: ${this.#status}`);
    this.timer.start();
    // TODO: 점령 시도 패킷 전송
  }

  clearOccupation() {
    this.#status = this.currentStatus;
    console.log(`${this.name}점령초기화 현재 상태: ${this.#status}`);
    this.timer.clear();
    // TODO: 점령 타이머 초기화 패킷 전송
  }
  pauseOccupation() {
    console.log(`${this.name}점령일시정지 현재 상태: ${this.#status}`);
    this.timer.pause();
    // TODO: 점령 일시정지 패킷 전송
  }
  resumeOccupation() {
    console.log(`${this.name}점령재개 현재 상태: ${this.#status}`);
    this.timer.resume();
    // TODO: 점령 재개 패킷 전송
  }

  completeOccupation() {
    this.#status = `occupied${this.#status.replace('attempting', '')}`;
    console.log(`${this.name}점령완료 현재 상태: ${this.#status}`);
    this.currentStatus = this.#status;
    this.timer.clear();
    // TODO: 점령완료 패킷 전송
  }
}

export default CheckPoint;

CheckPointManager 클래스

import CheckPoint from '../models/CheckPoint.class.js';

class CheckPointManager {
  #topPoint;
  #bottomPoint;
  constructor() {
    this.#topPoint = new CheckPoint('top');
    this.#bottomPoint = new CheckPoint('bottom');
  }
  addUnit(isTop, team, unit) {
    const checkPoint = isTop ? this.#topPoint : this.#bottomPoint; // isTop에 따른 체크포인트 인스턴스 선택
    checkPoint.modifyUnit(team, unit, 'add'); // 체크포인트에 유닛 추가
  }

  removeUnit(isTop, team, unit) {
    const checkPoint = isTop ? this.#topPoint : this.#bottomPoint;
    checkPoint.modifyUnit(team, unit, 'remove');
  }
}

export default CheckPointManager;
profile
하루 최소 1시간이라도 공부하자..

0개의 댓글