2013-03-07 11 views
6

Questo è un generatore di tic tac toe. Solo Computer vs. Computer, un po 'diverso dal solito Player vs. Computer. Ho scritto la maggior parte del mio codice per questo, ma il problema che sto avendo a volte quando genero il gioco, l'intera scheda si riempie e ci sarà una linea di X e una linea di O e verrà fuori come una cravatta . A volte ci sono due linee di X o due linee di O generate, e il gioco non si ferma dopo la prima riga con 3 di fila ... qualche intuizione? Grazie.Tic Tac Toe - Rileva vincere, perdere o pareggiare

namespace TicTacToe 
{ 
    public partial class Form1 : Form 
    { 
     private Random rn = new Random(); 

     const int SIZE = 9; 
     char[] cell = new char[SIZE]; 
     char firstPlayer = ' ', secondPlayer = ' '; 

     private void button1_Click(object sender, EventArgs e) 
     { 
      //Clear the labels and starting values 

      for (int i = 0; i < SIZE; i++) 
      { 
       cell[i] = ' '; 
      } 
      label10.Text = ""; 

      //Pick X or O to go first 
      switch (rn.Next(2)) 
      { 
       case 0: firstPlayer = 'O'; secondPlayer = 'X'; break; 
       case 1: firstPlayer = 'X'; secondPlayer = 'O'; break; 
      } 

      //Get five non-repeating numbers from 0 to 8 
      int[] positions = new int[5]; 
      positions[0] = rn.Next(9); 
      for (int i = 1; i < 5; i++) 
      { 
       int temp = rn.Next(9); 
       for (int j = 0; j < i; j++) 
       { 
        if (temp == positions[j]) 
        { 
         i--; 
         break; 
        } 
        else 
        { 
         positions[i] = temp; 
        } 
       } 
      } 

      //Set each position found to have first players letter 
      for (int i = 0; i < 5; i++) 
      { 
       cell[positions[i]] = firstPlayer; 
      } 

      for (int i = 0; i < SIZE; i++) 
      { 
       if (cell[i] != firstPlayer) 
       { 
        cell[i] = secondPlayer; 
       } 
      } 
      //Place cell values into the labels 
      label1.Text = cell[0].ToString(); 
      label2.Text = cell[1].ToString(); 
      label3.Text = cell[2].ToString(); 
      label4.Text = cell[3].ToString(); 
      label5.Text = cell[4].ToString(); 
      label6.Text = cell[5].ToString(); 
      label7.Text = cell[6].ToString(); 
      label8.Text = cell[7].ToString(); 
      label9.Text = cell[8].ToString(); 

      //Check for a winner 
      switch(checkWinner()) 
      { 
       case 'T' : label10.Text = "It's a tie!"; break; 
       case 'O' : label10.Text = "O Wins!"; break; 
       case 'X' : label10.Text = "X Wins!"; break; 
       default: label10.Text = "This will never appear"; break; 
      } 
     } 

     private char checkWinner() 
     { 
      //return either 'T' for tie, 'O' for O wins, and 'X' for X wins 
      char winner = ' '; 
      int winning_line = 0; 
      //check for a row win 
      if(cell[0].Equals(cell[1]) && cell[0].Equals(cell[2])) 
      { 
       winning_line++; 
       winner = cell[0]; 
      } 
      if (cell[3].Equals(cell[4]) && cell[3].Equals(cell[5])) 
      { 
       winning_line++; 
       winner = cell[3]; 
      } 
      if (cell[6].Equals(cell[7]) && cell[6].Equals(cell[8])) 
      { 
       winning_line++; 
       winner = cell[6]; 
      } 

      //check for column wins 
      if (cell[0].Equals(cell[3]) && cell[0].Equals(cell[6])) 
      { 
       winning_line++; 
       winner = cell[0]; 
      } 
      if (cell[1].Equals(cell[4]) && cell[1].Equals(cell[7])) 
      { 
       winning_line++; 
       winner = cell[1]; 
      } 
      if (cell[2].Equals(cell[5]) && cell[2].Equals(cell[8])) 
      { 
       winning_line++; 
       winner = cell[2]; 
      } 
      //check for diagonal winner 
      if (cell[0].Equals(cell[4]) && cell[0].Equals(cell[8])) 
      { 
       winning_line++; 
       winner = cell[0]; 
      } 
      if (cell[2].Equals(cell[4]) && cell[2].Equals(cell[8])) 
      { 
       winning_line++; 
       winner = cell[2]; 
      } 

      if (winning_line == 0 || winning_line > 1) 
      winner = 'T'; 

      return winner; 
     } 

