Skocz do zawartości
Pecet256

Problem z pętlami

Rekomendowane odpowiedzi

Witam

 

Ucze się programowania w jęcyku C. Jestem początkującym. Chciałem zrobić prosty program do gry w kółko i krzyżyk działający w CMD.

W chwili obecnej mam kilka problemów.

Program jest sterowany poprzez wybór opcji z klawiatury numerycznej i naciśnięcie ENTERA - umiejscowienie klawiszy na klaw. numerycznej odpowiada polu, do którego zostanie wpisany znak kółka.

 

W chwili obecnej mam kilka problemów

1)Źle działająca funkcja "pełna" sprawdzająca wypełnienie planszy (remis) - gdy jest remis to program wyświetla, że wygrał urzytkownik.

2)Wpadanie programu w pętlę nieskończoną (czarny ekran) po wybraniu opcji jeszcze jednej rundy po zakończeniu rundy. Nie dzieje się tak za każdym razem. Ten błąd występuje zazwyczaj gdy w właśnie zakończonej rundzie wygrał komputer. Jedna z pętli wpada w pętlę niskończoną - chyba ta na lini 128, ale nie umiem tego naprawić.

 

Bardzo proszę o pomoc.

 

Kod napisany w edytorze Code:Blocks 20.03, kompilowany przez gcc

 

Kod w załączniku

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Napisano (edytowane)

Wklejam kod

Uwaga - długi post - przepraszam


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//Urzytkownik gra kó³kami (O), program zaœ krzy¿ykami (X)
//
//WERSCJA V1.2
//27.05.2020
void rysujtablice(tablica);
void zeruj(tablica);
int testurzytkownika(tablica);
int testkomputera(tablica);
int pelna(tablica);
void menu();
void intrukcja();


int main (void){

int wyboruzytkownika;
int wyborkomputera;
int testwyboru;
int granie;
int kontrola;
int rozrywka;
int pelnaplansza;
int tryb;
int praca;
int wyborkoncowy;
int wybormenu;
int wykonane;
int tab;
granie=1;
kontrola=0;
rozrywka=1;
pelnaplansza=0;
tryb=0;
praca=1;
wyborkoncowy=8;
wybormenu=8;
wykonane=0;
tab=0;
while(praca==1){
if(tryb==0){
   menu();
   scanf("%d",&wybormenu);
   if(wybormenu==1){
       granie=1;
       praca=1;
       tryb=1;
       rozrywka=1;
       wybormenu=8;
   }
   if(wybormenu==9){
       tryb=9;
       wybormenu=8;
   }
   if(wybormenu==0){
       praca=0;
       granie=0;
       rozrywka=0;
       wybormenu=8;
       tryb=8;
   }
}
while(tryb==9){
   system("cls");
   wybormenu=8;
   intrukcja();
   scanf("%d",&wybormenu);
   if (wybormenu==9){
   granie=0;
   praca=1;
   tryb=0;
   rozrywka=0;
   pelnaplansza=0;
   system("cls");
}

}


while(tryb==1){

char tablica[9];
while(rozrywka==1){
srand(time(0));
zeruj (tablica);

system("cls");
rysujtablice (tablica);


while(granie==1){wyborkoncowy=8;
//WYBÓR POLA PRZEZ URZYTKOWNIKA
testwyboru=0;
while(testwyboru==0){
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;
  }
if (tablica[wyboruzytkownika]=='X'){
   testwyboru=0;
}
if (tablica[wyboruzytkownika]==' '){
   tablica[wyboruzytkownika]='O';
   testwyboru=1;
}
}
system("cls");
rysujtablice (tablica);

//SPRAWDZANIE
tab=(pelna(tablica));
if (tab==1){
   kontrola=3;
}
kontrola=testurzytkownika(tablica);
if(kontrola==1){
   granie=0;
}

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

}


rysujtablice (tablica);
}
if(granie==1){
//SPRAWDZANIE
tab=(pelna(tablica));
if (tab==1){
   kontrola=3;
}
kontrola=(testkomputera(tablica)+1);
if(kontrola==2){
   granie=0;
}
}
}

if(kontrola==1){
   printf("Wygral urzytkownik");
   tryb=8;
}
if(kontrola==2){
   printf("Wygral komputer");
   tryb=8;
}
if(kontrola==3){
   printf("REMIS\n");
   printf("Nastompilo wypelnienie planszy uniemozliwiajace rozstrygniecie rozgrywki\n");
   tryb=8;
}
printf("\n");
printf("Czy rozegrac jeszcze jedna runde?\n");
printf("Podaj opcje i nacisnij ENTER\n");
printf("1-kolejna runda\n");
printf("0-zakonczenie pracy programu\n");
printf("9-powrot do glownego menu\n");

scanf("%d", &wyborkoncowy);
if(wyborkoncowy==1){
   granie=1;
   praca=1;
   tryb=1;
   pelnaplansza=0;
   kontrola=0;
   testwyboru=0;
   wykonane=0;
   tab=0;
   zeruj (tablica);
   wyborkoncowy=8;
}
if (wyborkoncowy==0){
   praca=0;
   granie=0;
   rozrywka=0;
   pelnaplansza=0;
}
if (wyborkoncowy==9){
   granie=0;
   praca=1;
   tryb=0;
   rozrywka=0;
   pelnaplansza=0;
   kontrola=0;
   tab=0;
   wyborkoncowy=8;
   system("cls");
}

//kontrola=0;
}
}
}

return 0;
}

//funkcje
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;

   }

}

int testurzytkownika(char *tablica){
   int wynik;
   //poziome
   if (((tablica[6]=='O')&&(tablica[7]=='O'))&&(tablica[8]=='O')){
       wynik=1;
   }
   if (((tablica[3]=='O')&&(tablica[4]=='O'))&&(tablica[5]=='O')){
       wynik=1;
   }
   if (((tablica[0]=='O')&&(tablica[1]=='O'))&&(tablica[2]=='O')){
       wynik=1;
   }

   //pionowe
   if (((tablica[6]=='O')&&(tablica[3]=='O'))&&(tablica[0]=='O')){
       wynik=1;
   }
   if (((tablica[7]=='O')&&(tablica[4]=='O'))&&(tablica[1]=='O')){
       wynik=1;
   }
   if (((tablica[8]=='O')&&(tablica[5]=='O'))&&(tablica[2]=='O')){
       wynik=1;
   }

   //ukoœne
   if (((tablica[6]=='O')&&(tablica[4]=='O'))&&(tablica[2]=='O')){
       wynik=1;
   }
   if (((tablica[0]=='O')&&(tablica[4]=='O'))&&(tablica[8]=='O')){
       wynik=1;
   }

   return wynik;

}

