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

[c++] kółko i krzyżyk

Ostatnio zmodyfikowano 2015-05-19 20:23
Autor Wiadomość
skakun
Temat założony przez niniejszego użytkownika
[c++] kółko i krzyżyk
» 2015-05-19 15:53:01
Witam. Próbuje zrobić grę kółko i krzyżyk. Kompilator żadnego problemu nie znajduje, ale po uruchomieniu cały czas powtarza się zapytanie współrzędne dla tego samego gracza. Nie mam pomysłu gdzie mogą być błędy.


C/C++
#include <iostream>
#include <vector>

using namespace std;

class turn
{
public:
    char p;
   
    turn( char startp = 'X' )
    {
        p = startp;
    }
};

//przeladowanie zmiany tury
turn operator ++( turn player )
{
    turn next_turn;
    if( player.p == 'X' ) next_turn.p = 'O';
   
    if( player.p == 'O' ) next_turn.p = 'X';
   
    return next_turn; }



vector < vector < char > > create_empty_board( int x, int y ) //tworzenie pustej  planszy
{ char empty = '0';
    vector < vector < char > > tab; //wektor wektorow (wierszy)
    for( int i = 0; i != x; i++ )
    {
        vector < char > verse; //wiersz charow
        for( int j = 0; j != y; j++ )
        {
            verse.push_back( empty );
        }
        tab.push_back( verse );
    }
    return tab;
}


void change_square( turn player, vector < vector < char > >& board, int x, int y )
{
    board[ x ][ y ] = player.p;
};

bool check_victory( turn player, vector < vector < char > > board )
{
    int x, y, i;
    for( x = 1; x != 3; x++ ) //sprawdza pionowe
    {
        for( y = 1; y != 3; y++ )
        {
            if( board[ x ][ y ] != player.p ) break;
           
        }
        if(( board[ x ][ 3 ] == player.p ) &&( y == 3 ) ) return true; goto victory;
    }
   
    for( y = 1; y != 3; y++ ) //sprawdza poziome
    {
        for( x = 1; x != 3; x++ )
        {
            if( board[ x ][ y ] != player.p ) break; //przerywa jak znajdzie znak inny niz aktualnego gracza
           
        }
        if(( board[ 3 ][ y ] == player.p ) &&( x == 3 ) ) return true; goto victory; //wygra jak dojdzie petla po lini do konca bez przerwania
    }
   
    for( int i = 1; i++; i != 3 ) //sprawdza ukośne typu y=x
    {
        if( board[ i ][ i ] != player.p ) break;
       
    }
   
    if(( board[ i ][ i ] == player.p ) &&( i == 3 ) ) return true; goto victory;
    for( i = 1; i++; i =!3 )
    {
        if( board[ i ][ 4 - i ] != player.p ) break;
       
    }
    if(( board[ i ][ 4 - i ] == player.p ) &&( i == 3 ) ) return true; goto victory; // ukośne typu y=4-x
   
    return false;
    victory:;
}

void draw_board( vector < vector < char > > board )
{
    for( int x = 1; x++; x =!3 )
    {
        for( int y = 1; y++; y =!3 )
        {
            if( board[ x ][ y ] == '0' ) cout << " ";
            else cout << board[ x ][ y ];
           
        }
    }
    cout << endl;
}

bool check_end( vector < vector < char > > board )
{
    int x, y;
    for( x = 1; x != 3; x++ )
    {
        for( y = 1; y != 3; y++ ) if( board[ x ][ y ] == '0' ) return false; goto no_end; //czy sa puste pola, jak nie to koniec gry
       
    }
    return true;
    no_end:;
}

int main()
{
    vector < vector < char > > board;
    board = create_empty_board( 3, 3 );
    char bufor;
   
    int x, y;
    do
    {
        cout << " zaczyna O czy X" << endl;
        cin >> bufor;
    }
    while(( bufor != 'O' ) &&( bufor != 'X' ) );
   
    turn player( bufor );
   
    do
    {
        do
        {
            cout << "teraz wspolzedne wolnego pola do zapelnienia x,y z zakresu<1;3> podaje:" << player.p << endl;
            cin >> x;
            cin >> y;
        }
        while(( x <= 3 ) &&( x >= 1 ) &&( y <= 3 ) &&( y >= 1 ) &&( board[ x ][ y ] = '0' ) ); //musi miescic sie na planszy i musi trafic na puste pole
       
        change_square( player, board, x, y );
        draw_board( board );
        ++player;
    }
    while( !check_victory( player, board ) &&!( check_end( board ) ) );
   
    if( check_victory( player, board ) ) cout << "wygrywa" << player.p;
    else if( check_end( board ) ) cout << "remis";
   
    return 0;
}
P-132497
Monika90
» 2015-05-19 15:56:27

++player;
to nie modyfikuje zmiennej player wbrew Twoim oczekiwaniom.

W funkcji check_victory
goto victory;
 powoduje niezdefiniowane zachowanie, ponieważ pomija return.
P-132498
skakun
Temat założony przez niniejszego użytkownika
» 2015-05-19 17:25:38
Rozumiem, że skoro obie czynności mają być w po spełnieniu warunku przy if, to mają być w blokach, zgadza się?
Na tej zasadzie:

if(( board[ x ][ 3 ] == player.p ) &&( y == 3 ) ) { return true; goto victory; }


Czy pierwszy "działający" return automatycznie kończy działanie funkcji i
goto victory
 są niepotrzebne?

