LoginSignup
4
1

More than 3 years have passed since last update.

Vue.jsでチェス盤を作ってみたら7行だった。

Last updated at Posted at 2019-08-16

チェス盤はなぜ白黒なのか

あの違い互いの白黒盤のせいでちょっと苦戦した話です。

一応チェスを後々作る前提でボードを作ってみました。

今回のゴール

1.見た目的にチェス盤と認識できるものを作る
2.今後チェスを作る前提の構造になっていないとダメ

†考察†

実際チェスを作るとなると必須となるのが、
64マスそれぞれに座標が備わっていること。

つまりこういうこと。

[1-1, 1-2, 1-3, 1-4, 1-5, 1-6, 1-7, 1-8, 
 2-1, 2-2, 2-3, 2-4, 2-5, 2-6, 2-7, 2-8, 
 3-1, 3-2, 3-3, 3-4, 3-5, 3-6, 3-7, 3-8, 
 4-1, 4-2, 4-3, 4-4, 4-5, 4-6, 4-7, 4-8, 
 5-1, 5-2, 5-3, 5-4, 5-5, 5-6, 5-7, 5-8, 
 6-1, 6-2, 6-3, 6-4, 6-5, 6-6, 6-7, 6-8,
 7-1, 7-2, 7-3, 7-4, 7-5, 7-6, 7-7, 7-8,
 8-1, 8-2, 8-3, 8-4, 8-5, 8-6, 8-7, 8-8]

X軸とY軸の数値を合わせてるような感じ。

この配列を作るだけであれば簡単。

    let board = [];
    for(let x = 1; x < 9; x++) {
      for(let y = 1; y < 9; y++) {
        board.push(x + "-" + y)
      }
    }

8×8のループを行えば一瞬でできてしまうので、
Vue.jsでレンダリングするとしても、v-for="n in 8"を二回やればいいだけ。

将棋であればここで完成。
だがしかし、チェス盤となると少しやっかい。


ときて、
今度は

まあ冒頭でも言ってますが、
つまり、1行目と2行目だと、1列目の色が反転しているということです。

えらいこっちゃ~~~となっていろいろ考えて
しばらくしてやっとこちらの文系エンジニアも気づきました。

「奇数行と偶数行で出し分けすればいいんだ」

つまりはこういうこと。

  <div class="board">
    <div v-for="x in 8">
      <div v-for="y in 8">
        <div 
         v-bind:class="(x + y) % 2 == 0 ? 'square-black' : 'square-white'" 
         :id='`${x}-${y}`'
        >
        </div>
      </div>
    </div>
  </div>

FireShot Capture 010 - chess_board - localhost.png

おぉ~~~できた!

ちゃんとそれぞれidも1-1から8-8まで振れている。
そしてなによりコードがかなり短く収まった!!

一応解説

8回ループを二回するまでは同じ、
そしてそこからは、一回目のループxと二回目のループyそれぞれの値でv-if使って出し分け。

xの一回目とyの一回目であれば1と1になるので、
合計が2偶数なので黒スタート。

xの二回目とyの一回目であれば2と1になるので、
合計が3奇数なので白スタート。

最後に

座標もしっかり入っているので、
チェス作りの道も開けたといった感じですね。

筆者はこういう閃きみたいなのが圧倒的に欠如している
文系エンジニアなので時間はかかったものの、
法則を見つけて何かをスッキリ書くのはよだれが出てくるぐらい好きです。

いつになるかわからないですが、
次はチェスの動きの部分を投稿したいです。

スタイルも含めたコードを載せておきます。

Board.vue
<template>
  <div class="board">
    <div v-for="x in 8">
      <div v-for="y in 8">
        <div 
         v-bind:class="(x + y) % 2 == 0 ? 'square-black' : 'square-white'" 
         :id='`${x}-${y}`'
        >
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.board {
  width: 640px;
  height: 640px;
  border: 4px solid black;
}

.square-black {
  width: 80px;
  height: 80px;
  background-color: black;
  float: left;
}

.square-white {
  width: 80px;
  height: 80px;
  background-color: white;
  float: left;
}
</style>

追記:
もともと、v-ifとv-else使ってdomを出し分けしようと書いていたのですが、v-bind:classを使えばDOMが一つにまとまると思い、修正しました。
なので、

\8行から7行に変わりました/

そもそも、出し分けするとはいえ、全く同じidを両方に振っていたのもなんだが危なっかしいので、
classの切り替え処理のほうが正しい気がします。

元のコード:

<template>
  <div class="board">
    <div v-for="x in 8">
      <div v-for="y in 8">
        <div class="square-black" :id='`${x}-${y}`' v-if="(x + y) % 2 == 0"></div>
        <div class="square-white" :id='`${x}-${y}`' v-else></div>
      </div>
    </div>
  </div>
</div>
</template>
4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1