int testkomputera(char *tablica){
   int wynik;
   //poziome
   if (((tablica[6]=='X')&&(tablica[7]=='X'))&&(tablica[8]=='X')){
       wynik=1;
   }
   if (((tablica[3]=='X')&&(tablica[4]=='X'))&&(tablica[5]=='X')){
       wynik=1;
   }
   if (((tablica[0]=='X')&&(tablica[1]=='X'))&&(tablica[2]=='X')){
       wynik=1;
   }

   //pionowe
   if (((tablica[6]=='X')&&(tablica[3]=='X'))&&(tablica[0]=='X')){
       wynik=1;
   }
   if (((tablica[7]=='X')&&(tablica[4]=='X'))&&(tablica[1]=='X')){
       wynik=1;
   }
   if (((tablica[8]=='X')&&(tablica[5]=='X'))&&(tablica[2]=='X')){
       wynik=1;
   }

   //ukoœne
   if (((tablica[6]=='X')&&(tablica[4]=='X'))&&(tablica[2]=='X')){
       wynik=1;
   }
   if (((tablica[0]=='X')&&(tablica[4]=='X'))&&(tablica[8]=='X')){
       wynik=1;
   }

   return wynik;

}
int pelna(char *tablica){

   int wynik;
   int licznik;
   int test;
   licznik=0;
   test=0;
   wynik=0;
   while(licznik<9){
       if(tablica[licznik]=='X')
       {
           test=test+1;
       }
       if(tablica[licznik]=='O')
       {
           test=test+1;
       }
       licznik=licznik+1;
   }
   if(test==9){
       wynik=1;
   }else{wynik=0;}

   return wynik;

}

void menu(){
   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\n");
   printf("9-wyswietlenie instrukcji obslugi\n");
   printf("0-zakonczenie programu\n");

   printf("\n");

}
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");

}

Edytowane przez Pecet256

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

//SPRAWDZANIE
tab=(pelna(tablica));
if (tab==1){
   kontrola=3;
}
kontrola=(testkomputera(tablica)+1);
if(kontrola==2){
   granie=0;
}
}
}

 

Ten kod dla pełnej tablicy przy remisie kończy się tym, że masz z testu komputera 0, czyli do kontroli wpisujesz 0+1, a następnie sprawdzasz kto wygrał, co kończy się tym, że wygrał użytkownik.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Napisano (edytowane)

Ogólnie całość problemu leżała w sprawdzaniu, czy jest pełna tablica/czy ktoś wygrał. Również funkcje sprawdzające były źle napisane moim zdaniem, bo nie inicjowałeś zmiennej wynik, czyli funkcja zwracała null, co też mogło coś psuć. Po poprawieniu kolejności sprawdzania wyników i dodaniu kilku rzeczy do tego sprawdzania zaczęło działać jak należy. Masz tu kod żeby nie szukać. I ogólnie proponuję oduczyć się stosowania w kółko if za if, jeśli nie jest to potrzebne, a tu w wielu miejscach jest to nie potrzebne i można było robić if->else if-> else if ... co ułatwia sprawdzanie co nie działa i ogólnie skraca ilość operacji którą program musi wykonać. Porównaj sobie tą wersję ze swoją czym się różnią to ogarniesz gdzie miałeś błędy. I ogólnie proponuję nad ortografią popracować, bo to jest użytkownik a nie urzytkownik, nastąpiło, a nie nastompiło. No chyba że celowo tak piszesz w programie, ale to trochę dziwne jak dla mnie.

 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//Urzytkownik gra kó³kami (O), program zaœ krzy¿ykami (X)
//
//WERSCJA V1.2
//27.05.2020
void rysujtablice(tablica);
void zeruj(tablica);
int testurzytkownika(tablica);
int testkomputera(tablica);
int pelna(tablica);
void menu();
void intrukcja();


int main (void){

int wyboruzytkownika;
int wyborkomputera;
int testwyboru;
int granie;
int kontrola;
int rozrywka;
int pelnaplansza;
int tryb;
int praca;
int wyborkoncowy;
int wybormenu;
int wykonane;
int tab;
granie=1;
kontrola=0;
rozrywka=1;
pelnaplansza=0;
tryb=0;
praca=1;
wyborkoncowy=8;
wybormenu=8;
wykonane=0;
tab=0;
while(praca==1){
if(tryb==0){
   menu();
   scanf("%d",&wybormenu);
   if(wybormenu==1){
       granie=1;
       praca=1;
       tryb=1;
       rozrywka=1;
       wybormenu=8;
   }
   if(wybormenu==9){
       tryb=9;
       wybormenu=8;
   }
   if(wybormenu==0){
       praca=0;
       granie=0;
       rozrywka=0;
       wybormenu=8;
       tryb=8;
   }
}
while(tryb==9){
   system("cls");
   wybormenu=8;
   intrukcja();
   scanf("%d",&wybormenu);
   if (wybormenu==9){
   granie=0;
   praca=1;
   tryb=0;
   rozrywka=0;
   pelnaplansza=0;
   system("cls");
}

}


while(tryb==1){

char tablica[9];
while(rozrywka==1){
srand(time(0));
zeruj (tablica);

system("cls");
rysujtablice (tablica);


while(granie==1){wyborkoncowy=8;
//WYBÓR POLA PRZEZ URZYTKOWNIKA
testwyboru=0;
while(testwyboru==0){
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;
  }
if (tablica[wyboruzytkownika]=='X'){
   testwyboru=0;
}
if (tablica[wyboruzytkownika]==' '){
   tablica[wyboruzytkownika]='O';
   testwyboru=1;
}
}
system("cls");
rysujtablice (tablica);

//SPRAWDZANIE
tab=(pelna(tablica));
if (tab==1){
   kontrola=3;
   granie=0;
}
kontrola=testurzytkownika(tablica);
if(kontrola==1){
   granie=0;
}

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

}


rysujtablice (tablica);
}
if(granie==1){
//SPRAWDZANIE

kontrola=(testkomputera(tablica)+1);
if(kontrola==2){
   kontrola=3;
   granie=0;
}

}
}

if(kontrola==1){
   printf("Wygral urzytkownik");
   tryb=8;
}
if(kontrola==2){
   printf("Wygral komputer");
   tryb=8;
}
if(kontrola==3){
   printf("REMIS\n");
   printf("Nastompilo wypelnienie planszy uniemozliwiajace rozstrygniecie rozgrywki\n");
   tryb=8;
}
printf("\n");
printf("Czy rozegrac jeszcze jedna runde?\n");
printf("Podaj opcje i nacisnij ENTER\n");
printf("1-kolejna runda\n");
printf("0-zakonczenie pracy programu\n");
printf("9-powrot do glownego menu\n");

scanf("%d", &wyborkoncowy);
if(wyborkoncowy==1){
   granie=1;
   praca=1;
   tryb=1;
   pelnaplansza=0;
   kontrola=0;
   testwyboru=0;
   wykonane=0;
   tab=0;
   zeruj (tablica);
   wyborkoncowy=8;
}
if (wyborkoncowy==0){
   praca=0;
   granie=0;
   rozrywka=0;
   pelnaplansza=0;
}
if (wyborkoncowy==9){
   granie=0;
   praca=1;
   tryb=0;
   rozrywka=0;
   pelnaplansza=0;
   kontrola=0;
   tab=0;
   wyborkoncowy=8;
   system("cls");
}

//kontrola=0;
}
}
}

