--- tags: 2022 iThome 鐵人賽 title: 10/14 Arcade也能學演算法Ouo!? 演算法遊戲(5) AUTHOR: 鍾佳龍 --- # Arcade再進化 ## Arcade也能學演算法Ouo!? 演算法遊戲!(5) ### **第五篇:棋類遊戲-黑白棋實作篇** > ### 大綱 > * 遊戲內容 > * 基本設定 > * 下棋 > * 顯示結果 > * 結束了? ## 遊戲內容 [![](https://i.imgur.com/eA3H66l.gif)](https://arcade.makecode.com/S44558-75061-91805-02033) 點擊動圖可以進入遊戲 首先 有紅色框框可以選位置 然後下棋 最後結束的時候會告訴你是誰贏了 ## 製作開始!! 開始第一件事情就是建立角色拉 可以從上面的成果預覽看到 我們的物件就三個 1. 棋盤 1. 棋子 1. 紅色游標 ```typescript let backgroung_board = sprites.create(img` ... `, SpriteKind.Player) backgroung_board.changeScale(2, ScaleAnchor.Middle) let board = sprites.create(img` ... `, SpriteKind.Player) board.changeScale(2, ScaleAnchor.Middle) let choese = sprites.create(img` ... `, SpriteKind.Player) choese.setPosition(75, 55) ``` 然後是我們一路走熟到爆的控制選擇 這次有點小不一樣 因為我們有橫軸跟縱軸 聰明的你應該知道怎麼做了吧 ```typescript // control let now_x = 3 let now_y = 3 controller.right.onEvent(ControllerButtonEvent.Pressed, function () { now_x = (now_x + 1) % 8 choese.setPosition(39+now_x*12, 19+now_y*12) }) controller.left.onEvent(ControllerButtonEvent.Pressed, function () { if (now_x == 0) { now_x = 8; } now_x -= 1; choese.setPosition(39 + now_x * 12, 19 + now_y * 12) }) controller.down.onEvent(ControllerButtonEvent.Pressed, function () { now_y = (now_y + 1) % 8 choese.setPosition(39 + now_x * 12, 19 + now_y * 12) }) controller.up.onEvent(ControllerButtonEvent.Pressed, function () { if (now_y == 0) { now_y = 8; } now_y -= 1; choese.setPosition(39 + now_x * 12, 19 + now_y * 12) }) ``` 這次的話不只是左右移動了 還要上下 所以我們設定兩個軸 一個是X一個Y 接者就要進入上次文章的範圍了喔 ## 下棋 我設定A鍵下棋 ```typescript controller.A.onEvent(ControllerButtonEvent.Pressed, function () { let put = false; let X = now_x let Y = now_y ... }) ``` 先存個變數方便調用 然後第一件就是要偵測是否能下 也就是我們上篇的`check_put_legitimate`函式 那這邊基本上沒有改變喔 就是上一篇的程式碼搬過來了 不知道是什麼的可以回到上一篇 有變的就是在return的部分 下面會講到 ```typescript controller.A.onEvent(ControllerButtonEvent.Pressed, function () { let put = false; let X = now_x let Y = now_y // check put let check = check_put_legitimate(X, Y, turn); if (check) { put = true; play(X, Y, turn, mode, coun); } ... ``` 檢查位置是否合法後就可以執行下棋的部分了 不過有看上一篇的應該有發現我的play函式怎麼多了兩個參數阿 這是因為在typescript的關係喔 > 對arcade縮然說他是用javascript但事實上他是用typescript > 那因為typescript是強型態喔 > 所以return的變數型態如果照上篇的寫法 > 他的回傳值型代會變成`(boolen, number[])`然後就不能當作`number`用了 所以我另外把mode 跟count變成全域變數 阿但! 不知道為啥我名稱不能設`count`所以就退而求其次取`coun`了 剩下完全沒改 所以我就不貼程式碼瞜 大家自行到範例程式看 ## 顯示結果 ```typescript controller.A.onEvent(ControllerButtonEvent.Pressed, function () { let put = false; let X = now_x let Y = now_y // check put let check = check_put_legitimate(X, Y, turn); if (check) { put = true; play(X, Y, turn, mode, coun); } if (put) { print(); ... }) ``` 那這次不是因在console喔 所以這邊的`print`是完全不一樣 不過這次的方法各位也很熟悉了 ```typescript function print() { let bord_img = image.create(33, 33) for (let Y = 0; Y < 8; Y++) { for (let X = 0; X < 8; X++) { if(Data[Y][X] != " "){ let color = Data[Y][X] == "O" ? 1 : 15 bord_img.setPixel(2+4*X, + 2+4*Y, color) bord_img.setPixel(1 + 4 * X, + 2 + 4 * Y, color) bord_img.setPixel(3 + 4 * X, + 2 + 4 * Y, color) bord_img.setPixel(2 + 4 * X, + 1 + 4 * Y, color) bord_img.setPixel(2 + 4 * X, + 3 + 4 * Y, color) } } } board.setImage(bord_img) } ``` 就簡單的更改角色皮膚 ## 結束拉 最後是判斷是否結束 這邊的話也是上次飯粒程式改的喔 ```typescript controller.A.onEvent(ControllerButtonEvent.Pressed, function () { let put = false; let X = now_x let Y = now_y // check put let check = check_put_legitimate(X, Y, turn); if (check) { put = true; play(X, Y, turn, mode, coun); } if (put) { print(); turn = turn == "O" ? "X" : "O"; if (check_end(turn)) { turn = turn == "O" ? "X" : "O"; if (check_end(turn)) { game.splash(`${turn == "O"? "white": "black"} is win!!`) game.over(false) } } scene.setBackgroundColor(turn == "O" ? 1 : 15) } }) ``` 就是如果下一輪的人不能下 那就pass 阿但是在下一輪也不能下 那遊戲就結束了 最後數數看誰棋多 ```typescript function check_end(turn:string) { let end = true; for (let i = 0; i < 8; i++) { for (let j = 0; j < 8; j++) { if (Data[i][j] == " ") { if (check_put_legitimate(j, i, turn)) { end = false; } } } } return end; } function check_win() { let count = [0, 0]; for (let i = 0; i < 8; i++) { for (let j = 0; j < 8; j++) { if (Data[i][j] == "O") { count[0]++; } else if (Data[i][j] == "X") { count[1]++; } } } return count[0] > count[1] ? "white" : "black"; } ``` 這就是全部內容拉 --- > ## 下期預告 > **嗯?完結啦!!**