Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Dziwny błąd z przypisaniem do tablicy oraz połączenie kilku warunków w "if".

Ostatnio zmodyfikowano 2014-08-21 14:12
Autor Wiadomość
Cililing
Temat założony przez niniejszego użytkownika
Dziwny błąd z przypisaniem do tablicy oraz połączenie kilku warunków w "if".
» 2014-08-21 00:37:31
Witam. Mam dziwny problem z c++. Tworzę program - coś na przypomnienie sobie przed rokiem szkolnym. I pojawił mi się problem, którego nie jestem w stanie wytłumaczyć.
Program ten to prymitywne kółko i krzyżyk. Stworzyłem enum (kółko, krzyżyk, puste pole), oraz dwuwymiarową tablicę. Utknąłem w momencie, gdy podczas przypisywania tablicy odpowiednich odpowiedniego znaku, gdy wybiorę pole 3 lub 4 jednocześnie przypisuje mi znak do pól 3 i 4. Tak samo jest z polami 6 i 7. Reszta pól jest w porządku (znaczy, przypisuje jak trzeba). Nie jestem w stanie pojąć dlaczego program się tak zachowuje - nie jest on skończony, kod zapewne pozostawia wiele do życzenia, lecz bez rozwiązania tego problemu nie jestem w stanie ruszyć dalej. Wykluczyłem możliwość błędnego odczytywania pól, czy wykonania podwójnej instrukcji switch. Niżej załączam kod:

header:
C/C++
#include <iostream>
enum SIGN { CROSS = 'X', CIRCLE = 'O', NOTHING = '_' };
extern class CPlayer;

class CBoard
{
private:
public:
    CBoard();
    ~CBoard();
    bool Show();
    bool Move( CPlayer * Player1, CPlayer * Player2, CPlayer * ActivePlayer );
};

class CPlayer
{
private:
    std::string m_Imie;
public:
    //konstruktory
    CPlayer();
    CPlayer( std::string Imie ) { m_Imie = Imie; }
    ~CPlayer();
    //metody
    std::string PodajImie() { return m_Imie; }
};

plik cpp:
C/C++
#include "Header.h"
#include <iostream>
#include <string>
#include "conio.h"

extern SIGN Fields[ 2 ][ 2 ];

CBoard::CBoard()
{
    //wyzerowanie tablicy - przypisanie wartosci NOTHING
    for( int i = 0; i <= 2; i++ )
    {
        for( int j = 0; j <= 2; j++ )
        { Fields[ i ][ j ] = NOTHING; }
    }
};

bool CBoard::Show()
{
    //wypisanie planszy
    std::cout << "-------" << std::endl; //gorna linia
    int FieldNumber = 1;
    for( int i = 0; i <= 2; i++ )
    {
        std::cout << "|";
        for( int j = 0; j <= 2; j++ )
        {
            if( Fields[ i ][ j ] == NOTHING ) { std::cout << FieldNumber; }
            else { std::cout << static_cast < char >( Fields[ i ][ j ] ); }
            std::cout << "|";
            FieldNumber++;
        }
        std::cout << std::endl;
    }
    std::cout << "-------" << std::endl; //dolna linia
    return true;
};

bool CBoard::Move( CPlayer * Player1, CPlayer * Player2, CPlayer * ActivePlayer )
{
   
    int Number;
    std::cout << std::endl << "Podaj numer pola: ";
    std::cin >> Number;
    int x, y;
    switch( Number )
    {
    case 1:
        x = 0; y = 0; break;
    case 2:
        x = 0; y = 1; break;
    case 3:
        x = 0; y = 2; break;
    case 4:
        x = 1; y = 0; break;
    case 5:
        x = 1; y = 1; break;
    case 6:
        x = 1; y = 2; break;
    case 7:
        x = 2; y = 0; break;
    case 8:
        x = 2; y = 1; break;
    case 9:
        x = 2; y = 2; break;
    default: std::cout << "To nie jest wlasciwa liczba. Podaj ja jeszcze raz: "; std::cin >> Number;
    };
   
    if( ActivePlayer == Player1 ) Fields[ x ][ y ] = CROSS;
   
    if( ActivePlayer == Player2 ) Fields[ x ][ y ] = CIRCLE;
   
    return true;
};

no i plik main.cpp:
C/C++
#include "Header.h"
#include <iostream>
#include "conio.h"
#include <string>
#include <cstdlib>

//globalne zmienne
extern CPlayer * Player1;
extern CPlayer * Player2;
CPlayer * ActivePlayer;
SIGN Fields[ 2 ][ 2 ];