return 0;
}

//funkcje
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;

   }

}

int testurzytkownika(char *tablica){
   int wynik=0;
   //poziome
   if (((tablica[6]=='O')&&(tablica[7]=='O'))&&(tablica[8]=='O')){
       wynik=1;
   }
   if (((tablica[3]=='O')&&(tablica[4]=='O'))&&(tablica[5]=='O')){
       wynik=1;
   }
   if (((tablica[0]=='O')&&(tablica[1]=='O'))&&(tablica[2]=='O')){
       wynik=1;
   }

   //pionowe
   if (((tablica[6]=='O')&&(tablica[3]=='O'))&&(tablica[0]=='O')){
       wynik=1;
   }
   if (((tablica[7]=='O')&&(tablica[4]=='O'))&&(tablica[1]=='O')){
       wynik=1;
   }
   if (((tablica[8]=='O')&&(tablica[5]=='O'))&&(tablica[2]=='O')){
       wynik=1;
   }

   //ukoœne
   if (((tablica[6]=='O')&&(tablica[4]=='O'))&&(tablica[2]=='O')){
       wynik=1;
   }
   if (((tablica[0]=='O')&&(tablica[4]=='O'))&&(tablica[8]=='O')){
       wynik=1;
   }

   return wynik;

}

int testkomputera(char *tablica){
   int wynik=0;
   //poziome
   if (((tablica[6]=='X')&&(tablica[7]=='X'))&&(tablica[8]=='X')){
       wynik=1;
   }
   if (((tablica[3]=='X')&&(tablica[4]=='X'))&&(tablica[5]=='X')){
       wynik=1;
   }
   if (((tablica[0]=='X')&&(tablica[1]=='X'))&&(tablica[2]=='X')){
       wynik=1;
   }

   //pionowe
   if (((tablica[6]=='X')&&(tablica[3]=='X'))&&(tablica[0]=='X')){
       wynik=1;
   }
   if (((tablica[7]=='X')&&(tablica[4]=='X'))&&(tablica[1]=='X')){
       wynik=1;
   }
   if (((tablica[8]=='X')&&(tablica[5]=='X'))&&(tablica[2]=='X')){
       wynik=1;
   }

   //ukoœne
   if (((tablica[6]=='X')&&(tablica[4]=='X'))&&(tablica[2]=='X')){
       wynik=1;
   }
   if (((tablica[0]=='X')&&(tablica[4]=='X'))&&(tablica[8]=='X')){
       wynik=1;
   }

   return wynik;

}
int pelna(char *tablica){

   int wynik;
   int licznik;
   int test;
   licznik=0;
   test=0;
   wynik=0;
   while(licznik<9){
       if(tablica[licznik]=='X')
       {
           test=test+1;
       }
       if(tablica[licznik]=='O')
       {
           test=test+1;
       }
       licznik=licznik+1;
   }
   if(test==9){
       wynik=1;
   }else{wynik=0;}

   return wynik;

}

void menu(){
   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\n");
   printf("9-wyswietlenie instrukcji obslugi\n");
   printf("0-zakonczenie programu\n");

   printf("\n");

}
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");

}

Edytowane przez Makatak

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

1. Komentarze, komentarze, komentarze. Masz pełno zmiennych, które nie wiadomo do czego służą. Dodatkowo przypisujesz im "magiczne" wartości.

Teraz pewnie doskonale pamiętasz co jest do czego, co która wartość oznacza. Będziesz pamiętał, za tydzień, miesiąc, rok?

To jeszcze mały program bo niecałe 500 linii w jednym pliku. Przy większych projektach może się z tego zrobić kilka/naście/dziesiąt tysięcy w wielu plikach. Bez komentarzy łatwo się pogubić, zwłaszcza jak nie panuje się nad nazwami zmiennych/klas/funkcji.

 

Jeżeli pojawia się więcej wartości oznaczających coś innego niż liczbę, to warto zdefiniować ENUM-y lub stałe. W gąszczu kodu takie 1, 0, 8 przestają cokolwiek znaczyć, jednak kiedy odwoła się do nich jako np. GRACZ, ZAGRAJ_JESZCZE_RAZ, KONIEC, to o wiele łatwiej załapać co autor miał na myśli.

 

2. Odnośnie tych 500 linii, to da się skrócić program. Np. masz oddzielne funkcje na sprawdzenie czy wygrał gracz, czy komputer, są praktycznie identyczne, różnią się tylko 'O' i 'X'.

Można napisać jedną funkcję, która przyjmie parametr oznaczający gracza lub komputer.

Można też zrobić, tak że funkcja zwraca kto wygrał (porównujesz czy odpowiednie pole mają tą samą wartość, jeżeli tak, to ją zwracasz, na zewnątrz funkcji sprawdzasz kto wygrał).

Dodatkowo masz niepotrzebnie zawsze sprawdzane wszystkie przypadki. Po co robić kolejne jak już znalazło się wygrywający układ? Zamiast wpisywać wartość do wynik, lepiej od razu rzucić return-em, no chyba że chcesz jeszcze coś na tej zmiennej robić w funkcji. Ewentualnie tak jak pisał Makatak zastąpić to konstrukcją if else if else if ...

 

Przy sprawdzaniu czy gracz poprawnie podał pozycję, wystarczy jeden if - sprawdzenie czy pole jest puste, sprawdzanie czy jest tam O i czy X nie ma sensu, pole jest zajęte, więc nie można tam wstawić.

 

Pewnie jeszcze coś się znajdzie ale nie przeglądałem zbyt dokładnie.

 

3. Odnośnie if-ów. W menu masz konstrukcję:

if a==...;
if a==...;
if a==...;

To się świetnie nadaje do zastąpienia instrukcją switch

switch(a)
{
case xxx:
break;
case yyy:
break;
...
}

Do poczytania i ogarnięcia jak działa, także kiedy stosować break, a kiedy nie.

 

