2013-03-17 96 views
5

我目前正在爲自己研究一個基本的四連勝遊戲,但我更堅持它背後的邏輯。四連排邏輯

目前我有此表示該板

[ 
    [0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0] 
] 

0將表示一個空的插槽,而12表示玩家多維數組。 因此,讓後說,當你得到這個數組:

[ 
    [0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 1, 1, 0, 0], 
    [0, 0, 0, 1, 1, 0, 0], 
    [0, 0, 1, 2, 2, 2, 0], 
    [0, 1, 2, 2, 1, 2, 0] 
] 

我怎麼能寫出邏輯來檢查是否有連續4? 水平和垂直方向的計算看起來相當容易(儘管仍然找出最佳方法),但我怎樣才能做到這一點對角線?

+3

就像你會水平或垂直做,但你會增加/減少兩個座標而不只是一個。 – 2013-03-17 05:24:32

+0

@ H2CO3,甚至可以進一步進行編輯/標記,並使其完全與語言無關......我正在考慮這樣做。 – Till 2013-03-17 05:43:47

+0

@Till是的,這也是合理的。 – 2013-03-17 05:44:56

回答

12

最好的辦法是大概劃分搜索空間分爲四種:

  • 垂直;
  • 臥式;
  • 右和下;
  • 正確與否。

然後根據方向限制您的開始和結束座標。

例如,假設您的數組爲board[row=0-5][col=0-6],並且左上角爲board[0][0]

首先垂直(環是包括在在該僞代碼既端):

for row = 0 to 2: 
    for col = 0 to 6: 
     if board[row][col] != 0 and 
      board[row][col] == board[row+1][col] and 
      board[row][col] == board[row+2][col] and 
      board[row][col] == board[row+3][col]: 
       return board[row][col] 

這限制的可能性只有那些不延伸過邊緣板,一個問題大多數解決方案在他們通過檢查每個單元並從那裏向所有方向走出時簡單地開始。因此,我的意思是檢查3行的起始行是沒有意義的,只是因爲這涉及第3,4,5和6行(後者不存在)。

同樣,對於水平:

for row = 0 to 5: 
    for col = 0 to 3: 
     if board[row][col] != 0 and 
      board[row][col] == board[row][col+1] and 
      board[row][col] == board[row][col+2] and 
      board[row][col] == board[row][col+3]: 
       return board[row][col] 

對於向右和向下,然後向右和向上:

for row = 0 to 2: 
    for col = 0 to 3: 
     if board[row][col] != 0 and 
      board[row][col] == board[row+1][col+1] and 
      board[row][col] == board[row+2][col+2] and 
      board[row][col] == board[row+3][col+3]: 
       return board[row][col] 

for row = 3 to 5: 
    for col = 0 to 3: 
     if board[row][col] != 0 and 
      board[row][col] == board[row-1][col+1] and 
      board[row][col] == board[row-2][col+2] and 
      board[row][col] == board[row-3][col+3]: 
       return board[row][col] 

現在,通過將for col = 0 to 3外環你實際上可以結合這兩個並且只做一次而不是兩次,但我實際上更願意將它們分開(有適當的評論),以便更容易理解。但是,如果你沉迷於性能,你可以嘗試:

for col = 0 to 3: 
    for row = 0 to 2: 
     if board[row][col] != 0 and 
      board[row][col] == board[row+1][col+1] and 
      board[row][col] == board[row+2][col+2] and 
      board[row][col] == board[row+3][col+3]: 
       return board[row][col] 
    for row = 3 to 5: 
     if board[row][col] != 0 and 
      board[row][col] == board[row-1][col+1] and 
      board[row][col] == board[row-2][col+2] and 
      board[row][col] == board[row-3][col+3]: 
       return board[row][col] 

然後,如果在四個可能的方向沒有發現勝,只需返回0而不是贏家12的。

因此,舉例來說,你的樣品板:

row 
0 [0, 0, 0, 0, 0, 0, 0] 
1 [0, 0, 0, 0, 0, 0, 0] 
2 [0, 0, 0, 1, 1, 0, 0] 
3 [0, 0, 0, 1, 1, 0, 0] 
4 [0, 0, 1, 2, 2, 2, 0] 
5 > [0, 1, 2, 2, 1, 2, 0] 
     ^
     0 1 2 3 4 5 6 <- col 

將在右和上環,其中起始細胞是{5,1}因爲{5,1}{4,2}{3,3}{2,4}都設置爲1檢測贏家。

+0

令人驚歎的是,這真的幫了很多! – 2013-03-17 12:00:07

2

我在一段時間後連續開發了四款遊戲。下面是檢查連續四個條件的獲勝條件的代碼片段:(這是C語言)

int checkWinOrLose(int grid[][7],int result,int rowNum) { 
// For checking whether any win or lose condition is reached. Returns 1 if win or lose is reached. else returns 0 
// grid[][] is the 6X7 matrix 
// result is the column number where the last coin was placed 
// rowNum is the row number where the last coin was placed 

    int player=grid[rowNum][result]; 
    if(rowNum<=2 && grid[rowNum+1][result]==player && grid[rowNum+2][result]==player && grid[rowNum+3][result]==player) // 4 in a row vertically 
     return 1; 
    else { 
     int count=1,i,j; 
     for(i=result+1;i<7;i++) { // 4 in a row horizontally 
      if(grid[rowNum][i]!=player) 
       break; 
      count++; 
     } 
     for(i=result-1;i>=0;i--) { // 4 in a row horizontally 
      if(grid[rowNum][i]!=player) 
       break; 
      count++; 
     } 
     if(count>=4) 
      return 1; 
     count=1; 
     for(i=result+1,j=rowNum+1;i<7 && j<6;i++,j++) { // 4 in a row diagonally 
      if(grid[j][i]!=player) 
       break; 
      count++; 
     } 
     for(i=result-1,j=rowNum-1;i>=0 && j>=0;i--,j--) { // 4 in a row diagonally 
      if(grid[j][i]!=player) 
       break; 
      count++; 
     } 
     if(count>=4) 
      return 1; 
     count=1; 
     for(i=result+1,j=rowNum-1;i<7 && j>=0;i++,j--) { // 4 in a row diagonally 
      if(grid[j][i]!=player) 
       break; 
      count++; 
     } 
     for(i=result-1,j=rowNum+1;i>=0 && j<6;i--,j++) { // 4 in a row diagonally 
      if(grid[j][i]!=player) 
       break; 
      count++; 
     } 
     if(count>=4) 
      return 1; 
    } 
    return 0; 
}