嫁氏が作ったフレームワークでJavaScript初心者の私がオセロゲームを作る話。その1・状態を作る


嫁氏ことジョニー氏がJavaScriptで自作フレームワーク「dsand」を作ったことと、
「dsand」の使い方を紹介する記事がまだ無いという事なのでJavaScript初心者の筆者が何か記事を作成しようと思い筆を執りました。

※プログラミングの理解度について、筆者はJavaScriptは初心者ですが
 昔若干職業プログラマーやってたのでJavaとかVBは少し覚えている程度
 という前提を踏まえつつ読んでいただけると幸いです。
 (普段ははんだ付けとかやってる人だよ!ぶっちゃけプログラミング苦手だよ!

自身の備忘録的な役割込みなのと
初めてのQiita記事なので生暖かい目で読んでください(笑

「dsand」のリンクはこちら↓から
https://www.npmjs.com/package/dsand

「dsand」とは

ジョニー氏が基底ライブラリ含め2000行くらいで作ったフレームワーク。
2000行くらいで作ったフレームワーク。
大事なので2回言いました。

React.jsとやらに対抗する機能を持ってるらしい。(お手軽版?)
それを個人で作ってるのなんかおかしい気がする。変t(誉め言葉)

参考↓
俺のフレームワークが、1205行で実装できる訳がない!
続)俺のフレームワークが、1205行で実装できる訳がない!

作りたいもの

タイトルにも記載したように簡単なオセロゲームを作成します。
とりあえず、盤面は8×8の一人打ち(自分で検証する用)オセロを作成することを目標とします。

作業環境

OS : Windows10
IDE: VSCode
ブラウザ:GoogleChrome
この辺、ブラウザ以外は何でもいいと思われる。(理由は後述)

最初にやる事!

「dsand」を使って作りたいプロジェクトのフォルダを作ります!
普通のJavaScriptでも作る必要あり、

 css
 image
 js

の3種類のフォルダを作成しますが、
「dsand」の場合、「js」フォルダにすると、どの.jsファイルを使いたいか分からなくなるので

 css
 image
 data
 role
 pack

の5種類のフォルダを作成します。

 data(役割を演じる根拠)→ソフトウェア的に「責務」という
  ↓
 role(役割)
  ↓
 pack(着替え、リパック)→役割を終えた後に着替えるさま

の順番にSWが処理されていればコーディングしやすくなるらしい(ジョニー氏曰く)
が、現実はそうはいかない。。。
ちなみにdsandで使うhtmlは「index.html」のみ!!(ただし今回は出ません)

とりあえずフォルダが以下のように作成できていれば次に行きましょう!

IDEを起動しよう!

ここからはVSCodeなどのIDEを使って進めていきます。
File>OpenFolderから先ほど5種類のフォルダを作成した階層の上位フォルダ
※今回は「01_ocello」
を選択して開きます。

次に「data」フォルダ上で右クリック、NewFileを選択し、
空の「data.js」ファイルを作成します。

こうなればOK、次に進みましょう!

データを書いていく

最初にクロージャ(関数の即時実行形式のもの)を書きます。

(() => {

})();

↑これの事。
他言語でよくあるfunction(関数)の代わりみたいなものだそうです。

最初にクロージャを書く理由は、
定義した変数などがグローバルを汚染しないようにするため(カプセル化のため)

…つまり、
グローバルにしてしまうと他言語で言う所のスコープ的な問題が発生するから!
です。

「dsand」は基底ライブラリの「white_cats」を使わないと元々動かないので
「white_cats」のメソッドを使って「dsand」のための記述を行うと楽。

Classに例えると、

Class dsand extends white_cats

という感じ。
継承してるから無いと動かない、逆にwhite_catsは単体で動くのです。

「white_cats」のメソッドはどうして動くか理解するのが難しいらしいので
こう書けるし、それが便利に動くと覚えておくだけでも十分。
つまりjar(ClassをZipにまとめてて中見るとヤバいやつ)みたいなものと思っておけばよし。
「white_cats」のメソッド等は「_」から始まるようにできています。

若干逸れましたが続き。

(() => {
  _.put($.data, {

  });
})();

という訳で_.put~を追加しました。

$.dataは予約された空のオブジェクトが入っていて、
任意に関数や値を追加できる、つまり動的なオブジェクト。
JavaScriptは動的なオブジェクト指向という戦略を持っているので
カプセル化何それ美味しいの?が本当のところ。(ジョニー氏曰く)

次に$.dataにデータの元となるデータを追加します。
今回はオセロの状態(白、黒、空の3状態)を定義します。

但し、文字列で判別すると後のroleとpackの役割が複雑になるため
出来れば数字とかbooleanとnullの3状態を定義するほうがより良いです。
という事は、True(白)、False(黒)、Null(空)
または最初から構造体みたいなものを用意して(JavaScriptの場合はオブジェクトになる)
black:true white:false とかで何が置かれているか判別する事も出来ます。
構造体何それ美味しいの?な人は前者でもOKです。
ただ今回はJavaScript流の書き方をするのでJavaScriptオブジェクトを使いましょう!

(() => {
  _.put($.data, {
    black: {
      black: true,
      white: false
    },
    white: {
      black: false,
      white: true
    },
    blank: {
      black: false,
      white: false
    },
  });
})();

こんな感じに、
名前: 値, 名前: 値,… と書きます。
 this.black = true
のような記述を
 black: true 
と省略して書いてる感じです。
コンストラクタのようなものを定義する必要がなく、
即時でオブジェクトを定義できるのがJavaScriptの大きい特徴の一つ。(らしい)

ともかく、ここまでで石の状態のデータを定義できました。
つぎに盤面の定義をデータだけ作ります。(見た目は次回以降で!)

盤面(board)は2重配列をとっていて8x8のマス目を持っているはず…
なので、

(() => {
  _.put($.data, {
    black: {
      black: true,
      white: false
    },
    white: {
      black: false,
      white: true
    },
    blank: {
      black: false,
      white: false
    },
    board: [
      [blank, blank, blank, blank, blank, blank, blank, blank],
      [blank, blank, blank, blank, blank, blank, blank, blank],
      [blank, blank, blank, blank, blank, blank, blank, blank],
      [blank, blank, blank, blank, blank, blank, blank, blank],
      [blank, blank, blank, blank, blank, blank, blank, blank],
      [blank, blank, blank, blank, blank, blank, blank, blank],
      [blank, blank, blank, blank, blank, blank, blank, blank],
      [blank, blank, blank, blank, blank, blank, blank, blank]
    ]
  });
})();

愚直に書くとこうなります。
分からんでもないですが長いです。
が、こんなの書いてらんないよー!と思った時の省略方法があるのです。

(() => {
  _.put($.data, {
    black: {
      black: true,
      white: false
    },
    white: {
      black: false,
      white: true
    },
    blank: {
      black: false,
      white: false
    },
    board: new Array(8).fill(
      new Array(8).fill('blank')
    )
  });
})();

大分すっきりしました。10行あったのが3行になりました。
さて、

    board: new Array(8).fill(
      new Array(8).fill('blank')
    )

が何を言いたいのかと言いますと、初心者的には
 配列の外側定義(配列の内側定義(中身空))
という感じです。とりあえず配列こんなに簡単に作れるんだと覚えておけば…
ちゃんと動くか心配だったら、コンソールで確認しましょう!

このようにGoogleChrome等のコンソールから動作確認できます!
(新しいタブを右クリック>検証>Consoleタブから開けます)
VSCodeを使ってもコンソール表示はできますが、中のJavaScriptのエンジンが違う可能性があるそうです。
ちなみに「dsand」はGoogleChromeのみのサポートなのでChromeのコンソールを使うのが確実です。(作業環境のところでブラウザ以外は何でもいいと記載したのはこのため)

とりあえずここまでで
石の状態と盤面の状態
が書けました!

これから何か追加したくなったら追加すればいいので
勢いで実装し始めても後でカタチになる!(ジョニー氏曰く)
という事なので続きは次回!