4. Losowanie pozycji dla komputera warto zamknąć w funkcji. Jak kiedyś chciałbyś zmienić algorytm, to w głównej części podmienisz tylko funkcję, a nie będziesz przerabiał cały fragment kodu.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Napisano (edytowane)

Komentarze to zło i totalny anty-pattern. Tutaj należy się solidne nazewnictwo zmiennych i dzielenie kodu na funkcje/klasy/cokolwiek, również o sensownym nazewnictwie.

Edytowane przez Karister

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Drogi użytkowniku Makatak.

Sprawdziłem Pana kod i faktycznie przy remisie wyświetla się prawidłowy komunikat.

Natomiast przy graniu kilku rund pod rząd wciąż zdarza się czarny ekran (pętla nieskończona).

Ponadto wypisuje remis czasami także przy nie pełnej planszy.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Napisano (edytowane)

Sprawdź, w którą pętlę wpada. Masz ich tam tyle i zagnieżdżonych, że może się coś wykwasić.

Stawiam na brak czyszczenia jakiejś zmiennej.

 

@Karister

Taaaa, a_potem_wklepujesz_przez_pół_godziny_funkcję(z_długą_nazwą_ale_mówiącą_co_robi, do_tego_tak_samo_długie_nazwy_zmiennych); ;)

 

Nie ma jednej słusznej drogi ale ja wolę mieć krótsze nazwy i raz napisać komentarz (np. z dodatkowym objaśnieniem jakie wartości mogą się pojawić, jakie grupy bitów co oznaczają itp.), niż za każdym razem wklepywać przydługawe nazwy i rozwlekając wszystko niemiłosiernie.

Są też fragmenty kodu z jakimś hakiem lub matematyką, warto zanotować na czym polega zamysł autora niż za każdym razem rozkminiać od początku co tu się miało dziać.

 

Wiadomo, że dobre nazwy są podstawą ale według mnie to za mało.

Edytowane przez Bono[UG]

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Napisano (edytowane)

Również jestem zdania, że komentarze to ostateczność, gdy typy i dobre nazewnictwo zmiennych i funkcji wciąż nie jest wystarczające do opisania co się dzieje.

Jak nazwy nie wystarczają, to wprowadza się typy które przekazują informację nie tylko programiście, ale i kompilatorowi (a ten może pomóc i odmówić kompilacji kodu który nie ma sensu). To dobra alternatywa dla klasycznej, złej embedowej praktyki gdzie wszystko jest typedef'em na inta albo makrem.

 

Inna zła praktyka którą widzę, to tzw. single return statement, czyli ograniczanie się tylko do jednego return'a na samym końcu funkcji, i zbieranie wyniku w jakiejś zmiennej tymczasowej.

Jeżeli można, lepiej od razu przerwać wykonanie i zwrócić wartość - poprawia to czytelność funkcji.

 

Brak użycia enumeracji to utrudnianie sobie roboty. A do zmiennych które są prawdą/fałszem używa się typu bool, który jest także w c, w standardowej bibliotece <stdbool.h>.

 

Generalnie skoro umie się robić funkcje, to należy zacząć strukturyzować kod tak, by miał sens. Nie pakować wszystko co się da do maina, tylko zostawić w nim główną krótką, główną pętlę, która jasno oddziela i woła etapy czytania wejścia, wykonywania ruchu, wyświetlania stanu planszy...

 

Definiując zmienne od razu przypisywać im wartość.

Można mieszać kod i definicje zmiennych w funkcji w c od ponad 20 lat. Nie trzeba wszystkich zmiennych definiować na samym początku funkcji.

 

 

A tak w ogóle, to co to jest "URZYTKOWNIK"? :E

Edytowane przez MitycznyJeż

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Napisano (edytowane)

^

|

Problem pojawia się gdy użytkownik po pierwszej rozgrywce wybierze opcję jeszcze jednej rundy.

Wtedy program może wpaść w pętlę nieskończoną (czarny ekran) lub wyświetlić REMIS przy nie w pełni wypełnionej tablicy.

^

|

Wiem doskonale, że zminne można utworzyć w dowolnym miejscu pliku we współczesnych implementacjach. Po prostu wolę mieć je na początku pliku

^

|

"URZYTKOWNIK" to jest błąd ortograficzny. Przecież to wersja alpha :)

Edytowane przez Pecet256

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

No to monitoruj, w którym miejscu kodu lądujesz i jakie mają wartości zmienne użyte w tym fragmencie kodu. Musisz znaleźć która pętla "wisi" i potem dlaczego.

 

Podobnie z remisem. Wiesz w którym miejscu jest sprawdzany warunek na remis, patrzysz na wartości zmiennych i cofasz się w programie, żeby zobaczyć dlaczego został spełniony.

 

 

Takie błędy ortograficzne nie przystoją nawet na preAlfę ;)

 

Pobawiłem się chwilę pod linuksem i na dzień dobry nie mam funkcji 'cls'.

W czarny ekran lub pętlę nieskończoną nie udało mi się wejść.

Remis wywaliło mi przy pierwszym uruchomieniu jak dałem wygrać komputerowi.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Bo system"cls" to funkcja windowsowa. Na systemach uniksopodobnych ona nie działa. W MS Windows czyści ona konsolę.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Napisano (edytowane)

Wiem ;)

 

Błąd z tym remisem jak komputer wygra jest oczywisty, więc nie będę podpowiadał.

 

Z nieskończoną pętlę chyba też znalazłem.

Jeżeli komputer ma postawić wygrywający X, to 'testwyboru' ciągle jest 0, więc komputer robi kolejny ruch.

 

 

Jeszcze dużo tutaj do poprawek i nauki. Wygląda jakbyś nie do końca rozumiał co robisz, jak działa programowanie, pętle i warunki.

Może spróbować zrobić opis poszczególnych algorytmów (sprawdzanie wygranej, remisu, ruch komputera itp.). Wpadniesz sam, że coś jest nie tak lub spróbujemy to wspólnie przeanalizować, gdzie są błędy logiczne lub różnice między opisem a implementacją.

Edytowane przez Bono[UG]

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Napisano (edytowane)
' date='28 Maj 2020 - 17:09' timestamp='1590678598' post='15922418']

@Karister

Taaaa, a_potem_wklepujesz_przez_pół_godziny_funkcję(z_długą_nazwą_ale_mówiącą_co_robi, do_tego_tak_samo_długie_nazwy_zmiennych); ;)

 

Nie ma jednej słusznej drogi ale ja wolę mieć krótsze nazwy i raz napisać komentarz (np. z dodatkowym objaśnieniem jakie wartości mogą się pojawić, jakie grupy bitów co oznaczają itp.), niż za każdym razem wklepywać przydługawe nazwy i rozwlekając wszystko niemiłosiernie.

