Newsgroup: it.comp.lang.c
Titolo: Riavviare

Scusate del disturbo, ma avrei bisogno di un aiuto. Se io volessi in una
applicazione scritta in Borland C++ riavviare il programma come dovrei fare?
Più precisamente, il programma è scritto con più funzioni, e, qunado viene
chiamata quella che termina il programma ho inserito una domanda del tipo
Vuoi ricominciare? [s/n]. Qui, ho usato un if, ma come posso dirgli di
ricominciare da capo? Ho provato a scrivere main() ma dice che non posso
chiamare main dall'interno del programma, e non posso nemmeno utilizzare un
goto, visto che è in una funzione differente. Qualcuno può darmi qualche
suggerimento?
---
Ramses
---
icq:39860665
http://knowledgeparty.cjb.net
http://evilz0ne.cjb.net

int main()
{
 int c;
while(c != 'n')
{
    /* tuo programma */
    printf("Vuoi ricominciare? [s/n]\n");
   c = getc(stdin);
}
return 0;
}
Dome

 ha scritto

Ok, ma inizializza c oppure usa un do-while.
Inoltre, se non svuoti il "buffer" rischi che il ciclo venga eseguito piu'
volte senza chiedere alcun input da tastiera: es. Se io digitassi :
Vuoi ricominciare ? [s/n]
sicuramente
Cosa succederebbe ?!? Beh, probabilmente il ciclo verrebbe eseguito 8 volte
(dopo aver digitato "sicuramente") senza chiedere alcuna conferma da
tastiera (ma stampando la domanda). Arrivato alla 'n' di sicuramente si
uscirebbe dal ciclo !!! Non e' certamente quello che vuole l'utente visto
che ha scritto : sicuramente ;-)
Rischi un simile problema digitando anche solo la 's' visto che sul buffer
puo' andarci a finire anche il '\n'. (sempre che non termini con EOF !!!)
In sostanza o svuoti il buffer oppure usi un'altra funzione di input.
Alex

