馮地龍
五子棋大家都玩過,雙方分別使用黑白兩色的棋子,下在棋盤直線與橫線的交叉點上,先形成五子連珠者獲勝。五子棋起源于中國,還是全國智力運動會競技項目之一。由于規(guī)則簡單,老少皆宜,而且趣味橫生,引人入勝(圖1)。
今天跟大家分享怎么用Scratch制作五子棋游戲。想要把五子棋的規(guī)則完全用Scratch編程實現還是不容易的。在編寫程序之前,我們先梳理一下思路,程序需要實現以下目標:
①繪制棋盤
②限制光標移動
③實現落子功能
④判斷棋盤狀態(tài)
⑤判斷五子連珠
⑥實現人機對下
2021年第3期我們曾經介紹過用Scratch制作五子棋,當時實現了繪制棋盤和黑白交替落子功能,也就是完成了前3項功能,后面幾項沒能實現。現在我們的編程能力已經提高了,本文將能實現前5項功能,完成五子相連的勝負判斷。由于前3項功能已經介紹過,本文只提示一下要點,重點還是在于判斷棋盤狀態(tài)和判斷五子連珠。至于實現人機對下涉及算法策略,我們以后再來實現。
1.用一個角色隱藏繪制棋盤。
2.為了方便計算,起點坐標值取整數(XY軸方向分別為-150、150)。重復繪制16條橫線和豎線,每條長度300。
3.繪制XY方向的間距為20(也就是步長)。
4.用畫筆功能完成繪制15×15的棋盤。
參考代碼如圖2:
1.創(chuàng)建新的角色“光標”,用來提示當前操作者,含有兩個造型(黑色光標造型編碼為1;白色光標造型編碼為2),光標角色稍大于五子棋(因五子棋在光標內落子)。
2.利用邏輯與配合棋盤大小的坐標值把光標控制在棋盤內跟隨鼠標指針移動。
3.根據光標跟隨鼠標的坐標值可以計算出在棋盤的行數和列數,儲存在新建變量的“行數Y”和變量“列數X”中?!靶袛礩”是因為Y值不同則行數不同,同理兩個棋子的X值不同Y值一樣則兩個棋子在同一行,有相同的“行數Y”。
4.通過計算,把變量“行數Y”和“列數X”計算出來的舞臺坐標值分別賦值到鼠標XY軸坐標上,同時設為當前坐標,這樣我們就可以把角色固定在棋盤XY兩軸相交點上。
5.棋盤大小是15×15,行數和列數相交點也就是225個。
6.通過變量“行數Y”和變量“列數X”中的計算得出光標在棋盤內X、Y(行列相交的點)新的坐標值,賦值在新建變量ID上。(ID相當于在棋盤行列相交點的每一個坐標。每一個相交點都有一個對應的ID值。)
參考代碼如圖3:
1.創(chuàng)建角色五子棋,棋的造型為兩個,黑色棋1和白色棋2(對應光標造型的顏色)。
2.在光標角色里通過按下鼠標成立與不成立的邏輯,按下就廣播新建消息落子,切換下一個造型,如果沒有按下鼠標就一直等待。落子代碼在圖3中。
3.當角色五子棋接收到落子的消息,換成光標的造型編碼,移動到角色光標的位置蓋上圖章(實現落子功能)。如圖4。
1.新建“棋盤狀態(tài)”列表,這是15×15=225項的列表。將0加入狀態(tài)(空狀態(tài))(圖5)。
2.通過在光標角色里按下鼠標成立與不成立的邏輯,嵌套條件判斷如果列表的ID項等于0(也就是空狀態(tài),沒有棋子),廣播消息落子,并把造型的編號賦值在列表棋盤狀態(tài)的ID項(造型編號兩個,也就賦值1的狀態(tài),1就是黑棋),下一個造型。
3.如果列表的ID項不等于0(狀態(tài)兩種,0是空狀態(tài),1代表黑子和2代表白子),有棋子狀態(tài)的情況不能廣播落子消息,無動作。等待光標移動到棋盤是0的ID項才能實現按下鼠標條件成立并廣播落子的消息。具體代碼請參考圖3。落子之后列表對應效果如圖6。
1.判斷五子連珠首先要知道五子棋的連珠規(guī)則,以最近一個棋子落下為原點,橫豎斜等八個方向有5顆同色棋子連成一條線代表此方勝利。
2.創(chuàng)建繪制新的角色“判斷”。鼠標在棋盤內移動,注意行列的變量,你會發(fā)現方向變化的規(guī)律,總結出往八個方向每走一格數據的變化:
正方向,向上走X增加0、Y增加1;斜上走X增加1、 Y增加1;右走X增加1、Y增加0;斜下走X增加1、Y減少1(如圖7)。
反方向走的規(guī)律變化類似,只是根據方向變成負數,變量“列數X”和“行數Y”增加負1。
3.新建變量“判斷列數X”和“判斷行數Y”,并把變量“列數X”和“行數Y”賦值給這兩個變量上,用于判斷五子連珠。
4.自定義函數積木“判斷連珠XYK”,參數XY表示縱橫坐標,K為系數用作正反方向。
原理:變量“列數X”和“行數Y”分別賦值到對應“判斷列數X”和“判斷行數Y”;然后開始判斷,將“判斷列數X”和“判斷行數Y”增加“判斷連珠”函數里的X和Y的值乘以系數K(正數1和負數1),這樣可以將8個方向都試一遍。
先判斷落子在棋盤內,在行數與列數是-1到15之間。
如果棋盤狀態(tài)的ID項等于當前的造型編號(1或2)時,將變量計數增加1,重復4次,如果等于棋盤狀態(tài)的1或者2時,表示旁邊有同色的棋子,就按這個方向繼續(xù)去檢測,如果可以重復4次就表示五子連珠了,否則就停止這個腳本(如圖8)。
5. 在角色光標里,按下鼠標成立,廣播新建消息判斷方向消息,當判斷角色接收到判斷方向消息后把自定義函數積木判斷連珠方向值傳送一遍。
6. 自定義函數積木方向,把判斷連珠函數里面的系數K正反值輸入進去,將變量檢測設為1,如果變量計數的值檢測到大于4,且光標的造型編碼等于1,黑棋贏,等于2白棋贏(如圖9)。
到這里,我們的五子棋游戲也就成功了。其實五子棋的難點在于思路,判斷邏輯要明確清楚,涉及的數學知識比較廣泛,比如參數K就是向量知識。根據鼠標的指針坐標計算變量行數Y,變量列數X以及變量ID。你需要充分理解自定義積木里面參數之間的關系,判斷勝負的條件等。
這里我們只用五子連珠來判斷勝負,真實比賽中為了平衡先手的優(yōu)勢還會對黑棋規(guī)定“禁手”。如三三禁手(兩個以上的活三)、四四禁手、長連禁手。黑方禁手形成時,白方應立即指出。若白方在之后繼續(xù)落子,則禁手失效。黑方出現禁手,無論是自愿下或被迫下,均判負。黑方五連與禁手同時形成,判黑方勝。
最后給大家留一個問題,在目前的五子棋游戲中是屬于雙人對戰(zhàn),如果把一方改為自動(機器AI)落子實現人機大戰(zhàn)呢?好了,這個問題就交給下一篇文章了。我們一起動腦思考一下吧。