Są też fragmenty kodu z jakimś hakiem lub matematyką, warto zanotować na czym polega zamysł autora niż za każdym razem rozkminiać od początku co tu się miało dziać.

 

Wiadomo, że dobre nazwy są podstawą ale według mnie to za mało.

Jasne, że można przegiąć pałę z nazwą metody. Dlatego, ponownie, rolą dobrego programisty jest nazwać je sensownie. Zwięźle i na temat. A rolą początkującego jest taką wiedzę zdobywać. To nie jest moje zdanie, a standard. Akurat ten temat jest dobrze przerobiony w świecie IT i istnieją powszechnie przyjęte praktyki. W dużych, komercyjnych projektach komentarze są złe. Są o tym książki i artykułu Martina Fowlera czy Roberta C. Martina. "Czysty kod" to klasyka gatunku. Jeśli potrzebujesz komentować kod, znaczy, że jest on źle napisany. Powstaje pytanie "dlaczego?". Jeśli celowo robi się w kodzie coś dziwnego, bo jest bug w używanym SDK czy Frameworku i trzeba go obejść - ok. Padły dziwne decyzje biznesowe i klient tak sobie wyraźnie życzy - też ok. Ale jeśli jest to kod powstały w normalnych warunkach pracy i trzeba go komentować, coś poszło bardzo nie tak.

Argumenty ku temu są proste. Po pierwsze skoro kod wymaga tłumaczenia, jest zbyt trudny do analizy. Odpowiednie fragmenty ze skomplikowaną logiką/obliczeniami/czymkolwiek takim powinny trafić do odpowiednich metod/funkcji. Wtedy całość czytam od góry do dołu, jak książkę. A jeśli potrzebuję wejść w szczegóły - nawiguję do odpowiedniej funkcji. Taki kod o wiele łatwiej i szybciej się rozwija. Po drugie komentarze są poza kontrolą IDE i naturalnie się dezaktualizują i mogą z czasem wręcz wprowadzać w błąd. Masz rację, że samo dobre nazewnictwo to za mało. Są dodatkowe rozwiązania, jak testy automatyczne. Te, dobrze napisane :), pozwalają na powrót do projektu po czasie, przypomnienie sobie, co on robi. Dodatkowo chronią przed złą zmianą starego kodu. To oczywiście jest na teraz temat zbyt zaawansowany dla autora tematu, ale uważam, że od początku warto utrwalać dobre praktyki. Komentarze obecnie są w branży kontrprzykładem. Osobiście przy code review mocno drapałbym się w głowę, czemu ktoś poczynił komentarz swojego kodu. Na rozmowie kwalifikacyjnej nawet nie odważyłbym się tego słowa użyć.

Na początku programowania skupiłbym się na sensownym dzieleniu kodu i nazewnictwie. Tak, aby jego struktura pomagała w pracy, a nie ją utrudniała.

 

Inna zła praktyka którą widzę, to tzw. single return statement, czyli ograniczanie się tylko do jednego return'a na samym końcu funkcji, i zbieranie wyniku w jakiejś zmiennej tymczasowej.

Jeżeli można, lepiej od razu przerwać wykonanie i zwrócić wartość - poprawia to czytelność funkcji.

Święta wojna. Wedle autorów wspomnianych wyżej jest tak, jak mówisz. Ale jestem w stanie kupić argumenty, ze w programowaniu funkcyjnym, gdzie ideą jest niemutowalność i brak side-effectów, a funkcja ma mieć jedno wyjście, powinno się bazować na monadycznych przekształceniach bez returnów po drodze. Ponownie - skomplikowane tematy.

Edytowane przez Karister

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Pewnie tak jest, ja z tak dużymi i przede wszystkim ułożonymi projektami nie mam kontaktu - życie.

Jest też pewnie kwestia tak jak pisałeś uwarunkowań. Mam dosyć bliski kontakt ze sprzętem, przy komunikacji staramy się upychać ile się da, więc prowadzi to czasem do sytuacji, że zawartość jednego pola interpretuje się w zależności od innego. Dobrze mieć to opisane pod ręką np. w deklaracji struktury, a nie dogrzebywać się dokumentacji pisanej gdzieś oddzielnie (tu to może się rozjechać z kodem ;) ).

 

Aktualizacja komentarzy, to taka sama dyscyplina jak prawidłowe nazewnictwo i struktura. Jak ktoś na odwal robi nazwy, to i na odwal skomentuje.

 

Skomplikowana logika czy obliczenia nie zrobią się prostsze po rozbiciu na kilka funkcji.

Wiadomo, że jak funkcja rozrasta się przesadnie, to warto ją podzielić ale nie ma sensu robienie tego na siłę. Osobiście mam opory przed tworzeniem funkcji wykorzystywanych jedynie raz w jednej funkcji.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Napisano (edytowane)
' date='28 Maj 2020 - 18:46' timestamp='1590684413' post='15922505']

Osobiście mam opory przed tworzeniem funkcji wykorzystywanych jedynie raz w jednej funkcji.

Powiedzmy, że trzeba zwiększyć promo na zamówienia z bananami z 10% na 20% dla klientów premium. Wolałbyś szukać odpowiedniego miejsca w tym kodzie:

 

caclculateOrderTotal(customerId) {
 customer = customersDatabaseConnection.getCustomer(customerId)
 customerOrders = ordersDatabaseConnection.getCustomerOrders(customerId)

 applyThreeOrMoreItemsPromotion(order)
 applyBananasPromoForVip(order, customer)

 return calculateGoodsTotal(order) + calculateDeliveryCharge(order)
}

czy w tym:

 

caclculateOrderTotal(customerId) {
 customer = customersDatabaseConnection.getCustomer(customerId)
 customerOrders = ordersDatabaseConnection.getCustomerOrders(customerId)

 //calc promotion when more than two items
 for (order : customerOrders) {
   for (item : order.getItems()) {
     if (item.count > 2) {
       item.price *= 0.9
     }
   }
 }
 //bananas discount
 for (order : customerOrders) {
   for (item : order.getItems()) {
     if (item is banana) {
       item.price *= 0.9
     }
   }
 }

 //sum items cost
 goodsTotal = 0;
 for (order : customerOrders) {
   for (item : order.getItems()) {
     goodsTotal += item.price * item.count
   }
 }

 //calc delivery charge
 deliveryCharge = customer.deliveryPass() ? 0 : 40  
 //apply extra delivery charges for clean zones
 if(order.deliveryArea in zoneDatabaseConnection.getCleanZones()) {
   order.deliveryCharge *= 1.1
 }

 return goodsTotal + deliveryCarge
}

