Skocz do zawartości
Pecet256

Problem z pętlami

Rekomendowane odpowiedzi

Trzeba utworzyć projekt.

Swoją drogą ciut niewygodny mi się wydaje ten debugger ale to pewnie przyzwyczajenia z konsolowego gdb.

 

Proponowałbym skupić się na jednym błędzie na raz.

Podstawa, to maksymalne zawężenie przypadku jaki wywołuje błędne działanie.

 

Pętla nieskończona.

W jakich przypadkach to się dzieje:

-trzeba wybrać kolejną rundę, czy jeszcze przed wyborem?

-ktoś wygrał, był remis?

-inny przypadek?

 

U mnie pod Win7 wpada w tą pętlę jeżeli miałby być remis. Jednak nie ma wypisu, że jest remis, nie muszę też podawać, że chcę kolejną rundę.

Plansza się zapełnia bez wygranej i robi się czarny ekran.

Sprawdź to dokładnie u siebie, potwierdź czy w takiej samej sytuacji się to dzieje.

 

Jak potwierdzisz lub znajdziesz inne przypadki, to będę podpowiadał dalej i zaczniemy bawić się debuggerem.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dzień dobry.

 

Postanowiłem napisać program "prawie od zera".

Na razie nie ma jeszcze funkcji sprawdzania, czy ktoś wygrał ani menu końcowego po zakończeniu rundy.

Teraz lepiej zaznaczyłem pętle i zastosowałe "if ... else"

 

Co sądzicie?

Jak najlepiej zrobić sprawdzanie, czy ktoś wygrał?

!uwaga! - długi kod

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//WYBORY
#define NIEAKTYWNY 8
#define ZWYKLY 1
#define UPROSZCZONY 2
#define POZNYSTART 3
#define DWUOSOBOWY 4
#define INSTRUKCJA 9
#define POWROT 0

//Urzytkownik gra kolkami (O), program zas krzyzykami (X)
//
//WERSCJA V2.0
//01.06.2020


//FUNKCJE
void funkcjamenu();
void rysujtablice(tablica);
void zeruj(tablica);
void intrukcja();

int main (void){
   int praca=1;//Sterowanie glowną petla programu 1-PRACA 2-ZAKONCZENIE
   int menu=1;
   int wybormenu=NIEAKTYWNY;
   int wyborkoncowy=NIEAKTYWNY;
   int granie=0;//Petla z samym algorytmem gry
   int tryb;
   int testwyboru=0;
   char tablica[9];
   int wyboruzytkownika;
   int wykonane;
   int wyborkomputera;

   while(praca==1){//Główna pętla programu
       zeruj (tablica);
       //MENU
       while(menu==1){
           system("cls");
           funkcjamenu();
           scanf("%d",&wybormenu);
           if(wybormenu==ZWYKLY){
               menu=0;
               granie=1;
               praca=1;
               tryb=ZWYKLY;
               wybormenu=NIEAKTYWNY;
           }
           if(wybormenu==INSTRUKCJA){
               menu=0;
               granie=0;
               tryb=INSTRUKCJA;
               wybormenu=NIEAKTYWNY;
           }
           if(wybormenu==POWROT){
               praca=0;
               granie=0;
               wybormenu=NIEAKTYWNY;
               tryb=NIEAKTYWNY;
           }

       }

       //Pętla gry
       while (granie==1){
           system("cls");

           //WYBÓR POLA PRZEZ UZYTKOWNIKA
           testwyboru=0;
           while((testwyboru==0)&&(granie==1)){
               system("cls");
               rysujtablice (tablica);
               printf("Podaj numer pola do rysowania kolka\nzgodnie z numeracja na klawiaturze numerycznej\ni zatwierdz uzywajac klawisza ENTER\n");
               scanf("%d", &wyboruzytkownika);
               wyboruzytkownika=wyboruzytkownika-1;
               if (tablica[wyboruzytkownika]=='O'){
                   testwyboru=0;
               }else{
                   if (tablica[wyboruzytkownika]=='X'){
                       testwyboru=0;
                   }else{
                       if (tablica[wyboruzytkownika]==' '){
                           tablica[wyboruzytkownika]='O';
                           testwyboru=1;
                       }}}
           }
           system("cls");
           rysujtablice (tablica);
           testwyboru=0;


           //SPRAWDZANIE

           //LOSOWANIE AUTOMATYCZNE
           if(tryb!=DWUOSOBOWY){
               testwyboru=0;
               while((testwyboru==0)&&(granie==1)){
                   wykonane=0;
                   //POZIOME - LINIA1
                   if((((tablica[6]=='X')&&(tablica[7]=='X'))&&(tablica[8]==' '))&&(wykonane==0)){
                       tablica[8]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[6]=='X')&&(tablica[7]==' '))&&(tablica[8]=='X'))&&(wykonane==0)){
                       tablica[7]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[6]==' ')&&(tablica[7]=='X'))&&(tablica[8]=='X'))&&(wykonane==0)){
                       tablica[6]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //POZIOME - LINIA2
                   if((((tablica[3]=='X')&&(tablica[4]=='X'))&&(tablica[5]==' '))&&(wykonane==0)){
                       tablica[5]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[3]=='X')&&(tablica[4]==' '))&&(tablica[5]=='X'))&&(wykonane==0)){
                       tablica[4]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[3]==' ')&&(tablica[4]=='X'))&&(tablica[5]=='X'))&&(wykonane==0)){
                       tablica[3]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //POZIOME - LINIA3
                   if((((tablica[0]=='X')&&(tablica[1]=='X'))&&(tablica[2]==' '))&&(wykonane==0)){
                       tablica[2]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[0]=='X')&&(tablica[1]==' '))&&(tablica[2]=='X'))&&(wykonane==0)){
                       tablica[1]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[0]==' ')&&(tablica[1]=='X'))&&(tablica[2]=='X'))&&(wykonane==0)){
                       tablica[0]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //=============================================================================
                   //PIONOWE - KOLUMNA1
                   if((((tablica[6]=='X')&&(tablica[3]=='X'))&&(tablica[0]==' '))&&(wykonane==0)){
                       tablica[0]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[6]=='X')&&(tablica[3]==' '))&&(tablica[0]=='X'))&&(wykonane==0)){
                       tablica[3]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[6]==' ')&&(tablica[3]=='X'))&&(tablica[0]=='X'))&&(wykonane==0)){
                       tablica[6]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //PIONOWE - KOLUMNA2
                   if((((tablica[7]=='X')&&(tablica[4]=='X'))&&(tablica[1]==' '))&&(wykonane==0)){
                       tablica[1]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[7]=='X')&&(tablica[4]==' '))&&(tablica[1]=='X'))&&(wykonane==0)){
                       tablica[4]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[7]==' ')&&(tablica[4]=='X'))&&(tablica[1]=='X'))&&(wykonane==0)){
                       tablica[7]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //PIONOWE - KOLUMNA3
                   if((((tablica[8]=='X')&&(tablica[5]=='X'))&&(tablica[2]==' '))&&(wykonane==0)){
                       tablica[2]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[8]=='X')&&(tablica[5]==' '))&&(tablica[2]=='X'))&&(wykonane==0)){
                       tablica[5]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[8]==' ')&&(tablica[5]=='X'))&&(tablica[2]=='X'))&&(wykonane==0)){
                       tablica[8]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //=============================================================================
                   //UKOSNE - DOLNA-LEWA => GORNA PRAWA
                   if((((tablica[0]=='X')&&(tablica[4]=='X'))&&(tablica[8]==' '))&&(wykonane==0)){
                       tablica[8]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[0]=='X')&&(tablica[4]==' '))&&(tablica[8]=='X'))&&(wykonane==0)){
                       tablica[4]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[0]==' ')&&(tablica[4]=='X'))&&(tablica[8]=='X'))&&(wykonane==0)){
                       tablica[0]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //=============================================================================
                   //UKOSNE - GORNA-LEWA => DOLNA PRAWA
                   if((((tablica[6]=='X')&&(tablica[4]=='X'))&&(tablica[2]==' '))&&(wykonane==0)){
                       tablica[2]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[6]=='X')&&(tablica[4]==' '))&&(tablica[2]=='X'))&&(wykonane==0)){
                       tablica[4]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[6]==' ')&&(tablica[4]=='X'))&&(tablica[2]=='X'))&&(wykonane==0)){
                       tablica[6]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //=============================================================================
                   //LOSOWE POLA
                   if(wykonane==0){
                       wyborkomputera=(rand()%9);
                       if (tablica[wyborkomputera]=='O'){
                           testwyboru=0;
                           wykonane=0;
                       }else{
                       if (tablica[wyborkomputera]=='X'){
                           testwyboru=0;
                           wykonane=0;
                       }else{
                       if (tablica[wyborkomputera]==' '){
                           tablica[wyborkomputera]='X';
                           testwyboru=1;
                           wykonane=1;
                       }
                       }
                       }}}}}}}}}}}}}}}}}}}}}}}}}}

               }
           testwyboru=0;
           }

           //WYBÓR POLA PRZEZ UZYTKOWNIKA
           if(tryb==DWUOSOBOWY){
               testwyboru=0;
               while((testwyboru==0)&&(granie==1)){
               system("cls");
               rysujtablice (tablica);
               printf("Podaj numer pola do rysowania krzyzyka\nzgodnie z numeracja na klawiaturze numerycznej\ni zatwierdz uzywajac klawisza ENTER\n");
               scanf("%d", &wyboruzytkownika);
               wyboruzytkownika=wyboruzytkownika-1;
               if (tablica[wyboruzytkownika]=='X'){
                   testwyboru=0;
               }else{
                   if (tablica[wyboruzytkownika]=='O'){
                       testwyboru=0;
                   }else{
                       if (tablica[wyboruzytkownika]==' '){
                           tablica[wyboruzytkownika]='X';
                           testwyboru=1;
                       }}}
               }
               system("cls");
               rysujtablice (tablica);
               testwyboru=0;


               }

           //SPRAWDZANIE
       }

       //Wyswietlenie instrukcji obslugi
       while(tryb==INSTRUKCJA){
       system("cls");
       wybormenu=NIEAKTYWNY;
       intrukcja();
       scanf("%d",&wybormenu);
       if (wybormenu==9){
           menu=1;
           praca=1;
           granie=0;
           tryb=NIEAKTYWNY;
       }


       }











   }


}