A jak, w takim razie, powinien być ustawiony ten operator
++
 by zmieniał turę?
P-132508
Monika90
» 2015-05-19 17:44:39
Tak, goto victory; jest niepotrzebne.

Operator ++ niech będzie składową klasy

C/C++
class turn
{
public:
    turn & operator ++()
    {
        p =( p == 'X' ? 'O': 'X' );
        return * this;
    }
};

Ja w ogóle nie użyłabym do tego operatora tylko nazwanej funkcji.
P-132510
skakun
Temat założony przez niniejszego użytkownika
» 2015-05-19 19:04:40
Oprócz tego dałem w pętli do wpisywania wspólrzędnych warunek dokładnie odwrotny jak trzeba. Po poprawkach kod wygląda tak
C/C++
#include <iostream>
#include <vector>

using namespace std;

class turn
{
public:
    char p;
   
    turn( char startp = 'X' )
    {
        p = startp;
    }
   
    turn & operator ++()
    {
        p =( p == 'X' ? 'O': 'X' );
        return * this;
    }
   
};




vector < vector < char > > create_empty_board( int x, int y ) //tworzenie pustej  planszy
{ char empty = '0';
    vector < vector < char > > tab; //wektor wektorow (wierszy)
    for( int i = 0; i != x; i++ )
    {
        vector < char > verse; //wiersz charow
        for( int j = 0; j != y; j++ )
        {
            verse.push_back( empty );
        }
        tab.push_back( verse );
    }
    return tab;
}


void change_square( turn player, vector < vector < char > >& board, int x, int y )
{
    board[ x ][ y ] = player.p;
};

bool check_victory( turn player, vector < vector < char > > board )
{
    int x, y, i;
    for( x = 1; x != 3; x++ ) //sprawdza pionowe
    {
        for( y = 1; y != 3; y++ )
        {
            if( board[ x ][ y ] != player.p ) break;
           
        }
        if(( board[ x ][ 3 ] == player.p ) &&( y == 3 ) ) { return true; };
       
       
        for( y = 1; y != 3; y++ ) //sprawdza poziome
        {
            for( x = 1; x != 3; x++ )
            {
                if( board[ x ][ y ] != player.p ) break; //przerywa jak znajdzie znak inny niz aktualnego gracza
               
            }
            if(( board[ 3 ][ y ] == player.p ) &&( x == 3 ) ) { return true; } //wygra jak dojdzie petla po lini do konca bez przerwania
        }
       
        for( int i = 1; i++; i != 3 ) //sprawdza ukośne typu y=x
        {
            if( board[ i ][ i ] != player.p ) break;
           
        }
       
        if(( board[ i ][ i ] == player.p ) &&( i == 3 ) ) { return true; }
       
        for( i = 1; i++; i =!3 )
        {
            if( board[ i ][ 4 - i ] != player.p ) break;
           
        }
        if(( board[ i ][ 4 - i ] == player.p ) &&( i == 3 ) ) { return true; } // ukośne typu y=4-x
       
        return false;
        victory:;
    }; }

void draw_board( vector < vector < char > > board )
{
    for( int x = 1; x++; x =!3 )
    {
        for( int y = 1; y++; y =!3 )
        {
            if( board[ x ][ y ] == '0' ) cout << " ";
            else cout << board[ x ][ y ];
           
        }
    }
    cout << endl;
}


bool check_end( vector < vector < char > > board )
{
    int x, y;
    for( x = 1; x != 3; x++ )
    {
        for( y = 1; y != 3; y++ ) if( board[ x ][ y ] == '0' ) return false;
       
    }
    return true;
}

int main()
{
    vector < vector < char > > board;
    board = create_empty_board( 3, 3 );
    char bufor;
   
    int x, y;
    do
    {
        cout << " zaczyna O czy X" << endl;
        cin >> bufor;
    }
    while(( bufor != 'O' ) &&( bufor != 'X' ) );
   
    turn player( bufor );
   
   
    do
    {
        do
        {
            cout << "teraz wspolzedne wolnego pola do zapelnienia x,y z zakresu<1;3> podaje:" << player.p << endl;
            cin >> x;
            cin >> y;
        }
        while(( x > 3 ) ||( x < 1 ) ||( y > 3 ) ||( y < 1 ) ||( board[ x ][ y ] != '0' ) ); //musi miescic sie na planszy i musi trafic na puste pole
       
        change_square( player, board, x, y );
        draw_board( board );
        ++player;
    }
    while( !check_victory( player, board ) &&( !check_end( board ) ) );
   
    if( check_victory( player, board ) ) cout << "wygrywa" << player.p;
    else if( check_end( board ) ) cout << "remis";
   
    return 0;
};
Coś jeszcze musi być źle, bo teraz po wpisaniu współrzędnych pasujących do przedziału program się wyłącza.
P-132517
Monika90
» 2015-05-19 19:42:45
to jest źle
C/C++
void draw_board( vector < vector < char > > board )
{
    for( int x = 1; x++; x =!3 )
    {
        for( int y = 1; y++; y =!3 )
       
1. wektory indeksujemy od zera
2. masz warunek i inkrementację zamienione miejscami
3. =! to nie jest operator w ogóle
P-132521
skakun
Temat założony przez niniejszego użytkownika
» 2015-05-19 20:23:16
Teraz działa. Bardzo dziękuje!
P-132523
« 1 »
  Strona 1 z 1