Problem z ostatnim wierszem tablicy 2-wymiarowej.

0

Witam, po kilkugodzinnej walce z błędem szukam wsparcia na zewnątrz. Tworzę grę w oparciu o stawianie pionów na dynamicznej tablicy dwuwymiarowej, wszystko jest ok do momentu sprawdzania warunków zwycięstwa (szukanie rzędu 5 takich samych pionów poziomo, pionowo, lub na skos) - program wysypuje się po próbie umieszczenia pionu w ostatnim wierszu. Sądzę że błąd tkwi gdzieś w owym warunkach gdyż bez nich wszystko działa bez zarzutu. Zastanawia mnie, czy jeśli przepełniają się tablice, to dlaczego problem pojawia się tylko w ostatnim wierszu, a nie np. w przedostatnim itd. Niżej fragmenty kodu:

//Tworzenie dynamicznej tablicy

char** tab = new char *[x];

for(int i=0; i<x; i++)
{
   tab[i]=new char [x];

   for(int j=0; j<x; j++)
   {
      tab[i][j]='.';
   }
}
//Funkcja sprawdzająca warunki zwycięstwa

void zwyciestwo(char **tab, /*int w, int k,*/ int roz)
{
   int i, j;

   for(i=0; i<roz; i++)
   {
      for(j=0; j<roz; j++)
      {
         if((tab[i][j]=='X' && tab[i][j+1]=='X' && tab[i][j+2]=='X' && tab[i][j+3]=='X' && tab[i][j+4]=='X')||\
         (tab[i][j]=='X' && tab[i+1][j]=='X' && tab[i+2][j]=='X' && tab[i+3][j]=='X' && tab[i+4][j]=='X')||\
         (tab[i][j]=='X' && tab[i+1][j+1]=='X' && tab[i+2][j+2]=='X' && tab[i+3][j+3]=='X' && tab[i+4][j+4]=='X')||\
         (tab[i][j]=='X' && tab[i+1][j-1]=='X' && tab[i+2][j-2]=='X' && tab[i+3][j-3]=='X' && tab[i+4][j-4]=='X'))
         {
            cout << ("\n\nKONIEC! Gracz X wygral\n");
         }
         else if((tab[i][j]=='O' && tab[i][j+1]=='O' && tab[i][j+2]=='O' && tab[i][j+3]=='O' && tab[i][j+4]=='O')||\
         (tab[i][j]=='O' && tab[i+1][j]=='O' && tab[i+2][j]=='O' && tab[i+3][j]=='O' && tab[i+4][j]=='O')||\
         (tab[i][j]=='O' && tab[i+1][j+1]=='O' && tab[i+2][j+2]=='O' && tab[i+3][j+3]=='O' && tab[i+4][j+4]=='O')||\
         (tab[i][j]=='O' && tab[i+1][j-1]=='O' && tab[i+2][j-2]=='O' && tab[i+3][j-3]=='O' && tab[i+4][j-4]=='O'))
         {
            cout << ("\n\nKONIEC! Gracz O wygral\n");
         }
      }
   }
0

To nie problem z ostatnim wierszem, to problem z wierszami tab[-1][:], tab[-2][:], …, tab[roz][:], tab[roz+1][:]… I analogicznie z kolumnami.

Jeśli roz w twojej funkcji jest rozmiarem tablicy, to wielokrotnie i brutalnie odwołujesz się poza zakres przydzielonej pamięci poprzez indeksowanie i+1, i+2… W zasadzie w każdej linii kodu. Liczniki i i j jadą od 0 do roz-1, a odwołujesz się np. do i-1 w pętli – co dla i == 0 powoduje czytanie indeksu -1.

0

Rozumiem, ale dlaczego w takim razie program wysiada tylko przy ostatnim wierszu, a nie dwoma, trzema, czy czterema ostatnimi? Zastanawiam się teraz, czy wkręcać w tą pętlę teraz chmarę różnych warunków dla konkretnych wierszy, czy spróbować napisać jakiś inny mechanizm (np. najpierw wyszukiwanie takich samych "sąsiadów" i sumowanie ich aż do 5)

1
Alzhimer napisał(a):

... ale dlaczego w takim razie program wysiada tylko przy ostatnim wierszu, a nie dwoma, trzema, czy czterema ostatnimi? ...

Bo dopóki odwołujesz się do tb[0][-1] lub tb[0][roz] to masz bardzo duże prawdopodobieństwo że nadal trafiasz w przydzieloną tobie (ale nie pod tb) pamięć. przy odwołaniu: tb[-1][0] lub tb[roz][0] masz prawie zerowe szanse na trafienie w "twoją" pamięć.

0

Dzięki, to mi nieco rozjaśniło sprawę. Postawię odpowiednie warunki i jakoś to rozbuduję, dziękóweczka )

1

Rozważ następujący algorytm:
Zawsze liczysz tylko od miejsca wstawienia 'X' lub 'O' w pozycji X,Y

S=1; // jedną już mamy
for(int x=X+1;(x<MAX_WIDTH)&&(S<5)&&(tab[Y][X]==tab[Y][x]);++x) ++S;
for(int x=X-1;(x>=0)&&(S<5)&&(tab[Y][X]==tab[Y][x]);--x) ++S;
if(S>=5) // wygrana

Teraz to samo powtarzamy z pionem,
to samo powtarzamy z główną przekątną
to samo powtarzamy z dodatkową przekątną
i gotowe.

1 użytkowników online, w tym zalogowanych: 0, gości: 1