//FUNKCJE

void funkcjamenu(){
   printf("*****************************************\n");
   printf("    Program do gry w kolko i krzyzyk\n");
   printf("              Wersja V1.2\n");
   printf("                                    \n");
   printf("\n");
   printf("Wpisz numer opcji i nacisnij klawsz ENTER\n");
   printf("                 OPCJE\n");
   printf("1-rozgrywka w zwyklym trybie\n");
   printf("2-rozgrywka w trybie uproszczonym\n");
   printf("3-rozgrywka z opoznionym startem\n");
   printf("4-rozgrywka w trybie dwuosobowym\n");
   printf("9-wyswietlenie instrukcji obslugi\n");
   printf("0-zakonczenie programu\n");

   printf("\n");

}

void rysujtablice(char *tablica){
printf("+-+-+-+\n");
printf("|%c|%c|%c|\n",tablica[6],tablica[7],tablica[8]);
printf("+-+-+-+\n");
printf("|%c|%c|%c|\n",tablica[3],tablica[4],tablica[5]);
printf("+-+-+-+\n");
printf("|%c|%c|%c|\n",tablica[0],tablica[1],tablica[2]);
printf("+-+-+-+\n");
}

void zeruj(char *tablica){
   int licznik;
   licznik=0;
   while(licznik<9){
       tablica[licznik]=' ';
       licznik=licznik+1;

   }

}

void intrukcja(){
   printf("*****************************************\n");
   printf("            INSTRUKCJA OBSLUGI\n");
   printf("*****************************************\n");
   printf("    Program do gry w kolko i krzyzyk\n");
   printf("\n");
   printf("TEKST INSTRUKCJI\n");
   printf("\n");
   printf("nacisnij klawisz 9 i zatwierdz klawiszem\n");
   printf("ENTER, aby powrocic do glownego MENU\n");

}

 

PS. Tak, będzie tryb dwuosobowy.

Edytowane przez Pecet256

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Co sądzicie?

Wygląda jakbyś konsekwentnie ignorował chyba wszystkie porady dotyczące sensownego dzielenia kodu i stylu, dzięki któremu nie będziesz sobie strzelać w stopę :thumbdown:

 

W poprzedniej wersji przynajmniej próbowałeś jakoś rozbić całość na funkcje, teraz robisz makaron z prawie wszystkim w mainie. Dlaczego? :kwasny:

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

jak już nie chcesz użąć debuggera to dodaj co nieco kodu debugowego żeby było wiadomo w jakie bloki wchodzi program

 

' date='30 Maj 2020 - 08:38' timestamp='1590824285' post='15923958']

Swoją drogą ciut niewygodny mi się wydaje ten debugger ale to pewnie przyzwyczajenia z konsolowego gdb.

"treser pingwina"? (uczysz pingwina nowych sztuczek?)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ludzie...

 

Przecież brakuje tylko funkcji sprawdzania czy ktoś wygrał i czy tablica nie jest przepełniona...

Zamierzam te funkcje napisać od zera.

To co było wcześniej w funkcjach nadal w nich jest.

 

Ps. Jak Waszym zdaniem najlepiej zrobić to sprawdzanie czy ktoś wygrł/czy tablica nie jest przepełniona?

 

Ps. A jak ze stylem? Starałem się lepiej zaznaczyć pętle.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Na Twoim miejscu zrobiłbym od tego jedną funkcję, zwracającą informację czy ktoś wygrał, a jak nie, to jaki jest stan rozgrywki. Te stany wykluczają się wzajemnie, dlatego jest sens to posiadać w jednej funkcji.

Z grubsza coś takiego (jeżeli nie chcesz pisać kodu po angielsku):

