Come posso far funzionare questo mini gioco

di il
56 risposte

Come posso far funzionare questo mini gioco

Buongiorno,
perdonate se mi sono iscritto per chiedere aiuto, ma mi pareva che questo forum fosse uno dei forum italiani più autorevoli e non sapevo dove scrivere, ho questo codice che di per se è molto semplice, ma non riesco a completare.
Praticamente è un gioco Cowboys vs Cheerleaders, dove inserisci il numero di giocatori per squadra e decidi chi attacca per primo, ogni volta che attacchi il numero impostato cala di uno, finito di attaccare viene riproposto se si vuole attaccare con un loop, l'idea è che quando una squadra raggiunge lo 0 appare gameover, con il cout riguardo la relativa squadra che perde, ma per ora non ho idea di come comporlo, completarlo, sapete indirizzarmi?

#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
	char play_again = 's';
	char cow = 's';
	int numCo, numCh;

while (play_again == 's' || play_again == 'S') //loop
	{
	         cout<<"Numero cowboys:  \n";
	         cin>> numCo;
                 cout<<"Numero cheerleaders:  \n";
                 cin>> numCh;
                 cout<<"Chi attacca per primo? (s/n)\n";
                 cin>> cow;

		if ( cow = 's')
		{
			cout<<"I cowboys attaccano per primi, le cheerleaders perdono una unità\n";
			numCh--;
			cout<< numCo<< endl<< numCh<< endl;
        }
		else
		{
			cout<<"Le cheerleader attaccano per prime, i cowboys perdono una unità\n";
			numCo--;
			cout<< numCo<< endl<< numCh<< endl;
        }

		cout<<"\nVuoi attaccare ancora? (s/n)\n";
		cin>> play_again;
	}
	if (numCh = 0);
	{
        cout<<"game over per i cowboys\n";
        return 0;
        fflush(stdin);
        getchar();
    }
}

Il problema inoltre è che permette ai Cowboys di attaccare, ma non il contrario, però non mi pare che ci sia qualcosa di sbagliato, inoltre quando viene riproposto di attaccare il loop non funziona portandomi al game over, avete delucidazioni?
Se avete inoltre qualche consiglio su qualche sito riguardo questo argomento sono aperto pure a questo pur di impararlo, grazie tante

