2012-10-29 11 views
5

Ecco l'game board tanto per dare un'idea di come sembra (questa scheda sarà ampliato ad una 7x6)2 di fila C# programma di gioco

quello che voglio fare è individuare un vincitore quando 2 i colori sono in una fila simile al gioco "conmect four" che tiene conto anche delle combinazioni diagonali. Ma io voglio fare questo senza l'uso di forza bruta enumerazione ..

questo il codice che va dietro il programma ho fatto io non sto chiedendo soluzione che ho solo bisogno di un po 'di aiuto su un algoritmo efficace

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

Si espanderà mai più di un 2x2? –

+0

lo espanderò a 7x6 – Tacit

+0

C'è un limite ai colori? Come solo 2 o 3? – noMAD

risposta

10

In primo luogo, per efficienza e sanità mentale, manterrei lo stato della mia scheda in un array 2D.

In secondo luogo, per la rilevazione di vincere gli stati, dato che si avvia il gioco con una (presumibilmente ) bordo vuoto, si può ottenere solo in uno stato vittoria quando un pulsante cambia stato. E se lo stato di cambio pulsante ti mette in uno stato di vittoria, allora quel pulsante deve essere coinvolto in quello stato di vittoria (cioè deve essere parte della tua linea).

Quindi ... non è necessario forzare l'intera scheda. Hai solo bisogno di determinare se il pulsante che ha appena cambiato stato fa parte di una linea. In altre parole, guarda solo i pulsanti sopra, sotto, a sinistra ea destra (e forse in diagonale, la tua domanda non è chiara se hai inserito le diagonali) per vedere se sono dello stesso colore di quello che hai cambiato . Se uno di questi è, allora questo è uno stato di vittoria. Questo è dove l'uso di un array 2D ti renderà la vita molto più facile. Se il pulsante in (x, y) è cambiato, allora avete solo bisogno di controllare (x-1, y), (x + 1, y), (x , y-1) e (x, y + 1), (e forse diagonali) assicurandosi di fare controlli di confine appropriati, naturalmente.

Estendere questo a 3, 4 o più di fila non è molto più difficile, tranne che è necessario ricordare che si potrebbe essere nel mezzo di una riga piuttosto che un'estremità o l'altra.

non ottimizzato pseudo codice per 2 in una fila (nota, ho passato a punti cardinali per evitare di up-sinistra, in alto a destra, etc perché sento che diventa un po 'ingombrante):

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

Se si sta facendo più di 2, che ci avrei pensato una funzione ricorsiva per contare il numero di corrispondenti celle a sinistra, destra, su, giù, e 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 Stavo per scrivere una risposta simile. Si tratta della soluzione più efficiente in quanto è O (1) nonostante le dimensioni della scheda. –

+0

+1, bella soluzione –

+0

è possibile che si scriva un pseudocodice per favore (includerà anche la diagonale) – Tacit

1

per un n by m bordo e una combinazione vincente di k di seguito:

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