typedef enum
{
   WYGRAL_A,
   WYGRAL_B,
   REMIS,
   WCIAZ_TRWA
} WynikGry;

WynikGry sprawdzWynik(/* jakkolwiek przekazujesz planszę */);

 

Najpierw zaimplementuj ją by działała, dopiero potem usprawniaj. Przy grze 3x3 manualne traktowanie każdego przypadku nie jest zbrodnią.

Nie musisz przyrównywać do stałej, zawsze możesz porównać wartości ze sobą:

if ( plansza[0]!=' ' && plansza[0]==plansza[1] && plansza[0]==plansza[2] )

Po wejściu do takiego warunku już wiesz, że któryś gracz wygrał. W jaki sposób na podstawie wartości na planszy dojdziesz który to gracz - droga wolna. Można powiązać wartość enuma WYGRAL_A z wartością identyfikatora gracza, zrobić funkcję dostarczającą tą informację...

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Czyli mam utworzyć zmienną zawierającą informacje o bieżącym stanie gry.

Może być enum'em jak wyżej ^

albo int/char i wartości:

0 - rozgrywka trwa

1 - wygrał gracz 1

2 - wygrał gracz 2

3 - remis/przepełnienie

 

????

 

Może najlepiej zrobić tak, aby funkcja pierw sprawdzała przepełnienie, a potem czy ktoś wygrał?

Jak najlepiej zrobić kod sprawdzania, czy są takie same znaki?

Edytowane przez Pecet256

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Po co bawić się w przeszukiwanie tablicy i sprawdzać czy nastąpiło przepełnienie (cokolwiek ono znaczy)? Przecież wiesz jaki rozmiar ma plansza i ile ruchów można wykonać, więc można zrobić po prostu licznik.

 

Co ci da sprawdzenie zapełnienia planszy po wykonaniu ruchu? Przecież przed sprawdzeniem wygranej nie ma na nic żadnego wpływu. Zapełnienie planszy nie rozstrzyga o wygranej, dopiero z informacją o braku rozstrzygnięcia można wnioskować o remisie.

 

Jak najlepiej zrobić kod sprawdzania, czy są takie same znaki?

Wyżej masz przykład.

Generalnie musisz porównać ze sobą odpowiednie elementy tablicy. Dla przykładu jak masz 3 zmienne a, b, c, to np. trzeba sprawdzić czy a==b i b==c.

Kłania się reguła/prawo przechodniości z rachunku logicznego. Jak nie miałeś to warto liznąć podstaw, będzie łatwiej składać warunki, częściowo zazębia się z algebrą Boola: https://pl.wikipedia.org/wiki/Prawa_rachunku_zda%C5%84

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Trochę poprawiłem.

Po wybraniu ponownej gry nie ma już pętli nieskończonej.

Teraz nie chcą się wyświetlać komunikatu, kto wygrał.

Innym, poważniejszym problemem jest to, że program wpada w pętlę nieskończoną, gdy użytkownik wybierze opcję powrotu do menu, i dopiero z menu wybierze opcję nowej rozgrywki.

 

Nadal nie zrobiłem trybu dwuosobowego.

 

Wrzucam kod <uwaga> - długi. Pomożecie?

 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//WYBORY
#define NIEAKTYWNY 8
#define ZWYKLY 1
#define UPROSZCZONY 2
#define POZNYSTART 3
#define DWUOSOBOWY 4
#define INSTRUKCJA 9
#define POWROT 0
#define KONCOWKA 7

//Urzytkownik gra kolkami (O), program zas krzyzykami (X)
//
//WERSCJA V2.0
//09.06.2020


//FUNKCJE
void funkcjamenu();
void rysujtablice(tablica);
void zeruj(tablica);
void intrukcja();
int testowanie(tablica);
void koncowka1();
void koncowka2();

