Problema joc c++


(Tudor) #1

Deci, am facut un joc de Trivia. Intrebarile sunt incarcate dintr-un fisier. Folosesc functia rand ( ) pt. a genera o intrebare la intamplare. Problema e ca la iniSinglePlayerGame ( ) nu afiseaza intrebarea generata, iar dupa daca dai enter apare asta:

Code:

/** Trivia
* @date 08/10/2017
*
* @author Tudor Micu
*
*/

#include <iostream>

/* used for rand ( ) & system ( ) functions */
#include <cstdlib>

/* used for file managing */
#include <fstream>

/* used for strings */
#include <cstring>

using namespace std;

/* q & a constants */
const int maxQuestions = 1000;

/* q & a vars */
char question[ maxQuestions ][ 240 ],
     answer[ maxQuestions ][ 240 ],
     generatedQuestionID;

/* players (single player) constants */
const int player = 0;

/* players (multi player) constants */
const int playerWhite = 1,
          playerBlack = 2;

/* players vars*/
int playerErrors[ 3 ],
    playerGoodAnswers = 0;

/* other integer vars*/
int switchedModeType,
    switchedDifficulty;

/* other boolean vars*/
bool finishedAction;

/* functions */
void switchModeType ( ) {
    finishedAction = false;

    while ( finishedAction != true ) {
        cout << "\n\n" << " > Switch game mode." << "\n" << "> 1. Single player" << "\n" << "> 2. Multi player (2 players)" << "\n\n" << "> ";
         cin >> switchedModeType;

        if( switchedModeType == 1 || switchedModeType == 2 )
            finishedAction = true;
    }
}

void switchDifficulty ( ) {
    finishedAction = false;

    while ( finishedAction != true ) {
        cout << "\n\n" << " > Switch game difficulty." << "\n" << "> 1. Easy" << "\n" << "> 2. Medium" << "\n" << "> 3. Hard" << "\n\n" << "> ";
         cin >> switchedDifficulty;

        if( switchedDifficulty == 1 || switchedDifficulty == 2 || switchedDifficulty == 3 )
            finishedAction = true;
    }
}

void iniVars ( ) {
    if( switchedModeType == 1 ) {
        switch ( switchedDifficulty ) {
            case 1: playerErrors[ player ] = 5; break;
            case 2: playerErrors[ player ] = 3; break;
            case 3: playerErrors[ player ] = 1; break;
        }
    } else {
        switch ( switchedDifficulty ) {
            case 1: playerErrors[ playerWhite ] = 5, playerErrors[ playerBlack ] = 5; break;
            case 2: playerErrors[ playerWhite ] = 3, playerErrors[ playerBlack ] = 3; break;
            case 3: playerErrors[ playerWhite ] = 1, playerErrors[ playerBlack ] = 1; break;
        }
    }
}

void showRules ( ) {
    cout << "\n\n" << " > Rules:" << "\n\n";

    iniVars ( );

    if( switchedModeType == 1 ) {
        cout << "- you have " << playerErrors[ player ] << " wrong answers accepted. \n";
        cout << "- you need to give a good answer at 25 questions to win. \n\n";
    } else {
        cout << "- every player have " << playerErrors[ playerWhite ] << " wrong answers accepted. \n";
        cout << "- match end win a player is eliminated. \n\n";
    }

}

void loadQuestions ( ) {
    fstream loadQ ( "C:\\Users\\Tudor\\Desktop\\Trivia\\questions.txt", ios::in );

    /* http://www.cplusplus.com/forum/beginner/78150/ */
    if( loadQ.is_open ( ) ) {
        for ( int i = 0; i < maxQuestions; ++i )
        {
            loadQ >> question[i];
        }
    }
    else exit ( 0 );
}

