Bimbol Temat założony przez niniejszego użytkownika |
[C++] Dziwny problem w Kółko krzyżyk » 2013-07-13 13:02:04 Witam, napisałem OX używając klas, oraz porad z poprzednich tematów. Wszystko działa, a przynajmniej powinno działać, ale nie wiem skąd na planszy zamiast numerków mam znaki ASCII. Z kolei gdy w konstruktorze zamienie kolejność CreateBoard(); z CreateSolutions(); to plansza się wyświetla dobrze, jednak tablica z rozwiązaniami zaś z kolei wskazuje ciągle na pole 0. Gdy sprawdzam co się dzieje w obu funkcjach to rozwiązania są tworzone dobrze, a plansza jest wypełniana również dobrze. Jednak gdy przychodzi do wypisania na ekran, to nie wiem dlaczego wartości tych liczb się zmieniają. A w rozwiązaniach wszystko wskazuje na pole 0, ten kto tam postawi X albo O ten wygrywa. main.cpp: #include "ox.h"
int main() { BeginGame(); while( true ) { Board.ShowBoard(); unsigned field; cin >> field; cin.clear(); cin.sync(); Board.Move( field ); if( g_Game == G_DRAW || g_Game == G_WIN ) break; } return 0; }
ox.h: #ifndef OX_H_INCLUDED #define OX_H_INCLUDED
#include <iostream> #include <conio.h> #include <cstdlib> #include <ctime> using namespace std;
enum FIELD { FIELD_EMPYTY, FIELD_X = 'X', FIELD_O = 'O' }; enum GAMESTATE { G_NONSTARTED, G_MOVE, G_DRAW, G_WIN }; const unsigned BOARD_SIZE = 3;
class CPlayer { private: string m_Nick; FIELD m_Sign; public: CPlayer( string Nick ) : m_Nick( Nick ) { } void SetSign( FIELD field ) { m_Sign = field; } string GetNick() { return m_Nick; } FIELD GetSign() { return m_Sign; } };
class CBoard { private: unsigned m_Size; FIELD m_Board[]; unsigned m_Solutions[][ BOARD_SIZE ]; unsigned m_AmountSolutions; public: CBoard( unsigned Size ) : m_Size( Size ) , m_AmountSolutions( 0 ) { CreateBoard(); CreateSolutions(); } unsigned GetBoardSize() { return m_Size; } void CreateBoard(); void CreateSolutions(); void ShowBoard(); bool Move( unsigned field ); bool Check(); };
bool BeginGame();
extern CBoard Board; extern GAMESTATE g_Game;
#endif
ox.cpp: #include "ox.h"
CPlayer * Player[ 2 ]; GAMESTATE g_Game = G_NONSTARTED; unsigned g_ActivePlayer; CBoard Board( BOARD_SIZE );
bool BeginGame() { if( g_Game != G_NONSTARTED ) return false; for( unsigned i = 0; i < 2; ++i ) { cout << "Gracz " << i + 1 << ": "; string Nick; cin >> Nick; Player[ i ] = new CPlayer( Nick ); } srand( static_cast < unsigned >( time( NULL ) ) ); if( rand() % 2 == 0 ) { Player[ 0 ]->SetSign( FIELD_O ); Player[ 1 ]->SetSign( FIELD_X ); } else { Player[ 0 ]->SetSign( FIELD_X ); Player[ 1 ]->SetSign( FIELD_O ); } rand() % 2 == 0 ? g_ActivePlayer = 0 : g_ActivePlayer = 1; g_Game = G_MOVE; return true; }
void CBoard::CreateBoard() { for( unsigned i = 0; i < GetBoardSize() * GetBoardSize(); ++i ) { m_Board[ i ] = FIELD_EMPYTY; } }
void CBoard::CreateSolutions() { for( unsigned i = 0; i < GetBoardSize() * GetBoardSize(); i += GetBoardSize() ) { for( unsigned j = 0; j < GetBoardSize(); ++j ) { m_Solutions[ m_AmountSolutions ][ j ] = i + j; } m_AmountSolutions++; } }
void CBoard::ShowBoard() { system( "cls" ); cout << " KOLKO i KRZYZYK " << endl; cout << "---------------------------" << endl; for( unsigned i = 0; i < GetBoardSize() * GetBoardSize(); ++i ) { m_Board[ i ] != FIELD_EMPYTY ? cout << static_cast < char >( m_Board[ i ] ) << " " : cout << i + 1 << " "; if(( i + 1 ) % GetBoardSize() == 0 ) cout << endl; } if( g_Game != G_DRAW && g_Game != G_WIN ) cout << "Ruch gracza " << Player[ g_ActivePlayer ]->GetNick() << " (" << static_cast < char >( Player[ g_ActivePlayer ]->GetSign() ) << "): "; else if( g_Game == G_DRAW ) cout << "Remis!" << endl; else cout << "Wygral " << Player[ g_ActivePlayer ]->GetNick() << " (" << static_cast < char >( Player[ g_ActivePlayer ]->GetSign() ) << ")!" << endl; }
bool CBoard::Move( unsigned field ) { if( g_Game != G_MOVE ) return false; if( !( field >= 1 && field <= GetBoardSize() * GetBoardSize() ) ) { cout << "Zakres <1;" << GetBoardSize() * GetBoardSize() << ">" << endl; getch(); return false; } else if( m_Board[ field - 1 ] != FIELD_EMPYTY ) { cout << "Pole zajete!" << endl; getch(); return false; } m_Board[ field - 1 ] = Player[ g_ActivePlayer ]->GetSign(); if( Board.Check() ) { g_Game = G_WIN; CBoard::ShowBoard(); return true; } unsigned counter = 0; for( unsigned i = 0; i < GetBoardSize() * GetBoardSize(); ++i ) if( m_Board[ i ] != FIELD_EMPYTY ) counter++; if( counter == GetBoardSize() * GetBoardSize() ) { g_Game = G_DRAW; CBoard::ShowBoard(); return true; } g_ActivePlayer == 0 ? g_ActivePlayer = 1: g_ActivePlayer = 0; return true; }
bool CBoard::Check() { unsigned AmountMatchingField = 0; for( unsigned i = 0; i < m_AmountSolutions; ++i ) { for( unsigned j = 0; j < GetBoardSize(); ++j ) { if( m_Board[ m_Solutions[ i ][ j ] ] == Player[ g_ActivePlayer ]->GetSign() ) { cout << i << " " << j << " " << m_Solutions[ i ][ j ] << " " << m_Board[ m_Solutions[ i ][ j ] ] << " " << Player[ g_ActivePlayer ]->GetSign() << endl; getch(); } else break; } if( AmountMatchingField == GetBoardSize() ) { return true; } AmountMatchingField = 0; } return false; }
Dziękuję za pomoc. Liczę się również z krytyką tej prymitywnej gry. |
|
Monika90 |
» 2013-07-13 13:16:31 Jak drukujesz znaki, to się wyświetlają znaki m_Board[ i ] != FIELD_EMPYTY ? cout << static_cast < char >( m_Board[ i ] ) << " "
Poza tym twój program jest błędny i nie da się nawet skompilować. Używasz typu std::string a nie masz #include <string> Nie można też deklarować niestatycznych składowych klas typu tablicowaego bez podania rozmiaru FIELD m_Board[]; unsigned m_Solutions[][ BOARD_SIZE ];
|
|
Bimbol Temat założony przez niniejszego użytkownika |
» 2013-07-13 14:19:29 Nie rozumiem dlaczego kompiluje się się u mnie na IDE Code::Blocks. Myślałem, że skoro Kompilator przyjął taką formę tablicy to pomyślałem, że jest to dozwolone. Wyrzuca błędy tylko gry próbuje tak zrobić, więcej niż 1 wymiar. Jak drukujesz znaki, to się wyświetlają znaki |
Tyle, że CBoard::CreateBoard() tutaj dochodzi przypisania planszy pustych pól, a mimo to pokazuje inne znaki. |
|
pekfos |
» 2013-07-13 14:24:04 Nie rozumiem dlaczego kompiluje się się u mnie na IDE Code::Blocks. |
Bez dołączania <string> program może się skompilować, ale nie musi. Poza tym, Code::Blocks to, jak sam napisałeś, IDE, a nie kompilator ;) Myślałem, że skoro Kompilator przyjął taką formę tablicy to pomyślałem, że jest to dozwolone. |
Nie wszystko, co kompilator przyjmuje, jest dozwolone. [cytat] |
|
Bimbol Temat założony przez niniejszego użytkownika |
» 2013-07-13 14:29:04 Ale pobrałem wersje z kompilatorem minigw. (Wybaczcie jeśli źle mówię) Dodałem #include <string> mimo to nie ma żadnych błędów. Zaś inne błędy wykrywa normalnie. |
|
Monika90 |
» 2013-07-13 14:31:59 Tyle, że CBoard::CreateBoard() tutaj dochodzi przypisania planszy pustych pól, a mimo to pokazuje inne znaki. |
Ale nie podałeś rozmiaru tablicy, nie wiem co g++ robi w takiej sytuacji. Załóżmy że przyjmuje rozmiar zero. Wtedy zapisywanie danych do tej tablicy spowoduje zmiany jakiś innch składowych klasy. Np. modyfikujesz m_board, a zmienia się m_Solutions i m_AmountSolutions i odwrotnie. Możesz kompilować z flagą -pedantic, to przynajmniej dostaniesz warning, w sytuacji kiedy, źle zadeklarujesz tablicę. |
|
Bimbol Temat założony przez niniejszego użytkownika |
» 2013-07-13 14:34:05 No to już wiem skąd się wzięły te "dziwne błędy".
A więc inne pytanie, czy jest jakiś sposób by nie trzeba było określać wielkości tablicy od razu w klasie? Czy można z tym w jakiś sposób poczekać? |
|
Berux |
» 2013-07-13 14:41:28 Zawsze możesz użyć vectora ;) |
|
« 1 » 2 |