Algorytm, który działa należycie w osobnym pliku, ale nie w głównym pliku.

0

Witam.
Tworząc kółko i krzyżyk, tworzyłem coś na wzór minimax. Tworzyłem go w osobnym pliku i tak go testowałem.
Po wielu próbach, bólach, zwątpieniach, doszedłem do czegoś co można zaimplementować w programie. Wszystko niby działało, tylko tak jakby wadliwie. Sprawdzałem dane na całości oraz tylko na algorytmie. Na algorytmie działa poprawnie tak jak chciałem, w głównym pliku już nie. Czy to wina przepełnienia stosu?
Główny plik - http://wklej.org/id/1220521/
Algorytm - http://wklej.org/id/1220535/

0

O debugerze słyszałeś?

0

Słyszałem, ale myślałem, że jest to coś poważniejszego niż tylko co się w końcu okazało problemem zbyt mała zmienna znakowa char.

0

Panowie, Czy ktoś mi może powiedzieć, dlaczego działa tak jak oczekuje na Windowsie, w Microsoft Visual Studio 2013? A nie działa na Linuxie w gcc dołączonym standardowo do Ubuntu 13.10?

A co za tym idzie, także nie działa w Code::Blocks?

0

Oczywiście o debugierze zdążyłeś zapomnieć?
Szukaj niezainicjalizowanych zmiennych lub drobnego wyjścia poza zakres tablicy.

2

Ten algorytm jest popotrzebny?

Kod gry: ktoś dokonał zamach terrorystycznego? - To najpierw znajdź i unieszkodliwij sprawcę.

Funkcja czymozesz_zapis()
Else zupełnie niepotrzebne. Jeżeli żaden warunek nie zostanie spełniony zwróci 1. Zamiast switch..case wystarczy if..else if:

if(klawisz==55 && tab[0][0]==0) { tab[0][0]=(wybor==49)?1:2; return 0; }
else if(klawisz==56 && tab[0][1]==0) { tab[0][1]=(wybor==49)?1:2; return 0; }
//...
return 1; 

Dlaczego indeksujesz pola w tablcy od lewego dolnego rogu, a nie jak to powszechnie przyjęte od górnego lewego.
Zwracany typ - wystarczy int (tak jak masz wewnątrz funkcji). Nie doczepij zbędnych nagłówków (i konwersji).
Gdybyś normalnie indeksował pola (użytkownik też raczej nie domyśli się, że pole o indeksie 1 znajduje się w lewym dolnym rogu planszy) to można bardzo uprościć:

bool czymozesz_zapis(short int klawisz, short int wybor, short int tab[MAXSTAN][MAXSTAN])
{
  int k = klawisz - 49; //indeksy tablic od 0 a nie 1
  szort int* tab1 = tab[0]; //działa tylko dla 'dwuwmiarowych' tablic na stosie 
  if(tab1[k]==0)
  {
    tab1[k]=(wybor==49)?1:2;
    return 0;
  }
  return 1;
} 

Funkcja sprawdzczywygral():