int main (void){
   int praca=1;//Sterowanie glowną petla programu 1-PRACA 2-ZAKONCZENIE
   int menu=1;
   int wybormenu=NIEAKTYWNY;
   int wyborkoncowy=NIEAKTYWNY;
   int granie=0;//Petla z samym algorytmem gry
   int tryb;
   int testwyboru=0;
   char tablica[9];
   int wyboruzytkownika;
   int wykonane;
   int wyborkomputera;
   int wynik_testu=0;//0-rozgrywka trwa, 1-wygral gracz 1, 2-wygral komputer/gracz2, 3-remis/przepelnienie planszy
   int pomijanie=0;
   int poptryb;

   while(praca==1){//Główna pętla programu
       zeruj (tablica);
       //MENU
       while(menu==1){
           system("cls");
           funkcjamenu();
           scanf("%d",&wybormenu);
           if(wybormenu==ZWYKLY){
               menu=0;
               granie=1;
               praca=1;
               tryb=ZWYKLY;
               wybormenu=NIEAKTYWNY;
           }
           if(wybormenu==INSTRUKCJA){
               menu=0;
               granie=0;
               tryb=INSTRUKCJA;
               wybormenu=NIEAKTYWNY;
           }
           if(wybormenu==POWROT){
               praca=0;
               granie=0;
               wybormenu=NIEAKTYWNY;
               tryb=NIEAKTYWNY;
           }

       }

       //Pętla gry
       while (granie==1){
           system("cls");

           //WYBÓR POLA PRZEZ UZYTKOWNIKA
           if (pomijanie==0){
           testwyboru=0;
           while((testwyboru==0)&&(granie==1)){
               system("cls");
               rysujtablice (tablica);
               printf("Podaj numer pola do rysowania kolka\nzgodnie z numeracja na klawiaturze numerycznej\ni zatwierdz uzywajac klawisza ENTER\n");
               scanf("%d", &wyboruzytkownika);
               wyboruzytkownika=wyboruzytkownika-1;
               if (tablica[wyboruzytkownika]=='O'){
                   testwyboru=0;
               }else{
                   if (tablica[wyboruzytkownika]=='X'){
                       testwyboru=0;
                   }else{
                       if (tablica[wyboruzytkownika]==' '){
                           tablica[wyboruzytkownika]='O';
                           testwyboru=1;
                       }}}
           }
           system("cls");
           rysujtablice (tablica);
           testwyboru=0;
           }

           //SPRAWDZANIE
           wynik_testu=testowanie(tablica);
           if (wynik_testu!=0){
               pomijanie=1;
               poptryb=tryb;
               tryb=KONCOWKA;
               granie=0;
           }

           //LOSOWANIE AUTOMATYCZNE
           if (pomijanie==0){
           if(tryb!=DWUOSOBOWY){
               testwyboru=0;
               while((testwyboru==0)&&(granie==1)){
                   wykonane=0;
                   //POZIOME - LINIA1
                   if((((tablica[6]=='X')&&(tablica[7]=='X'))&&(tablica[8]==' '))&&(wykonane==0)){
                       tablica[8]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[6]=='X')&&(tablica[7]==' '))&&(tablica[8]=='X'))&&(wykonane==0)){
                       tablica[7]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[6]==' ')&&(tablica[7]=='X'))&&(tablica[8]=='X'))&&(wykonane==0)){
                       tablica[6]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //POZIOME - LINIA2
                   if((((tablica[3]=='X')&&(tablica[4]=='X'))&&(tablica[5]==' '))&&(wykonane==0)){
                       tablica[5]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[3]=='X')&&(tablica[4]==' '))&&(tablica[5]=='X'))&&(wykonane==0)){
                       tablica[4]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[3]==' ')&&(tablica[4]=='X'))&&(tablica[5]=='X'))&&(wykonane==0)){
                       tablica[3]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //POZIOME - LINIA3
                   if((((tablica[0]=='X')&&(tablica[1]=='X'))&&(tablica[2]==' '))&&(wykonane==0)){
                       tablica[2]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[0]=='X')&&(tablica[1]==' '))&&(tablica[2]=='X'))&&(wykonane==0)){
                       tablica[1]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[0]==' ')&&(tablica[1]=='X'))&&(tablica[2]=='X'))&&(wykonane==0)){
                       tablica[0]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //=============================================================================
                   //PIONOWE - KOLUMNA1
                   if((((tablica[6]=='X')&&(tablica[3]=='X'))&&(tablica[0]==' '))&&(wykonane==0)){
                       tablica[0]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[6]=='X')&&(tablica[3]==' '))&&(tablica[0]=='X'))&&(wykonane==0)){
                       tablica[3]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[6]==' ')&&(tablica[3]=='X'))&&(tablica[0]=='X'))&&(wykonane==0)){
                       tablica[6]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //PIONOWE - KOLUMNA2
                   if((((tablica[7]=='X')&&(tablica[4]=='X'))&&(tablica[1]==' '))&&(wykonane==0)){
                       tablica[1]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[7]=='X')&&(tablica[4]==' '))&&(tablica[1]=='X'))&&(wykonane==0)){
                       tablica[4]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[7]==' ')&&(tablica[4]=='X'))&&(tablica[1]=='X'))&&(wykonane==0)){
                       tablica[7]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //PIONOWE - KOLUMNA3
                   if((((tablica[8]=='X')&&(tablica[5]=='X'))&&(tablica[2]==' '))&&(wykonane==0)){
                       tablica[2]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[8]=='X')&&(tablica[5]==' '))&&(tablica[2]=='X'))&&(wykonane==0)){
                       tablica[5]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[8]==' ')&&(tablica[5]=='X'))&&(tablica[2]=='X'))&&(wykonane==0)){
                       tablica[8]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //=============================================================================
                   //UKOSNE - DOLNA-LEWA => GORNA PRAWA
                   if((((tablica[0]=='X')&&(tablica[4]=='X'))&&(tablica[8]==' '))&&(wykonane==0)){
                       tablica[8]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[0]=='X')&&(tablica[4]==' '))&&(tablica[8]=='X'))&&(wykonane==0)){
                       tablica[4]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[0]==' ')&&(tablica[4]=='X'))&&(tablica[8]=='X'))&&(wykonane==0)){
                       tablica[0]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //=============================================================================
                   //UKOSNE - GORNA-LEWA => DOLNA PRAWA
                   if((((tablica[6]=='X')&&(tablica[4]=='X'))&&(tablica[2]==' '))&&(wykonane==0)){
                       tablica[2]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[6]=='X')&&(tablica[4]==' '))&&(tablica[2]=='X'))&&(wykonane==0)){
                       tablica[4]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if((((tablica[6]==' ')&&(tablica[4]=='X'))&&(tablica[2]=='X'))&&(wykonane==0)){
                       tablica[6]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //=============================================================================
                   //LOSOWE POLA
                   if(wykonane==0){
                       wyborkomputera=(rand()%9);
                       if (tablica[wyborkomputera]=='O'){
                           testwyboru=0;
                           wykonane=0;
                       }else{
                       if (tablica[wyborkomputera]=='X'){
                           testwyboru=0;
                           wykonane=0;
                       }else{
                       if (tablica[wyborkomputera]==' '){
                           tablica[wyborkomputera]='X';
                           testwyboru=1;
                           wykonane=1;
                       }
                       }
                       }}}}}}}}}}}}}}}}}}}}}}}}}}

               }
           testwyboru=0;
           }}

           //WYBÓR POLA PRZEZ UZYTKOWNIKA
           if (pomijanie==0){
           if(tryb==DWUOSOBOWY){
               testwyboru=0;
               while((testwyboru==0)&&(granie==1)){
               system("cls");
               rysujtablice (tablica);
               printf("Podaj numer pola do rysowania krzyzyka\nzgodnie z numeracja na klawiaturze numerycznej\ni zatwierdz uzywajac klawisza ENTER\n");
               scanf("%d", &wyboruzytkownika);
               wyboruzytkownika=wyboruzytkownika-1;
               if (tablica[wyboruzytkownika]=='X'){
                   testwyboru=0;
               }else{
                   if (tablica[wyboruzytkownika]=='O'){
                       testwyboru=0;
                   }else{
                       if (tablica[wyboruzytkownika]==' '){
                           tablica[wyboruzytkownika]='X';
                           testwyboru=1;
                       }}}
               }
               system("cls");
               rysujtablice (tablica);
               testwyboru=0;


               }
               }
           if (pomijanie==0){
           //SPRAWDZANIE
           wynik_testu=testowanie(tablica);
           if (wynik_testu!=0){
               pomijanie=1;
               poptryb=tryb;
               tryb=KONCOWKA;
               granie=0;
           }
           }
           wynik_testu=0;
       }




       //Wyswietlenie instrukcji obslugi
       while(tryb==INSTRUKCJA){
       system("cls");
       wybormenu=NIEAKTYWNY;
       intrukcja();
       scanf("%d",&wybormenu);
       if (wybormenu==9){
           menu=1;
           praca=1;
           granie=0;
           tryb=NIEAKTYWNY;
       }


       }
       //Menu koncowe
       if(tryb==KONCOWKA){
           //system("cls");
           koncowka1();
           if (wynik_testu==1){
               if (tryb==DWUOSOBOWY){
                   printf("Wygral gracz 1\n");
                   printf("\n");
               }else{
                   printf("Wygral uzytkownik \n");
                   printf("\n");
               }
           }
           if (wynik_testu==2){
               if (tryb==DWUOSOBOWY){
                   printf("Wygral gracz 2\n");
                   printf("\n");
               }else{
                   printf("Wygral komputer \n");
                   printf("\n");
               }
           }
           if (wynik_testu==3){
                   printf("REMIS - NASTAPELO PRZEPELNIENIE PLANSZY\n");
                   printf("UNIEMOZLIWIAJACE ROZSTRYGNIECIE WYNIKU\n");

           }
           koncowka2();
           scanf("%d",&wybormenu);
           if(wybormenu==0){
               menu=1;
               wynik_testu=0;
               granie=0;
               testwyboru=0;
               tryb=NIEAKTYWNY;
               wybormenu=NIEAKTYWNY;
           }
           if(wybormenu==1){
               menu=0;
               zeruj (tablica);
               granie=1;
               wynik_testu=0;
               pomijanie=0;
               tryb=poptryb;
               wybormenu=NIEAKTYWNY;
           }
           if(wybormenu==9){
               menu=0;
               granie=0;
               praca=0;
               tryb=NIEAKTYWNY;
               wybormenu=NIEAKTYWNY;
           }
       }









   }