void loadAnswers ( ) {
    fstream loadA ( "C:\\Users\\Tudor\\Desktop\\Trivia\\answers.txt", ios::in );

    /* http://www.cplusplus.com/forum/beginner/78150/ */
    if( loadA.is_open ( ) ) {
        for ( int i = 0; i < maxQuestions; ++i )
        {
            loadA >> answer[i];
        }
    }
    else exit ( 0 );
}

/* https://stackoverflow.com/questions/1912199/better-random-algorithm */
void generateQuestion ( ) { generatedQuestionID = 1 + ( int ) ( 1000.0 * ( rand( ) / ( RAND_MAX + 1.0 ) ) ); }

void iniSinglePlayerGame ( ) {
    loadQuestions ( );
    loadAnswers ( );

    while ( playerErrors[ player ] != 0 ) {
        generateQuestion ( );

        char typedAnswer[ 240 ];

        /* https://cboard.cprogramming.com/cplusplus-programming/61145-cin-get-problem.html */
        cout << question[ generatedQuestionID ];
         cin.ignore ( );
         cin.get ( typedAnswer, 240 );

        if ( strcmp ( typedAnswer, answer[ generatedQuestionID ] ) == 0 ) {
            cout << "Good answer. Next question.";
        } else {
            playerErrors[ player ]--;
            cout << "Wrong answer (correct answer: " << answer[ generatedQuestionID ] << "). Now, you can give a wrong answer for just "
                 << playerErrors[ player ] << " times.";
        }
    }
}

void iniMultiPlayerGame ( ) {
    loadQuestions ( );
    loadAnswers ( );
}

int main ( ) {
    cout << " > Trivia. Are you a genius?" << "\n";

    system ( "pause" );

    switchModeType ( );

    switchDifficulty ( );

    showRules ( );

    system ( "pause" );

    if( switchedModeType == 1 ) {
        iniSinglePlayerGame ( );
    } else {
        iniMultiPlayerGame ( );
    }

    return 0;
}

(Serghei Amelian) #2

Vad ca de data asta le-ai spart in funcţii, dar continui sa folosesti variabile globale si array-uri fixe in loc de std::vector sau std::list.

Am senzatia ca ai elementele array-ului playerErrors neinitializate si probabil playerErrors[player] e diferita de zero din start, de aia probabil nu intra in while.

Despre variabile neinitializate, aici: https://en.wikipedia.org/wiki/Uninitialized_variable

A common assumption made by novice programmers is that all variables are set to a known value, such as zero, when they are declared. While this is true for many languages, it is not true for all of them, and so the potential for error is there. Languages such as C use stack space for variables, and the collection of variables allocated for a subroutine is known as a stack frame. While the computer will set aside the appropriate amount of space for the stack frame, it usually does so simply by adjusting the value of the stack pointer, and does not set the memory itself to any new state (typically out of efficiency concerns). Therefore, whatever contents of that memory at the time will appear as initial values of the variables which occupy those addresses.


(Luca Andrei) #3

Am senzatia ca ai elementele array-ului playerErrors neinitializate si probabil playerErrors[player] e diferita de zero din start, de aia probabil nu intra in while.

Cum adica nu intra in while? Dupa output, pare ca tocmai asta se intampla, intra in while.

Problema pare sa fie de la linia asta :

 if ( strcmp ( typedAnswer, answer[ generatedQuestionID ] ) == 0 ) {

Verifica printr-un output ceva, ce valori au variabilele astea doua.


(Serghei Amelian) #4

Da, m-a pacalit ca a bagat iniVars() in showRules() si presupus din start ca are variabile neinitializateā€¦ Mamma mia, mi-a sucit creierii sa inteleg relatiile dintre functii si variablele globale, ma dau bătut :slight_smile:


(Tudor) #5

Mdaā€¦ noob mai sunt. Am uitat ca am doar 2 intrebari respectiv 2 raspunsuri in fisierele .txt, iar random-ul genereaza un numar de la 0 - 1000ā€¦ deci asta era problema :slight_smile: