初心者がvueで5x5の将棋のようなwebアプリを作る

![スクリーンショット 2021-04-25 18.02.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1390656/a560787c-2312-11a3-bba1-ad58732330c3.png)
#この記事に書く物
コマの表示と次に動ける場所を表示するところまで出来たので、そこまでの事を書きます。
#最終目標
vueの勉強をするために将棋の様なアプリを作ります。
#コードの中身
template部分はこんな感じです。

```vue
<template>
<div id='field-wrapper'>
  <div id='bord'>
    <div v-for='x in 5' v-bind:key='x' class='row'>
      <div v-for='y in 5' v-bind:key='y' class='clumn'>
        <div class='mass' 
        v-on:click="select_place(x,y)" 
        v-bind:style="next_place(x,y)" 
        v-bind:id='`${x}-$[y]`'>
          <button v-on:click="select_king(x,y)" v-show='king_position(x,y)'>
            王
          </button>
          <button class='enemy' 
          v-on:click="enemy_select_king(x,y)" 
          v-show='enemy_king_position(x,y)'>
            玉
          </button>
          <button v-on:click="select_knight(x,y)" v-show='knight_position(x,y)'>
            騎
          </button>
        </div>
      </div>
    </div>
  </div>
</div>
</template>
```
v-forを２つ使う事で5x5の盤上を作りました。
![スクリーンショット 2021-04-25 18.02.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1390656/728ecf9a-a762-9e49-01cc-690516861166.png)

v-showに返ってくる値はこんな感じです。

```vue
<script>
methods: {
    king_position: function(x,y) {
        if(x == this.place.king_x && y == this.place.king_y){
          this.king_piece_wait = false
          return true
        }
    },
}
</script>
```
一番最初の位置をplaceの中にking_xとking_yに与えておきます。
味方の王なので今回はking_xに５をking_yには３が入っています。
他のコマには初期位置に表示したいところの座標をそれぞれ与えます。
###初期位置の座標を最初に与えておく

```vue
      place: {
        king_x: 5,
        king_y: 3,
        enemy_king_x: 1,
        enemy_king_y: 3,
        knight_x: 5,
        knight_y: 4,
      },
```
次にコマをクリックした時にそのコマが動けるマスの色を変えるようにしました。

```vue
<script>
methods: {
    select_king: function(x,y) {
      this.select_knight_status = false
      this.select_enemy_king_status = false
      this.next_place(x,y)
      this.select_king_status = true
      return
    },
}
</script>
```
next_place関数では色をv-bind:styleにどの色にするのか返します。

動かそうとしているコマをクリックした時にそのコマのselect_king_statusをtrueにします。

```vue
<script>
methods: {
    next_place: function(x,y) {
      if(this.select_king_status == true){
        if(x == this.place.king_x - 1 && y == this.place.king_y - 1 ||
          x == this.place.king_x - 1 && y == this.place.king_y ||
          x == this.place.king_x - 1 && y == this.place.king_y + 1 ||
          x == this.place.king_x && y == this.place.king_y - 1 ||
          x == this.place.king_x && y == this.place.king_y + 1 ||
          x == this.place.king_x + 1 && y == this.place.king_y - 1 ||
          x == this.place.king_x + 1 && y == this.place.king_y ||
          x == this.place.king_x + 1 && y == this.place.king_y + 1
        ) {
          return {backgroundColor: 'aqua'}
        }
      }
}
</script>
```
そのコマが次に動ける座表をifで条件を与えて、色の情報を返します。
![スクリーンショット 2021-04-25 18.16.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1390656/82121827-728b-1cdd-1b79-df3f92205041.png)

次に色がついている場所をクリックした時にその場所に移動しなければいけません。

```vue
<script>
methods: {
    select_place: function(x,y) {
     if(this.king_piece_wait == true) {
        if(x == this.place.king_x - 1 && y == this.place.king_y - 1 ||
          x == this.place.king_x - 1 && y == this.place.king_y ||
          x == this.place.king_x - 1 && y == this.place.king_y + 1 ||
          x == this.place.king_x && y == this.place.king_y - 1 ||
          x == this.place.king_x && y == this.place.king_y + 1 ||
          x == this.place.king_x + 1 && y == this.place.king_y - 1 ||
          x == this.place.king_x + 1 && y == this.place.king_y ||
          x == this.place.king_x + 1 && y == this.place.king_y + 1
        ) {
          if(this.select_knight_status == false) {
            this.place.king_x = x
            this.place.king_y = y
            this.king_position(x,y)
          }
        }
      }
   }
}
</script>
```

