2013-03-07 4 views
6

To generator tic tac toe. Komputer kontra komputer, trochę inny niż zwykły gracz kontra komputer. Mam większość mojego kodu napisanego na ten temat, ale kwestią, którą mam, jest czasami, kiedy generuję grę, cała tablica wypełnia się, a pojawi się linia X i linia O, a pojawi się jako remis . Czasami generowane są dwie linie X lub dwóch linii O, a gra nie zatrzymuje się po pierwszym wierszu z 3 w rzędzie ... żadnych wglądów? Dziękuję Ci.Tic Tac Toe - Wykrywanie wygranej, przegranej lub remisu

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

Twoje przekątnych posiada bug, jesteś sprawdzania '0 == 4 == 8' , ale także '2 == 4 == 8 (zamiast 6)' – Nolonar

+2

Jeśli chcesz ćwiczyć, to chciałbym spróbować zaimplementować całą twoją logikę gry oddzielnie od twojego interfejsu użytkownika. Możesz tworzyć klasy dla samej gry, graczy, każdej reguły wygrywającej itd. Możesz wtedy łatwiej bawić się z AI i innymi rzeczami. Tylko sugestia, choć ... – Jobo

+0

Chciałbym zagłosować na komentarz Jobo, gdybym mógł. Jeśli utworzysz klasę, która obsługuje grę, możesz umieścić ją w innym interfejsie użytkownika, np. jeden dla komputera kontra komputera lub inny dla gracza kontra gracz lub gracz kontra komputer. – SteveP

Odpowiedz

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

Jeśli istnieją dwie linie, spowoduje przesunięcie krawata. Jeśli chcesz przestać, gdy tworzona jest linia, musisz sprawdzić zwycięzcę po każdym ruchu, a nie po wypełnieniu całej planszy.

+0

Tak, również jeśli sprawdzasz za każdym razem, gdy umieszczony jest symbol, musisz tylko sprawdzić linie od ostatniego umieszczonego symbolu. – MrFox

+0

@SteveP - Jestem całkiem nowy, ponieważ jest to ćwiczenie dla początkujących polecane w książce, którą czytam, aby wypróbować. Jeśli możesz pomóc mi zrozumieć co do sprawdzania po każdym stwierdzeniu, byłoby to bardzo cenne. Rozumiem, do czego zmierzasz, po prostu problemy z łączeniem ... Dziękuję. – TomandGeriatric

+0

W zasadzie, aby zasymulować prawdziwą grę, bierzemy aktualną pozycję, stosujemy ruch gracza, a następnie sprawdzamy, czy ten ruch wygrał. Możesz zoptymalizować wygrywający czek, ponieważ każdy wygrywający wiersz musi zawierać ruch, który właśnie został zrobiony. – SteveP

2

Druga przekątna check zwycięzca powinien być 6 zamiast 8.

Aktualnie sprawdzenie:
xoo
OXO
OOX

oraz:
OOX
OXO
OOX

Oczywiście ostatnie x powinno znajdować się po lewej stronie.

Dodatkowo, jak napisali inni. Robienie dwóch linii nie powinno prowadzić do remisu. Jeden gracz może nawet zrobić dwie linie samodzielnie, powodując remis.
Zmień funkcję, aby od razu zwrócić wynik, gdy znajdzie zwycięski wiersz i sprawdź go po każdym ruchu.

+0

To jest problem. Ale to nie rozwiąże jego obecnego problemu. –

1

To działa: Trzeba pozbyć się ...

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

zastąpienia tej linii kodu z tymi trzema sztukę kodu:

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

Więc zmieniłem kilka rzeczy. Nie użyłem "winning_line ++;" trochę kodu. Zamiast tego zrobiłem coś takiego dla każdego z sprawdzeń instrukcji 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 "; 
      } 
     } 

Mam więc 4 ciągi, których używam, jeden do śledzenia, czy X ma wygrywającą linię, taką samą dla O.Mam wtedy ciąg zwycięzców, aby śledzić remis. jego jedyny używany zamiast miejsca, gdzie twój stary krawat sprawdzał, czy wypowiedź była.

Potrzebny będzie również zmienić switch zbyt jeśli zdecydujesz się użyć zamiast ciągów liczb całkowitych tj

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; 
     } 
Powiązane problemy