TypeScript 学習 part4

はじめに

こちらの本でTypeScriptの学習を進めています。

前回は、「Chapter3 Node.jsで動くアプリケーションを作ってみよう」に入りました。今回は、その続きです。

コミット履歴はこちら

完成したゲーム

今回作成しているゲームはこちらです。

一通りゲームが完成したので、ターミナルで実行して遊んでみました。

npm run buildで、tsをjsにビルド

Mac:node-app shibatahiroshitaka$ npm run build

> node-app@1.0.0 build /Users/shibatahiroshitaka/Desktop/study-typescript/node-app
> tsc

npm run startで、jsを実行

Mac:node-app shibatahiroshitaka$ npm run start

> node-app@1.0.0 start /Users/shibatahiroshitaka/Desktop/study-typescript/node-app
> node dist/index.js


「,」区切りで3つの数字を入力してください

ゲーム開始

正解の3桁は、ランダムに生成されているので、それを当てていきます。

1,2,3と入力すると、Blowが1だったので、1,2,3のどれかが含まれる(位置は違う)ということです。

「,」区切りで3つの数字を入力してください
>1,2,3
---
Hit: 0
Blow: 1

そのまま続けていき、Hitが1になりました。1,2,3のどれかが位置も含めて正解ということです。

「,」区切りで3つの数字を入力してください
>2,3,1
---
Hit: 0
Blow: 1
---n
「,」区切りで3つの数字を入力してください
>3,1,2
---
Hit: 1
Blow: 0

その後も試行錯誤を続け、途中で3が一番左に来ることが確定し、

「,」区切りで3つの数字を入力してください
>5,4,2
---
Hit: 0
Blow: 0
---n
「,」区切りで3つの数字を入力してください
>3,9,8
---
Hit: 1
Blow: 0

0か6が含まれることが分かりました。

「,」区切りで3つの数字を入力してください
>3,0,6
---
Hit: 1
Blow: 1

さらに進めていき、Hit: 1 Blow: 2になりました。

「,」区切りで3つの数字を入力してください
>3,6,5
---
Hit: 1
Blow: 0
---n
「,」区切りで3つの数字を入力してください
>3,0,7
---
Hit: 1
Blow: 2

3が一番左に来ることは確定しているので、0と7の位置を合わせたら正解しました!

「,」区切りで3つの数字を入力してください
>3,7,0
正解です!

行ったこと

クラスとインスタンスの作成

クラス

class HitAndBlow {
  answerSource = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
  answer: string[] = []
  tryCount = 0
}

インスタンス

  ;(async () => {
    const hitAndBlow = new HitAndBlow()
  })()

ゲーム開始時の処理

以下のようなsettingメソッドを追加しました。

  setting() {
    const answerLength = 3

    while (this.answer.length < answerLength) {
      const randNum = Math.floor(Math.random() * this.answerSource.length)
      const selectedItem = this.answerSource[randNum]
      if (!this.answer.includes(selectedItem)) {
        this.answer.push(selectedItem)
      }
    }
  }

即時関数内で呼び出す記述も追加しました。

;(async () => {
    const hitAndBlow = new HitAndBlow()
    hitAndBlow.setting()
  })()

playメソッドの追加

ユーザーの入力部分の処理が書かれたplayメソッドを追加しました。

  async play() {
    const inputArr = (await promptInput('「,」区切りで3つの数字を入力してください')).split(',')
  }

こちらも即時関数で呼び出しました。

;(async () => {
    const hitAndBlow = new HitAndBlow()
    hitAndBlow.setting()
    await hitAndBlow.play()
  })()

checkメソッドの追加

ユーザーが入力したhitとblowの数を確認するためのcheckメソッドを作成しました。

  private check(input: string[]) {
    let hitCount = 0
    let blowCount = 0

    input.forEach((val, index) => {
      if (val === this.answer[index]) {
        hitCount += 1
      } else if (this.answer.includes(val)) {
        blowCount += 1
      }
    })

    return {
      hit: hitCount,
      blow: blowCount,
    }
  }

playメソッド内で使用

作成したcheckメソッドは、playメソッド内で使用しました。

  async play() {
    const inputArr = (await promptInput('「,」区切りで3つの数字を入力してください')).split(',')
    const result = this.check(inputArr)

    if (result.hit !== this.answer.length) {
      printLine(`---\nHit: ${result.hit}\nBlow: ${result.blow}\n---`)
      this.tryCount += 1
      await this.play()
    } else {
      this.tryCount += 1
    }
  }

hitの数がanswer.lengthの数(settingメソッド内で定義した3)と異なっていれば、Hitの数とBlowの数を表示し、再びplayメソッドを実行します。

hitの数が3なら、終了します。

endメソッドの追加

ゲームが完了した後の処理を追加しました。

HitAndBlowクラス内

  end() {
    printLine(`正解です!\n試行回数: ${this.tryCount}回`)
    process.exit()
  }

即時関数内

  ;(async () => {
    const hitAndBlow = new HitAndBlow()
    hitAndBlow.setting()
    await hitAndBlow.play()
    hitAndBlow.end()
  })()

発生したエラーとその解決方法

プロパティ〇〇に初期化子がなく、コンストラクターで明確に割り当てられません(ts2564)

下記のコードを書いたら発生しました。

class HitAndBlow {
  answerSource: String[]
  answer: string[]
  tryCount: number
}

解決方法

その先のコードを書いたら解決しました。コンストラクターを作成していなかったのが、原因のようです。

class HitAndBlow {
  answerSource: String[]
  answer: string[]
  tryCount: number

  constructor() {
    this.answerSource = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
    this.answer = []
    this.tryCount = 0
  }
}

到達できないコードが検出されました。 ts(7027)

前回作成した即時関数に赤色部分の記述を追加したときに発生しました。

  ;(async () => {
    const name = await promptInput('名前を入力してください')
    console.log(name)
    const age = await promptInput('年齢を入力してください')
    console.log(age)
    process.exit()
    const hitAndBlow = new HitAndBlow()
  })()

解決方法

不要な部分を削除したら解決されました。

  ;(async () => {
    const hitAndBlow = new HitAndBlow()
  })()

次回

ゲーム終了後の「試行回数: 〇〇回」が表示されなかったので、その修正を行い、残りのページを進めていきます。

chapter3は、残り60ページほどです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です