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

Problem z silnikiem graficznym gier tekstowych

Ostatnio zmodyfikowano 2014-12-19 02:17
Autor Wiadomość
Szustarol
Temat założony przez niniejszego użytkownika
Problem z silnikiem graficznym gier tekstowych
» 2014-12-17 22:51:09
Witam! Ostatnio celem sprawdzenia swoich umiejętności w C++ chciałem napisać prosty kod gry (silnika gry) tekstowej (konsolowej)
Wypociłem coś takiego:
C/C++
#include <iostream>
#include <string>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
//wartości startowe powinny pozostać takie same
using namespace std;
int iloscodpowiedzi;
int wybrane;
int nextpage = 1;
bool activatenextpage;

void cls() {
    #ifdef WIN32
    system( "cls" );
    #else
    system( "clear" );
    #endif
}

void banner() {
    cout << "/===============================================================\\" << endl;
    cout << "|                          THE TEXT RPG                         |" << endl;
    cout << "|                            0.03 a                             |" << endl;
    cout << "\\===============================================================/" << endl;
}

class Strony {
public:
    void pierwsza( int selected ) {
        int ile = 3; //ile odpowiedzi ma strona
        string odpowiedzi[ ile ];
        iloscodpowiedzi = ile;
        string trescpytania = "TRESC STRONY PIERWSZEJ";
        if( selected == 0 ) { odpowiedzi[ 0 ] = ">"; nextpage = 2; }
        if( selected == 1 ) { odpowiedzi[ 1 ] = ">"; nextpage = 3; }
        if( selected == 2 ) { odpowiedzi[ 2 ] = ">"; nextpage = 4; }
        odpowiedzi[ 0 ] += "Strona 2";
        odpowiedzi[ 1 ] += "Strona 3";
        odpowiedzi[ 2 ] += "Strona 4";
        //itd. itp.
       
        cout << trescpytania << endl;
        cout << odpowiedzi[ 0 ] << endl;
        cout << odpowiedzi[ 1 ] << endl;
        cout << odpowiedzi[ 2 ] << endl;
    }
    void druga( int selected ) {
        int ile = 3; //ile odpowiedzi ma strona
        string odpowiedzi[ ile ];
        iloscodpowiedzi = ile;
        string trescpytania = "TRESC STRONY DRUGIEJ";
        if( selected == 0 ) { odpowiedzi[ 0 ] = ">"; nextpage = 1; }
        if( selected == 1 ) { odpowiedzi[ 1 ] = ">"; nextpage = 3; }
        if( selected == 2 ) { odpowiedzi[ 2 ] = ">"; nextpage = 4; }
        odpowiedzi[ 0 ] += "Strona 1";
        odpowiedzi[ 1 ] += "Strona 3";
        odpowiedzi[ 2 ] += "Strona 4";
        //itd. itp.
       
        cout << trescpytania << endl;
        cout << odpowiedzi[ 0 ] << endl;
        cout << odpowiedzi[ 1 ] << endl;
        cout << odpowiedzi[ 2 ] << endl;
       
    }
    void trzecia( int selected ) {
        int ile = 3; //ile odpowiedzi ma strona
        string odpowiedzi[ ile ];
        iloscodpowiedzi = ile;
        string trescpytania = "TRESC STRONY TRZECIEJ";
        if( selected == 0 ) { odpowiedzi[ 0 ] = ">"; nextpage = 1; }
        if( selected == 1 ) { odpowiedzi[ 1 ] = ">"; nextpage = 2; }
        if( selected == 2 ) { odpowiedzi[ 2 ] = ">"; nextpage = 4; }
        odpowiedzi[ 0 ] += "Strona 1";
        odpowiedzi[ 1 ] += "Strona 2";
        odpowiedzi[ 2 ] += "Strona 4";
        //itd. itp.
       
        cout << trescpytania << endl;
        cout << odpowiedzi[ 0 ] << endl;
        cout << odpowiedzi[ 1 ] << endl;
        cout << odpowiedzi[ 2 ] << endl;
    }
    void czwarta( int selected ) {
        int ile = 3; //ile odpowiedzi ma strona
        string odpowiedzi[ ile ];
        iloscodpowiedzi = ile;
        string trescpytania = "TRESC STRONY CZWARTEJ";
        if( selected == 0 ) { odpowiedzi[ 0 ] = ">"; nextpage = 1; }
        if( selected == 1 ) { odpowiedzi[ 1 ] = ">"; nextpage = 2; }
        if( selected == 2 ) { odpowiedzi[ 2 ] = ">"; nextpage = 3; }
        odpowiedzi[ 0 ] += "Strona 1";
        odpowiedzi[ 1 ] += "Strona 2";
        odpowiedzi[ 2 ] += "Strona 3";
        //itd. itp.
       
        cout << trescpytania << endl;
        cout << odpowiedzi[ 0 ] << endl;
        cout << odpowiedzi[ 1 ] << endl;
        cout << odpowiedzi[ 2 ] << endl;
    }
};