Ja bym wolał w tym:

 

caclculateOrderTotal(customerId) {
 return calculateGoodsTotal() + calculateDeliveryCharge()
}

ponieważ w rzeczywistym projekcie tego kodu będzie 50 razy tyle. Bo customowe podatki na różne kraje dostawy, bo ograniczenia w zakupach dla nieletnich, bo ograniczenia w zakupach alkoholu w konkretnych godzinach, bo to i bo tamto. Każde nowoczesne IDE pozwala nawigować po wywołaniach funkcji, więc szybko trafię do caclculateOrderTotal(...) -> calculateGoodsTotal(...) -> applyPromotions(...) -> applyBananaPromo(...).

 

Metoda/funkcja powinna robić jedną rzecz. To jest kolejna obecnie obowiązująca praktyka zwana Single Responsibility Principle (SRP). Rozbijanie dużej funkcji na małe, nawet używane tylko raz jest bardzo dobrym zwyczajem. Zwłaszcza w połączeniu z umieszczaniem głównych i publicznych funkcji na górze, a prywatnych i pomocniczych na dole. Wtedy, jak wcześniej pisałem, kod czyta się jak książkę i łatwo się połapać, co on ma robić. A dopiero w potrzebnym mi miejscu wchodzę w szczegóły, aby przeanalizować, jak on to robi. Piszę to z punktu widzenia aplikacji typu sklepy online, bankowość internetowa, system rezerwacji lotów, itp. W aplikacjach HFT/low latency by to nie przeszło, bo tam się zabija o każą milisekundę i szkoda cyklu procesora na przekazywanie wskaźnika do funkcji pomocniczej na stos. :D

 

P.S. powyższy styl programowania totalnie ssie, bo mutuje listę zakupów podczas liczenia jej kosztu. Za każdym razem, gdy się tak robi, umiera mały kotek. To jest tylko w celach demonstracyjnych dzielenia kodu na małe funkcje.

I sorry za offtop, ale musiałem się do tego odnieść. ;) Wierzę, że już na starcie pisania kodu warto poznać obowiązujące standardy, których trzymają się takie firmy technologiczne, jak Amazon, Google, czy Netflix.

Edytowane przez Karister

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Może ktoś mi pomoże?

Oba te błędy pojawaiają się przy wybraniu opcji jeszcze jednej rundy bez wyłączania i ponownego włączania programu

PS. A ten "Oczywisty" błąd to która linia kodu, co konkretniej?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Użyj debuggera.

Ustaw breakpoint na samym początku maina, i przechodź krok po kroku przez swój program, obserwując wartości zmiennych.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

W aplikacjach HFT/low latency by to nie przeszło, bo tam się zabija o każą milisekundę i szkoda cyklu procesora na przekazywanie wskaźnika do funkcji pomocniczej na stos. :D

No i w moim przypadku, to jest kontakt z podobnym oprogramowaniem. Może mój kawałek nie ma aż takiego reżimu czasowego ale inne są liczone w cyklach pojedynczych ms czy wręcz us. Blisko sprzętu robimy, często jesteśmy od niego zależni.

 

Może ktoś mi pomoże?

Oba te błędy pojawaiają się przy wybraniu opcji jeszcze jednej rundy bez wyłączania i ponownego włączania programu

PS. A ten "Oczywisty" błąd to która linia kodu, co konkretniej?

Będę brutalny ale nauka programowania, to też nauka szukania błędów.

 

Pisałeś ten kod, to powinieneś wiedzieć gdzie sprawdzasz remis.

Swoją drogą ten błąd to dodał Makatak, próbując naprawić inny.

 

Zrób jak podpowiada MistycznyJeż, przejście przez program krok po kroku pomoże zrozumieć jak działa program, zobaczyć gdzie twoje spojrzenie na problem i algorytm rozmija się z tym co i jak się wykonuje.

W przyszłości część rzeczy już na oko wyłapiesz, że coś jest nie tak, nielogicznie zrobione.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Zmodyfikowałem nieco kod - dodałem wspomniane else (nie wiem czy dobrze) oraz "wyłączyłem" czyszczenie ekranu (zanki//). Błąd z pętlą nieskończoną zdarza się tylko przy wyborze kolejnej rundy tj. nigdy nie występuje w czasie trwania pierwszej rundy. Czasem ta pętla nieskończona występuje od razu po zatwierdzeniu nowej rundy, a czasami po zatwierdzeniu przez użytkownika pola. Wklejam kod:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//Urzytkownik gra kó³kami (O), program zaœ krzy¿ykami (X)
//
//WERSCJA V1.2
//27.05.2020
void rysujtablice(tablica);
void zeruj(tablica);
int testurzytkownika(tablica);
int testkomputera(tablica);
int pelna(tablica);
void menu();
void intrukcja();


int main (void){

int wyboruzytkownika;
int wyborkomputera;
int testwyboru;
int granie;
int kontrola;
int rozrywka;
int pelnaplansza;
int tryb;
int praca;
int wyborkoncowy;
int wybormenu;
int wykonane;
int tab;
granie=1;
kontrola=0;
rozrywka=1;
pelnaplansza=0;
tryb=0;
praca=1;
wyborkoncowy=8;
wybormenu=8;
wykonane=0;
tab=0;
while(praca==1){
if(tryb==0){
   menu();
   scanf("%d",&wybormenu);
   if(wybormenu==1){
       granie=1;
       praca=1;
       tryb=1;
       rozrywka=1;
       wybormenu=8;
   }
   if(wybormenu==9){
       tryb=9;
       wybormenu=8;
   }
   if(wybormenu==0){
       praca=0;
       granie=0;
       rozrywka=0;
       wybormenu=8;
       tryb=8;
   }
}
while(tryb==9){
   //system("cls");
   wybormenu=8;
   intrukcja();
   scanf("%d",&wybormenu);
   if (wybormenu==9){
   granie=0;
   praca=1;
   tryb=0;
   rozrywka=0;
   pelnaplansza=0;
   //system("cls");
}

}


while(tryb==1){

char tablica[9];
while(rozrywka==1){
srand(time(0));
zeruj (tablica);

//system("cls");
rysujtablice (tablica);


while(granie==1){wyborkoncowy=8;
//WYBÓR POLA PRZEZ URZYTKOWNIKA
testwyboru=0;
while(testwyboru==0){
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);

//SPRAWDZANIE
tab=(pelna(tablica));
if (tab==1){
   kontrola=3;
}
kontrola=testurzytkownika(tablica);
if(kontrola==1){
   granie=0;
}

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


rysujtablice (tablica);
}
if(granie==1){
//SPRAWDZANIE
tab=(pelna(tablica));
if (tab==1){
   kontrola=3;
}
kontrola=(testkomputera(tablica)+1);
if(kontrola==2){
   granie=0;
}
}
}

if(kontrola==1){
   printf("Wygral urzytkownik");
   tryb=8;
}else{
if(kontrola==2){
   printf("Wygral komputer");
   tryb=8;
}else{
if(kontrola==3){
   printf("REMIS\n");
   printf("Nastompilo wypelnienie planszy uniemozliwiajace rozstrygniecie rozgrywki\n");
   tryb=8;
}}}
printf("\n");
printf("Czy rozegrac jeszcze jedna runde?\n");
printf("Podaj opcje i nacisnij ENTER\n");
printf("1-kolejna runda\n");
printf("0-zakonczenie pracy programu\n");
printf("9-powrot do glownego menu\n");

scanf("%d", &wyborkoncowy);
if(wyborkoncowy==1){
   granie=1;
   praca=1;
   tryb=1;
   pelnaplansza=0;
   kontrola=0;
   testwyboru=0;
   wykonane=0;
   tab=0;
   zeruj (tablica);
   wyborkoncowy=8;
}else{
if (wyborkoncowy==0){
   praca=0;
   granie=0;
   rozrywka=0;
   pelnaplansza=0;
}else{
if (wyborkoncowy==9){
   granie=0;
   praca=1;
   tryb=0;
   rozrywka=0;
   pelnaplansza=0;
   kontrola=0;
   tab=0;
   wyborkoncowy=8;
   //system("cls");
}}}

//kontrola=0;
}
}
}

return 0;
}

