基于單片機的棋盤設(shè)計
摘要:本文摒棄了諸多傳統(tǒng)象棋的弊端,減輕了下棋人員的負(fù)擔(dān),增加了下棋的趣味性,實現(xiàn)自動采集對局信息發(fā)送到采集服務(wù)器進(jìn)行處理的功能,具體包括語音提示,計著子數(shù),自動計時,判斷行棋是否符合規(guī)則等功能。
本系統(tǒng)是基于嵌入式單片機技術(shù),利用相關(guān)光電檢測等技術(shù),自主實現(xiàn)棋盤的裁判功能,具有價格便宜,性價比高,制作簡單,易于實現(xiàn)功能擴展等優(yōu)點。文章重點對棋子編碼及程序邏輯控制方面進(jìn)行了探討。
引言
筆者進(jìn)行本文章研究的目的和意義體現(xiàn)在這些方面:將信息化技術(shù)引入到中國象棋這項運動中來,促進(jìn)其參與品味的提升,在一定程度上解放棋手和裁判,使得中國象棋這項運動變得更加簡單,進(jìn)一步拓寬中國象棋運動的視野,吸引更多的人參與到此項運動中來。
文章的主要工作是如何在保持棋手對壘慣性思維的基礎(chǔ)上,將先進(jìn)的軟硬件技術(shù)應(yīng)用到象棋這一項傳統(tǒng)運動及項目中來,利用信息技術(shù)完成記錄、裁決等操作,充分發(fā)揮傳感器、單片機等設(shè)備,以及C語言編程技術(shù)等電子信息專業(yè)的所學(xué)知識來完成計時、聲音提示、判斷行棋規(guī)則等重要功能。
此課題將改變老式象棋諸多弊端,提高比賽的品味和檔次以及減輕棋手負(fù)擔(dān),提高對局質(zhì)量,實現(xiàn)自動采集對局信息發(fā)送到采集服務(wù)器進(jìn)行處理的功能,能夠自動判斷棋手下棋是否符合規(guī)則,做出判斷,并且自動記錄棋手步數(shù)。具體包括自動計時,語音報警,自動判斷規(guī)則等功能。
中國象棋的每個棋子擺放的位置均為橫縱交叉點上,而本次論文設(shè)計引用了文件[1-2]中的傳感器技術(shù),為每個交叉點上均采用一個光電傳感器來接收棋子的移動或者變更信號,根據(jù)每個棋子的初始位置判斷棋子種類,根據(jù)棋子的運動軌跡判斷每個棋子是否符合行棋規(guī)則。弈棋交替進(jìn)行,直到某一方的將或者帥被對方吃掉為止。
比賽時,雙方輪流倒計時,即一方棋子落地開始為另一方倒計時,另一方的思考時間不能超過倒計時的時長。行棋前,智能棋盤會根據(jù)棋子所處的位置及其類型,對所有的棋子展開編碼處理,任何棋手完成一步行棋后,棋盤都會再次進(jìn)行掃描棋子的位置碼和種類碼并及時更新,直到本局對壘結(jié)束。
由于篇幅關(guān)系本文主要探討棋盤的軟件設(shè)計。
1 棋盤棋子編碼
為了使棋盤設(shè)計更加人性化,更加方便選手完成比賽,也為了使棋盤更加的人性化,將棋盤及棋子根據(jù)其位置進(jìn)行了編碼,中國的象棋棋盤如圖1所示,有橫9,縱10,共計90個格,交叉點為90個。紅黑雙方交替行棋,每人輪流走一步,可走棋、可吃棋,將帥吃掉為贏。
圖1 象棋初始棋盤
1.1 棋盤坐標(biāo)編碼
為了清楚知道下棋過程中,每個棋子行走的位置,先將棋盤的每個格進(jìn)行編碼,本著通俗易懂,易于理解的原則,將棋盤編碼。
中國象棋中共有7種棋子,紅黑雙方棋子對稱,這樣將棋子按照種類進(jìn)行編碼,如表1所示,這樣編碼的好處就是,因為紅黑雙方棋子初始狀態(tài)完全一樣,只需判斷正負(fù)符號就可以判斷處棋子是哪一方的,0即為無棋子,空格。
表1 棋子種類編碼
紅帥 | 紅車 | 紅馬 | 紅炮 | 紅相 | 紅士 | 紅兵 | 無棋子 |
1 | 2 | 3 | 4 | 5 | 6 | 7 | 0 |
黑將 | 黑車 | 黑馬 | 黑炮 | 黑象 | 黑士 | 黑卒 | |
-1 | -2 | -3 | -4 | -5 | -6 | -7 |
1.2 棋子個體編碼
編碼完棋盤、定義完棋子種類,則需要將棋盤坐標(biāo)與棋子個體進(jìn)行一一對應(yīng),先將棋子個體進(jìn)行編碼,如表2所示,注意“0”為無棋子,其中車、馬、炮、士、象雙方均為兩個,故占用兩個編碼,兵雙方各占用五個。
表2 棋子個體編碼
0 | 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 | |
紅帥 | 紅車 | 紅馬 | 紅炮 | 紅士 | 紅象 | 紅卒 |
1.3 棋盤索引數(shù)組
棋盤索引數(shù)組是將棋子種類編碼與棋盤坐標(biāo)編碼有機的結(jié)合在一起,能夠完成根據(jù)棋手走的每步棋子進(jìn)行調(diào)用修改,并儲存到單片機程序當(dāng)中去,這里的數(shù)組代表的是棋子的位置以及移動的位置,數(shù)組的編碼即表示棋子的實際位置。
這里引用的為一維數(shù)組,此數(shù)組簡單方便,運算較少、方便調(diào)用,并且比較直觀。中國象棋的初始局面下,棋盤索引數(shù)組如下所示:
Boardlndex[90]={-2,-3,-6,-5,-1,-5,-6,-3,-2
0, 0, 0, 0, 0, 0, 0, 0, 0,
0,-4, 0, 0, 0, 0, 0, -4, 0,
-7,0, -7, 0, -7,0, -7, 0, -7,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
7, 0, 7, 0, 7, 0, 7, 0, 7,
0, 4, 0, 0, 0, 0, 0, 4, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 3, 6, 5, 1, 5, 6, 3, 2,}
棋盤使用之前還要經(jīng)過下面三個步驟[3]。
1)使用前先將所有棋子初始化:
void Initchessman();//初始化所有棋子,以及坐標(biāo)
2)然后定義象棋棋子的結(jié)構(gòu)體
struct Chessman
{
char name[10];
ID3DXMesh*mesh;
D3DXVECTOR3 pos;
Bool Alive;
IDirect3DTexture9*texture;
POINT coord;
};
Coored為棋子在數(shù)組中的坐標(biāo),數(shù)組Chessman*ary[10][9]為相應(yīng)棋盤所在的位置,pos為空間位移,alive是棋子存活,mesh為每個棋子指向的指針,name是名字;其他除了chessman指針以外的部分為空格null。
3)規(guī)則設(shè)定繪制
在使用時,為了正確的選取棋子,讓棋子能夠按照規(guī)則正確的行走,調(diào)取了如下函數(shù):
①RayGetPickRay(int,int);//獲得選取射線;
②void InitChessman();//初始化所有棋子,以及坐標(biāo),
③bool IsMovingOk(int,int);//是否能行走到某一個點上;
④bool GetPlanePickPoint(D3DXVECTOR3,D3DXVECTOR3,Ray);//通過拾取射線與棋盤,從而得到拾取點;
⑤bool PickChessman(Ray);//是否拾取棋子;
2 下棋子程序設(shè)計
當(dāng)棋手開始下棋時,下棋使用的程序共分為:走棋程序、吃棋程序、行棋規(guī)則。三種程序同時調(diào)用,下面以我方走馬和走車分別為例進(jìn)行說明。
2.1 帥行棋設(shè)計
帥的行棋規(guī)則實現(xiàn)方法與前面車和馬類似。首先是否符合行棋規(guī)則,行棋范圍為九宮格內(nèi)部,帥每步只能走一步,可上可下可左可右。然后判斷走棋還是吃棋,中間出現(xiàn)不符合行棋規(guī)則的地方則報警,如圖2所示。
圖2 帥行棋圖
帥與將行棋規(guī)則一樣編程原理如圖3所示。
圖3 將和相行棋程序框圖
程序如下:
if(toY>2||toX<3||toX>5){//出了九宮格
Return false;
}
if((Math.abs(fromY-toY)+Math.abs(toX-fromX))>1){//只能走一步
return false;
}
2.2 象行棋規(guī)則
象的行棋規(guī)則與士和馬類似,象不能過河,存在蹩象眼的情況,象行走田字,即象只能夠跨格走斜線,象只能走到田字格對角線三個位置上,而不能走到其他位置[4-5]。當(dāng)棋手走象時,步驟如下。
1)根據(jù)是否僅有一個子動作判斷調(diào)用走棋程序還是吃棋程序。
2)若僅有一個子動作則調(diào)用走棋程序。
3)再根據(jù)行棋規(guī)則判斷是否符合象的行棋規(guī)則,判斷方法為橫縱坐標(biāo)中橫和縱向分別移動兩格,如不符合則報警。
4)如果沒有犯規(guī)記錄則自動將象的程序編碼及移動位置進(jìn)行儲存。
5)若有兩個棋子位置發(fā)生改變,則判定調(diào)用吃棋程序,當(dāng)棋手吃完棋后,再根據(jù)行棋規(guī)則判斷是否符合,如若不符合則自動報警。
6)如果沒有犯規(guī)記錄則自動將象的程序編碼及移動位置進(jìn)行儲存。
7)同時要注意根據(jù)事先設(shè)定的程序,吃棋時需要先拿起自己的子再去拿對方的子。
所以其程序如下所示:
if(toY>4){//不能過河
return false;
}
if((Math.abs(fromX-toY)!=2||Math.abs(fromY-toY)!=2){//象走田字
return false;
}
if(qizi[(fromY+toY)/2][(fromX+toX)/2]!=0){
return false;//象眼處有棋子
}
2.3 兵行棋規(guī)則
兵的行棋規(guī)則比較簡單,與帥類似,每次只能走一步。同時也要判斷行棋還是吃棋。行走范圍不同:過河之前只能直走,而過河之后可以走到任意一格。過河之前只能向前走,過河之后可以向左右前三個方向行走,不過不可回頭。
兵與卒行棋規(guī)則相同,不再累述。
3 結(jié)語
本次智能棋盤設(shè)計,可在硬件上選用較為常見的單片機進(jìn)行配置,并且性能穩(wěn)定,操作簡單,方便,整體電路搭配較為完善。
由于篇幅的限制筆者并沒有給出所有棋子的編譯程序和邏輯圖,僅列出了帥士相三種棋子的行棋程序,本論文作為一項智能系統(tǒng)的研究的理論與嘗試,想投入實際的應(yīng)用還有一些技術(shù)難點。隨著軟件設(shè)計技術(shù),微電子技術(shù),和相關(guān)技術(shù)的發(fā)展。此課題還會不斷完善,不斷改進(jìn),最終實現(xiàn)功能上的不斷更新。
參考文獻(xiàn):
[1] 孫傳友,等.感測技術(shù)與系統(tǒng)設(shè)計.北京:科學(xué)出版社,2004.
[2] 浦昭邦.光電測試技術(shù).北京:機械工業(yè)出版,2004.
[3] 秦維佳,侯春光,等.C/C++程序設(shè)計教程.北京:機械工業(yè)出版社,2007.
[4] 向紅.51系列單片機應(yīng)用與實踐教程.北京:北京航空航天大學(xué)出版社,2008.
[5] BARRY B B. The Intel Microprocessors.6th ed.2005.
(本文來源于《電子產(chǎn)品世界》雜志社2021年2月期)
評論