黑白子交換

2022-05-05 07:48:06 字數 1965 閱讀 2804

有三個白子和三個黑子如下圖布置:

○ ○ ○ . ● ● ●

遊戲的目的是用最少的步數將上圖中白子和黑子的位置進行交換:

● ● ● . ○ ○ ○

遊戲的規則是:(1)一次只能移動乙個棋子; (2)棋子可以向空格中移動,也可以跳過乙個對方的棋子進入空格,但不能向後跳,也不能跳過兩個子。請用計算機實現上述遊戲。

*問題分析與演算法設計

計算機解決勝這類問題的關鍵是要找出問題的規律,或者說是要制定一套計算機行動的規則。分析本題,先用人來解決問題,可總結出以下規則:

(1) 黑子向左跳過白子落入空格,轉(5)

(2) 白子向右跳過黑子落入空格,轉(5)

(3) 黑子向左移動一格落入空格(但不應產生棋子阻塞現象),轉(5)

(4) 白子向右移動一格落入空格(但不應產生棋子阻塞現萌),轉(5)

(5) 判斷遊戲是否結束,若沒有結束,則轉(1)繼續。

所謂的「阻塞」現象就是:在移動棋子的過程中,兩個尚未到位的同色棋子連線在一起,使棋盤中的其它棋子無法繼續移動。例如按下列方法移動棋子:

0○ ○ ○ . ● ● ●

1 ○ ○ . ○ ● ● ●

2 △ ○ ○ ● ○ . ● ●

3○ ○ ● . ○ ● ●

4 兩個●連在一起產生阻塞

○ ○ ● ● ○ . ●

或4 兩個白連在一起產生阻塞

○ . ● ○ ○ ● ●

產生阻塞的現象的原因是在第2步(△狀態)時,棋子○不能向右移動,只能將●向左移動。

總結產生阻塞的原因,當棋盤出現「黑、白、空、黑」或「白、空、黑、白」狀態時,不能向左或向右移動中間的棋子,只移動兩邊的棋子。

按照上述規則,可以保證在移動棋子的過程中,不會出現棋子無法移動的現象,且可以用最少的步數完成白子和黑子的位置交換。

*程式說明與注釋

#include

int number;

void print(int a);

void change(int *n,int *m);

int main()

; /*初始化陣列1:白子 2:黑子 0:空格*/

int i,flag;

print(t);

while(t[0]+t[1]+t[2]!=6||t[4]+t[5]+t[6]!=3) /*判斷遊戲是否結束

若還沒有完成棋子的交換則繼續進行迴圈*/

for(i=0;flag&&i<5;i++) /*若黑子可以向左跳過白子,則黑子向左跳*/

if(t[i]==0&&t[i+1]==1&&t[i+2]==2)

for(i=0;flag&&i<6;i++) /*若向右移動白子不會產生阻塞,則白子向右移動*/

if(t[i]==1&&t[i+1]==0&&(i==0||t[i-1]!=t[i+2]))

for(i=0;flag&&i<6;i++) /*若向左移動黑子不會產生阻塞,則黑子向左移動*/

if(t[i]==0&&t[i+1]==2&&(i==5||t[i-1]!=t[i+2]))}}

void print(int a)

void change(int *n,int *m)

*問題的進一步討論

本題中的規則不僅適用於三個棋子的情況,而且可以推而廣之,適用於任意n個棋子的情況。讀者可以程式設計驗證,按照本規則得到的棋子移動步數是最少的。

事實上,制定規則是解決這類問題的關鍵。乙個遊戲程式「思考水平的高低,完全取決於使用規則的好壞。」

*思考題

有兩個白子和兩個黑子如下左圖布置:

○ . ○

. . .

● . ●

棋盤中的棋子按」馬步「規則行走,要求用最少的步數將圖中白子和黑子的位置進行交換,最終結果如下一幅圖所示。

● . ●

. . .

○ . ○