欧美色欧美亚洲高清在线观看,国产特黄特色a级在线视频,国产一区视频一区欧美,亚洲成a 人在线观看中文

  1. <ul id="fwlom"></ul>

    <object id="fwlom"></object>

    <span id="fwlom"></span><dfn id="fwlom"></dfn>

      <object id="fwlom"></object>

      五子棋游戲軟件工程課程設(shè)計

      時間:2019-05-14 14:36:44下載本文作者:會員上傳
      簡介:寫寫幫文庫小編為你整理了多篇相關(guān)的《五子棋游戲軟件工程課程設(shè)計》,但愿對你工作學(xué)習(xí)有幫助,當(dāng)然你在寫寫幫文庫還可以找到更多《五子棋游戲軟件工程課程設(shè)計》。

      第一篇:五子棋游戲軟件工程課程設(shè)計

      軟件工程設(shè)計

      專 業(yè):班 級:姓 名:學(xué) 號:指導(dǎo)老師:

      I

      目錄

      第一章 需求分析.......................................................1 1.1 總體分析..........................................................1 1.2 初始化............................................................1 1.3 主循環(huán)控制模塊....................................................1 1.4 玩家下子..........................................................1 1.5 盤面分析填寫棋型表................................................2 1.6 對方下子..........................................................2 1.7 勝負(fù)判斷..........................................................2 第二章 功能描述.......................................................3 2.1 功能模塊圖........................................................3 2.2 功能說明..........................................................3 第三章 系統(tǒng)設(shè)計.......................................................4 3.1 流程圖............................................................4 3.2 流程圖說明........................................................5 第四章 運行結(jié)果.......................................................6 第五章 總結(jié)...........................................................7 附錄一 源代碼.........................................................8

      II

      軟件工程設(shè)計

      五子棋游戲

      第一章 需求分析

      1.1 總體分析

      軟件需求分析是軟件開發(fā)周期的第一個階段,也是關(guān)系到軟件開發(fā)成敗的關(guān)鍵一步。對于任何一個軟件而言,需求分析工作都是至關(guān)重要的一步。只有通過軟件需求分析,才能把軟件的功能和性能由總體的概念性描述轉(zhuǎn)化為具體的規(guī)格說明,進(jìn)而建立軟件開發(fā)的基礎(chǔ)。實踐表明,需求分析工作進(jìn)行得好壞,在很大程度上決定了軟件開發(fā)的成敗。

      軟件需求分析的任務(wù)是:讓用戶和開發(fā)者共同明確將要開發(fā)的是一個什么樣的軟件。具體而言,就是通過對問題及其環(huán)境的理解、分析和綜合,建立邏輯模型,完成新軟件的邏輯方案設(shè)計。

      基于本游戲,首先得為整個棋盤建立一張表格用以記錄棋子信息,我們使用一個15*15的二維數(shù)組Table[15][15](15*15是五子棋棋盤的大小),數(shù)組的每一個元素對應(yīng)棋盤上的一個交叉點,用‘0’表示空位、‘1’代表己方的子、‘2’代表對方的子;這張表也是今后分析的基礎(chǔ)。在此之后還要為兩個玩家雙方各建立一張棋型表Computer[15][15][4]和Player[15][15][4],用來存放棋型數(shù)據(jù)。

      1.2 初始化

      首先,建立盤面數(shù)組Table[15][15]、對戰(zhàn)雙方的棋型表Computer[15][15][4]和Player[15][15][4]并將它們清零以備使用;然后初始化顯示器、鍵盤、鼠等輸入輸出設(shè)備并在屏幕上畫出棋盤(棋盤可以不顯示)。

      1.3 主循環(huán)控制模塊

      控制下棋順序,當(dāng)輪到某方下子時,負(fù)責(zé)將程序轉(zhuǎn)到相應(yīng)的模塊中去,主要擔(dān)當(dāng)一個調(diào)度者的角色。

      1.4 玩家下子

      當(dāng)輪到玩家下時,您通過鍵盤或鼠標(biāo)在棋盤上落子,程序會根據(jù)該點的位置,在Table[15][15]數(shù)組的相應(yīng)地方記錄‘2’,以表明該子是玩家下的。

      軟件工程設(shè)計

      1.5 盤面分析填寫棋型表

      您在下五子棋時,一定會先根據(jù)棋盤上的情況,找出當(dāng)前最重要的一些點位,如“活三”、“沖四”等;然后再在其中選擇落子點。先來分析己方的棋型,我們從棋盤左上角出發(fā),向右逐行搜索,當(dāng)遇到一個空白點時,以它為中心向左挨個查找,如果遇到己方的子則記錄然后繼續(xù),如果遇到對方的子、空白點或邊界就停止查找。左邊完成后再向右進(jìn)行同樣的操作;最后把左右兩邊的記錄合并起來,得到的數(shù)據(jù)就是該點橫向上的棋型,然后把棋型的編號填入到Computer[x][y][n]中就行了(x、y代表坐標(biāo),n=0、1、2、3分別代表橫、豎、左斜、右斜四個方向)。而其他三個方向的棋型也可用同樣的方法得到,當(dāng)搜索完整張棋盤后,己方棋型表也就填寫完畢了。然后再用同樣的方法填寫對方棋型表。

      注意:所有棋型的編號都要事先 定義好,越重要的號數(shù)越大!

      1.6 對方下子

      有了上面填寫的兩張棋型表,就是遍歷棋型表Computer[15][15][4]和Player[15][15][4]找出其中數(shù)值最大的一點,在該點下子即可。但這種算法的弱點非常明顯,只顧眼前利益,不能顧全大局,這就和許多五子棋初學(xué)者一樣犯了“目光短淺”的毛病。如果在這兒下子將會形成對手不得不防守的棋型(例如:‘沖四’、‘活三’);那么下一步對手就會照您的思路下子來防守您,如此一來便完成了第一步的預(yù)測。這時再調(diào)用模塊4對預(yù)測后的棋進(jìn)行盤面分析,如果出現(xiàn)了‘四三’、‘雙三’或‘雙四’等制勝點,那么己方就可以獲勝了(當(dāng)然對黑棋而言‘雙三’、‘雙四’是禁手,另當(dāng)別論);否則照同樣的方法向下分析,就可預(yù)測出第二步、第三步??

      等一等,要是盤面上沒有對手必須防的棋型,哪該怎么辦呢?進(jìn)攻不成的話就得考慮防守了,將自己和對手調(diào)換一下位置,然后用上面的方法來預(yù)測對手的棋,這樣既可以防住對手巧妙的攻擊,又能待機發(fā)動反擊,何樂而不為呢!

      1.7 勝負(fù)判斷

      務(wù)須多言,某方形成五子連即獲勝;若黑棋走出‘雙三’、‘雙四’或長連即以禁手判負(fù)。

      軟件工程設(shè)計

      第二章 功能描述

      2.1 功能模塊圖

      五子棋游戲判斷棋盤是否已滿判斷是否出錯并提示判斷那方獲勝交替循環(huán)雙方下棋 圖2.1 功能模塊圖

      2.2 功能說明

      該五子棋程序基本上實現(xiàn)了五子棋的游戲功能,有雙方下棋的界面及最終判定結(jié)果的界面。同時該游戲采用二維坐標(biāo)實現(xiàn),明了易懂,方便玩家在游戲過程中的基本操作,使游戲更加簡便。在細(xì)節(jié)方面,該系統(tǒng)提供實時存儲功能,隨時記錄為完成的游戲,使用戶可以很好的處理意外中斷的情況。該游戲基本實現(xiàn)了游戲的一些要求和特征。在游戲的源程序及文檔方面,我們也嚴(yán)格遵守軟件工程思想,立足實驗要求,確定任務(wù),需求分析,設(shè)計和編碼,每個步驟力求清晰易懂。原代碼注釋詳盡,各功能模塊功能分明,可移植性強。當(dāng)然該系統(tǒng)也有很多不足的地方,第一次進(jìn)行獨立的課程設(shè)計,也有很多細(xì)節(jié)方面是考慮到的,這款游戲也是在不斷的調(diào)試和修改中產(chǎn)生和完善的。希望老師能夠指出不足,幫助我不斷提高。

      軟件工程設(shè)計

      第三章 系統(tǒng)設(shè)計

      3.1 流程圖

      開始棋盤已滿是輸出平局否“0”方選位置判斷該位置是否有棋有另找位置無“0”方落子否判斷“0”方是否獲勝是輸出“0”方獲勝否棋盤已滿是輸出平局結(jié)束否“x”方選位置判斷該位置是否有棋有另找位置無“x”方落子判斷“x”方是否獲勝是輸出“x”方獲勝 圖3.1 流程圖

      軟件工程設(shè)計

      3.2 流程圖說明

      本程序定義了各種操作函數(shù)、各種狀態(tài)判定宏,思想明確,思路清晰。各個判斷選擇了不同路徑,因此繼續(xù)進(jìn)行或輸出結(jié)果。程序中,“循環(huán)”的利用非常直接和清晰,雙方交替下棋,因此循環(huán)往復(fù)。最終決出勝負(fù)或最終平局。分析時,也考慮了許多種情況,針對各個情況均作出了相對措施和解決方案。

      程序采用循環(huán)進(jìn)行雙方交替下棋,并進(jìn)行了很多判斷。首先判斷棋盤是否已滿,若棋盤已滿,則輸出平局,結(jié)束游戲;若棋盤未滿,則繼續(xù)進(jìn)行。然后判斷“0”方是否勝出,若“0”方獲勝,則輸出“0”方獲勝,結(jié)束游戲;若“0”方?jīng)]有獲勝,則繼續(xù)進(jìn)行。再判斷“x”方是否獲勝,若“x”方獲勝,則輸出“x”方獲勝,結(jié)束游戲;若“x”方?jīng)]有獲勝,則繼續(xù)進(jìn)行?;氐健笆紫取钡呐袛唷H绱搜h(huán)??

      軟件工程設(shè)計

      第四章 運行結(jié)果

      圖4.1 運行結(jié)果初始圖

      圖4.2 游戲過程圖

      圖4.3

      軟件工程設(shè)計

      圖4.4

      圖4.5

      軟件工程設(shè)計

      圖4.6

      圖4.7

      軟件工程設(shè)計

      圖4.8 游戲進(jìn)行圖

      圖4.9 “0”方獲勝圖

      軟件工程設(shè)計

      附錄一 源代碼

      #include

      using namespace std;

      int Hsheng(char a[][15]);

      //判斷o子是否獲勝的函數(shù)

      int Bsheng(char a[][15]);

      //判斷x子是否獲勝的函數(shù)

      int he(char a[][15]);

      //判斷是否平局(也就是棋盤下滿了)的函數(shù)

      void qipan(char a[15][15])

      //執(zhí)行輸出棋盤命令 {

      cout<<“本游戲采用二維數(shù)組實現(xiàn),棋盤為15X15的二維直角坐標(biāo)系,均從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)//用循環(huán)語句執(zhí)行o,x交替下子,這些while語句看起來似乎是個死循環(huán)~實際上都會經(jīng)過break結(jié)束

      {

      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;}

      軟件工程設(shè)計

      qipan(a);

      //下好o子后將棋盤顯示

      if(Hsheng(a))

      //判斷o子是否已經(jīng)獲勝

      {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子是否已經(jīng)獲勝

      {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')

      軟件工程設(shè)計

      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]==' ')

      //當(dāng)棋盤全部子都不是' '時才能return 1,即棋盤已下滿

      return 0;

      }

      return 1;

      }

      第二篇:數(shù)據(jù)結(jié)構(gòu)課程設(shè)計-五子棋

      姓 名: 劉旭

      學(xué) 院: 計算機與通信學(xué)院

      班 級: 通信工程101班

      指導(dǎo)老師: 文志誠

      目錄

      一、需求分析..................................................................................................................................3 1.1 開發(fā)背景....................................................................................................................................3 2.2 功能簡介....................................................................................................................................3

      二、系統(tǒng)設(shè)計..................................................................................................................................4 2.1 函數(shù)一覽....................................................................................................................................4 2.2 “封面”的設(shè)計........................................................................................................................4 2.3 二維數(shù)組與控制臺....................................................................................................................5 2.4 鍵盤操作....................................................................................................................................6 2.5判定.............................................................................................................................................7 2.6 悔棋的實現(xiàn)................................................................................................................................8

      三、調(diào)試運行..................................................................................................................................9 3.1 進(jìn)入界面....................................................................................................................................9 3.2 棋盤的初始狀態(tài)......................................................................................................................10 3.3 激戰(zhàn)中……..............................................................................................................................10 3.4 游戲結(jié)束..................................................................................................................................11

      四、解決問題的關(guān)鍵....................................................................................................................11

      五、課設(shè)總結(jié)................................................................................................................................11

      六、附錄........................................................................................................................................12 6.1 畫圖代碼..................................................................................................錯誤!未定義書簽。6.2 初始化......................................................................................................錯誤!未定義書簽。6.3 Play函數(shù)..................................................................................................錯誤!未定義書簽。

      一、需求分析

      1.1 開發(fā)背景

      學(xué)習(xí)了數(shù)據(jù)結(jié)構(gòu)該門課程,對于枯燥無味的理論知識,我們是否能夠通過所學(xué)的知識在課程設(shè)計中做出有趣味東西,然后讓我們對于數(shù)據(jù)結(jié)構(gòu)更加的感興趣呢?于是我和我的室友陳明建開始醞釀著寫些什么東西。上個學(xué)期就已經(jīng)寫了通訊錄那之類的鏈?zhǔn)浇Y(jié)構(gòu),這次我們決心有所改變,我們學(xué)習(xí)了棧、隊列、樹、圖,字典樹有人選了,我們就來寫一個基于圖的小程序,五子棋,對,圖的簡單應(yīng)用,于是我們開始著手來寫這個小小的程序,祝我們好運!

      2.2 功能簡介

      既然是五子棋,我們要做的是時時刻刻的將整個圖(以下稱為棋局)的狀態(tài)呈現(xiàn)出來,那么界面就是必不可少的。MFC不會?沒關(guān)系,我們就用基于控制臺的字符輸出來構(gòu)建這個棋局吧,當(dāng)然這只是第一步,詳細(xì)如下: 1擁有一個良好的進(jìn)入界面,以及必要的選項; ○2擁有一個二維的數(shù)組來記錄和更新實時的狀態(tài),并且能夠有一種方法在DOS界面下繪制○出整個棋局的實時狀態(tài)(包括棋盤和棋子);

      3能夠通過鍵盤上的按鍵完成所選位置的移動和選定操作; ○4能夠在每一次的走棋后判定是否游戲結(jié)束(棋盤走滿或者是一方勝出); ○5能夠完成悔棋的功能,并保證這之間的棋局繪圖能夠與二維數(shù)組數(shù)據(jù)同步,做到真正意○義上的悔棋。

      二、詳細(xì)設(shè)計

      2.1 函數(shù)一覽

      2.2 “封面”的設(shè)計

      首先還是講些題外話,該程序由于與控制臺有密切的關(guān)系,于是在代碼中使用了不少 conio.h 中的函數(shù),當(dāng)然在顯示時又使用了windows.h 中的 Sleep()函數(shù),正是有了這些函數(shù)的使用,程序才得以順利完成,尤其是后面頻繁使用的gotoxy()函數(shù)。

      進(jìn)入正題,由于是一個小的程序,因此將每一個功能分成一個一個的函數(shù),這樣將在以后的修改和完成進(jìn)度上都有很大的幫助。由上面的函數(shù)一覽可以知道這個“封面”就是在Logo()函數(shù)里面實現(xiàn)的,函數(shù)實現(xiàn)過程中使用了Sleep()函數(shù),使之有動態(tài)效果:

      void Logo(){

      char Wel[30]= { “Made By Lyush&& Mirs Chen” };

      printf(“ttt

      歡迎試用五子棋系統(tǒng)n”);

      printf(“tt

      ”);

      for(int i= 0;i< strlen(Wel);++i)

      {

      putchar(Wel[i]);

      Sleep(200);// 可使字符一個一個的輸出

      }

      putchar(10);// 換行對應(yīng)的 ASCII 碼值為十進(jìn)制的 10 }

      2.3 二維數(shù)組與控制臺

      二維數(shù)組是用來使得整個棋盤的信息全部記錄下來,因此在結(jié)構(gòu)體中二維數(shù)組的聲明是最關(guān)鍵的。

      struct {

      int Status[MAX/2+2][MAX/2+2];

      int MINBOX;

      int Step;

      char Graph[3][3];

      char *FillGraph[9];

      Sta Stack;} ChessBoard;

      聲明全局變量是為了使得各函數(shù)能夠更方便地使用到這個結(jié)構(gòu)體,現(xiàn)假設(shè)某點的坐標(biāo)為(1, 1),那么如何在屏幕上打印這個點呢?這就利用到了ChangeCoordinates()與gotoxy()函數(shù),前者使坐標(biāo)進(jìn)行轉(zhuǎn)換,后者讓光標(biāo)走到所指的那個點,其實主要還是因為類似“┣、╋、●、○”在橫向上所占都是兩個英文字母的距離,因此在控制臺上反映的就是和數(shù)組下標(biāo)倍數(shù)關(guān)系了。部分代碼如下:

      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)//這是光標(biāo)的函數(shù) {

      COORD coord;

      coord.Y= x;

      // 在實際的應(yīng)用過程中發(fā)現(xiàn)交換x與y的賦值

      coord.X= y;

      // 更好理解,即橫行位x,縱行為y。

      SetConsoleCursorPosition(hConsole, coord);

      }

      2.4 鍵盤操作

      在剛開始寫這個五子棋的時候是以坐標(biāo)來確定玩家的每一步棋,但后來發(fā)現(xiàn)這樣操作性實在是差,鍵盤操作是更好的選擇。這里又要用到一個函數(shù) getch(),其作用是無回顯的接受從鍵盤輸入的字符,讓屏幕不會出現(xiàn)你輸入的字符且等待著按回車確定…… 有了這個寶貝函數(shù),馬上得到 “↑” 對應(yīng)的ASCII碼為-32和72 兩個連著的數(shù)值,依次可得其他對應(yīng)的ASCII碼。后面在使玩家一和玩家二分離操作,玩家一則是利用 W、S、A、D + space來操作,玩家二則是 上下左右+ enter。配合ChangeCoordinates()與gotoxy()函數(shù),完成對走棋的控制。部分代碼如下:

      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(…){ … }

      // 這是接下來的轉(zhuǎn)換操作

      ChangeCoordinates(Move_X, Move_Y, &Temp_X, &Temp_Y);Gotoxy(Temp_X, Temp_Y);

      2.5判定

      對于每次走棋后,首先應(yīng)該做的就是判定一否有五個棋子已經(jīng)連成一線,也是一個簡單的搜索過程,由于每次走的點不一定是最外部的點,因此從每次走的點的兩頭同時搜索,當(dāng)遇到兩端同時結(jié)束時,搜索結(jié)束。當(dāng)滿足五子時游戲結(jié)束。當(dāng)然,當(dāng)棋盤被走滿時,游戲亦結(jié)束。代碼如下: 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 悔棋的實現(xiàn)

      雖說下棋悔棋是一種不道義的行為,但是如果雙方約定好了,未嘗不可。在沒寫悔棋之前,只是記錄了“上一次”的位置,聲明了Last_X,Last_Y;當(dāng)然既然要求悔棋,那么直接調(diào)用棧頂元素,即可定位上次走棋的位置。那么悔棋呢,取出“上一次”的位置,判定位置(不同的位置對應(yīng)不同的填充圖形類型)在二維數(shù)組中撤銷走棋時所賦予的 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;

      } }

      三、調(diào)試運行

      3.1 進(jìn)入界面

      3.2 棋盤的初始狀態(tài)

      3.3 激戰(zhàn)中……

      3.4 游戲結(jié)束

      四、解決問題的關(guān)鍵

      這個五子棋的程序并沒有什么復(fù)雜的算法,只是利用了簡單的圖知識和一個棧的應(yīng)用,在這里主要的關(guān)鍵問題就是如何將程序有條理的寫下來,有一個好的邏輯思維。將程序分成了多個功能函數(shù),盡量的讓一個函數(shù)的功能單一,只是在內(nèi)部調(diào)用了其他的函數(shù)以輔助改函數(shù)功能的實現(xiàn),比如判定坐標(biāo)是否越界,坐標(biāo)是否合法,悔棋的點的位置狀態(tài)…… 這樣便能做到各個擊破,程序的形成也就變得暢通許多了。

      五、課設(shè)總結(jié)

      剛開始寫這個程序,認(rèn)為一定要用到 graphics.h, 無奈電腦TC不兼容,因此只好強行來畫這個界面了,使用輸入法里面的制表符,效果還不錯,通過一長串的if … else … 最好還是畫出來了,這個時候覺得控制臺的簡單圖形還是能夠畫出來的,并且可以盡量去美化它的界面。后面的附錄中將給出畫棋盤和棋子的源代碼。在程序設(shè)計的過程中,尤其是為源程序加上悔棋的功能,這期間總是有許多意想不到的錯誤,比如加上后,有時走了5個連子棋,但是程序并沒有判定輸贏,而是可以繼續(xù)走、有時沒有五個卻已經(jīng)結(jié)束了,光標(biāo)沒有復(fù)位,悔棋后,玩家的走棋順序沒有跟著改變……通過后來的一步步修改終于使得這些問題都一一解決了,比如說對 Prompt(提示)函數(shù)引進(jìn)了返回值,判斷該次操作是否成功,如果下了棋則為 true,如果是悔棋就是 false 了,這樣便使得后面的操作更規(guī)范了和統(tǒng)一了。

      六、附錄

      #include #include #include #include #include #include #include #define MAX 31 #define STA_1 1 #define STA_2 2 #define STA_0 0

      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)//這是光標(biāo)的函數(shù) {

      COORD coord;

      coord.Y= x;

      coord.X= y;

      SetConsoleCursorPosition(hConsole, coord);

      }

      void Logo(){

      char Wel[30]= { “Made By Lyush&& Mirs Chen” };

      printf(“ttt

      歡迎試用五子棋系統(tǒng)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]= '