華容道解題報告

2021-04-02 06:48:07 字數 1477 閱讀 6970

基本思想:

廣度優先遍歷搜尋所有可能棋局。

實現方法:

1.棋子的型別(hrd.h)

#define chess_blank  0 //空白

#define chess_g4  1 //四格棋子

#define chess_g2h  2 //橫向兩格棋子

#define chess_g2v  3 //縱向兩個棋子

#define chess_g1  4 //一格棋子

#define bound   5 //邊界

可用3位編碼表示。

2.布局的表示方法(board.h)

typedef struct board *board;

id為布局的壓縮表示方法。3位表示乙個格仔的狀態,共需60位,使用乙個64位的整數表示。gen_id()函式用於由layout陣列計算id。

layout為布局的直觀表示方法。布局儲存在位於**的layout[2...6][2...5]中。周圍保留寬度為2的邊界,均填入bound型別。(便於行棋時的比較判斷)。

index中儲存每一枚棋子的橫縱座標的索引。共10枚棋子,加兩個空格。

3.棋子的屬性(board.h)

extern int wh[12][3];

與index對應,儲存每一枚棋子的長度、寬度、和型別值。順序為:

0   1    2    3    4    5    6   7   8   9   10     11

g4, g2v, g2v, g2v, g2v, g2h, g1, g1, g1, g1, blank, blank

4.採用hash表儲存和查詢已有的棋局id。(hash.h)

void add_hash(unsigned long long id);

int get_hash(unsigned long long id);

5.逆向的搜尋樹:每獲得新的狀態節點都設乙個鏈結指向父節點。(tree.h)

typedef struct treenode *tnode;

6.佇列用於bfs。(queue.h, 迴圈鍊錶實現)

typedef struct queuenode *qnode;

優化策略:

使用棋局壓縮編碼進行與先前棋局的比較是提高效率的關鍵。我開始沒有想到,是看到他人的解法才獲得啟示。hash表可以提供常數的查詢時間,hash函式隨便寫了乙個(hash.c),看來還可以。

棋子的移動方式要考慮周全,g4有四種可能,g2h/g2v各有六種可能,g1則有16種可能。需要合理的安排條件語句,避免不必要的開銷。

這裡只實現了對於標準「橫刀立馬」布局的搜尋,沒有做進一步的推廣。

題目的規模並不大。profiling顯示呼叫開銷佔前三位的是gen_id(), add_hash()和get_hash()。在我的600mhzcpu上求解「橫刀立馬」81步解法需要0.3s左右,共搜尋23822個狀態節點。

------------------

源**: hrd.tar.bz2

華容道系列 開篇 《華容道與資料結構》

此為轉貼,原文出處 本系列內容將分成兩大部分 華容道與資料結構 以及 華容道與設計模式 兩者之間會有一些交叉。這個學期給學生上 設計模式 的課程,有些學生提出找些題目練練手,增強一些實戰經驗,我決定讓他們編寫 華容道 遊戲。說實在的,當時並沒有深思熟慮。後來自己仔細想想,發現這裡面東西還真不少,甚至...

華容道3x3的技巧 數字華容道 無上限解題技巧

之前就聽過數字華容道,但是一直沒有上手,今天發現室友再玩,我就下了乙個,試了一下3x3 26秒,挺簡單的 有玩了下5x5 說實話,前面3行很順利,但是最後2行就比較 碰運氣 以及燒腦了。真不是謙虛,我完成了,但我知道我真的靠運氣,緊接著玩8x8 到最後兩行擺弄了20分鐘,直接放棄,我實在不想破壞上一...

華容道程式求解

題解部落格 blog.lzh.today klotski solver 專案分期計畫 實現對橫刀立馬布局的求解,匯出步驟快照 實現對標準華容道滑塊 卒 五虎上將 曹操 任意布局的求解 實現對任意自定義滑塊 自定義棋盤的求解 技術路線 spring boot,junit 閱讀建議 新頁面開啟關鍵類圖,...