56 Risposte

  • Re: Come posso far funzionare questo mini gioco

    Impara la funzione cin.ignore().
    Questo elimina dei dati rimasti nel buffer ed è da usare prima di acquisire dei nuovi dati. Il tuo problema nasce dal fatto che dopo una acquisizione nel buffer di input è rimasto ancora il carattere new-line che alla prossima acquisizione verrà acquisito lui invece che l'input dell'utente.

    Un altra cosa: togli fflush(stdin). Oltre ad essere sbagliato, vale solo in C e non in C++ e solo se stai lavorando con compilatori Microsoft.
    Togli anche il getchar() che vale per il C. In C++ puoi usare cin.get().
  • Re: Come posso far funzionare questo mini gioco

    skynet ha scritto:


    impara la funzione cin.ignore().
    Questo elimina dei dati rimasti nel buffer ed è da usare prima di acquisire dei nuovi dati. Il tuo problema nasce dal fatto che dopo una acquisizione nel buffer di input è rimasto ancora il carattere new-line che alla prossima acquisizione verrà acquisito lui invece che l'input dell'utente.

    Un altra cosa: togli fflush(stdin). Oltre ad essere sbagliato, vale solo in C e non in C++ e solo se stai lavorando con compilatori Microsoft.
    Togli anche il getchar() che vale per il C. In C++ puoi usare cin.get().
    Oh wow tante funzioni inutili che ho inserito, vedrò di studiare cin.ignore() e ripassare la logica del buffer, che il libro che ho sembra che lo sorvoli leggermente dando una definizione generica, riguardo il format com'era però? Ho la sensazione che mettere il "game over" alla fine in quel modo sia veramente sbagliato.
  • Re: Come posso far funzionare questo mini gioco

    Utilizzo corretto di cin.ignore
    
    #include <iostream>
    #include <limits>
    ........
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    cin >> variabile;
    
    Questo svuota il buffer e lo rende pronto per un nuovo input.
  • Re: Come posso far funzionare questo mini gioco

     if (numCh = 0);
    Questo non è corretto. Devi togliere il punto e virgola e fare la comparazione con ==
     if (numCh == 0)
  • Re: Come posso far funzionare questo mini gioco

    skynet ha scritto:


     if (numCh = 0);
    Questo non è corretto. Devi togliere il punto e virgola e fare la comparazione con ==
     if (numCh == 0)
    Grazie domani correggo e vedo se riesco a inserire un random cosí assomiglia di piú ad un "gioco" vero e proprio
  • Re: Come posso far funzionare questo mini gioco

    
    #include<iostream>
    #include<limits>
    using namespace std;
    
    int main()
    {
    	char play_again = 's';
    	char cow = 's';
    	int numCo, numCh;
    
    
    		cout<<"Numero cowboys:  \n";
    		cin>> numCo;
            cout<<"Numero cheerleaders:  \n";
            cin>> numCh;
            while (play_again == 's' || play_again == 'S')
    	{
            cout<<"Chi attacca per primo? (s/n)\n";
            cin>> cow;
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    		if ( cow = 's')
    		{
    			cout<<"I cowboys attaccano per primi, le cheerleaders perdono una unità\n";
    			numCh--;
    			cout<< numCo<< endl<< numCh<< endl;
            }
    		else
    		{
    			cout<<"Le cheerleader attaccano per prime, i cowboys perdono una unità\n";
    			numCo--;
    			cout<< numCo<< endl<< numCh<< endl;
            }
    
    	}
    	if (numCh == 0)
    	{
            cout<<"Game over per le Cheerleaders";
            return 0;
        }
        if (numCo == 0)
        {
            cout<<"Game over per i Cowboys";
            return 0;
        }
        else
        {
            
    		cout<<"\nVuoi attaccare ancora? (s/n)\n";
    		cin>> play_again;
        }
    }
    
    Almeno ora ho corretto il while così tiene in memoria le unità senza richiederle ogni volta, l'aggiunta del cin.ignore non sembra aver portato grandi cambiamenti, si comporta identicamente senza il suo uso.
    Ora i problemi rimasti sono due, sembra che numCh non cali mai, ma la formattazione e grammatica non mi pare abbia errori, eppure non riesco mai a fare attaccare le Cheerleaders, inoltre non si attiva mai la funzione gameover, ma riparte sempre dal while.
  • Re: Come posso far funzionare questo mini gioco

    Chiedo venia per il post affrettato, ho corretto l'errore if dove solo i cowboys attaccano
    
    		if ( cow == 's')
    		{
    			cout<<"I cowboys attaccano per primi, le cheerleaders perdono una unità\n";
    			numCh--;
    			cout<< numCo<< endl<< numCh<< endl;
            }
    		else if  ( cow == 'n')
    		{
    			cout<<"Le cheerleader attaccano per prime, i cowboys perdono una unità\n";
    			numCo--;
    			cout<< numCo<< endl<< numCh<< endl;
            }
    
    rimane il problema del gameover che non vuole proprio apparire
  • Re: Come posso far funzionare questo mini gioco

    Le if che controllano il termine del gioco e l'input sono fuori dal while. Non saranno mai eseguite ...
  • Re: Come posso far funzionare questo mini gioco

    oregon ha scritto:


    Le if che controllano il termine del gioco e l'input sono fuori dal while. Non saranno mai eseguite ...
    
    #include<iostream>
    #include<limits>
    
    using namespace std;
    
    int main()
    {
    	char play_again = 's';
    	char war = 's';
    	int numCo, numCh;
    
    
    		cout <<"Numero cowboys: ";
    		cin >> numCo;
            cout << "Numero cheerleaders: ";
            cin >> numCh;
            while (play_again == 's' || play_again == 'S')
    	{
            cout << "\nChi attacca per primo? (s/n)\n";
            cin >> war;
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    		if ( war == 's')
    		{
    			cout<<"\nI cowboys attaccano per primi, le cheerleaders perdono una unità" << endl << endl;
    			numCh--;
    			cout << "Numero cowboys " << numCo << endl << "Numero cheerleaders " << numCh << endl;
            }
    		else if  ( war == 'n')
    		{
    			cout<<"\nLe cheerleader attaccano per prime, i cowboys perdono una unità\n" << endl << endl;
    			numCo--;
    			cout << "Numero cowboys " << numCo << endl << "Numero cheerleaders " << numCh << endl;
            }
        if (numCh == 0)
    	{
            cout <<"\nGame over per le Cheerleaders." << endl << endl;
            cout << "Premi enter per chiudere" << endl;
            cin.get();
            return 0;
        }
        if (numCo == 0)
        {
            cout <<"\nGame over per i Cowboys." << endl << endl;
            cout << "Premi enter per chiudere" << endl;
            cin.get();
            return 0;
        }
        else
        {
            
    		cout<<"\nVuoi attaccare ancora? (s/n)\n";
    		cin>> play_again;
        }
    	}
    }
    
    Alla fine sembra abbia deciso di funzionare finalmente, ho più passato tempo a trovare una alternativa a system("PAUSE") per ovvi motivi piuttosto che risolvere il resto, ma è normale accodare così tanti if uno dopo l'altro? Non esiste un modo più pulito?

    Inoltre per dividere l'output delle frasi in modo più separato ho abusato della funzione endl e \n, va bene così o ci sono metodi più ottimali al riguardo?
    Più tardi aggiungo un random con seed dal tempo attuale.

    E' un peccato che l'indentazione funzioni male qua, sarebbe già più semplice se apparisse esattamente come nell'IDE.
  • Re: Come posso far funzionare questo mini gioco

    Alla fine sembra abbia deciso di funzionare finalmente
    Il codice non decide di funzionare o no. Il codice corretto funziona, quello sbagliato no.

    Adesso che hai inserito le if nel ciclo, ha senso.

    L'ultima else non ha senso di esistere.

    Non ha senso parlare di "abuso" di endl o di \n ... quelle che ci vogliono vanno usate.

    "Accodare le if" non è anormale o normale. Vanno usate quelle necessarie e dipende dal problema e dall'algoritmo usato. Non c'è un numero di if valido in assoluto.

    Al posto della system("PAUSE") puoi usare una semplice chiamata a getchar();
  • Re: Come posso far funzionare questo mini gioco

    oregon ha scritto:


    Il codice non decide di funzionare o no. Il codice corretto funziona, quello sbagliato no.
    Si era più sarcasmo ovvio che non decide da se se ha voglia o meno di farlo.

    oregon ha scritto:


    L'ultima else non ha senso di esistere.
    Ero dell'idea che "se nessuna delle due variabili raggiunge lo 0 allora richiama il while", vedo che in effetti funziona lo stesso senza l'else solo che non capisco troppo il senso, dava idea di essere più chiaro aggiungendo l'else.

    oregon ha scritto:


    Non ha senso parlare di "abuso" di endl o di \n ... quelle che ci vogliono vanno usate.
    Capito, credevo solo che l'uso anche se di una semplice funzione, ma in modo frequente potesse appesantire in futuro il programma.

    oregon ha scritto:


    "Accodare le if" non è anormale o normale. Vanno usate quelle necessarie e dipende dal problema e dall'algoritmo usato. Non c'è un numero di if valido in assoluto.
    Più o meno lo stesso discorso del quote precedente, sembra possa appesantirlo, e crei solo che confusione una struttura così, per quello mi dava questa impressione.

    oregon ha scritto:


    Al posto della system("PAUSE") puoi usare una semplice chiamata a getchar();
    Non ho usato getchar() per i motivi elencati da skynet, porta vantaggi ad usare questo piuttosto di cin.get() ?
  • Re: Come posso far funzionare questo mini gioco

    Le cin.ignore si mettono PRIMA DELLA RICHIESTA INPUT non dopo, altrimenti non hanno senso di esistere
    cout <<"Numero cowboys: ";
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            cin >> numCo;
            cout << "Numero cheerleaders: ";
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            cin >> numCh;
            while (play_again == 's' || play_again == 'S')
       {
            cout << "\nChi attacca per primo? (s/n)\n";
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            cin >> war;
    
    ecc......................................
            
  • Re: Come posso far funzionare questo mini gioco

    skynet ha scritto:


    le cin.ignore si mettono PRIMA DELLA RICHIESTA INPUT non dopo, altrimenti non hanno senso di esistere
    Scusami, devo aver letto il forum sbagliato mentre cercavo un po' di teoria, ma è necessario anche nel caso in cui abbiamo differenti variabili, anche se tutto viene memorizzato nel buffer non diversifica tra esse?
    Capirei il senso di usare l'ignore nel caso in cui si chiede di attaccare, perchè è una richiesta ricorrente, ma un numero come la variabile della squadra che viene chiesto in una singola istanza necessita l'ignore visto che non viene richiamata?
  • Re: Come posso far funzionare questo mini gioco

    Se leggi il link che ti ho postato prima capirai che il ruolo del cin.ignore è quello di pulire l'input e renderlo vuoto da dati presenti nel buffer, pronto per accettare un nuovo dato qualunque esso sia. Sarà poi compito del estrattore >>, assegnare il nuovo dato preso in input e assegnarlo alla variabile alla dx dell'estrattore. Se l'estrattore fallisce (dato di tipo sbagliato, altri errori ecc) lo stream sarà messo in stato bad oppure eof a seconda del caso, quindi in realta la soluzione ottima sarebbe quella di togliere prima lo stato bad/eof con cin.clear(), poi svuotare il buffer con cin.ignore() e poi usare l'estrattore >> per ricevere di nuovo il dato. Sembra un procedura lunga ma così sei in una botte di ferro contro qualsiasi possibile input. Se mi dai un minuto ti riscrivo il tuo programma come si deve, così almeno impari dai tuoi errori.
Devi accedere o registrarti per scrivere nel forum
56 risposte