return 0;
}


//FUNKCJE

void funkcjamenu(){
   printf("*****************************************\n");
   printf("    Program do gry w kolko i krzyzyk\n");
   printf("              Wersja V2.0\n");
   printf("                                    \n");
   printf("\n");
   printf("Wpisz numer opcji i nacisnij klawsz ENTER\n");
   printf("                 OPCJE\n");
   printf("1-rozgrywka w zwyklym trybie\n");
   printf("2-rozgrywka w trybie uproszczonym\n");
   printf("3-rozgrywka z opoznionym startem\n");
   printf("4-rozgrywka w trybie dwuosobowym\n");
   printf("9-wyswietlenie instrukcji obslugi\n");
   printf("0-zakonczenie programu\n");

   printf("\n");

}

void rysujtablice(char *tablica){
printf("+-+-+-+\n");
printf("|%c|%c|%c|\n",tablica[6],tablica[7],tablica[8]);
printf("+-+-+-+\n");
printf("|%c|%c|%c|\n",tablica[3],tablica[4],tablica[5]);
printf("+-+-+-+\n");
printf("|%c|%c|%c|\n",tablica[0],tablica[1],tablica[2]);
printf("+-+-+-+\n");
}

void zeruj(char *tablica){
   int licznik;
   licznik=0;
   while(licznik<9){
       tablica[licznik]=' ';
       licznik=licznik+1;

   }

}

void intrukcja(){
   printf("*****************************************\n");
   printf("            INSTRUKCJA OBSLUGI\n");
   printf("*****************************************\n");
   printf("    Program do gry w kolko i krzyzyk\n");
   printf("\n");
   printf("TEKST INSTRUKCJI\n");
   printf("\n");
   printf("nacisnij klawisz 9 i zatwierdz klawiszem\n");
   printf("ENTER, aby powrocic do glownego MENU\n");

}

int testowanie(char *tablica){
   int wynik_testu=0;
   char wygrana;
   int licznik=0;
   int zajete_pola=0;
   //KONTROLA PRZEPELNIENIA <= WYLACZONA
   //while(licznik<9){
   //    if (tablica[licznik]!=' '){
   //        zajete_pola=zajete_pola+1;
   //    }
   //    licznik=licznik+1;
   //}
   //if(zajete_pola==9){
   //    wynik_testu=3;
   //}




   //POZIOME
         if ( tablica[0]!=' ' && tablica[0]==tablica[1] && tablica[0]==tablica[2] ){
           wygrana=tablica[0];
   }else if ( tablica[3]!=' ' && tablica[3]==tablica[4] && tablica[3]==tablica[5] ){
       wygrana=tablica[3];
   }else if ( tablica[6]!=' ' && tablica[6]==tablica[7] && tablica[6]==tablica[8] ){
       wygrana=tablica[6];

   //PIONOWE
   }else if ( tablica[6]!=' ' && tablica[6]==tablica[3] && tablica[6]==tablica[0] ){
       wygrana=tablica[6];
   }else if ( tablica[7]!=' ' && tablica[7]==tablica[4] && tablica[7]==tablica[1] ){
       wygrana=tablica[7];
   }else if ( tablica[8]!=' ' && tablica[8]==tablica[5] && tablica[8]==tablica[2] ){
       wygrana=tablica[8];

   //UKOSNE
   }else if ( tablica[6]!=' ' && tablica[6]==tablica[4] && tablica[6]==tablica[2] ){
       wygrana=tablica[6];
   }else if ( tablica[8]!=' ' && tablica[8]==tablica[4] && tablica[8]==tablica[0] ){
       wygrana=tablica[8];
   }






        if (wygrana=='O'){
       wynik_testu=1;
   }
   else if (wygrana=='X'){
       wynik_testu=2;
   }


   return wynik_testu;
}

void koncowka1(){
   printf("*****************************************\n");
   printf("                KONIEC GRY\n");
   printf("*****************************************\n");


}

void koncowka2(){
   printf("Wpisz numer opcji i nacisnij klawsz ENTER\n");
   printf("                 OPCJE\n");
   printf("0-Powrot do menu programu\n");
   printf("1-Rozpoczecie kolejnej rundy\n");
   printf("9-Zakonczenie pracy programu\n");
}

Edytowane przez Pecet256

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Na początek proponuję poprawnie zadeklarować funkcje. Zobacz jakie ostrzeżenia wypisuje kompilator, jak nie ma żadnych, to dodaj flagę -Wall

 

1. W głównym menu nie da się wyjść z programu. Nie zmieniasz wartości dla zmiennej 'menu', ani nie podejmujesz innych działań, więc pętla cały czas działa.

2. Program wisi, bo zostawiasz zmienną 'pomijanie' z wartością 1. Czyli pętla 'granie' ciągle chodzi ale żaden warunek pomijanie==0 nie jest spełniony.

3. Nie wyświetla kto wygrywa, bo na koniec pętli 'granie' zerujesz wynik sprawdzenia.

4. Przy wygranej komputera nie rysuje planszy.

 

 

Ciągle za dużo dziwnych zmiennych sterujących przebiegiem programu, więc łatwo się pogubić co, gdzie i kiedy się dzieje.

Edytowane przez Bono[UG]

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Wrzucam poprawioną (finalną ?) wersję kodu.

 

Nie znalazłem błędów.

Przy kompilacji w code:blocks nie ma errorów, są tylko 3 warningi - parameter names without tags.

Ale program działa bez problemu.

Gdyby ktoś chciał kompilować na Linuksie/Uniksie to musiałby zmienić sposób czyszczenia ekranu bo program wykorzystuje Windowsowe system("cls");.

 

Oto kod.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//WYBORY
#define NIEAKTYWNY 8
#define ZWYKLY 1
#define UPROSZCZONY 2
#define POZNYSTART 3
#define DWUOSOBOWY 4
#define INSTRUKCJA 9
#define POWROT 0
#define KONCOWKA 7

//Urzytkownik gra kolkami (O), program zas krzyzykami (X)
//
//WERSCJA V2.2
//18.06.2020


//FUNKCJE
void funkcjamenu();
void rysujtablice(tablica);
void zeruj(tablica);
void intrukcja();
int testowanie(tablica);
void koncowka1();
void koncowka2();