king_piece_waitはコマをクリックした時にtrueにしています。
next_place関数で色をつけた時と同じ条件で次に動ける場所だったらコマを動かします。
その時にking_xとking_yに次の座標を代入してコマを動かします。

#ソースコード
```vue
<template>
<div id='field-wrapper'>
  <div id='bord'>
    <div v-for='x in 5' v-bind:key='x' class='row'>
      <div v-for='y in 5' v-bind:key='y' class='clumn'>
        <div class='mass' 
        v-on:click="select_place(x,y)" 
        v-bind:style="next_place(x,y)" 
        v-bind:id='`${x}-$[y]`'>
          <button v-on:click="select_king(x,y)" v-show='king_position(x,y)'>
            王
          </button>
          <button class='enemy' 
          v-on:click="enemy_select_king(x,y)" 
          v-show='enemy_king_position(x,y)'>
            玉
          </button>
          <button v-on:click="select_knight(x,y)" v-show='knight_position(x,y)'>
            騎
          </button>
        </div>
      </div>
    </div>
  </div>
</div>
</template>

<script>
export default {
  data() {
    return {
      place: {
        king_x: 5,
        king_y: 3,
        enemy_king_x: 1,
        enemy_king_y: 3,
        knight_x: 5,
        knight_y: 4,
      },
      //コマが次に動けるマスを表示するかしないか
      //コマを押した時に値がtrueに
      //コマを動かし終わった時にfalseに
      select_king_status: false,
      select_knight_status: false,

      select_enemy_king_status: false,
      //コマを一番最初に押した時に値を変える
      king_piece_wait: false,
      knight_piece_wait: false,

      enemy_king_piece_wait: false,

      next_place_now: false,
    }
  },
  computed: {
  },
  methods: {
    //王の初期位置
    king_position: function(x,y) {
        if(x == this.place.king_x && y == this.place.king_y){
          this.king_piece_wait = false
          return true
        }
    },
    knight_position: function(x,y) {
        if(x == this.place.knight_x && y == this.place.knight_y){
          this.knight_piece_wait = false
          return true
        }
    },
    enemy_king_position: function(x,y) {
        if(x == this.place.enemy_king_x && y == this.place.enemy_king_y){
          this.enemy_king_piece_wait = false
          return true
        }
    },
    next_place: function(x,y) {
      if(this.select_king_status == true){
        if(x == this.place.king_x - 1 && y == this.place.king_y - 1 ||
          x == this.place.king_x - 1 && y == this.place.king_y ||
          x == this.place.king_x - 1 && y == this.place.king_y + 1 ||
          x == this.place.king_x && y == this.place.king_y - 1 ||
          x == this.place.king_x && y == this.place.king_y + 1 ||
          x == this.place.king_x + 1 && y == this.place.king_y - 1 ||
          x == this.place.king_x + 1 && y == this.place.king_y ||
          x == this.place.king_x + 1 && y == this.place.king_y + 1
        ) {
          return {backgroundColor: 'aqua'}
        }
      }
      if(this.select_knight_status == true){
        if(x == this.place.knight_x - 1 && y == this.place.knight_y - 1 ||
            x == this.place.knight_x - 1 && y == this.place.knight_y ||
            x == this.place.knight_x - 1 && y == this.place.knight_y + 1 ||
            x == this.place.knight_x + 1 && y == this.place.knight_y - 1 ||
            x == this.place.knight_x + 1 && y == this.place.knight_y + 1
          ) {
            return {backgroundColor: 'aqua'}
        }
      }
      if(this.select_enemy_king_status == true){
        if(x == this.place.enemy_king_x - 1 && y == this.place.enemy_king_y - 1 ||
          x == this.place.enemy_king_x - 1 && y == this.place.enemy_king_y ||
          x == this.place.enemy_king_x - 1 && y == this.place.enemy_king_y + 1 ||
          x == this.place.enemy_king_x && y == this.place.enemy_king_y - 1 ||
          x == this.place.enemy_king_x && y == this.place.enemy_king_y + 1 ||
          x == this.place.enemy_king_x + 1 && y == this.place.enemy_king_y - 1 ||
          x == this.place.enemy_king_x + 1 && y == this.place.enemy_king_y ||
          x == this.place.enemy_king_x + 1 && y == this.place.enemy_king_y + 1
        ) {
          return {backgroundColor: 'aqua'}
        }
      }
    },
    select_king: function(x,y) {
      this.select_knight_status = false
      this.select_enemy_king_status = false
      this.next_place(x,y)
      this.select_king_status = true
      return
    },
    select_knight: function(x,y) {
      this.select_king_status = false
      this.select_enemy_king_status = false
      this.next_place(x,y)
      this.select_knight_status = true
      return
    },
    enemy_select_king: function(x,y) {
      this.select_knight_status = false
      this.select_king_status = false
      this.next_place(x,y)
      this.select_enemy_king_status = true
      return
    },
    select_place: function(x,y) {
      if(x == this.place.king_x && y == this.place.king_y) {
        console.log('select_king');
        this.king_piece_wait = true
        return
      }
      if(x == this.place.knight_x && y == this.place.knight_y) {
        console.log('select_kingt');
        this.knight_piece_wait = true
        return
      }
      if(x == this.place.enemy_king_x && y == this.place.enemy_king_y) {
        console.log('select_enemy_king');
        this.enemy_king_piece_wait = true
        return
      }
      if(this.king_piece_wait == true) {
        if(x == this.place.king_x - 1 && y == this.place.king_y - 1 ||
          x == this.place.king_x - 1 && y == this.place.king_y ||
          x == this.place.king_x - 1 && y == this.place.king_y + 1 ||
          x == this.place.king_x && y == this.place.king_y - 1 ||
          x == this.place.king_x && y == this.place.king_y + 1 ||
          x == this.place.king_x + 1 && y == this.place.king_y - 1 ||
          x == this.place.king_x + 1 && y == this.place.king_y ||
          x == this.place.king_x + 1 && y == this.place.king_y + 1
        ) {
          if(this.select_knight_status == false) {
            console.log('next_king');
            this.place.king_x = x
            this.place.king_y = y
            this.king_position(x,y)
          }
        }
      }
      if(this.knight_piece_wait == true) {
        if(x == this.place.knight_x - 1 && y == this.place.knight_y - 1 ||
          x == this.place.knight_x - 1 && y == this.place.knight_y ||
          x == this.place.knight_x - 1 && y == this.place.knight_y + 1 ||
          x == this.place.knight_x + 1 && y == this.place.knight_y - 1 ||
          x == this.place.knight_x + 1 && y == this.place.knight_y + 1
        ) {
          if(this.select_king_status == false) {
            console.log('next_knight');
            this.place.knight_x = x
            this.place.knight_y = y
            this.knight_position(x,y)
          }
        }
      }
      if(this.enemy_king_piece_wait == true) {
        if(x == this.place.enemy_king_x - 1 && y == this.place.enemy_king_y - 1 ||
          x == this.place.enemy_king_x - 1 && y == this.place.enemy_king_y ||
          x == this.place.enemy_king_x - 1 && y == this.place.enemy_king_y + 1 ||
          x == this.place.enemy_king_x && y == this.place.enemy_king_y - 1 ||
          x == this.place.enemy_king_x && y == this.place.enemy_king_y + 1 ||
          x == this.place.enemy_king_x + 1 && y == this.place.enemy_king_y - 1 ||
          x == this.place.enemy_king_x + 1 && y == this.place.enemy_king_y ||
          x == this.place.enemy_king_x + 1 && y == this.place.enemy_king_y + 1
        ) {
          if(this.select_knight_status == false) {
            console.log('next_enemy_king');
            this.place.enemy_king_x = x
            this.place.enemy_king_y = y
            this.enemy_king_position(x,y)
          }
        }
      }
      this.select_king_status = false
      this.select_knight_status = false
      this.select_enemy_king_status = false
    },
  }
}
</script>
<style>
#bord {
  margin: 0 auto;
  width: 510px;
  height: 510px;
  border: 1px solid #333333;
}
.enemy {
  transform:rotate(180deg);    /* 中心を基準点に時計回りに回転する */
}
.row {
  display: flex;
}
.mass {
  width: 100px;
  height: 100px;
  border: 1px solid #333333;
  font-size: 0px;
}
#king {
  font-size: 30px;
}
</style>
```
#次にすること
敵のコマを取る機能を実装しようとしています。
もっと綺麗なコードを書くことは出来ると思うので何かアドバイスなどがありましたらよろしくお願いします。