2012-10-29 80 views
5

這裏是game board只給你它的樣子(這個委員會將擴大到7x6)的想法2連勝C#程序遊戲

我想要做的是檢測時贏家2顏色與遊戲「conmect four」類似,也考慮到對角線組合。但我想用蠻力枚舉與做出來的..

這一點,去我已經我沒有要求的解決方案,我只是需要一點幫助上一個有效的算法程序後面的代碼

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 

     private Button[] btns; 
     private Button[] btns2; 

     public Form1() 
     { 
      InitializeComponent(); 

      btns = new Button[] { button2, button3 }; 
      btns2 = new Button[] { button4, button5 }; 


     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 

      foreach (var btn in btns) 
      { 
       btn.Enabled = false; 
       btn.BackColor = Color.LightCyan; 
      } 

      foreach (var btn in btns2) 
      { 
       btn.Enabled = false; 
       btn.BackColor = Color.LightCyan; 
      } 
     } 
     public int state; 
     int cc = 0; 
     private void button1_Click(object sender, EventArgs e) 
     { 
      foreach (var btn in btns) 
      { 
        { 
        if (!btn.Enabled) 
        { 
         btn.Enabled = true; 

         if (cc == 0) 
         { 
          cc = 1; 
          btn.BackColor = Color.Red; 
         } 
         else 
         { 
          cc = 0; 
          btn.BackColor = Color.Yellow; 
         } 
         return; 
        } 

       } 
      }  
     } 

     private void button6_Click(object sender, EventArgs e) 
     { 
      foreach (var btn in btns2) 
      { 
       if (!btn.Enabled) 
       { 
        btn.Enabled = true; 

        if (cc == 0) 
        { 
         cc = 1; 
         btn.BackColor = Color.Red; 
        } 
        else 
        { 
         cc = 0; 
         btn.BackColor = Color.Yellow; 

        } 

        return; 
       } 
      } 
     } 
    } 
} 
+0

這會不會擴大超過2x2? –

+0

我會將其展開至7x6 – Tacit

+0

顏色是否有限制?只有2或3? – noMAD

回答

10

首先,爲了提高效率和健全性,我將板子的狀態保持在二維陣列中。

其次,用於檢測取勝狀態,因爲你以一個(大概)空板的比賽中,你只能得到一個雙贏的狀態,當一個按鈕改變狀態。如果按鈕更改狀態將您置於勝利狀態,那麼該按鈕必須參與該勝出狀態(即它必須是您的一部分線路)。

所以......你不需要蠻力整個板子。你只需要確定剛剛改變狀態的按鈕是否是一條線的一部分。換句話說,只看上面,下面,左邊和右邊的按鈕(也許對角線,你的問題不清楚,如果你包含對角線),看看它們是否與你改變的顏色相同。如果其中任何一個是,那麼這是一個勝利的狀態。這是使用二維數組會讓你的生活更輕鬆的地方。如果在按鈕(Xÿ)發生變化,那麼你只需要檢查(X-1ÿ),(X + 1ÿ),(X ,(y-1)和(x,y + 1),(可能是對角線),當然,確保做適當的邊界檢查。

將此擴展到3,4行或更多行並不困難,除非您需要記住您可能位於行的中間而不是一端或另一端。

未優化的僞碼連續2(注意,我已經切換到指南針點,以避免上左,上,右,等等,因爲我覺得它變得有點笨拙):

// cell is the cell that last changes, it has an x and y property and a color property 
// board is a member variable, a 2D array of cells. Note [0,0] is the upper-left (NW) corner of the board. 
// boardHeight and boardWidth are member variable with the dimensions of the board 
// board[boardWidth-1, boardHeight-1] is the lower-right (SE) corner of the board 
// returns true for a win, false otherwise 
function checkWin(cell) returns bool { 
    // check west 
    if (cell.x > 0 && board[cell.x - 1, cell.y].color == cell.color) 
     return true; 
    // check northwest 
    if (cell.x > 0 && cell.y > 0 && board[cell.x-1, cell.y-1].color == cell.color) 
     return true; 
    // check north 
    if (cell.y > 0 && board[cell.x, cell.y-1].color == cell.color) 
     return true; 
    // check northeast 
    if (cell.y > 0 && cell.x < boardWidth && board[cell.x+1, cell.y-1].color == cell.color) 
     return true; 
    // checking the other directions is left as an exercise for the reader, hopefully you get the point 
    return false; 
} 

如果你正在做超過2個,我想一個遞歸函數來計算匹配的單元格向左,向右,向上,向下的數量和diagnoals

// k is the number of cells in a row for a win 
function checkWin(cell) returns bool { 
    // check west/east 
    int count = checkWest(cell); 
    if (count > k) 
     return true; 
    count += checkEast(cell); 
    if (count > k) 
     return true; 
    // check nw/se 
    count = checkNW(cell); 
    if (count > k) 
     return true; 
    count += checkSE(cell); 
    if (count > k) 
     return true; 
    // and so on, checking N/S and NE/SW 
    return false; 
} 

function checkWest(cell) returns int { 
    // base case, check the boundaries! 
    if (cell.x == 0) 
     return 0; 
    // base case, the cell next to this one doesn't match 
    if (board[cell.x-1,cell.y].color != cell.color) 
     return 0; 
    // recursion, check the next cell in the line 
    return 1 + checkWest(board[cell.x-1,cell.y]); 
} 
+0

+1我正要寫一個類似的答案。這是最有效的解決方案,因爲儘管板子很大,它仍然是O(1)。 –

+0

+1,很好的解決方案 –

+0

它會是可能的towrite一些僞代碼請(也將包括對角線) – Tacit

1

對於n by m板和一個成功的組合k連續排列:

int n, m, k; 
byte[,] color = new byte[n, m]; // for two colors, a 0 would correspond to blue, 1 would be red, or however you like 

for (int i = 0; i <= n - k; i++) // don't check all the way to the right because there's no room to win 
{ 
    for (int j = 0; j <= m - k; j++) // don't check all the way down because there's no room to win 
    { 
     // Check here for a win. Check for a win to the right, down right, and down 
    } 
}