第一篇:五子棋游戲軟件工程課程設計
軟件工程設計
專 業:班 級:姓 名:學 號:指導老師:
I
目錄
第一章 需求分析.......................................................1 1.1 總體分析..........................................................1 1.2 初始化............................................................1 1.3 主循環控制模塊....................................................1 1.4 玩家下子..........................................................1 1.5 盤面分析填寫棋型表................................................2 1.6 對方下子..........................................................2 1.7 勝負判斷..........................................................2 第二章 功能描述.......................................................3 2.1 功能模塊圖........................................................3 2.2 功能說明..........................................................3 第三章 系統設計.......................................................4 3.1 流程圖............................................................4 3.2 流程圖說明........................................................5 第四章 運行結果.......................................................6 第五章 總結...........................................................7 附錄一 源代碼.........................................................8
II
軟件工程設計
五子棋游戲
第一章 需求分析
1.1 總體分析
軟件需求分析是軟件開發周期的第一個階段,也是關系到軟件開發成敗的關鍵一步。對于任何一個軟件而言,需求分析工作都是至關重要的一步。只有通過軟件需求分析,才能把軟件的功能和性能由總體的概念性描述轉化為具體的規格說明,進而建立軟件開發的基礎。實踐表明,需求分析工作進行得好壞,在很大程度上決定了軟件開發的成敗。
軟件需求分析的任務是:讓用戶和開發者共同明確將要開發的是一個什么樣的軟件。具體而言,就是通過對問題及其環境的理解、分析和綜合,建立邏輯模型,完成新軟件的邏輯方案設計。
基于本游戲,首先得為整個棋盤建立一張表格用以記錄棋子信息,我們使用一個15*15的二維數組Table[15][15](15*15是五子棋棋盤的大小),數組的每一個元素對應棋盤上的一個交叉點,用‘0’表示空位、‘1’代表己方的子、‘2’代表對方的子;這張表也是今后分析的基礎。在此之后還要為兩個玩家雙方各建立一張棋型表Computer[15][15][4]和Player[15][15][4],用來存放棋型數據。
1.2 初始化
首先,建立盤面數組Table[15][15]、對戰雙方的棋型表Computer[15][15][4]和Player[15][15][4]并將它們清零以備使用;然后初始化顯示器、鍵盤、鼠等輸入輸出設備并在屏幕上畫出棋盤(棋盤可以不顯示)。
1.3 主循環控制模塊
控制下棋順序,當輪到某方下子時,負責將程序轉到相應的模塊中去,主要擔當一個調度者的角色。
1.4 玩家下子
當輪到玩家下時,您通過鍵盤或鼠標在棋盤上落子,程序會根據該點的位置,在Table[15][15]數組的相應地方記錄‘2’,以表明該子是玩家下的。
軟件工程設計
1.5 盤面分析填寫棋型表
您在下五子棋時,一定會先根據棋盤上的情況,找出當前最重要的一些點位,如“活三”、“沖四”等;然后再在其中選擇落子點。先來分析己方的棋型,我們從棋盤左上角出發,向右逐行搜索,當遇到一個空白點時,以它為中心向左挨個查找,如果遇到己方的子則記錄然后繼續,如果遇到對方的子、空白點或邊界就停止查找。左邊完成后再向右進行同樣的操作;最后把左右兩邊的記錄合并起來,得到的數據就是該點橫向上的棋型,然后把棋型的編號填入到Computer[x][y][n]中就行了(x、y代表坐標,n=0、1、2、3分別代表橫、豎、左斜、右斜四個方向)。而其他三個方向的棋型也可用同樣的方法得到,當搜索完整張棋盤后,己方棋型表也就填寫完畢了。然后再用同樣的方法填寫對方棋型表。
注意:所有棋型的編號都要事先 定義好,越重要的號數越大!
1.6 對方下子
有了上面填寫的兩張棋型表,就是遍歷棋型表Computer[15][15][4]和Player[15][15][4]找出其中數值最大的一點,在該點下子即可。但這種算法的弱點非常明顯,只顧眼前利益,不能顧全大局,這就和許多五子棋初學者一樣犯了“目光短淺”的毛病。如果在這兒下子將會形成對手不得不防守的棋型(例如:‘沖四’、‘活三’);那么下一步對手就會照您的思路下子來防守您,如此一來便完成了第一步的預測。這時再調用模塊4對預測后的棋進行盤面分析,如果出現了‘四三’、‘雙三’或‘雙四’等制勝點,那么己方就可以獲勝了(當然對黑棋而言‘雙三’、‘雙四’是禁手,另當別論);否則照同樣的方法向下分析,就可預測出第二步、第三步??
等一等,要是盤面上沒有對手必須防的棋型,哪該怎么辦呢?進攻不成的話就得考慮防守了,將自己和對手調換一下位置,然后用上面的方法來預測對手的棋,這樣既可以防住對手巧妙的攻擊,又能待機發動反擊,何樂而不為呢!
1.7 勝負判斷
務須多言,某方形成五子連即獲勝;若黑棋走出‘雙三’、‘雙四’或長連即以禁手判負。
軟件工程設計
第二章 功能描述
2.1 功能模塊圖
五子棋游戲判斷棋盤是否已滿判斷是否出錯并提示判斷那方獲勝交替循環雙方下棋 圖2.1 功能模塊圖
2.2 功能說明
該五子棋程序基本上實現了五子棋的游戲功能,有雙方下棋的界面及最終判定結果的界面。同時該游戲采用二維坐標實現,明了易懂,方便玩家在游戲過程中的基本操作,使游戲更加簡便。在細節方面,該系統提供實時存儲功能,隨時記錄為完成的游戲,使用戶可以很好的處理意外中斷的情況。該游戲基本實現了游戲的一些要求和特征。在游戲的源程序及文檔方面,我們也嚴格遵守軟件工程思想,立足實驗要求,確定任務,需求分析,設計和編碼,每個步驟力求清晰易懂。原代碼注釋詳盡,各功能模塊功能分明,可移植性強。當然該系統也有很多不足的地方,第一次進行獨立的課程設計,也有很多細節方面是考慮到的,這款游戲也是在不斷的調試和修改中產生和完善的。希望老師能夠指出不足,幫助我不斷提高。
軟件工程設計
第三章 系統設計
3.1 流程圖
開始棋盤已滿是輸出平局否“0”方選位置判斷該位置是否有棋有另找位置無“0”方落子否判斷“0”方是否獲勝是輸出“0”方獲勝否棋盤已滿是輸出平局結束否“x”方選位置判斷該位置是否有棋有另找位置無“x”方落子判斷“x”方是否獲勝是輸出“x”方獲勝 圖3.1 流程圖
軟件工程設計
3.2 流程圖說明
本程序定義了各種操作函數、各種狀態判定宏,思想明確,思路清晰。各個判斷選擇了不同路徑,因此繼續進行或輸出結果。程序中,“循環”的利用非常直接和清晰,雙方交替下棋,因此循環往復。最終決出勝負或最終平局。分析時,也考慮了許多種情況,針對各個情況均作出了相對措施和解決方案。
程序采用循環進行雙方交替下棋,并進行了很多判斷。首先判斷棋盤是否已滿,若棋盤已滿,則輸出平局,結束游戲;若棋盤未滿,則繼續進行。然后判斷“0”方是否勝出,若“0”方獲勝,則輸出“0”方獲勝,結束游戲;若“0”方沒有獲勝,則繼續進行。再判斷“x”方是否獲勝,若“x”方獲勝,則輸出“x”方獲勝,結束游戲;若“x”方沒有獲勝,則繼續進行。回到“首先”的判斷。如此循環??
軟件工程設計
第四章 運行結果
圖4.1 運行結果初始圖
圖4.2 游戲過程圖
圖4.3
軟件工程設計
圖4.4
圖4.5
軟件工程設計
圖4.6
圖4.7
軟件工程設計
圖4.8 游戲進行圖
圖4.9 “0”方獲勝圖
軟件工程設計
附錄一 源代碼
#include
using namespace std;
int Hsheng(char a[][15]);
//判斷o子是否獲勝的函數
int Bsheng(char a[][15]);
//判斷x子是否獲勝的函數
int he(char a[][15]);
//判斷是否平局(也就是棋盤下滿了)的函數
void qipan(char a[15][15])
//執行輸出棋盤命令 {
cout<<“本游戲采用二維數組實現,棋盤為15X15的二維直角坐標系,均從1到15,祝二位游戲愉快.”;for(int i=0;i<15;i++)
//打印棋盤
{
for(int j=0;j<15;j++)cout< } } int main(){ char a[15][15]; int x,y; for(int i=0;i<15;i++) for(int j=0;j<15;j++) a[i][j]=' ';qipan(a); while(1)//用循環語句執行o,x交替下子,這些while語句看起來似乎是個死循環~實際上都會經過break結束 { int a1=1; while(1) { for(;a1;) { cout<<“請輸入o子下的位置:”; //輸入o子的位置 cin>>x>>y;if(a[x][y]=='o'||a[x][y]=='x') //判斷是否已有子 {cout<<“已有子請重下”<<“,”;continue;} else if(x>=15||y>=15){cout<<“輸入錯誤請重輸”<<“,”;continue;} else { a[x][y]='o';a1=0;} } break;} 軟件工程設計 qipan(a); //下好o子后將棋盤顯示 if(Hsheng(a)) //判斷o子是否已經獲勝 {cout<<“o子獲勝”< while(1) //下x子 { cout<<“請輸入x子下的位置:”; cin>>x>>y; if(a[x][y]=='o'||a[x][y]=='x'||x>=15||y>=15) { for(;a[x][y]=='o'||a[x][y]=='x';) { cout<<“已有子請重下”; cout<<“請輸入x子下的位置:”; cin>>x>>y;continue;} for(;x>=15||y>=15||x;) { cout<<“輸入錯誤請重輸”<<“,”; //判斷輸入棋子位置是否正確 cout<<“請輸入x子下的位置:”; cin>>x>>y;continue;} a[x][y]='x';break; } else {a[x][y]='x';break;} } qipan(a); //再一次輸出棋盤 if(Bsheng(a)) //判斷x子是否已經獲勝 {cout<<“x子獲勝”< if(he(a)) //判斷是否平局 {cout<<“平局”< } return 0; } int Hsheng(char a[][15]){ int i,j; //判斷橫著的5個是否都相等 for(i=0;i<15;i++) for(j=0;j<15;j++) if(a[i][j]=='o'&&a[i][j+1]=='o'&&a[i][j+2]=='o'&&a[i][j+3]=='o'&&a[i][j+4]=='o') return 1; for(j=0;j<15;j++) //判斷豎著的5個是否都相等 for(i=0;i<15;i++) if(a[i][j]=='o'&&a[i+1][j]=='o'&&a[i+2][j]=='o'&&a[i+3][j]=='o'&&a[i+4][j]=='o') 軟件工程設計 return 1; for(i=0;i<15;i++) //判斷左斜5個 for(j=0;j<15;j++) if(a[i][j]=='o'&&a[i+1][j+1]=='o'&&a[i+2][j+2]=='o'&&a[i+3][j+3]=='o'&&a[i+4][j+4]=='o') return 1; for(i=0;i<15;i++) //右斜5個 for(j=14;j>3;j--) if(a[i][j]=='H'&&a[i+1][j-1]=='o'&&a[i+2][j-2]=='o'&&a[i+3][j-3]=='o'&&a[i+4][j-4]=='o') return 1; return 0; } int Bsheng(char a[][15]) //同o,只是改字符 { int i,j; for(i=0;i<15;i++) for(j=0;j<15;j++) if(a[i][j]=='x'&&a[i][j+1]=='x'&&a[i][j+2]=='x'&&a[i][j+3]=='x'&&a[i][j+4]=='x') return 1; for(j=0;j<15;j++) for(i=0;i<15;i++) if(a[i][j]=='x'&&a[i+1][j]=='x'&&a[i+2][j]=='x'&&a[i+3][j]=='x'&&a[i+4][j]=='x') return 1; for(i=0;i<15;i++) for(j=0;j<15;j++) if(a[i][j]=='x'&&a[i+1][j+1]=='x'&&a[i+2][j+2]=='x'&&a[i+3][j+3]=='x'&&a[i+4][j+4]=='x') return 1; for(i=0;i<15;i++) for(j=14;j>3;j--) if(a[i][j]=='x'&&a[i+1][j-1]=='x'&&a[i+2][j-2]=='x'&&a[i+3][j-3]=='x'&&a[i+4][j-4]=='x') return 1; return 0; } int he(char a[][15]) { for(int i=0;i<15;i++) for(int j=0;j<15;j++) { if(a[i][j]==' ') //當棋盤全部子都不是' '時才能return 1,即棋盤已下滿 return 0; } return 1; } 姓 名: 劉旭 學 院: 計算機與通信學院 班 級: 通信工程101班 指導老師: 文志誠 目錄 一、需求分析..................................................................................................................................3 1.1 開發背景....................................................................................................................................3 2.2 功能簡介....................................................................................................................................3 二、系統設計..................................................................................................................................4 2.1 函數一覽....................................................................................................................................4 2.2 “封面”的設計........................................................................................................................4 2.3 二維數組與控制臺....................................................................................................................5 2.4 鍵盤操作....................................................................................................................................6 2.5判定.............................................................................................................................................7 2.6 悔棋的實現................................................................................................................................8 三、調試運行..................................................................................................................................9 3.1 進入界面....................................................................................................................................9 3.2 棋盤的初始狀態......................................................................................................................10 3.3 激戰中……..............................................................................................................................10 3.4 游戲結束..................................................................................................................................11 四、解決問題的關鍵....................................................................................................................11 五、課設總結................................................................................................................................11 六、附錄........................................................................................................................................12 6.1 畫圖代碼..................................................................................................錯誤!未定義書簽。6.2 初始化......................................................................................................錯誤!未定義書簽。6.3 Play函數..................................................................................................錯誤!未定義書簽。 一、需求分析 1.1 開發背景 學習了數據結構該門課程,對于枯燥無味的理論知識,我們是否能夠通過所學的知識在課程設計中做出有趣味東西,然后讓我們對于數據結構更加的感興趣呢?于是我和我的室友陳明建開始醞釀著寫些什么東西。上個學期就已經寫了通訊錄那之類的鏈式結構,這次我們決心有所改變,我們學習了棧、隊列、樹、圖,字典樹有人選了,我們就來寫一個基于圖的小程序,五子棋,對,圖的簡單應用,于是我們開始著手來寫這個小小的程序,祝我們好運! 2.2 功能簡介 既然是五子棋,我們要做的是時時刻刻的將整個圖(以下稱為棋局)的狀態呈現出來,那么界面就是必不可少的。MFC不會?沒關系,我們就用基于控制臺的字符輸出來構建這個棋局吧,當然這只是第一步,詳細如下: 1擁有一個良好的進入界面,以及必要的選項; ○2擁有一個二維的數組來記錄和更新實時的狀態,并且能夠有一種方法在DOS界面下繪制○出整個棋局的實時狀態(包括棋盤和棋子); 3能夠通過鍵盤上的按鍵完成所選位置的移動和選定操作; ○4能夠在每一次的走棋后判定是否游戲結束(棋盤走滿或者是一方勝出); ○5能夠完成悔棋的功能,并保證這之間的棋局繪圖能夠與二維數組數據同步,做到真正意○義上的悔棋。 二、詳細設計 2.1 函數一覽 2.2 “封面”的設計 首先還是講些題外話,該程序由于與控制臺有密切的關系,于是在代碼中使用了不少 conio.h 中的函數,當然在顯示時又使用了windows.h 中的 Sleep()函數,正是有了這些函數的使用,程序才得以順利完成,尤其是后面頻繁使用的gotoxy()函數。 進入正題,由于是一個小的程序,因此將每一個功能分成一個一個的函數,這樣將在以后的修改和完成進度上都有很大的幫助。由上面的函數一覽可以知道這個“封面”就是在Logo()函數里面實現的,函數實現過程中使用了Sleep()函數,使之有動態效果: void Logo(){ char Wel[30]= { “Made By Lyush&& Mirs Chen” }; printf(“ttt 歡迎試用五子棋系統n”); printf(“tt ”); for(int i= 0;i< strlen(Wel);++i) { putchar(Wel[i]); Sleep(200);// 可使字符一個一個的輸出 } putchar(10);// 換行對應的 ASCII 碼值為十進制的 10 } 2.3 二維數組與控制臺 二維數組是用來使得整個棋盤的信息全部記錄下來,因此在結構體中二維數組的聲明是最關鍵的。 struct { int Status[MAX/2+2][MAX/2+2]; int MINBOX; int Step; char Graph[3][3]; char *FillGraph[9]; Sta Stack;} ChessBoard; 聲明全局變量是為了使得各函數能夠更方便地使用到這個結構體,現假設某點的坐標為(1, 1),那么如何在屏幕上打印這個點呢?這就利用到了ChangeCoordinates()與gotoxy()函數,前者使坐標進行轉換,后者讓光標走到所指的那個點,其實主要還是因為類似“┣、╋、●、○”在橫向上所占都是兩個英文字母的距離,因此在控制臺上反映的就是和數組下標倍數關系了。部分代碼如下: HANDLE hConsole= GetStdHandle(STD_OUTPUT_HANDLE); void ChangeCoordinates(int _X, int _Y, int *X, int *Y){ *X=(_X-1)* 2; *Y=(_Y-1)* 4;} void gotoxy(int x, int y)//這是光標的函數 { COORD coord; coord.Y= x; // 在實際的應用過程中發現交換x與y的賦值 coord.X= y; // 更好理解,即橫行位x,縱行為y。 SetConsoleCursorPosition(hConsole, coord); } 2.4 鍵盤操作 在剛開始寫這個五子棋的時候是以坐標來確定玩家的每一步棋,但后來發現這樣操作性實在是差,鍵盤操作是更好的選擇。這里又要用到一個函數 getch(),其作用是無回顯的接受從鍵盤輸入的字符,讓屏幕不會出現你輸入的字符且等待著按回車確定…… 有了這個寶貝函數,馬上得到 “↑” 對應的ASCII碼為-32和72 兩個連著的數值,依次可得其他對應的ASCII碼。后面在使玩家一和玩家二分離操作,玩家一則是利用 W、S、A、D + space來操作,玩家二則是 上下左右+ enter。配合ChangeCoordinates()與gotoxy()函數,完成對走棋的控制。部分代碼如下: if(Opreat[0]== 13&& Ply== 2|| Opreat[0]== 32&& Ply== 1){ if(ChessBoard.Status[Move_X][Move_Y]== 0) { int TTop= ++ChessBoard.Stack.Top;ChessBoard.Status[Move_X][Move_Y]= Ply;ChessBoard.Stack.Record[TTop][0]= Move_X;ChessBoard.Stack.Record[TTop][1]= Move_Y;printf(“%s”, Graph);return true;// 該次走棋操作有效 } else { … } } if(Opreat[0]==-32&& Opreat[1]== 72|| Opreat[0]== 'w'|| Opreat[0]== 'W'){// 凡是接受了“上操作”,則Move_X的值減一,if(Currect(Move_X-1, Move_Y)) { Move_X-= 1; } } else if(…){ … } // 這是接下來的轉換操作 ChangeCoordinates(Move_X, Move_Y, &Temp_X, &Temp_Y);Gotoxy(Temp_X, Temp_Y); 2.5判定 對于每次走棋后,首先應該做的就是判定一否有五個棋子已經連成一線,也是一個簡單的搜索過程,由于每次走的點不一定是最外部的點,因此從每次走的點的兩頭同時搜索,當遇到兩端同時結束時,搜索結束。當滿足五子時游戲結束。當然,當棋盤被走滿時,游戲亦結束。代碼如下: bool Legal(int Point){ if(Point< 1|| Point> MAX/ 2+ 1) return false; else return true;} //搜索45度角是否為滿足ChessBoard.MINBOX 以X正軸為參考軸 if(!Flag){ Count= 1;for(int i1= X-1, j1= Y+ 1, i2= X+ 1, j2= Y-1;Legal(i1)&& Legal(j1)|| Legal(i2)&& Legal(j2);i1--, j1++, i2++, j2--){ int LastCount= Count; if(Legal(i1)&& Legal(j1)&& ChessBoard.Status[i1][j1]== Ply) { Count++; } if(Legal(i2)&& Legal(j2)&& ChessBoard.Status[i2][j2]== Ply) { Count++; } if(LastCount== Count) break; if(Count== ChessBoard.MINBOX){ Flag= 1; return true; } } } 2.6 悔棋的實現 雖說下棋悔棋是一種不道義的行為,但是如果雙方約定好了,未嘗不可。在沒寫悔棋之前,只是記錄了“上一次”的位置,聲明了Last_X,Last_Y;當然既然要求悔棋,那么直接調用棧頂元素,即可定位上次走棋的位置。那么悔棋呢,取出“上一次”的位置,判定位置(不同的位置對應不同的填充圖形類型)在二維數組中撤銷走棋時所賦予的 Ply 值(玩家一走時,其值為1,玩家二走時,其值為2),重新將 ChessBoard.Status[ Last_X ][ Last_Y ] 賦為0。代碼如下: int GetFillType(int X, int Y){ if(X== 1) { if(Y== 1) return 0; else if(Y== 16) return 2; else return 1; } else if(X== 16) { if(Y== 1) return 6; else if(Y== 16) return 8; else return 7; } else { if(Y== 1) return 3; else if(Y== 16) return 5; else return 4; } } bool Retract(int *X, int *Y){ int Temp_X, Temp_Y, TTop, FillType; if(!StackEmpty()) { TTop= ChessBoard.Stack.Top--; *X= ChessBoard.Stack.Record[TTop][0]; *Y= ChessBoard.Stack.Record[TTop][1]; ChessBoard.Status[*X][*Y]= 0;// 將該點置為真正意義上的空點 FillType= GetFillType(*X, *Y); ChangeCoordinates(*X, *Y, &Temp_X, &Temp_Y); Gotoxy(Temp_X, Temp_Y); printf(“%s”, ChessBoard.FillGraph[FillType]); return true; } else { Gotoxy(9, 65); printf(“您已不能悔棋”); Sleep(300); Gotoxy(9, 65); printf(“ ”); return false; } } 三、調試運行 3.1 進入界面 3.2 棋盤的初始狀態 3.3 激戰中…… 3.4 游戲結束 四、解決問題的關鍵 這個五子棋的程序并沒有什么復雜的算法,只是利用了簡單的圖知識和一個棧的應用,在這里主要的關鍵問題就是如何將程序有條理的寫下來,有一個好的邏輯思維。將程序分成了多個功能函數,盡量的讓一個函數的功能單一,只是在內部調用了其他的函數以輔助改函數功能的實現,比如判定坐標是否越界,坐標是否合法,悔棋的點的位置狀態…… 這樣便能做到各個擊破,程序的形成也就變得暢通許多了。 五、課設總結 剛開始寫這個程序,認為一定要用到 graphics.h, 無奈電腦TC不兼容,因此只好強行來畫這個界面了,使用輸入法里面的制表符,效果還不錯,通過一長串的if … else … 最好還是畫出來了,這個時候覺得控制臺的簡單圖形還是能夠畫出來的,并且可以盡量去美化它的界面。后面的附錄中將給出畫棋盤和棋子的源代碼。在程序設計的過程中,尤其是為源程序加上悔棋的功能,這期間總是有許多意想不到的錯誤,比如加上后,有時走了5個連子棋,但是程序并沒有判定輸贏,而是可以繼續走、有時沒有五個卻已經結束了,光標沒有復位,悔棋后,玩家的走棋順序沒有跟著改變……通過后來的一步步修改終于使得這些問題都一一解決了,比如說對 Prompt(提示)函數引進了返回值,判斷該次操作是否成功,如果下了棋則為 true,如果是悔棋就是 false 了,這樣便使得后面的操作更規范了和統一了。 六、附錄 #include HANDLE hConsole= GetStdHandle(STD_OUTPUT_HANDLE); void HideCursor(){ CONSOLE_CURSOR_INFO cursor_info = {1, 0}; SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);} typedef struct { int Record[260][2]; int Base; int Top;} Sta; struct { int Status[MAX/2+2][MAX/2+2]; int MINBOX; int Step; char Graph[3][3]; char *FillGraph[9]; Sta Stack; } ChessBoard; void Gotoxy(int x, int y)//這是光標的函數 { COORD coord; coord.Y= x; coord.X= y; SetConsoleCursorPosition(hConsole, coord); } void Logo(){ char Wel[30]= { “Made By Lyush&& Mirs Chen” }; printf(“ttt 歡迎試用五子棋系統n”); printf(“tt ”); for(int i= 0;i< strlen(Wel);++i) { putchar(Wel[i]); Sleep(200); } putchar(10);} int Login(){ int Mode, Skip= 0; char Request; if(!Skip) { printf(“nn在這兒你能DIY(Do it youself!)你的棋子,每個棋子接受一個漢字”); printf(“ Y Orz Nn”); scanf(“%c”, &Request); if(Request== 'Y'|| Request== 'y') { printf(“玩家一的 DIY 棋子-->”); scanf(“%s”, ChessBoard.Graph[1]); ChessBoard.Graph[1][2]= '
主站蜘蛛池模板:
亚洲精品日本一区二区三区|
亚洲国产精品一区二区久久|
一本大道东京热无码aⅴ|
成 人 网 站 免 费 av|
午夜精品一区二区三区在线观看|
国产乡下三级全黄三级bd|
人妻少妇不满足中文字幕|
97国产精品视频在线观看|
日韩精品人妻系列无码专区|
亚洲国产精品久久精品|
人妻被按摩师玩弄到潮喷|
欧美最猛黑人xxxx黑人猛交98|
国产亚洲精品无码成人|
伊人精品久久久久7777|
亚洲午夜福利院在线观看|
亚洲日本va午夜在线影院|
激烈的性高湖波多野结衣|
国产成人精品高清在线电影|
香蕉久久人人爽人人爽人人片av|
无码h片在线观看网站|
日本一卡二卡不卡视频查询|
国产香蕉尹人在线观看视频|
成年午夜无码av片在线观看|
欧美性猛交99久久久久99按摩|
制服丝袜人妻有码无码中文字幕|
免费观看羞羞视频网站|
婷婷成人丁香五月综合激情|
国产全肉乱妇杂乱视频|
韩国无码无遮挡在线观看|
日韩中文字幕无码一区二区三区|
漂亮人妻洗澡被公强 日日躁|
一区二区不卡av免费观看|
国产午夜无码片在线观看影院|
久久精品国产999久久久|
99国产揄拍国产精品人妻|
久草网站|
国产99久久久久久免费看|
高h纯肉无码视频在线观看|
国产精品一区二区av片|
伊人久久成综合久久影院|
国产无遮挡18禁网站免费|
第二篇:數據結構課程設計-五子棋