圍棋打譜軟體中自動提子功能的實現,C/C++源碼

來源:互聯網
上載者:User

本文首發地址:http://blog.csdn.net/liigo/archive/2009/09/22/4582018.aspx

轉載請註明出處:http://blog.csdn.net/liigo

作者:liigo, 2009/09/22

 

  在下圍棋時,當一個棋子落到棋盤上,它會對周圍對方棋子的死活產生影響,如果對方棋子沒有氣了(死了),必須從棋盤上拿掉(提子)。這個過程體現到圍棋軟體中,就需要通過程式碼判斷某一個棋子或某一片棋子的死活狀態,進而把死掉的棋子從棋盤上移除。

  進一步分析的話,剛落下的棋子,只可能威脅到周圍與其緊臨的上下左右方向的四個對方棋子(也可能是三個或兩個,如在邊角的話),而這四個方向上的對方棋子,可能是孤立的一個棋子,也可能是多個棋子相連的一片棋子(一塊棋)。要判斷一塊棋是否還活著,需要逐個檢查這塊棋中的每一個棋子:如果其中某個棋子旁邊沒有棋子,說明這塊棋至少還有一口氣,因而確定它還沒有死;如果檢查完這塊棋中的所有棋子,始終不能找到一口氣,可以確定這整塊棋都死掉了。看上去這是一個需要採用遞迴處理的情況。遞迴處理整塊棋時,切記需要記錄已經處理過的棋子,不能重複處理同一個棋子,否則可能會導致迴圈遞迴、死遞迴的情況發生。一旦確定了棋子的生死,從棋盤上拿掉它是很容易的事情,只是在程式中做一些標記而已。

  注意,我(liigo)這裡說的某塊棋“還活著”,並不等同於圍棋術語中的“已做活”,而只是表示這塊棋“暫時還沒有死”,至於將來會不會死,不在現在的處理範圍之內。別忘了,我們的目標是“如果棋子死了,把它從棋盤上拿掉”,既然還沒死(或沒死絕),又何必管它呢(如果非要提前提子,反而違反圍棋規則了)。

  以下C/C++原始碼,實現了上面說到的自動提子功能。

 

//處理剛落下的子對周邊對方子的死活影響<br />void processLiving(int row, int col)<br />{<br />StoneColor color = m_board[row-1][col-1];<br />assert(color != SC_BLANK);<br />StoneColor otherColor = (color == SC_BLACK ? SC_WHITE : SC_BLACK);<br />if(m_killedStones[m_stoneIndex] == NULL)<br />m_killedStones[m_stoneIndex] = new BufferedMem(20);<br />BufferedMem* pKilledStones = m_killedStones[m_stoneIndex];<br />pKilledStones->Empty();<br />//如果周邊是對方的子, 則檢查其死活情況, 死了的拿掉<br />BufferedMem stoneIndexList;<br />if(row>1 && m_board[row-1-1][col-1]==otherColor && checkLiving(row-1,col,color,&stoneIndexList)==false)<br />processDeadStones(&stoneIndexList);<br />stoneIndexList.Empty();<br />if(row<19 && m_board[row+1-1][col-1]==otherColor && checkLiving(row+1,col,color,&stoneIndexList)==false)<br />processDeadStones(&stoneIndexList);<br />stoneIndexList.Empty();<br />if(col>1 && m_board[row-1][col-1-1]==otherColor && checkLiving(row,col-1,color,&stoneIndexList)==false)<br />processDeadStones(&stoneIndexList);<br />stoneIndexList.Empty();<br />if(col<19 && m_board[row-1][col+1-1]==otherColor && checkLiving(row,col+1,color,&stoneIndexList)==false)<br />processDeadStones(&stoneIndexList);<br />InvalidateRect(m_hWnd, NULL, true);<br />}

 

//檢查row/col所在的子的死活, color為另一方子的顏色.<br />//返回 1 表示活著(沒死), 返回 0 表示死了, 返回 -1 表示生死未定<br />int checkLiving(int row, int col, StoneColor color, BufferedMem* pStoneIndexList)<br />{<br />int index = RowColToIndex(row, col);<br />if(m_board[row-1][col-1] == SC_BLANK) //有氣, 所以活著<br />return 1;<br />if(m_board[row-1][col-1] == color) //這是對方的子<br />return -1;<br />int* pIndex = (int*) pStoneIndexList->GetData();<br />for(int i = 0, n = pStoneIndexList->GetDataSize()/sizeof(int); i < n; i++)<br />{<br />if(pIndex[i] == index)<br />return -1; //已經處理過該子了<br />}<br />pStoneIndexList->AppendMem(&index, sizeof(index));<br />//遞迴檢查周邊己方的子, 只要整塊有一口氣就說明活著<br />//這裡存在重複檢查的情況, 需要最佳化<br />if(row > 1 && m_board[row-1-1][col-1] != color && checkLiving(row-1, col, color, pStoneIndexList)==1)<br />return 1;<br />if(row < 19 && m_board[row+1-1][col-1] != color && checkLiving(row+1, col, color, pStoneIndexList)==1)<br />return 1;<br />if(col > 1 && m_board[row-1][col-1-1] != color && checkLiving(row, col-1, color, pStoneIndexList)==1)<br />return 1;<br />if(col < 19 && m_board[row-1][col+1-1] != color && checkLiving(row, col+1, color, pStoneIndexList)==1)<br />return 1;<br />return 0;<br />}

 

void processDeadStones(BufferedMem* deathStoneIndexList)<br />{<br />int* pIndex = (int*) deathStoneIndexList->GetData();<br />StoneColor* pBoard = &m_board[0][0];<br />for(int i = 0, n = deathStoneIndexList->GetDataSize()/sizeof(int); i < n; i++)<br />pBoard[pIndex[i]] = SC_BLANK;<br />//把死掉的子記錄下來, 供向前打譜時使用<br />if(deathStoneIndexList->GetDataSize() > 0)<br />{<br />BufferedMem* pKilledStones = m_killedStones[m_stoneIndex];<br />assert(pKilledStones);<br />pKilledStones->AppendMem(deathStoneIndexList->GetData(), deathStoneIndexList->GetDataSize());//此處可能會有重複,但無所謂<br />}<br />}

 

以上代碼來自我(liigo)最近開發的“M8圍棋譜”軟體,此項目已在 Google Code 上開源:http://code.google.com/p/m8weiqipu/。

如有錯漏疏忽之處,誠請批評指正。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.