기록 기능 구현

YEONGHUN KO·2021년 11월 11일
0
post-thumbnail

1. 기록 기능 구현 알고리즘

기록 기능은 의외로 복잡했다. 마지막 stage까지 갔을때 총 몇초 걸렸느냐를 측정해서 순위를 매기고 toggle에 띄우려고 했다.
알고리즘은 아래와 같이 짰다.

1. 우선 다음 차시로 넘어갈때마다 게임이 끝났을때 타이머를 가져온다.

2. 가져올때마다 slice해서 숫자만 가져오고 agg란 array에 담는다.

3. 그 array에 있는 모든 숫자를 더해 최종 걸린 시간을 구한다.

4. 최종시간을 가져와서 record란 array에 담는다.

5. 비교해서 분류하고 순위를 정한다.

6. 순위를 표시한다.

7. 저장하고 agg array를 초기화시킨다.

8. 시작할때 저장한 기록을 가져와서 표시한다.

그리고 현재 기록이 이전기록중에 똑같을때 추가하면 안되고, 기록이 3개까지만 표시되야하기 때문에 4개이상되면 표시되지 않도록해야한다.

2. 실제 구현하기

우선 엘리님 처럼 필요할 것 같은 함수를 updateRecord에 쭉 적어본다.

recordToggle.js

export class RecordToggle {
  constructor() {
    this._restoreRecordStorage();
    this._loadRecord();
  }

  updateRecord() {
    this.timeRecord = this.aggregateRecord();
    this._compareRecord(this.timeRecord);
    this._paintRecord(this.recordList);
    this._saveRecord();
  }

  _getTime() {
    return this.timeDisplay.innerHTML;
  }

  aggregateRecord() {
    this.timeRecord = this._getTime();
    const modifiedCurrentValue = this.gameDuration - this.timeRecord.slice(-2);
    this.recordBoxtoAgg.push(modifiedCurrentValue);
    return this.recordBoxtoAgg.reduce((a, b) => {
      return a + b;
    }, 0);
  }
  _compareRecord(recordTime) {
    for (var i = 0; i < this.recordList.length; i++) {
      if (recordTime === this.recordList[i] || recordTime === NaN) {
        return;
      }
    }

    this.recordList.push(recordTime);
    // compare function passed to sort the array in ascending order
    this.recordList.sort((a, b) => a - b);
    if (this.recordList.length > 3) {
      // remove the last element of the array
      this.recordList.pop();
    }
  }

  _paintRecord(recordList) {
    this.fromSecondSpan.innerHTML = "";
    recordList.forEach((record, index) => {
      const span = document.createElement("span");
      if (record === null) {
        return;
      }
      switch (index) {
        case 0:
          this.firstRankingSpan.innerHTML = `1st: ${record} sec`;
          break;
        case 1:
          span.innerHTML = `2nd: ${record} sec`;
          break;
        case 2:
          span.innerHTML = `3rd: ${record} sec`;
          break;
        default:
          throw Error("not valid index");
      }
      this.fromSecondSpan.appendChild(span);
    });
  }

  _saveRecord() {
    localStorage.setItem(this.RECORD_LS, JSON.stringify(this.recordList));
    this.recordBoxtoAgg = [];
  }

  _loadRecord() {
    this._paintRecord(this.recordList);
  }

  _restoreRecordStorage() {
    this.recordList = JSON.parse(localStorage.getItem(this.RECORD_LS)) || [];
  }
}

그리고 gameControl에 추가해준다. 어디에 추가해줘야 할까? 바로 모든 게임이 다 끝났을때 이 함수가 실행되어야 할것이므로 level = final stage 일때 추가해줘야한다. 그리고 매 차시 이길때 마다 기록이 쌓여야한다.

gameControl.js

countCarrotFunc() {
    const carrotCount = this.field.carrotCount.length;
    if (carrotCount < 1) {
      if (this.level === 4) {
        this.finish(FinishReason.finalStageWin);
        this.levelInitalized();
        // this.recordToggle.aggregateRecord();
        // update에서 aggregateRecord() 선언할때 이미 실행되므로 여기서 굳이 실행할 필요없음
        this.recordToggle.updateRecord();
      } else {
         this.recordToggle.aggregateRecord();
      }
    }
}

이렇게 되면 이제 마지막 차수를 완료할때마다 기록이 분류되면서 저장되어 표시될 것이다. 자 그럼 이제 신기록이 갱신될때 마다 특별한 이벤트를 발생하도록 해보자.

profile
'과연 이게 최선일까?' 끊임없이 생각하기

0개의 댓글