ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 지뢰찾기를 만들어보자 #4 - 승리 조건 구성
    기술 관련/etc 2022. 9. 25. 19:24

     

    지난번 글까지 지뢰 찾기가 어느 정도는 실행되는 모습을 갖추었었다. https://mc500.tistory.com/670 이번 글에서는 지뢰찾기 게임의 성공/실패 조건을 구현해 보도록 하겠다.

     

    지뢰 찾기의 게임의 승리조건은 아주 단순하다. 게임판에 있는 모든 지뢰를 정확하게 찾는 것이다. 그렇다면 깃발을 지뢰 위에 올려 놓으면 되는것 같아 보인다. 하지만 깃발은 여기가 지뢰가 있을 수 있으니 건드릴 수 없도록 막아 놓는 것일 뿐 실제 지뢰의 존재 여부는 명확하지 않다. 그렇다면 어떻게 모든 지뢰를 찾았다는 것을 알 수 있을까? 

     

    지뢰 찾기 게임에서 모든 지뢰를 찾았다는 것은, 곧 지뢰를 제외한 나머지 부분이 안전하다는 것이다. 따라서, 사용자가 지뢰가 아닌 상자를 모두 열었다면 이것은 모든 지뢰를 찾았다는 것이 된다. 예를 들어, 10x10판에 지뢰 10개인 게임이라면 전체 100칸 중 10개가 지뢰이므로 열려있는 상태가 100-10=90개가 될 때까지 지뢰를 건드리지 않았다면 이 게임을 이긴 것이다.

     

    따라서, 다음과 같이 게임 data에 성공 조건 정보와 현재 열려진 상자 정보를 추가한다.

    data() {
        return {
          canvas: undefined,
          ctx: undefined,
          sprite: undefined,
          boxes: [],
          box_width: 30,
          gameover: false,
          flags: 0,
          target: 0,
          cleared: 0,
        }
      },

    그리고, 상자를 열 때마다 cleared의 값을 하나씩 늘려 나아가다 마지막에 target 값과 비교하여 성공 상태를 확인한다. 또한, 상자가 이미 열려 있는 경우는 이 조건으로 진입하지 않아야 한다.

    } else if (!box.revealed) {
      self.cleared++
      box.revealed = true
      self.drawBox(box)
      if (box.value == 0) {
        self.traverseBoxes(x, y, self.expandSafeArea)
      }
      if (self.cleared == self.target) {
        alert('You Win')
        self.gameover = true
      }
    }

    또한, expandSafeArea에서도 상자가 열릴 때 마다 cleared 값을 증가해 주도록 한다.

    expandSafeArea(x, y) {
      let box = this.boxes[x+y*this.width]
      if (!box.revealed && !box.flagged) {
        this.cleared++
        box.revealed = true
        this.drawBox(box)
        if (box.value == 0) {
          this.traverseBoxes(x, y, this.expandSafeArea)
        }
      }
    },

    마지막으로 게임을 시작할 때 이 정보를 초기화해 주도록 코드를 추가한다.

    mounted () {
      // Initialie Configuration
      let self = this
      this.cleared = 0
      this.target = this.width * this.height - this.mines

    게임에서 이기면 이렇게 You Win이라는 팝업이 뜨도록 되어 있다.

    근데 게임을 하다보니 좀 어색한 부분이 있는데, 위에 그림 윗 부분에 아직 빈곳이 확정되지 않은 상태에서 게임에서 이겼다고 팝업이 나왔다. 사실 이부분은 JavaScritp로 구동 되는 게임에서 window.alert()를 이용해서 메시지를 보여주는 경우 스크립트가 중지되는 특징 때문에 발생한 일이다. OK 버튼을 누르면 정상적으로 다 열려진 것임을 알 수 있다.

    이런 현상을 막기 위해 alert() 호출을 대략 0.3초 이후에 실행되도록 다음과 같은 메소드를 추가하고 이를 이용하도록 한다.

    alert(message) {
      setTimeout(() => {
        alert(message)
      }, 300)
    }

     

    성공 조건이 완성되었으니 실패했을 때 어떻게 할 것인지를 처리해야 한다. 현재는 게임에서 이기거나 져도 알림만 나올 뿐 OK를 누른 후 계속해서 다른 부분을 찾아 나갈 수 있다. 따라서, 게임이 실패했을 때는 재시작을 할 수 있도록 마우스 클릭 이벤트 처리 함수에 다음 코드를 추가한다.

      if (self.gameover) {
        self.alert('Game is over')
        return false
      }

     

     

    또한, 게임이 끝난 경우 확실하게 게임이 끝났다는 것을 알려주기 위해 가려졌던 모든 박스를 열어 놓는다. 이를 위해 다음 method를 추가한다.

    revealBoxes() {
      for (let box of this.boxes) {
        if (!box.revealed && !box.flagged) {
          box.revealed = true
          this.drawBox(box)
        }
      }
    },

    이제는 지뢰 찾기 게임의 많은 부분이 구현되었다. 다음 글에서는 이 지뢰찾기 게임의 사용성 개선을 다뤄보도록 하겠다.

    댓글

Designed by Tistory.