class Wybor {
public:
    void gora() {
        if( wybrane < iloscodpowiedzi - 1 )
             wybrane++;
       
    }
    void dol() {
        if( wybrane > 0 )
             wybrane--;
       
    }
    short unsigned int opcja() {
        return wybrane;
    }
};

int main() {
    int teraz = 0;
    Strony ktora;
    Wybor aktualny;
    while( 1 ) {
        cin.sync();
        cin.clear();
        banner();
        if( activatenextpage == true ) {
            switch( nextpage ) {
            case 1:
                ktora.pierwsza( wybrane );
                break;
            case 2:
                ktora.druga( wybrane );
                break;
            case 3:
                ktora.trzecia( wybrane );
                break;
            case 4:
                ktora.czwarta( wybrane );
                break;
            }
        }
        else {
            ktora.pierwsza( wybrane );
        }
        while( 1 ) {
            activatenextpage = false;
            int teraz = getch();
            if( teraz == 80 ) {
                aktualny.gora();
                break;
            }
            if( teraz == 72 ) {
                aktualny.dol();
                break;
            }
            if( teraz == 27 ) {
                break;
            }
            if( teraz == 13 ) {
                activatenextpage = true;
                break;
            }
        }
        cls();
    }
}

Wszystko fajnie, pierwsza strona lux, ale jak wejdę na drugą albo i trzecią stronę to od razu cofa do pierwszej. Nie mam pojęcia w którym miejscu idzie nie tak i nie mam zielonego pojęcia co zawiniło
PS. wiem że nieprofesjonalnie napisany kod :)
P-123047
darko202
» 2014-12-17 23:26:54
1.
deklaracje
int iloscodpowiedzi;
int wybrane;
int nextpage = 1;
bool activatenextpage;

powinny się znaleźć w main
nie twórz i używaj zmiennych globalnych
to jest zła praktyka i prowadzi do trudnych do zdiagnozowania błędów

2.
możesz używać zmiennych w funkcjach/procedurach jeśli przekazujesz je jako parametry
lub zmienne lokalne
inne użycie jest błędem

3.
w kodzie main nie widzę miejsca w którym zmieniasz zmienną nextpage 
tu mogę się mylić, bo trudno się czyta co właściwie robisz
nie widzę jednak miejsca gdzie dałbyś użytkownikowi sterować programem
np. cin, getchar, itp. rozwiązania


4.
W metodach klas odwołujesz się do zmiennych globalnych
to jest bardzo złe
* doczytaj sobie o budowie klas, właściwościach, metodach, hermetyczności
* przenieś deklaracje z punktu 1 do main i zobaczysz liczne problemy
  nie miałoby to miejsca gdybyś lepiej zaprojektował te klasy 





 
P-123051
Szustarol
Temat założony przez niniejszego użytkownika
» 2014-12-18 15:27:02
Ok, przepisalem wszystko od nowa:
C/C++
#include <iostream>
#include <string>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>

using namespace std;

void cls() {
    #ifdef WIN32
    system( "cls" );
    #else
    system( "clear" );
    #endif
}

class Strona {
public:
    int nextpage = 0;
    void pierwsza( int & wybrana ) {
        string odpowiedz[ 999 ];
        cout << "TRESC STRONY PIERWSZEJ" << endl;
        if( wybrana == 0 ) { odpowiedz[ 0 ] = ">"; nextpage = 1; } else odpowiedz[ 0 ] = " "; //strona - 1
       
        if( wybrana == 1 ) { odpowiedz[ 1 ] = ">"; nextpage = 2; } else odpowiedz[ 1 ] = " "; //strona - 1
       
        odpowiedz[ 0 ] += "Strona 2";
        odpowiedz[ 1 ] += "Strona 3";
        cout << odpowiedz[ 0 ] << endl;
        cout << odpowiedz[ 1 ] << endl;
    }
    void druga( int & wybrana ) {
        cout << "TRESC STRONY DRUGIEJ" << endl;
        string odpowiedz[ 999 ];
        if( wybrana == 0 ) { odpowiedz[ 0 ] = ">"; nextpage = 0; } else odpowiedz[ 0 ] = " "; //strona - 1
       
        if( wybrana == 1 ) { odpowiedz[ 1 ] = ">"; nextpage = 2; } else odpowiedz[ 1 ] = " "; //strona - 1
       
        odpowiedz[ 0 ] += "Strona 1";
        odpowiedz[ 1 ] += "Strona 3";
        cout << odpowiedz[ 0 ] << endl;
        cout << odpowiedz[ 1 ] << endl;
    }
    void trzecia( int & wybrana ) {
        cout << "TRESC STRONY TRZECIEJ" << endl;
        string odpowiedz[ 999 ];
        if( wybrana == 0 ) { odpowiedz[ 0 ] = ">"; nextpage = 0; } else odpowiedz[ 0 ] = " "; //strona - 1
       
        if( wybrana == 1 ) { odpowiedz[ 1 ] = ">"; nextpage = 1; } else odpowiedz[ 1 ] = " "; //strona - 1
       
        odpowiedz[ 0 ] += "Strona 1";
        odpowiedz[ 1 ] += "Strona 2";
        cout << odpowiedz[ 0 ] << endl;
        cout << odpowiedz[ 1 ] << endl;
    }
    int nastepna() {
        return nextpage;
    }
};