int main (void){
   int praca=1;//Sterowanie glowną petla programu 1-PRACA 0-ZAKONCZENIE
   int menu=1;
   int wybormenu=NIEAKTYWNY;
   int wyborkoncowy=NIEAKTYWNY;
   int granie=0;//Petla z samym algorytmem gry
   int tryb;
   int testwyboru=0;
   char tablica[9];
   int wyboruzytkownika;
   int wykonane;
   int wyborkomputera;
   int wynik_testu=0;//0-rozgrywka trwa, 1-wygral gracz 1, 2-wygral komputer/gracz2, 3-remis/przepelnienie planszy
   int pomijanie=0;
   int poptryb=NIEAKTYWNY;
   int licznikiteracji;

   while(praca==1){//Główna pętla programu
       zeruj (tablica);
       licznikiteracji=0;
       //MENU
       while(menu==1){
           system("cls");
           funkcjamenu();
           scanf("%d",&wybormenu);
           if(wybormenu==ZWYKLY){
               menu=0;
               granie=1;
               praca=1;
               tryb=ZWYKLY;
               wybormenu=NIEAKTYWNY;
           }
           if(wybormenu==UPROSZCZONY){
               menu=0;
               granie=1;
               praca=1;
               tryb=UPROSZCZONY;
               wybormenu=NIEAKTYWNY;
           }
           if(wybormenu==INSTRUKCJA){
               menu=0;
               granie=0;
               tryb=INSTRUKCJA;
               wybormenu=NIEAKTYWNY;
           }
           if(wybormenu==DWUOSOBOWY){
               menu=0;
               granie=1;
               praca=1;
               tryb=DWUOSOBOWY;
               wybormenu=NIEAKTYWNY;
           }
           if(wybormenu==POZNYSTART){
               menu=0;
               granie=1;
               praca=1;
               tryb=POZNYSTART;
               wybormenu=NIEAKTYWNY;
           }
           if(wybormenu==POWROT){
               praca=0;
               granie=0;
               menu=0;
               wybormenu=NIEAKTYWNY;
               tryb=NIEAKTYWNY;
           }

       }

       //Pętla gry
       while (granie==1){
           wynik_testu=0;
           system("cls");
           if ((tryb==POZNYSTART)&&(licznikiteracji==0)){
               pomijanie=1;
           }

           //WYBÓR POLA PRZEZ UZYTKOWNIKA
           if (pomijanie==0){
           testwyboru=0;
           while((testwyboru==0)&&(granie==1)){
               system("cls");
               if (tryb!=DWUOSOBOWY){
                   printf("*****************************************\n");
               }
               if (tryb==DWUOSOBOWY){
                   printf("********** GRACZ NR.1 - SYMBOL O ********\n");
               }
               rysujtablice (tablica);
               printf("*****************************************\n");
               printf("Podaj numer pola do rysowania kolka\nzgodnie z numeracja na klawiaturze numerycznej\ni zatwierdz uzywajac klawisza ENTER\n");
               scanf("%d", &wyboruzytkownika);
               wyboruzytkownika=wyboruzytkownika-1;
               if (tablica[wyboruzytkownika]=='O'){
                   testwyboru=0;
               }else{
                   if (tablica[wyboruzytkownika]=='X'){
                       testwyboru=0;
                   }else{
                       if (tablica[wyboruzytkownika]==' '){
                           tablica[wyboruzytkownika]='O';
                           testwyboru=1;
                       }}}
           }
           system("cls");
           rysujtablice (tablica);
           testwyboru=0;
           }

           //SPRAWDZANIE
           wynik_testu=testowanie(tablica);
           if (wynik_testu!=0){
               pomijanie=1;
               poptryb=tryb;
               tryb=KONCOWKA;
               granie=0;
           }
           if ((tryb==POZNYSTART)&&(licznikiteracji==0)){
               pomijanie=0;
           }

           //LOSOWANIE AUTOMATYCZNE
           if (pomijanie==0){
           if(tryb!=DWUOSOBOWY){
               testwyboru=0;
               while((testwyboru==0)&&(granie==1)){
                   wykonane=0;
                   //POZIOME - LINIA1
                   if(((((tablica[6]=='X')&&(tablica[7]=='X'))&&(tablica[8]==' '))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[8]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[6]=='X')&&(tablica[7]==' '))&&(tablica[8]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[7]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[6]==' ')&&(tablica[7]=='X'))&&(tablica[8]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[6]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //POZIOME - LINIA2
                   if(((((tablica[3]=='X')&&(tablica[4]=='X'))&&(tablica[5]==' '))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[5]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[3]=='X')&&(tablica[4]==' '))&&(tablica[5]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[4]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[3]==' ')&&(tablica[4]=='X'))&&(tablica[5]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[3]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //POZIOME - LINIA3
                   if(((((tablica[0]=='X')&&(tablica[1]=='X'))&&(tablica[2]==' '))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[2]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[0]=='X')&&(tablica[1]==' '))&&(tablica[2]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[1]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[0]==' ')&&(tablica[1]=='X'))&&(tablica[2]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[0]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //=============================================================================
                   //PIONOWE - KOLUMNA1
                   if(((((tablica[6]=='X')&&(tablica[3]=='X'))&&(tablica[0]==' '))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[0]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[6]=='X')&&(tablica[3]==' '))&&(tablica[0]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[3]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[6]==' ')&&(tablica[3]=='X'))&&(tablica[0]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[6]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //PIONOWE - KOLUMNA2
                   if(((((tablica[7]=='X')&&(tablica[4]=='X'))&&(tablica[1]==' '))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[1]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[7]=='X')&&(tablica[4]==' '))&&(tablica[1]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[4]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[7]==' ')&&(tablica[4]=='X'))&&(tablica[1]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[7]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //PIONOWE - KOLUMNA3
                   if(((((tablica[8]=='X')&&(tablica[5]=='X'))&&(tablica[2]==' '))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[2]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[8]=='X')&&(tablica[5]==' '))&&(tablica[2]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[5]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[8]==' ')&&(tablica[5]=='X'))&&(tablica[2]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[8]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //=============================================================================
                   //UKOSNE - DOLNA-LEWA => GORNA PRAWA
                   if(((((tablica[0]=='X')&&(tablica[4]=='X'))&&(tablica[8]==' '))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[8]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[0]=='X')&&(tablica[4]==' '))&&(tablica[8]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[4]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[0]==' ')&&(tablica[4]=='X'))&&(tablica[8]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[0]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //=============================================================================
                   //UKOSNE - GORNA-LEWA => DOLNA PRAWA
                   if(((((tablica[6]=='X')&&(tablica[4]=='X'))&&(tablica[2]==' '))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[2]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[6]=='X')&&(tablica[4]==' '))&&(tablica[2]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[4]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   if(((((tablica[6]==' ')&&(tablica[4]=='X'))&&(tablica[2]=='X'))&&(wykonane==0))&&(tryb!=UPROSZCZONY)){
                       tablica[6]='X';
                       wykonane=1;
                       testwyboru=1;
                   }else{
                   //=============================================================================
                   //LOSOWE POLA
                   if(wykonane==0){
                       wyborkomputera=(rand()%9);
                       if (tablica[wyborkomputera]=='O'){
                           testwyboru=0;
                           wykonane=0;
                       }else{
                       if (tablica[wyborkomputera]=='X'){
                           testwyboru=0;
                           wykonane=0;
                       }else{
                       if (tablica[wyborkomputera]==' '){
                           tablica[wyborkomputera]='X';
                           testwyboru=1;
                           wykonane=1;
                       }
                       }
                       }}}}}}}}}}}}}}}}}}}}}}}}}}

               }
           testwyboru=0;
           }}

           //WYBÓR POLA PRZEZ UZYTKOWNIKA
           if (pomijanie==0){
           if(tryb==DWUOSOBOWY){
               testwyboru=0;
               while((testwyboru==0)&&(granie==1)){
               system("cls");
               printf("********** GRACZ NR.2 - SYMBOL X ********\n");
               rysujtablice (tablica);
               printf("*****************************************\n");
               printf("Podaj numer pola do rysowania krzyzyka\nzgodnie z numeracja na klawiaturze numerycznej\ni zatwierdz uzywajac klawisza ENTER\n");
               scanf("%d", &wyboruzytkownika);
               wyboruzytkownika=wyboruzytkownika-1;
               if (tablica[wyboruzytkownika]=='X'){
                   testwyboru=0;
               }else{
                   if (tablica[wyboruzytkownika]=='O'){
                       testwyboru=0;
                   }else{
                       if (tablica[wyboruzytkownika]==' '){
                           tablica[wyboruzytkownika]='X';
                           testwyboru=1;
                       }}}
               }
               system("cls");
               rysujtablice (tablica);
               testwyboru=0;


               }
               }
           if (pomijanie==0){
           //SPRAWDZANIE
           wynik_testu=testowanie(tablica);
           if (wynik_testu!=0){
               pomijanie=1;
               poptryb=tryb;
               tryb=KONCOWKA;
               granie=0;
           }
           }
           //wynik_testu=0;
           licznikiteracji=licznikiteracji+1;
       }




       //Wyswietlenie instrukcji obslugi
       while(tryb==INSTRUKCJA){
       system("cls");
       wybormenu=NIEAKTYWNY;
       intrukcja();
       scanf("%d",&wybormenu);
       if (wybormenu==9){
           menu=1;
           praca=1;
           granie=0;
           tryb=NIEAKTYWNY;
       }


       }
       //Menu koncowe
       if(tryb==KONCOWKA){
           system("cls");
           printf("*****************************************\n");
           rysujtablice (tablica);
           koncowka1();
           if (wynik_testu==1){
               if (poptryb==DWUOSOBOWY){
                   printf("Wygral gracz 1\n");
                   printf("\n");
               }else{
                   printf("Wygral uzytkownik \n");
                   printf("\n");
               }
           }
           if (wynik_testu==2){
               if (poptryb==DWUOSOBOWY){
                   printf("Wygral gracz 2\n");
                   printf("\n");
               }else{
                   printf("Wygral komputer \n");
                   printf("\n");
               }
           }
           if (wynik_testu==3){
                   printf("REMIS - NASTAPELO PRZEPELNIENIE PLANSZY\n");
                   printf("UNIEMOZLIWIAJACE ROZSTRYGNIECIE WYNIKU\n");

           }
           koncowka2();
           scanf("%d",&wybormenu);
           if(wybormenu==0){
               menu=1;
               wynik_testu=0;
               granie=0;
               testwyboru=0;
               pomijanie=0;
               tryb=NIEAKTYWNY;
               wybormenu=NIEAKTYWNY;
           }
           if(wybormenu==1){
               menu=0;
               zeruj (tablica);
               granie=1;
               wynik_testu=0;
               pomijanie=0;
               tryb=poptryb;
               wybormenu=NIEAKTYWNY;
           }
           if(wybormenu==9){
               menu=0;
               granie=0;
               praca=0;
               pomijanie=0;
               tryb=NIEAKTYWNY;
               wybormenu=NIEAKTYWNY;
           }
       }









   }

return 0;
}


//FUNKCJE

void funkcjamenu(){
   printf("*****************************************\n");
   printf("    Program do gry w kolko i krzyzyk\n");
   printf("**************Wersja V2.2****************\n");
   printf("                                    \n");
   printf("\n");
   printf("Wpisz numer opcji i nacisnij klawsz ENTER\n");
   printf("                 OPCJE\n");
   printf("1-rozgrywka w zwyklym trybie\n");
   printf("2-rozgrywka w trybie uproszczonym\n");
   printf("3-rozgrywka z opoznionym startem\n");
   printf("4-rozgrywka w trybie dwuosobowym\n");
   printf("9-wyswietlenie instrukcji obslugi\n");
   printf("0-zakonczenie programu\n");

   printf("\n");

}

void rysujtablice(char *tablica){
printf("+-+-+-+\n");
printf("|%c|%c|%c|\n",tablica[6],tablica[7],tablica[8]);
printf("+-+-+-+\n");
printf("|%c|%c|%c|\n",tablica[3],tablica[4],tablica[5]);
printf("+-+-+-+\n");
printf("|%c|%c|%c|\n",tablica[0],tablica[1],tablica[2]);
printf("+-+-+-+\n");
}

void zeruj(char *tablica){
   int licznik;
   licznik=0;
   while(licznik<9){
       tablica[licznik]=' ';
       licznik=licznik+1;

   }

}

void intrukcja(){
   printf("*****************************************\n");
   printf("            INSTRUKCJA OBSLUGI\n");
   printf("*****************************************\n");
   printf("    Program do gry w kolko i krzyzyk\n");
   printf("\n");
   printf("W trybach jednoosobowych uzytkownik gra\n");
   printf("symbolami kolek (O), a program symbolani\n");
   printf("krzyzykow (X)\n");
   printf("\n");
   printf("W trybie dwuosobowym gracz zaczynajcy \n");
   printf("rozgrywke uzywa symbolu kolka (O)\n");
   printf("Drugi zas symbolu krzyzyka (X)\n");
   printf("\n");
   printf("W trybach jednoosobowych zaczyna gracz,\n");
   printf("Za wyjatkiem trybu z opuzionym startem\n");
   printf("\n");
   printf("Wybor pola nastepuje poprzez \n");
   printf("Wprowadzenie liczby z klaw. numerycznej\n");
   printf("(funkcja NUM LOCK klawiatury musi byc\n");
   printf("wlaczona) i zatwierdzenie klawiszem \n");
   printf("ENTER\n");
   printf("\n");
   printf("Pola numerowane sa tak, jak klawisze\n");
   printf("na klawiaturze numerycznej\n");
   printf("\n");
   printf("Schemat numeracji pol gry\n");//To jest numeracja w sterowaniu programem
   printf("+-+-+-+\n");//Numeryy identyfikacyjne w tablicy sa zawsze o 1 mniejsze od numeru wpisywanej liczby
   printf("|7|8|9|\n");
   printf("+-+-+-+\n");
   printf("|4|5|6|\n");
   printf("+-+-+-+\n");
   printf("|1|2|3|\n");
   printf("+-+-+-+\n");
   printf("\n");
   printf("nacisnij klawisz 9 i zatwierdz klawiszem\n");
   printf("ENTER, aby powrocic do glownego MENU\n");

}

