質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.33%

  • TypeScript

    376questions

    TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

TypeScriptでまるばつゲームを実装したがわからない箇所がある。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 208

shinzooon

score 1

わからないこと

TypeScriptで資料を写経してまるばつゲームを実装したのですが、分からない箇所があります。(ページ下)
参考資料:TypeScript リファレンス 著:わかめまさひろ

まるばつゲームの仕様

2人が対戦するゲームで3×3のマス目に○(先手)と×(後手)を交互においていき、縦・横・斜めのどれか一列に同じマークを先揃えた方が勝ち

ソース

module MaruBatsu {
    // 先手・後手を表す
    export enum Piece {
        Maru,
        Batsu
    }

    // ゲーム盤の管理・進行を行うクラス
    export class GameLogic {
        SIDE = 3;
        board: Piece[][];
        turn: Piece;

        constructor(public el: HTMLElement) {   
        }

        // ゲームの初期設定を行いゲームを開始する
        start(): void {
            // ゲーム画面用のHTMLElementの中身を消している。
            this.el.innerHTML = '';
            // 最初の手番を○に設定する
            this.turn = Piece.Maru;
            // 盤面の状態を初期化する (3×3)
            // 各マスはnullで初期化する
            // 画面の状態を盤面の状態に合わせる
            // この後に追加してある addPiece メソッドで1マスごとに作成する。
            this.board = [];
            for (var i = 0; i < this.SIDE; i++) {
                this.board.push([]);
            }
            for (var y = 0; y < this.SIDE; y++) {
                for (var x = 0; x < this.SIDE; x++) {
                    this.board[x][y] = null;
                    this.addPiece(x, y);
                }
            }
        }

        // 勝敗をチェックする
        isWinner(turn: Piece): boolean {
            // 縦横の判定
            for (var i = 0; i < this.SIDE; i++) {
                var v = true;
                var h = true;
                for (var j = 0; j < this.SIDE; j++) {
                    if (this.board[i][j] !== turn) {
                        v = false
                    }
                    if (this.board[j][i] !== turn) {
                        h = false
                    }
                }
                if (v || h) {
                    return true;
                }
            }

            // 斜めの判定
            var c = true;
            var r = true;
            for (var i = 0; i < this.SIDE; i++) {
                if (this.board[i][i] !== turn) {
                    c = false;
                }
                if (this.board[i][this.SIDE - i - 1] !== turn) {
                    r = false;
                }
            }
            if (c || r) {
                return true;
            }

            return false;
        }

        // 1手指す
        put(x: number, y: number, el: HTMLElement): void {
            if (this.board[x][y] !== null) {
                // 既に何か置かれていたら無視する
                return;
            }
            var current = this.turn;
            this.board[x][y] = this.turn;
            // 表示の変更と指し手の交代
            if (this.turn === Piece.Maru) {
                el.innerText = '○';
                this.turn = Piece.Batsu
            } else {
                el.innerText = '×';
                this.turn = Piece.Maru;
            }
            // 勝者になったのかチェックと結果表示
            if (this.isWinner(current)) {
                alert('○の勝ち!');
            } else {
                alert('×の勝ち!');
            }
        }

        // 1マスに相当するHTML要素を作成し追加する。
        addPiece(x: number, y: number): void {
            var div = document.createElement('div');
            div.addEventListener('click', () => {
                this.put(x, y, div);
            });
            div.className = 'piece';
            if (x === 0) {
                div.className += ' head';
            }
            this.el.appendChild(div);
        }
    }    
}

window.onload = () => {
    var el = document.getElementById('game');
    var logic = new MaruBatsu.GameLogic(el);
    logic.start();
};

console.log(this);
<!DOCTYPE html>
<html>
<head>
    <title>まるばつゲーム</title>
    <link rel="stylesheet" type="text/css" href="main.css" charset="utf-8">
</head>
<body>
    <h1>まるばつゲーム</h1>

    <div id="game">Javacript is not running?</div>

    <script type"text/javascript" src="main.js" charset="utf-8"></script>
</body>
</html>
@charset "utf-8";

.head {
    clear: both;
}

.piece {
    display: block;
    float: left;
    width: 30px;
    height: 30px;
    border-width: 1px;
    border-style: solid
}

分からない箇所

/** GameLogic クラスのメンバ変数です。 */
board: Piece[][];

/** 省略 */

/** startメソッドのスコープ内です。 */
this.board = [];            
for (var i = 0; i < this.SIDE; i++) {
this.board.push([]);
}
Q1.メンバ変数 boad になぜ enum を型定義しているのか?

enum は別の関数に number を渡すメソッドだと理解しています。
2つの要素しかない enum がどうして盤面(3×3)のプロパティの型となるのか理解できませんでした。

Q2.start内ので行われている処理は筆者の解釈は合っていますか?

まず、board に大枠の配列を一つ代入し、その後、その配列の中に更に3つの配列を代入し二次元配列を完成させている。つまり、boardの中身はこうなっている。

board = [ [], [] , [], ]

もしこれで合っているとすれば、board に大枠の配列を代入した時のエラーが出ないのか不思議です。
なぜなら、メンバ変数 board の型は二次元配列のはずだからです。二次元配列型のオブジェクトに一次配列が代入できるのは矛盾していませんか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

enum は別の関数に number を渡すメソッドだと理解しています。

いえ、enumも引数専用ではなく、単なる型の1つです(公式)。今回の三目並べのマス目の状態のような「決まった状態のうちどれか1つを持つ」という用途にはぴったりです。

メンバ変数 board の型は二次元配列のはずだからです。二次元配列型のオブジェクトに一次配列が代入できるのは矛盾していませんか?

TypeScript、JavaScriptともに「2次元配列」というのは存在せず、実際にあるのは配列の配列です。外側の1次元配列の要素として別の配列を入れることで、2次元配列のように使える形となっています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/20 08:38

    ご回答ありがとうございます。
    enum の解釈が誤っていました。ご指摘ありがとうございます。
    ようやく謎が解けました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • TypeScript

    376questions

    TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。