, [D0M3] wrote:
Volendo essere pignoli io lo cambierei cosi`:
int main(void)
{
int c;
do
{
    /* tuo programma */
   printf("Vuoi ricominciare? [s/n]\n");
   c = getc(stdin);
} while ((c=tolower(c))!='n');
return 0;
}
-- 
"I've a wonderful proof for this theorem,
but the border of this page is too small
for writing it here" - Pierre Fermat
--

 }
Ringrazio tutti per la risposta, ma forse mi ero spiegato male. Così l'ho
fatto spesso anch'io. Ora la mia difficoltà era che la funzione main chiama
alcune altre funzioni all'interno dello stesso file sorgente. Una di queste,
che si chiama GameOver(), visualizza la famosa domanda, e da qui dovrei
decidere se riavviare il gioco, oppure no. Quindi non penso di poter
utilizzare il sistema del ciclo. Forse però, mi viene in mente ora, potrei
giocare sul risultato che da la funzione GameOver e non farle terminare il
programma, ma farle restituire due valori diversi, ed usare il ciclo while
nella main come mi avete detto voi sul risultato della funzione GameOver().
Fattibile? Ora forse mi sono spiegato meglio, qualche altra idea?
Grazie ancora per il vostro tempo.


 decidere se riavviare il gioco, oppure no.
Scusate, correggo pure me stesso. La funzione main non chiama direttamente
la GameOver(), ma questa viene chiamata da un'altra funzione ancora che
viene chiamata da main() :-)). Insomma, un casino.


 utilizzare il sistema del ciclo.
Allora premetto che non ho idea di come tu abbia programmato il gioco,
ma.....
I giochi hanno (quasi) sempre un game-loop che chiama le varie funzioni del
gioco, le quali possono chiamare a loro volta altre funzioni, quindi se hai
programmato il gioco con rigore il problema non dovrebbe porsi. Il problema
invece si pone se lo hai programmato un po' a caso. Ecco un esempio di
semplice game-loop.
for(;;){    /* Game Loop */
     ...funzione1(...)
     ...funzione 2(...)
     ...funzione 3(...)
     ...funzione 4(...)
     if(GameOver())
          break;
     if(!Ancora())
          break;
}
[E' solo un esempio che termina solo in caso di gameover oppure quando
l'utente non vuole piu' continuare...]
Insomma, nella maggior parte dei casi (programmazione procedurale e non OOP,
ma visto che stiamo parlando di C mi pare ok) i giochi si riescono ad
progettare con un ciclo che chiama piu' funzioni... (oppure con piu' cicli,
ma di cui sempre uno principale (main game loop)).
Alex

 }
Direi che questo non è proprio il mio caso. Per esempio, questa è la mia
main():
void main(void)
{
  unsigned int bordo;
  // Dò alla variabile Direction il valore 0 per dire che la direzione
iniziale
  //  0 è sempre la stessa.
  int direction[2] = {0, 0};
  // Visualizzo i bordi
  DrawGameBorders(5);
  // Visualizzo il punteggio e le scritte
  DrawGameBord();
  // Creo la meletta
  CreateApple();
  // Costruisco lo snake
  BuildSnake();
  // Ottengo la lunghezza dello snake
  GetSnakeLength();
  label:
  while(kbhit() == 0)
  {
    if (direction[1] == 0)
    {
      MoveSnake(KEYPAD_UP);
      if (SnakeNew_x_Pos[1] == (max_screen_width - 1) || SnakeNew_y_Pos[1]
==
         (max_screen_height - 2) || SnakeNew_x_Pos[1] == 2 ||
SnakeNew_y_Pos[1]
         == 2)
      {
        if (bordo) {SleepEx(500, true); bordo = 0;}
      }
      else {SleepEx(50, true); bordo = 1;}
    }
    else
    {
      MoveSnake(direction[1]);
      if (SnakeNew_x_Pos[1] == (max_screen_width - 1) || SnakeNew_y_Pos[1]
==
         (max_screen_height - 2) || SnakeNew_x_Pos[1] == 2 ||
SnakeNew_y_Pos[1]
         == 2)
      {
        if (bordo) {SleepEx(500, true); bordo = 0;}
      }
      else {SleepEx(50, true); bordo = 1;}
    }
  }
  while(kbhit() != 0)
  {
    direction[0] = getch();
    for (int i = 0; i <= 4; i++)
    {
      if (direction[0] == AllowedMoves[i])
      {
        // Ho trovato un tasto valido e muovo il verme. Prima di muoverlo
però
        //  controllo che il movimento sollecitato non sia stato
        //  nella stessa direzione del movimento.
        if (direction[1] != direction[0])
        {
          MoveSnake(direction[1]);
          direction[1] = direction[0];
          goto label;
        }
        goto label;
      }
      else if (direction[0] == ESCAPE) return;
    }
  }
  goto label;
}
Quindi non ho inserito alcun ciclo all'interno di questa funzione.
Tra l'altro, come puoi vedere non c'è neanche la funzione GameOver() perchè
viene chiamata da altre funzioni che spesso non sono neanche quelle che vedi
qui, ma vengono ancora chiamate da queste. Quindi la cosa è complessa. Però
pensavo di fare in modo che la funzione GameOver() chiedesse all'utente se
riprovare o meno, in caso positivo, per esempio, faccio ritornare 2 alla
funzione, altrimenti 0. A questo punto, pensavo di inserire un while
all'interno di questa funzione main() che la comprenda interamente. Ed il
ciclo continua funchè la GameOver() non ritorna 0.
Questo è fattibile? L'ho provato ovviamente, ma mi da errore.
Qualche altra idea???


viene chiamata da main() :-)). Insomma, un casino.
void PlayGame() {
	/* ... */
}
int main() {
	PlayGame();
	return 0;
}
Per ricominciare basta richiamare PlayGame().
Anto
--
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.6, higher than 98% of all previous test takers.
C Language: 3.32, higher than 79% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

   goto label;
Ancora ?!?!?
In sostanza quando ci sono tutti questi goto significa che ti sei perso....
implementa questo codice dall'inizio, ma non programmare cosi' come viene,
fermati a pensare e progetta un attimino, altrimenti .......
E per giochi come questo prova ad utilizzare un "main game loop" dentro una
funzione a parte e per ricominciare semplicemente, quando esci dal ciclo e
quindi da quella funzione, richiami quella funzione....
E' semplicissimo, no ?!?
Prova cosi' !
Alex

 Alex


 Qualche altra idea???
int main () {
	int some_vars;
	while(1) {
		do_something();
		another_function();
		foo();
		bar();
	}
}
void GaveOver(int args) {
	/*...*/
	if (esci) {
		cleanup();
		exit(EXIT_SUCCESS);
	}
}
Imposti   il  programma   in   modo  che   di   default  ricominci   (lo
inserisci  completamente in  un ciclo  infinito). Se devi  uscire chiami
esplicitamente exit().
ciao Ramses
-- 
Home: 
http://kronoz.cjb.net
Non ho ancora capito se il mio cane e` maschio o femmina:
quando fa la pipi` si chiude in bagno

 quando fa la pipi` si chiude in bagno.
Guarda da come va in macchina. Ieri due stavano per venirmi addoso in
macchina....ho notato che erano due ragazze :-)) Non scherzo.

soluzione a venirmi in mente.
dato che esiste (quasi) sempre un costrutto alternativo al goto
sforzati di cercare un'altra soluzione, il tuo prog ne guadagnerà in
semplicità, manutenibilità e chiarezza.
Uno dei pochi casi in cui è indispensabile l'uso del goto è l'uscita
anticipata da più cicli innestati:
for(;;)
	for(i=0; i<10; i++)
		if (i==5) goto label;
label:
 /* ...*/