//funkcje
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;

   }

}

int testurzytkownika(char *tablica){
   int wynik;
   //poziome
   if (((tablica[6]=='O')&&(tablica[7]=='O'))&&(tablica[8]=='O')){
       wynik=1;
   }else{
   if (((tablica[3]=='O')&&(tablica[4]=='O'))&&(tablica[5]=='O')){
       wynik=1;
   }else{
   if (((tablica[0]=='O')&&(tablica[1]=='O'))&&(tablica[2]=='O')){
       wynik=1;
   }else{

   //pionowe
   if (((tablica[6]=='O')&&(tablica[3]=='O'))&&(tablica[0]=='O')){
       wynik=1;
   }else{
   if (((tablica[7]=='O')&&(tablica[4]=='O'))&&(tablica[1]=='O')){
       wynik=1;
   }else{
   if (((tablica[8]=='O')&&(tablica[5]=='O'))&&(tablica[2]=='O')){
       wynik=1;
   }else{

   //ukoœne
   if (((tablica[6]=='O')&&(tablica[4]=='O'))&&(tablica[2]=='O')){
       wynik=1;
   }else{
   if (((tablica[0]=='O')&&(tablica[4]=='O'))&&(tablica[8]=='O')){
       wynik=1;
   }}}}}}}}

   return wynik;

}

int testkomputera(char *tablica){
   int wynik;
   //poziome
   if (((tablica[6]=='X')&&(tablica[7]=='X'))&&(tablica[8]=='X')){
       wynik=1;
   }else{
   if (((tablica[3]=='X')&&(tablica[4]=='X'))&&(tablica[5]=='X')){
       wynik=1;
   }else{
   if (((tablica[0]=='X')&&(tablica[1]=='X'))&&(tablica[2]=='X')){
       wynik=1;
   }else{

   //pionowe
   if (((tablica[6]=='X')&&(tablica[3]=='X'))&&(tablica[0]=='X')){
       wynik=1;
   }else{
   if (((tablica[7]=='X')&&(tablica[4]=='X'))&&(tablica[1]=='X')){
       wynik=1;
   }else{
   if (((tablica[8]=='X')&&(tablica[5]=='X'))&&(tablica[2]=='X')){
       wynik=1;
   }else{

   //ukoœne
   if (((tablica[6]=='X')&&(tablica[4]=='X'))&&(tablica[2]=='X')){
       wynik=1;
   }else{
   if (((tablica[0]=='X')&&(tablica[4]=='X'))&&(tablica[8]=='X')){
       wynik=1;
   }}}}}}}}

   return wynik;

}
int pelna(char *tablica){

   int wynik;
   int licznik;
   int test;
   licznik=0;
   test=0;
   wynik=0;
   while(licznik<9){
       if(tablica[licznik]=='X')
       {
           test=test+1;
       }
       if(tablica[licznik]=='O')
       {
           test=test+1;
       }
       licznik=licznik+1;
   }
   if(test==9){
       wynik=1;
   }else{wynik=0;}

   return wynik;

}

void menu(){
   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\n");
   printf("9-wyswietlenie instrukcji obslugi\n");
   printf("0-zakonczenie programu\n");

   printf("\n");

}
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");

}

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Zagadka - co zwraca funkcja testkomputera, gdy wykonanie nie wejdzie do żadnego z if'ów?

 

Ponadto, preferuj

   int wynik=0;
   int licznik=0;
   int test=0;

Zamiast

   int wynik;
   int licznik;
   int test;
   licznik=0;
   test=0;
   wynik=0;

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Napisano (edytowane)

Zagadka - co zwraca funkcja testkomputera, gdy wykonanie nie wejdzie do żadnego z if'ów?

 

Odpowiedź: to samo, co funkcja "testurzytkownika" (oczy bolą niesamowicie!) :E

Edytowane przez Kitu

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Napisano (edytowane)

Linie 265 - 266. Teraz lepiej?

 

if(testkomputera(tablica)!=0){

kontrola=(testkomputera(tablica)+1);}

 

edit: dalej może pojawić się pętla nieskończona. Remis czasem wyświetla się przy niepełnej planszy.

Ps. kod bez modyfikacji Pana Makatak'a. (chyba - miałem mały młyn z plikami...)

Pps.wklejam kod. Może potem dodam to else

 


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//Urzytkownik gra kó³kami (O), program zaœ krzy¿ykami (X)
//
//WERSCJA V1.2
//27.05.2020
void rysujtablice(tablica);
void zeruj(tablica);
int testurzytkownika(tablica);
int testkomputera(tablica);
int pelna(tablica);
void menu();
void intrukcja();