bool ChangePlayer( CPlayer * Player1, CPlayer * Player2 )
{
    if( ActivePlayer == Player1 ) { ActivePlayer = Player2; return true; }
    if( ActivePlayer == Player2 ) { ActivePlayer = Player1; return true; }
    return false;
};

bool Text( CPlayer * Player1, CPlayer * Player2, CBoard * Board )
{
    system( "cls" );
    std::cout << "Kolko i krzyzyk - wersja obiektowa\n----------------------------\n";
    std::cout << "Gracz 1: " << Player1->PodajImie() << std::endl;
    std::cout << "Gracz 2: " << Player2->PodajImie() << std::endl;
    Board->Show();
    return true;
};

int main()
{
    //stworzenie graczy:
    std::cout << "Kolko i krzyzyk - wersja obiektowa\n----------------------------\n";
    std::cout << "Podaj imie pierwszego gracza: ";
    std::string Imie_1;
    std::cin >> Imie_1;
    CPlayer * Player1 = new CPlayer( Imie_1 );
    std::cout << "Podaj imie drugiego gracza: ";
    std::string Imie_2;
    std::cin >> Imie_2;
    CPlayer * Player2 = new CPlayer( Imie_2 );
    //ustalenie aktywnego gracza na gracza nr 1;
    ActivePlayer = Player1;
    //utworzenie planszy
    CBoard * Board = new CBoard;
   
    for(;; )
    {
        Text( Player1, Player2, Board );
        std::cout << "Aktualny gracz: " << ActivePlayer->PodajImie(); //wypisanie imienia aktywnego gracza
        Board->Move( Player1, Player2, ActivePlayer );
        ChangePlayer( Player1, Player2 );
        std::cout << static_cast < char >( Fields[ 0 ][ 2 ] );
        std::cout << static_cast < char >( Fields[ 1 ][ 0 ] );
        getch();
    }
}

Mógłby ktoś postawić diagnozę co tu jest nie tak? :(
P-115842
Witold
» 2014-08-21 08:44:20
Fields ma rozmiar 2x2 a nie 3x3.

Czemu Fields jest globalną zmienną zamiast być w ciele klasy CBoard?
Tym sposobem złamałeś zasady objektowości a metody klasy CBoard równie dobrze mogły by być zwykłymi funkcjami.
P-115846
Cililing
Temat założony przez niniejszego użytkownika
» 2014-08-21 13:32:41
Ok, dziękuję - bardzo głupi błąd. Byłem przekonany, że wielkość tablicy jest tak samo jak jest numerowanie pomniejszona o 1.
Biję się po piersiach za karygodny błąd umieszczenia tablicy poza ciałem klasy CBoard - naprawione, więcej się nie powtórzy.
Teraz pojawił się nieco inny problem, a raczej pytanie o poprawność kodu - mogę połączyć kilka warunków w poniższy sposób, czy muszę żmudnie tworzyć koniunkcję każdego warunku z każdym?
C/C++
bool CBoard::Check()
{
    if( Fields[ 0 ][ 0 ] == Fields[ 0 ][ 1 ] == Fields[ 0 ][ 2 ] != NOTHING ) return true;
   
    if( Fields[ 1 ][ 0 ] == Fields[ 1 ][ 1 ] == Fields[ 1 ][ 2 ] != NOTHING ) return true;
   
    if( Fields[ 2 ][ 0 ] == Fields[ 2 ][ 1 ] == Fields[ 2 ][ 2 ] != NOTHING ) return true;
   
    if( Fields[ 0 ][ 0 ] == Fields[ 1 ][ 0 ] == Fields[ 2 ][ 0 ] != NOTHING ) return true;
   
    if( Fields[ 0 ][ 1 ] == Fields[ 1 ][ 1 ] == Fields[ 2 ][ 1 ] != NOTHING ) return true;
   
    if( Fields[ 0 ][ 2 ] == Fields[ 1 ][ 2 ] == Fields[ 2 ][ 2 ] != NOTHING ) return true;
   
    if( Fields[ 0 ][ 0 ] == Fields[ 1 ][ 1 ] == Fields[ 2 ][ 2 ] != NOTHING ) return true;
   
    if( Fields[ 0 ][ 2 ] == Fields[ 1 ][ 1 ] == Fields[ 2 ][ 0 ] != NOTHING ) return true;
    else return false;
   
};
Czyli, innymi słowy - czy powyższy kod jest poprawny?
P-115860
pekfos
» 2014-08-21 14:12:33
czy powyższy kod jest poprawny?
Poprawny - ale nie robi tego, czego oczekujesz.
P-115862
« 1 »
  Strona 1 z 1