     public int i { get; set; } 
    } 
} 
+3

I suoi diagonali hanno un bug, si sta controllando per '0 == 4 == 8' , ma anche '2 == 4 == 8 (invece di 6)' – Nolonar

+2

Se vuoi esercitarti, prenderei in considerazione il tentativo di implementare tutta la tua logica di gioco separata dalla tua interfaccia utente. Potresti creare classi per il gioco stesso, i giocatori, ogni regola vincente, ecc. Potresti quindi giocare con l'IA e farcela molto più facilmente. Solo un suggerimento, però ... – Jobo

+0

Vorrei votare il commento di Jobo se potessi. Se crei una classe che gestisce il gioco, puoi inserirla nell'interfaccia utente diversa, ad es. uno per computer vs computer, o uno diverso per giocatore vs giocatore o giocatore vs computer. – SteveP

risposta

3
if (winning_line == 0 || winning_line > 1) 

Se ci sono due righe, verrà eseguito un pareggio. Se vuoi fermarti quando viene fatta una linea, devi controllare un vincitore dopo ogni mossa, non dopo che l'intera scacchiera è stata riempita.

+0

Sì, anche se si controlla ogni volta che viene inserito un simbolo, è sufficiente controllare le linee dall'ultimo simbolo posizionato. – MrFox

+0

@SteveP - Sono piuttosto nuovo in questo, poiché questo è un esercizio per principianti raccomandato dal libro che sto leggendo per provare. Se puoi aiutarmi ulteriormente a capire fino al controllo dopo ogni affermazione, sarebbe molto apprezzato. Capisco quello che stai facendo, solo avendo problemi a metterlo insieme ... Grazie. – TomandGeriatric

+0

in pratica, per simulare un gioco reale, si prende la posizione corrente, si applica una mossa di giocatori, e poi si controlla se quella mossa ha vinto la partita. Puoi ottimizzare il controllo vincente in quanto ogni riga vincente deve includere la mossa appena effettuata. – SteveP

2

Il secondo controllo vincitore diagonale dovrebbe essere 6 anziché 8.

State attualmente verificando:
XOO
OXO
OOX

e:
OOX
OXO
OOX

Ovviamente l'ultima x dovrebbe essere a sinistra.

Addizionale come altri hanno pubblicato. Realizzare due linee non dovrebbe portare a un pareggio. Un giocatore potrebbe anche fare solo due linee, causando un pareggio.
Modificare la funzione per restituire immediatamente un risultato quando trova una riga vincente e controllarla dopo ogni mossa.

+0

Questo è un problema. Ma non risolverà il suo attuale problema. –

1

Questo funziona: è necessario liberarsi del ...

se (winning_line == 0 || winning_line> 1)

sostituire quella riga di codice con questi tre pezzi di codice:

if (winnerX == " X ") 
    { 
     theWinner = winnerX; 
    } 
    if (winnerO == " O ") 
    { 
     theWinner = winnerO; 
    } 
    if(winnerX == " X " && winnerO == " O ") 
    { 
     winnerT = " T "; 
     theWinner = winnerT; 
    } 

Quindi quello che ho fatto è stato cambiare un paio di cose. Non ho usato "winning_line ++;" un po 'di codice. invece ho fatto qualcosa di simile per ciascuno dei controlli di dichiarazione if.

if (cell[2, 0].Equals(cell[1, 1]) && cell[2, 0].Equals(cell[0, 2])) 
     { 
      if (cell[2, 0] == 0) 
      { 
       winnerX = " X "; 
      } 

      else if (cell[2, 0] == 1) 
      { 
       winnerO = " O "; 
      } 
     } 

così ho 4 stringhe che sto usando, uno per tenere traccia se X è ha una linea vincente, lo stesso per O.Poi ho la stringa vincente per tenere traccia del legame. è usato solo al posto di dove la tua vecchia cravatta controlla se la dichiarazione è stata.

Sarà inoltre necessario cambiare la vostra istruzione switch anche se si decide di utilizzare le stringhe al posto di interi IE

switch (checkWinner()) 
     { 
      case " X ": 
       textBox1.Text = "X Wins!"; 
       break; 
      case " O ": 
       textBox1.Text = "O Wins!"; 
       break; 
      case " T ": 
       textBox1.Text = "It's a tie!"; 
       break; 
     }