HoulScream Temat założony przez niniejszego użytkownika |
[C++] Kółko i krzyżyk. Problem z warunkiem wygranej » 2016-06-15 18:57:19 Witam, jestem tutaj nowy i próbuję napisać prostą grę, kółko i krzyżyk. Może z grubsza zasady dla jasności: Gramy na planszy 9x9 i warunkiem zwycięstwa jest postawienie 5ciu takich samych znaczków w górę, dół, lub na skosy. Nie wszystko jest jeszcze zrobione ale nie chcę iść dalej niczym nie uporam się z niniejszym problemem, otóż po stworzeniu "szkicu" gry zacząłem dodawać warunki zwycięstwa (konkretnie pierwszy). Chciałem dodać warunek który będzie nam sprawdzał czy mamy pięć takich samych symboli w jednym wierszu. Jeżeli tak, metoda GameOver() zwraca true i gra się kończy, lecz jeżeli warunek nie zostanie spełniony zwraca ona false i gramy dalej. Problem polega na tym, że warunek zwraca poprawne wartości tylko jeżeli postawimy krzyżyk lub kółko w polach 1,2,3,4,5. Jeżeli wprowadzimy np 2,3,4,5,6 metoda ciągle będzie zwracać false, dopóki nie pojawi się kompletny ciąg 1,2,3,4,5. Proszę o wyrozumiałość, gdyż jestem na początku swojej drogi z C++. Oto kod i bardzo proszę o pomoc. Pozdrawiam #include <iostream> #include <string> #include <ios> using namespace std;
#define SIZE 9 enum Figure { o, x }; class Point { public: char element = '\0'; Point( char c ) { this->element = c; } Point() { this->element = '\0'; } };
class Place { public: Point place[ SIZE * SIZE + 1 ]; Place() { } void MakeStep( int i, Figure f ) { place[ i ] =( f == Figure::o ? 'O': 'X' ); } bool GameOver() { for( int i = 1; i <= SIZE * SIZE; i = + SIZE ) { if(( place[ i ].element == 'O' ) &&( place[ i + 1 ].element == 'O' ) &&( place[ i + 2 ].element == 'O' ) &&( place[ i + 3 ].element == 'O' ) &&( place[ i + 4 ].element == 'O' ) ) { cout << "Wygral Gracz: O"; return true; } else if(( place[ i ].element == 'X' ) &&( place[ i + 1 ].element == 'X' ) &&( place[ i + 2 ].element == 'X' ) &&( place[ i + 3 ].element == 'X' ) &&( place[ i + 4 ].element == 'X' ) ) { cout << "Wygral Gracz: X"; return true; } else return false; } return false; } void ShowPlace() { system( "cls" ); for( int i = 1; i <= SIZE * SIZE; i++ ) { cout << " " << place[ i ].element << " "; if( i % SIZE ) cout << "|"; else if( i != SIZE * SIZE ) { string poprzeczka = "+---"; cout << "\n---"; for( int i = 0; i < SIZE - 1; i++ ) { cout << poprzeczka; } cout << "\n"; } else cout << endl; } } void FillPlace() { for( int i = 0; i <= SIZE * SIZE + 1; i++ ) { place[ i ].element = '0'; } } };
void main() { Place * place = new Place(); place->FillPlace(); int i = 0; place->ShowPlace(); while( !place->GameOver() ) { int a; cin >> a; place->MakeStep( a, i % 2 == 0 ? Figure::o: Figure::x ); place->ShowPlace(); i++; } cin.get(); cin.get(); };
|
|
mateczek |
» 2016-06-16 04:55:14 Błędów masz kilka !!! 1. return kończy ci pętle i funkcje. Dlatego sprawdza ci tylko pierwsze 5 i wychodzi z prawdą lub fałszem for( int i = 1; i <= SIZE * SIZE; i = + SIZE )
for( int i = 1; i <= SIZE * SIZE; i += SIZE )
for( int i = 1; i <= SIZE * SIZE; i++ )
Zapoznaj się z debuggerem Szybko sam namierzysz takie niedociągnięcia A tu algorytm oparty na liczeniu pod rząd wystąpień bool GameOver() { int countX = 0; int countO = 0; for( int i = 1; i <= SIZE * SIZE; i++ ) { if( place[ i ].element == 'X' ) { countX++; if( countX == 5 ) { cout << "wygraly X: "; return true; } } else countX = 0; if( place[ i ].element == 'O' ) { countO++; if( countO == 5 ) { cout << "wygraly O: "; return true; } } else countO = 0; } return false; } |
|
HoulScream Temat założony przez niniejszego użytkownika |
Dziękuję » 2016-06-16 07:31:01 Bardzo dziękuję za skorygowanie błędów i sugestię. Zobaczymy co będzie dalej. Pozdrawiam :)
// EDIT
Zasugerowany algorytm również nie spełnia moich oczekiwań. Działa ale jest z nim pewien problem. Gdy ciąg np w polach 2,3,4,5,6 wszystko jest ok ale gdy na przykład podamy ciąg 8,9,(tu zaczna się nowy wiersz)10,11,12 algorytm nadal widzi w tym zwycięstwo. Jakieś sugestie ? |
|
kargi191 |
» 2016-06-16 08:49:32 Natknąłem się kiedyś na ten filmik w sieci:
https://www.youtube.com/watch?v=vd0zDG4vwOw
Może okaże się dla Ciebie pomocny |
|
mateczek |
» 2016-06-16 08:54:03 zrobić macierz 2D i dwie pętle for pierwsza pętla indeksuje wiersze druga jedzie po elementach wierszy |
|
carlosmay |
» 2016-06-16 09:58:49 zrobić macierz 2D i dwie pętle for |
Można zostawić jak jest, tylko dodaj do warunku pętli drugą zmienną określająca koniec wiersza. Dodanie jedynki do rozmiaru aby móc indeksować od 1 to kiepski pomysł. Lepiej przyzwyczaić się do indeksowania naturalnego. Wiem, że teraz jest wygodniej, ale gdy dojdą inne pętlę program z mało czytelnego stanie się całkiem nieczytelny. |
|
HoulScream Temat założony przez niniejszego użytkownika |
» 2016-06-16 18:01:11 Zastosowałem się do powyższych sugestii i z grubsza nawet to działa, lecz napotkałem kolejny problem z którym nie mogę się uporać, mój warunek: for( int i = 1; i <= SIZE * SIZE; i++ ) { if(( place[ i ].element == 'O' ) &&( place[ i + 1 ].element == 'O' ) &&( place[ i + 2 ].element == 'O' ) &&( place[ i + 3 ].element == 'O' ) &&( place[ i + 4 ].element == 'O' ) ) { cout << "Wygral Gracz: O" << endl; cout << "Koniec gry" << endl; return true; }
działa "aż za dobrze", konkretnie chodzi mi o to, że jeżeli pojawi się ciąg na skraju wiersza pojawia się np kółka (np 8,9) a kolejny zaczynał się będzie (10,11,12) również kółkami, to warunek wygranej również zajdzie. Myślałem o ograniczeniu wszystkiego jeszcze jednym warunkiem: niestety również bez większych rezultatów, warunek wprowadził to, że w dolnym rzędzie muszą być co najmniej 4 jednakowe elementy aby gra się zakończyła (ciąg 9,10,11,12,13 - również wygrywał ale np 8,9,10,11,12 - już nie) ma ktoś jakiś pomysł jak to ugryźć ? Pozdrawiam |
|
carlosmay |
» 2016-06-16 23:54:02 Taki przykład dla poziomych wierszy: auto main()->int { constexpr int SIZE = 4; constexpr int LENGTH_WIN_STRING = 3; std::array < int, SIZE * SIZE > arr { }; arr[ 0 ] = 1; arr[ 1 ] = 1; arr[ 7 ] = 1; arr[ 8 ] = 1; arr[ 13 ] = 1; for( int i = 0; i < SIZE; ++i ) { for( int j = i * SIZE; j <( SIZE + i * SIZE ) && j <( SIZE * SIZE - 2 ); ++j ) { bool isCheckLineCorrect =( j % SIZE ) <=( SIZE - LENGTH_WIN_STRING ); bool isWinString =( arr[ j ] == 0 ) &&( arr[ j + 1 ] == 0 ) &&( arr[ j + 2 ] == 0 ); if( isWinString && isCheckLineCorrect ) { std::cout << "Wygrałeś w wierszu nr: " << i + 1 << '\n'; } } } }
|
|
« 1 » |