0%

挑戰一小時!用Vue寫一個五子棋

前幾天在網路上看到了一個直播 第0屆前端接力賽

順便幫直播大大推他的課程 HiSKIO 搜尋 姚偉揚 就可以找到囉!

看完之後覺得挺有趣的,那身為半個前端工程師,我也來挑戰看看囉!
以下將當時思考的過程整理成文章如下:

  1. 假設棋盤為15x15=225個格子,0為空格、1為黑子(player:1),2為白子(player:2)
    1
    2
    3
    4
    5
    6
    data:function () {
    return {
    checkerboardData: Array(225).fill(0),
    player: 1,
    }
    }
  2. 畫格子,不解釋…

html

1
2
3
4
5
<div class="container">
<div class="square" v-for="(data,index) in checkerboardData" :key="index" @click="clickPoint(index)">
{{data}}
</div>
</div>

stylus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<style lang="stylus" scoped>
.container
width 630px
display flex
flex-wrap wrap
margin 0 auto
.square
width 20px
height 20px
padding 10px
border 1px solid #000
border-collapse collapse
background #F9CC9D
margin 0px -1px -1px 0px
</style>

3.Square點擊事件

  • 預設player:1,每次點擊換人
  • 點擊時checkerboardData更新該index的值(黑子or白子)
  • 若不是空格return
1
2
3
4
5
6
7
8
9
10
11
clickPoint (index) {
if(this.checkerboardData[index] !== 0)
return;
this.checkerboardData[index] = this.player
this.$set(this.checkerboardData, index, this.player)
// this.isWin(index) 預留,判斷是否有輸贏
if(this.player === 1)
this.player = 2
else
this.player = 1
}
  1. 判斷輸贏

思考一下,獲勝的條件是任意連續五個一樣的棋子
我們只有在最後點擊的位置往 左右(橫線) 上下(直線) 左上右下(斜線) 左下右上(斜線)

先思考橫線:
假設點擊的座標為 (row, col)
往左最多4格: (row, col-4), (row, col-3), … (row, col)
往右最多4格: (row, col), (row, col+1), … (row, col+4)
這9格中只組成字串,只要字串中包含11111or22222代表獲勝

那直線,斜線也可以依此邏輯推演,這邊就不解釋了,程式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
isWin (index) {
let row = parseInt(index / 15);
let col = index % 15;
let left = col-4
let right = col+4
let top = row-4
let bottom = row+4
// console.log(index, row, col, top, bottom)
//left to right (橫線)
let result = '';
for(let c = left; c <= right; c++) {
if(c < 0 || c > 14)
continue;
result += this.checkerboardData[this.row_col_to_index(row, c)];
}
this.alertIfWin(result);
result = '';

//top to bottom (直線)
for(let t = top; t <= bottom; t++) {
if(t < 0 || t > 14)
continue;
result += this.checkerboardData[this.row_col_to_index(t, col)];
}
this.alertIfWin(result);
result = '';

//leftTop to rightBottom (左上右下斜線)
for(let c = left, t = top; c <= right && t <= bottom; c++, t++) {
if(c < 0 || c > 14 || t < 0 || t > 14)
continue;
result += this.checkerboardData[this.row_col_to_index(t, c)];
}
this.alertIfWin(result);
result = '';

//leftBottom to rightTop (左下右上斜線)
for(let c = left, t = bottom; c <= right && t >= top; c++, t--) {
if(c < 0 || c > 14 || t < 0 || t > 14)
continue;
result += this.checkerboardData[this.row_col_to_index(t, c)];
}
this.alertIfWin(result);
},
row_col_to_index (row, col) {
return 15*row+col;
}
  1. 將數字轉成棋子,那就寫個Component吧
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <!--circle.vue-->
    <template>
    <div class="circle" :class="(point == 1? 'black': 'white')">
    </div>
    </template>

    <script>
    export default {
    props: {
    point: Number
    }
    }
    </script>

    <style lang="stylus" scoped>
    .circle
    width 20px
    height 20px
    border-radius 999em

    .black
    background #000
    .white
    background #fff
    </style>

好,由於本人太廢,CSS寫半天才搞定,到此為止…共花了1小時40分
嗯,而且還沒完成…應該要把棋子調整到線上才行
程式先附上 程式碼-Sandbox ,看有沒有高手能幫我搞定吧…

最後,如果你有興趣學程式,可以參考下列平台:

  1. Udemy
  2. 六角學院
  3. HaHow

裡面有很多豐富的課程,線上學習不用出門唷!

↓↓↓ 如果喜歡我的文章,可以幫我按個Like! ↓↓↓
>> 或者,請我喝杯咖啡,這樣我會更有動力唷! <<<
街口支付

街口支付

街口帳號: 901061546

歡迎關注我的其它發布渠道