int testowanie(char *tablica){
   int wynik_testu=0;
   char wygrana;
   int licznik=0;
   int zajete_pola=0;
   //KONTROLA PRZEPELNIENIA <= WYLACZONA
   while(licznik<9){
       if (tablica[licznik]!=' '){
           zajete_pola=zajete_pola+1;
       }
       licznik=licznik+1;
   }
   if(zajete_pola==9){
       wynik_testu=3;
   }




   //POZIOME
         if ( tablica[0]!=' ' && tablica[0]==tablica[1] && tablica[0]==tablica[2] ){
           wygrana=tablica[0];
   }else if ( tablica[3]!=' ' && tablica[3]==tablica[4] && tablica[3]==tablica[5] ){
       wygrana=tablica[3];
   }else if ( tablica[6]!=' ' && tablica[6]==tablica[7] && tablica[6]==tablica[8] ){
       wygrana=tablica[6];

   //PIONOWE
   }else if ( tablica[6]!=' ' && tablica[6]==tablica[3] && tablica[6]==tablica[0] ){
       wygrana=tablica[6];
   }else if ( tablica[7]!=' ' && tablica[7]==tablica[4] && tablica[7]==tablica[1] ){
       wygrana=tablica[7];
   }else if ( tablica[8]!=' ' && tablica[8]==tablica[5] && tablica[8]==tablica[2] ){
       wygrana=tablica[8];

   //UKOSNE
   }else if ( tablica[6]!=' ' && tablica[6]==tablica[4] && tablica[6]==tablica[2] ){
       wygrana=tablica[6];
   }else if ( tablica[8]!=' ' && tablica[8]==tablica[4] && tablica[8]==tablica[0] ){
       wygrana=tablica[8];
   }






        if (wygrana=='O'){
       wynik_testu=1;
   }
   else if (wygrana=='X'){
       wynik_testu=2;
   }


   return wynik_testu;
}

void koncowka1(){
   printf("*****************************************\n");
   printf("                KONIEC GRY\n");
   printf("*****************************************\n");


}

void koncowka2(){
   printf("Wpisz numer opcji i nacisnij klawsz ENTER\n");
   printf("                 OPCJE\n");
   printf("0-Powrot do menu programu\n");
   printf("1-Rozpoczecie kolejnej rundy\n");
   printf("9-Zakonczenie pracy programu\n");
}

 

Co sądzicie?

Edytowane przez Pecet256

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Trochę lepiej, ale to wciąż jest makaron. Za dużo zmiennych na raz, za dużo kodu w mainie.

 

Znajdź jakiś nowy projekt do zrobienia, o podobnym poziomie skomplikowania, i poćwicz w nim dalsze rozbijanie kodu na funkcje pomocnicze, użycie enumów, zbieranie ściśle powiązanych ze sobą rzeczy w struktury...

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ja bym sugerował przerabiać ten, ponieważ już działa i pewne rzeczy algorytmicznie są rozwiązane, więc można skupić się na zgrabniejszym kodzie, a nie od nowa wymyślać jak coś ma działać.

Możemy też wskazać konkretne błędy i pokazać jak można ładniej, skuteczniej i wydajniej coś zrobić. Można też pobawić się w dokumentację programu, jego opis logiczny, coś co pomoże lepiej zrozumieć jak program działa i dlaczego, a w przyszłości da podstawy do projektowania.

 

@Pecet256

Przy kompilacji w code:blocks nie ma errorów, są tylko 3 warningi - parameter names without tags.

Ostrzeżenia też warto czytać, bo potrafią naprowadzić na błędy w działaniu programu, np. braki w inicjacji zmiennych.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Przejrzałem z grubsza i co mi się rzuciło w oczy:

 

1. Jest kilka miejsc gdzie naturalne jest użycie pętli for zamiast while, np.

void zeruj(char *tablica){
   int licznik;
   licznik=0;
   while(licznik<9){
       tablica[licznik]=' ';
       licznik=licznik+1;

   }

}

Nie jest to błąd ale dla mnie for wygląda zgrabniej, w jednym miejscu jest wartość początkowa, warunek i inkrementacja licznika:

void zeruj(char *tablica){
   for(int licznik=0;licznik<9;licznik++) tablica[licznik]=' ';
}

Jakby kiedyś przyszło walczyć z wydajnością, to polecam zapoznać się z funkcją 'memset'. Jest zdecydowanie szybsza od iteracji w pętli ale trzeba uważać, bo to dosyć niskopoziomowe pisanie po pamięci.

 

2. Drabinki if else

Przy ruchu komputera niepotrzebnie tyle nawiasów {} nawalone, potem na końcu masz }}}}}}}}}}}}}}}}}}}}}}}}}}

Przy takim złożeniu warunków else zawiera jedną instrukcję if, więc nie ma sensu otwierać na nią bloku.

 

3. Ruch komputera.

a. Za dużo składanych warunków. Nie trzeba sprawdzać wykonania ruchu. W pierwszym warunku wiemy, że ruch nie został wykonany, w else wejdzie jeżeli warunek nie został spełniony, czyli ruch nie wykonany.

Dalej, jeżeli w każdym warunku sprawdzasz tryb uproszczony, to wyrzuć ten warunek wyżej, tak żeby pominąć tą całą drabinkę if else. Po co w nią w ogóle wchodzić jak wiemy, że nie mamy tam wejść?

b. Za dużo nawiasów w warunkach. Poćwicz kolejność wykonywania oraz łączenie wyrażeń logicznych. Jeżeli jest a i b i c, to po co dawać to w nawiasy ((a i b) i c), a dodatkowo masz jeszcze pojedyncze wyrażenia w nawiasach: ( ( ( a ) i ( b ) ) i ( c ) ), idzie się pogubić.

c. Bardzo fajnie byłoby zamknąć to w kilku funkcjach. Jedna od losowania ruchu, druga od sprawdzenia czy jest możliwy ruch wygrywający, ewentualna trzecia czy przeciwnik w następnym ruchu może wygrać i trzeba go zablokować. Drugą i trzecią można przy odrobinie sprytu zamknąć w jednej funkcji, bo sprawdza się praktycznie to samo, tylko dla drugiego gracza.

 

4. Warningi raz jeszcze.

U mnie wypisuje ciut dokładniej: U:\kolko\main.c|22|warning: parameter names (without types) in function declaration|

Czyli deklarujesz funkcje bez podania typów parametrów wchodzących do niej. Jak widać kompilator C to przepuszcza ale C++ już wywali błąd.

Tak czy inaczej nie jest dobrze jak się trafia na deklarację funkcji i nie wiadomo jakiego typu parametry przyjmuje. Przy bardziej rozbudowanych programach można nie mieć dostępu do implementacji funkcji, są same nagłówki, a reszta skompilowana w postaci bibliotek (dynamicznych lub statycznych) i teraz głów się co można w funkcję wpuścić.

 

U mnie pojawia się jeszcze: U:\kolko\main.c|33|warning: unused variable 'wyborkoncowy'|

Czyli deklarujesz jakąś zmienną ale jej nie używasz. Lepiej żeby takie rzeczy nie wisiały, chyba że robisz to intencjonalnie w jakimś celu (np. wiesz że się przyda jak niedługo będziesz rozbudowywał program ale wtedy warto dać jakiś komentarz).

Edytowane przez Bono[UG]

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×
×
  • Dodaj nową pozycję...