class Menu {
public:
    void gora( int & wybrana ) {
        if( wybrana > 0 )
             wybrana--;
       
    }
    void dol( int & wybrana, int ile ) {
        if( wybrana < ile )
             wybrana++;
       
    }
};

int main() {
    string odpowiedz[ 999 ];
    Strona strona;
    Menu menu;
    int iloscodpowiedzi;
    int actualpage = 0;
    int wybrana = 0;
    while( 1 ) {
        switch( actualpage ) {
        case 0:
            iloscodpowiedzi = 2;
            strona.pierwsza( wybrana );
            break;
        case 1:
            iloscodpowiedzi = 2;
            strona.druga( wybrana );
            break;
        case 2:
            iloscodpowiedzi = 2;
            strona.trzecia( wybrana );
            break;
        }
        int a = getch();
        switch( a ) {
        case 72: menu.gora( wybrana );
            break;
        case 80: menu.dol( wybrana, iloscodpowiedzi - 1 );
            break;
        case 13: actualpage = strona.nastepna();
            strona.nextpage = 0;
            break;
        }
        cls();
    }
}
Kod zostawiam tutaj, może komuś się przyda.

Jak oceniacie spójność programowania teraz? Czy robię jeszcze jakieś "większe" błędy z programowaniem?
PS. Wiem, że obiekty trochę nieudolnie wykorzystane, po prostu chciałem ogarnąć obiektowość :)
P-123064
darko202
» 2014-12-19 02:17:51
bardzo duża poprawa :)
no i  błąd sam znalazłeś !


ale oczywiście mogłoby być jeszcze lepiej
1.
? string odpowiedz[ 999 ]; w main
? w class Strona  niezainicjowana

2.
jeśli mówimy o obiektowości to :
- obiekty przechowują informację o sobie a nie jakieś zmienne zewnętrzne
?
   int iloscodpowiedzi;
    int actualpage = 0;
    int wybrana = 0;

- klasa powinna mieć konstruktor,  destruktor
  a. zasada
  b. nextpage = 0; // konstruktor

- właściwości prywatne + metody dostępu do nich publiczne - zasada

- nazwy metod z Dużej litery Pierwsza (pola mała) konwencja

3.
 ? klasa menu, a sterowanie w main
 
4.
 class Strona 
* nadmiarowość kodu - metody pierwsza, druga trzecia robią chyba to samo
  nie należy czekać, aż będziesz miał do obsłużenia N stron.

* zbyt wiele celów klasy - string odpowiedz[ 999 ] jest jakby innym obiektem
  aż prosi się o zrealizowaniu tego jako oddzielna klasa

5.
 Po zakończeniu pracy, programista powinien krytycznie odnieść się do tego co zrobił, ale jak ma to zrobić jeśli tworząc program, klasy, metody nie umieścił minimum komentarza
np. classa X - realizuje :..
    własność (properties) przechowuje informację o
    itp.
 jest to bardzo ważne, bo założenie co dana metoda ma wykonywać  robi a co faktycznie robi jest potem trudne do weryfikacji.
  
brak komentarza nie jest błędem programowania, ale może prowadzić do błędów fundamentalnych programu. np. program/klasa/metoda nie realizuje założeń.   
 
6.
  to co napisałem w p.5 zauważam w Twoim programie.   
na początku napisałeś
>>chciałem napisać prosty kod gry (silnika gry) tekstowej (konsolowej)

czy to co przedstawiłeś to realizuje ? moim zdaniem nie - bo czym jest silnik.
dajesz zasilanie ( program dane) i jedziemy.

Czy Twój silnik może np. obsłużyć test na prawo jazdy (stara wersja 500 pytań, 21 egzaminacyjnych, wiele poprawnych odpowiedzi 1-3,  zwrócić wynik testu
 
Wprawdzie nie jest to gra, ale czym to się różni od takiego testu ?





P-123095
« 1 »
  Strona 1 z 1