2013-03-17 13 views
5

Obecnie pracuję nad podstawową grą w cztery rzędy dla siebie, ale raczej utknąłem w logice stojącej za tym.Cztery z rzędu logika

Obecnie mam ten wielowymiarową tablicę reprezentującą płytę

[ 
    [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 stanowiłoby puste gniazdo, natomiast 1 i 2 stanowią odtwarzacza. Więc powiedzmy, że po jakimś czasie dostaniesz tej tablicy:

[ 
    [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] 
] 

Jak mogę napisać logiki, aby sprawdzić, czy istnieją cztery w rzędzie? Obliczenie tego dla poziomych i pionowych wydaje się raczej łatwe (chociaż wciąż znajduje najlepszy sposób), ale jak to zrobić dla ukośnych linii?

+3

Podobnie jak byś go poziomo lub pionowo, ale można zwiększyć/zmniejszyć zarówno współrzędne zamiast jednego. –

+0

@ H2CO3 można nawet pójść dalej z edycją/tagowaniem i sprawić, że będzie całkowicie agnostykiem językowym ... Myślałem o tym. – Till

+0

@ Till Yeah, to też jest rozsądne. –

Odpowiedz

12

Najprościej jest prawdopodobnie podzielić przestrzeń przeszukiwania na cztery:

  • pionu;
  • pozioma;
  • prawo i dół;
  • prawo i górę.

następnie ogranicz swoje początkowe i końcowe współrzędne w zależności od kierunku.

Na przykład, powiedzmy, że twoja tablica to board[row=0-5][col=0-6] z board[0][0] w lewym górnym rogu.

pierwszą pionową (pętle zawierają co obu końcach, w tym pseudo-kod):

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] 

Ogranicza to możliwości tylko te, które nie rozciągają się poza krawędź płyty, który to problem większość rozwiązań ma wtedy, gdy zaczynają się od uproszczenia, sprawdzając każdą komórkę i wychodząc ze wszystkich stron stamtąd. Rozumiem przez to, że nie ma sensu sprawdzać rzędu początkowego 3, po prostu dlatego, że wymagałoby to wierszy 3, 4, 5 i 6 (ten ostatni, który nie istnieje).

Podobnie na poziomie:

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] 

Na prawo i na dół, a następnie w prawo i do góry:

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] 

Teraz można rzeczywiście połączyć tych dwóch dokonując for col = 0 to 3 zewnętrznej pętli i robię to tylko raz, a nie dwa razy, ale tak naprawdę wolę trzymać je oddzielnie (z odpowiednimi komentarzami), aby łatwiej było je zrozumieć. Jednakże, jeśli jesteś uzależniony od wydajności, można spróbować:

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] 

Następnie, jeśli nie wygrywa stwierdzono w czterech możliwych kierunkach, po prostu wrócić 0 zamiast zwycięzcy 1 lub 2.

Tak więc, na przykład, płyta próbki:

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 

by wykryć zwycięzcę w prawo i do góry pętli gdzie komórka wyjściowa została {5,1} ponieważ {5,1}, {4,2}, {3,3} i {2,4} są ustawione na 1.

+0

Niesamowite, to naprawdę bardzo pomogło! –

2

Rozwinąłem cztery z rzędu grę z powrotem. Oto fragment kodu, aby sprawdzić stan, który wygrywając cztery w stanie rząd: (To jest w języku 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; 
}