int main (void){

int wyboruzytkownika;
int wyborkomputera;
int testwyboru;
int granie;
int kontrola;
int rozrywka;
int pelnaplansza;
int tryb;
int praca;
int wyborkoncowy;
int wybormenu;
int wykonane;
int tab;
granie=1;
kontrola=0;
rozrywka=1;
pelnaplansza=0;
tryb=0;
praca=1;
wyborkoncowy=8;
wybormenu=8;
wykonane=0;
tab=0;
while(praca==1){
if(tryb==0){
   menu();
   scanf("%d",&wybormenu);
   if(wybormenu==1){
       granie=1;
       praca=1;
       tryb=1;
       rozrywka=1;
       wybormenu=8;
   }
   if(wybormenu==9){
       tryb=9;
       wybormenu=8;
   }
   if(wybormenu==0){
       praca=0;
       granie=0;
       rozrywka=0;
       wybormenu=8;
       tryb=8;
   }
}
while(tryb==9){
   system("cls");
   wybormenu=8;
   intrukcja();
   scanf("%d",&wybormenu);
   if (wybormenu==9){
   granie=0;
   praca=1;
   tryb=0;
   rozrywka=0;
   pelnaplansza=0;
   system("cls");
}

}


while(tryb==1){

char tablica[9];
while(rozrywka==1){
srand(time(0));
zeruj (tablica);

system("cls");
rysujtablice (tablica);


while(granie==1){wyborkoncowy=8;
//WYBÓR POLA PRZEZ URZYTKOWNIKA
testwyboru=0;
while(testwyboru==0){
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;
  }
if (tablica[wyboruzytkownika]=='X'){
   testwyboru=0;
}
if (tablica[wyboruzytkownika]==' '){
   tablica[wyboruzytkownika]='O';
   testwyboru=1;
}
}
system("cls");
rysujtablice (tablica);

//SPRAWDZANIE
tab=(pelna(tablica));
if (tab==1){
   kontrola=3;
}
kontrola=testurzytkownika(tablica);
if(kontrola==1){
   granie=0;
}

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

}


rysujtablice (tablica);
}
if(granie==1){
//SPRAWDZANIE
tab=(pelna(tablica));
if (tab==1){
   kontrola=3;
}if(testkomputera(tablica)!=0){
kontrola=(testkomputera(tablica)+1);}
if(kontrola==2){
   granie=0;
}
}
}

if(kontrola==1){
   printf("Wygral urzytkownik");
   tryb=8;
}
if(kontrola==2){
   printf("Wygral komputer");
   tryb=8;
}
if(kontrola==3){
   printf("REMIS\n");
   printf("Nastompilo wypelnienie planszy uniemozliwiajace rozstrygniecie rozgrywki\n");
   tryb=8;
}
printf("\n");
printf("Czy rozegrac jeszcze jedna runde?\n");
printf("Podaj opcje i nacisnij ENTER\n");
printf("1-kolejna runda\n");
printf("0-zakonczenie pracy programu\n");
printf("9-powrot do glownego menu\n");

scanf("%d", &wyborkoncowy);
if(wyborkoncowy==1){
   granie=1;
   praca=1;
   tryb=1;
   pelnaplansza=0;
   kontrola=0;
   testwyboru=0;
   wykonane=0;
   tab=0;
   zeruj (tablica);
   wyborkoncowy=8;
}
if (wyborkoncowy==0){
   praca=0;
   granie=0;
   rozrywka=0;
   pelnaplansza=0;
}
if (wyborkoncowy==9){
   granie=0;
   praca=1;
   tryb=0;
   rozrywka=0;
   pelnaplansza=0;
   kontrola=0;
   tab=0;
   wyborkoncowy=8;
   system("cls");
}

//kontrola=0;
}
}
}

return 0;
}

//funkcje
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;

   }

}

int testurzytkownika(char *tablica){
   int wynik;
   //poziome
   if (((tablica[6]=='O')&&(tablica[7]=='O'))&&(tablica[8]=='O')){
       wynik=1;
   }
   if (((tablica[3]=='O')&&(tablica[4]=='O'))&&(tablica[5]=='O')){
       wynik=1;
   }
   if (((tablica[0]=='O')&&(tablica[1]=='O'))&&(tablica[2]=='O')){
       wynik=1;
   }

   //pionowe
   if (((tablica[6]=='O')&&(tablica[3]=='O'))&&(tablica[0]=='O')){
       wynik=1;
   }
   if (((tablica[7]=='O')&&(tablica[4]=='O'))&&(tablica[1]=='O')){
       wynik=1;
   }
   if (((tablica[8]=='O')&&(tablica[5]=='O'))&&(tablica[2]=='O')){
       wynik=1;
   }

   //ukoœne
   if (((tablica[6]=='O')&&(tablica[4]=='O'))&&(tablica[2]=='O')){
       wynik=1;
   }
   if (((tablica[0]=='O')&&(tablica[4]=='O'))&&(tablica[8]=='O')){
       wynik=1;
   }

   return wynik;

}

int testkomputera(char *tablica){
   int wynik;
   //poziome
   if (((tablica[6]=='X')&&(tablica[7]=='X'))&&(tablica[8]=='X')){
       wynik=1;
   }
   if (((tablica[3]=='X')&&(tablica[4]=='X'))&&(tablica[5]=='X')){
       wynik=1;
   }
   if (((tablica[0]=='X')&&(tablica[1]=='X'))&&(tablica[2]=='X')){
       wynik=1;
   }

   //pionowe
   if (((tablica[6]=='X')&&(tablica[3]=='X'))&&(tablica[0]=='X')){
       wynik=1;
   }
   if (((tablica[7]=='X')&&(tablica[4]=='X'))&&(tablica[1]=='X')){
       wynik=1;
   }
   if (((tablica[8]=='X')&&(tablica[5]=='X'))&&(tablica[2]=='X')){
       wynik=1;
   }

   //ukoœne
   if (((tablica[6]=='X')&&(tablica[4]=='X'))&&(tablica[2]=='X')){
       wynik=1;
   }
   if (((tablica[0]=='X')&&(tablica[4]=='X'))&&(tablica[8]=='X')){
       wynik=1;
   }

   return wynik;

}
int pelna(char *tablica){

   int wynik;
   int licznik;
   int test;
   licznik=0;
   test=0;
   wynik=0;
   while(licznik<9){
       if(tablica[licznik]=='X')
       {
           test=test+1;
       }
       if(tablica[licznik]=='O')
       {
           test=test+1;
       }
       licznik=licznik+1;
   }
   if(test==9){
       wynik=1;
   }else{wynik=0;}

   return wynik;

}

void menu(){
   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\n");
   printf("9-wyswietlenie instrukcji obslugi\n");
   printf("0-zakonczenie programu\n");

   printf("\n");

}
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");

}


 

Bardzo proszę o pomoc

Edytowane przez Pecet256

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Przepraszam za double post, ale bardzo proszę o pomoc.

Może znajdzie się jakaś pomocna dłoń, która naprawi ten remis i te nieszczęsne pętle nieskończone.

Ps. jak załączyć debugger w CodeBlocks?

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ę...