2011-03-08 25 views
3

我正在寫一個井字遊戲,我想知道我怎麼能進行有效的功能來檢查誰贏了。一個包含X,O或空格的二維數組表示該板。檢查誰贏得井字更高效的C++

char CheckWin(const char board[][NUM_COLS], int& sum) // tic tac toe board - IN 
{ 
    char tmp; 
    int lcv; 
    tmp = ' '; 

    if (sum == 9) 
    { 
     return 'T'; 
    } 
    else if (sum != 9) 
    { 
     if (((tmp = board[1][1]) != ' ' && board[0][0] == tmp && board[2][2] == tmp) || (board[2][0] == tmp && board[0][2] == tmp)) 
     { 
      return tmp; 
     } 

     for (lcv = 0; lcv < 3; lcv++) 
     { 
      if ((tmp = board[lcv][0]) != ' ' && board[lcv][1] == tmp && board[lcv][2] == tmp) 
      { 
       return tmp; 
      } 
      else if ((tmp = board[lcv][0]) != ' ' && board[lcv][1] == tmp && board[lcv][2] == tmp) 
      { 
       return tmp; 
      } 
     } 
    } 

    return 'N'; 
} 

除了一遍又一遍地做類似這樣的事情,我怎麼能查誰贏了,如果X贏得了返回X,一個O,如果O具有一個,一件T如果它是一個平局,和N如果沒有人有。提前致謝。我一直試圖熟悉C++和編程。

編輯:我剛剛去用簡單的方法,但我有點搞砸了,誰知道怎麼樣?它看起來像,因爲當我把它的主要玩家挑選一個行和列(這是工作的罰款)後,它不輸出任何它不返回任何東西

+0

僅供參考:'const char board [] [3]'不會做你認爲它做的事情。我認爲你的意思是'const char(&board)[3] [3]'? – Mehrdad 2011-03-08 09:34:56

+9

只返回先行者:P – 2011-03-08 09:36:25

+0

當有領帶時返回什麼? – 2011-03-08 09:38:02

回答

13

您可以在數組轉換成兩個九位值,一個用於將O位置,一個用於X軸位置和空白空間的計數:

x_mask = 0 
y_mask = 0 
empty_count = 0 
mask = 1 
for each square 
    if x then x_mask |= mask 
    if y then y_mask |= mask 
    if empty then empty_count++ 
    mask <<= 1 

然後比較對八個可能獲勝組合的x_mask和y_mask:

for each player 
    for each winning combination 
    if player_mask & winning_mask == winning_mask then player has won 

,然後辦理案件既不球員先後榮獲:

if neither player won 
    if empty_count == 0 
    its a tie 
    else 
    moves still available 
2

一個簡單的「結構化」的做法

如果您認爲董事會爲:

A B C 
D E F 
G H I 

然後箱子一個最小的選擇,任何成功的佈局必須接觸將是:

A B C 
D 
G 

可以設想在0,1或-1的位置在每一個X和Y方向的偏移而言從任何在獲勝線這些位置的移動。我們可以列出你需要檢查走勢:

A: (++x) (++x, ++y) (++y) 
B: (++y) 
C: (++y) (--x, ++y) 
D: (++x) 
E: (++x) 

在C++中,你可以創建的出發點的X/Y座標列表/矢量和+/-/0 X/Y上面顯示的運動變化量,然後使用三個嵌套循環評估板上的每條線。

這不僅僅是硬編碼在X和Y座標的兩個環和兩個對角線(如下圖)相當多的工作,但它可能會智力喜愛的更加算法方法:更喜歡你可能有,如果你是做什麼處理更大的板子。


明顯的暴力方法

爲了記錄在案,這更簡單的方法是這樣的:

int x; 
for (row = 0; row < 3; ++row) 
    if ((x = board[row][0]) != Empty && 
     board[row][1] == x && board[row][2] == x) 
     return x; 
// similar loop for columns... 
... 
// hardcode diagonals... 
if ((x = board[1][1]) != Empty && 
    (board[0][0] == x && board[2][2] == x || 
    board[2][0] == x && board[0][2] == x)) 
    return x 
+0

我嘗試過採用你提到的蠻力方法,因爲它對我來說最有意義,但它看起來像我搞砸了。我用我的問題編輯了原文 – Michael 2011-03-08 13:42:00

2

我想你可以一個號碼分配給每個獲獎板可能性(基本上是散列值),然後檢查當前的板通過產生其散列值相匹配的任何在表中的值的。在另一方面,我不建議花太多時間試圖讓CheckWin功能超高效。除非被稱爲數百萬次或什麼東西需要非常快,否則將時間花在別的東西上 - 它可能不會成爲瓶頸。