short int sprawdzczywygral(short int tab[MAXSTAN][MAXSTAN]) 
{ 
  int i,j;
  for(i=0; i<(MAXSTAN); i++)
  {
    //działa dla tablic o tej samej liczbie wierszy i kolumn 
    if((tab[i][0]==tab[i][1])&&(tab[i][0]==tab[i][2])) return tab[i][0]; //zwróci 1 lub 2 
    if((tab[0][i]==tab[1][i])&&(tab[0][i]tab[2][i])) return tab[0][i];
  } 
  if((tab[0][0]==tab[1][1])&&(tab[0][0==tab[2][2])) return tab[0][0];
  if((tab[2][0]==tab[1][1])&&((tab[2][0]==tab[0][2])) return tab[2][0];
  return 0;
}

Wartość większa od zera - gra skończona(od razu wiadomo czy wygrał gracz stawiający kółka czy krzyżyki); zero - w toku. No i funkcja sprawdzczyremis() - niepotrzebna. Grz może zakończyć się remisem?

o sie tyczy użycia goto w programie. Jest to sygnał, że coś nie tak z projektem lub algorytmem.
Proponuję (proszę potraktuj to jako żart, nic osobistego) na początku maina coć takiego:

    goto ksiażka_z_podstawami_programowania;
ogarnięte:
    goto: projekt;
zrobiony:
    //a teraz już tylko kodzenie...  

Wszystkiego nie przegladałem.

0

@_13th_Dragon

_13th_Dragon napisał(a):

Oczywiście o debugierze zdążyłeś zapomnieć?
Oczywiście, że nie.

_13th_Dragon napisał(a):

Szukaj niezainicjalizowanych zmiennych lub drobnego wyjścia poza zakres tablicy.
Szukałem, ale niczego niestety nie znalazłem.

@Rekman Dziękuje za zainteresowanie oraz wyczerpującą odpowiedź. Próbując odpowiedzieć na twoją wiadomość musiałem podzielić wiadomość na kilka części.

Rekman napisał(a):

Ten algorytm jest popotrzebny?

  • Tak mi się wydaje, ponieważ od dłuższego czasu próbuje napisać AI do kółka i krzyżyka. A co wymaga jednego z algorytmów MIN-MAX lub Negamax. Czy to z alfą i betą czy to bez. Z racji tego, że nie umiem napisać samego Min-Max, dlatego on jest bez alfy i bety.
Rekman napisał(a):

Funkcja czymozesz_zapis()
Else zupełnie niepotrzebne. Jeżeli żaden warunek nie zostanie spełniony zwróci 1. Zamiast switch..case wystarczy if..else if:

if(klawisz==55 && tab[0][0]==0) { tab[0][0]=(wybor==49)?1:2; return 0; }
else if(klawisz==56 && tab[0][1]==0) { tab[0][1]=(wybor==49)?1:2; return 0; }
//...
return 1; 
  • A czy to nie podniesie za to złożoności tego algorytmu?
Rekman napisał(a):

Dlaczego indeksujesz pola w tablcy od lewego dolnego rogu, a nie jak to powszechnie przyjęte od górnego lewego.

  • To mam zamiar zmienić, dlaczego? Wyświetlanie takiej tablicy było po prostu łatwiejsze.
Rekman napisał(a):

Zwracany typ - wystarczy int (tak jak masz wewnątrz funkcji). Nie doczepij zbędnych nagłówków (i konwersji).

  • To już zmieniłem, dziękuje za uwagę.
Rekman napisał(a):

Funkcja sprawdzczywygral():
Wartość większa od zera - gra skończona(od razu wiadomo czy wygrał gracz stawiający kółka czy krzyżyki); zero - w toku.

  • Tu niestety, czy stety, będę musiał bronić swojej funkcji. Ona mi jest potrzebna do algorytmu minimax, który ma dawać komputerowi najlepsze klawisze do wygrania. Jest to tak zwana moja funkcja oceniająca, kończąca moją rekurencje.
Rekman napisał(a):

No i funkcja sprawdzczyremis() - niepotrzebna. Grz może zakończyć się remisem?

  • Gra kółko i krzyżyk jak najbardziej może się zakończyć remisem, no ewentualnie wygraną komputera co do czego dążę.
Rekman napisał(a):

o sie tyczy użycia goto w programie. Jest to sygnał, że coś nie tak z projektem lub algorytmem.

  • Rozumiem, sprzeciw co do używania goto. Rozumiem, sprzeciw do używania goto, żeby skakać po programie. Ale goto, użyłem w tym przypadku dlatego, ponieważ nie chciałem użyć 18 return, jeśli dobrze pamiętam. A na algorytmach zawsze mnie uczyli, żeby powrotów z funkcji było jak najmniej. To w takim razie co jest większym grzechem programisty? Używanie wielu returnów czy goto?

I dalej nie wiem dlaczego na Ubuntu działa tak jak powinien a na Windows nie.
Debugger powiedział, a raczej wskazał, że problem mogę mieć z algorytmem ponieważ, mój algorytm szuka najmniejszej liczby i ją zwraca. Coś w stylu tego: http://wazniak.mimuw.edu.pl/images/7/74/SI_M8_minimax.png
Tylko dla moich liści zwracane są wartości 1,-1,0 lub zero, na węzłach szukany jest najmniejszy i największy w zależności kto gra. Ale prawdopodobnie na węzłach bliższych korzeniu wszędzie jest -1. Czy ktoś może wyjaśnić, dlaczego na tym grafie się znalazł np 4 2 -1? Rozumiem, że to z funkcji oceniającej, ale czy to są już liście?

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