Snake in C++ [RISOLTO]

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Avatar utente
m@
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 476
Iscrizione: sabato 19 agosto 2006, 15:59
Località: Viareggio
Contatti:

Snake in C++ [RISOLTO]

Messaggio da m@ »

oggi all'univ...m'era venuta in mente un modo per fare una versione rozzissima di snake...ma era tanto per fare qualcosa...
ecco cosa ho tirato giù

Codice: Seleziona tutto

#include <stdlib.h>
#include <iostream>
#include <unistd.h>

using namespace std;

const int sizel=10;
const int empty=32; //spazio
const int full=35; //@

void initialize_refresh (char[][sizel]);
void print_refresh (char[][sizel]);

int main (){
	char move='a';
	char last='a';
	int x=sizel/2, y=sizel/2;
	char refresh[sizel][sizel];
	initialize_refresh(refresh);
	print_refresh(refresh);
	while (move!='q' && move !='Q'){
		if (move!='a'&&move!='s'&&move!='d'&&move!='w')
			move=last;
		switch (move){
			case 'a':
				refresh[x][y]=empty;
				if (x==0)
					x=sizel;
				refresh[--x][y]=full;
				break;
			case 's':
				refresh[x][y]=empty;
				if (y==(sizel-1))
					y=-1;
				refresh[x][++y]=full;
				break;
			case 'd':
				refresh[x][y]=empty;
				if (x==(sizel-1))
					x=-1;
				refresh[--x][y]=full;
				break;
			case 'w':
				refresh[x][y]=empty;
				if (y==0)
					y=sizel;
				refresh[x][--y]=full;
				break;
		}
		last=move;
		system ("clear");
		print_refresh(refresh);
		system ("sleep 1");
		cin.get (move);
	}			
	return 0;
}

void initialize_refresh (char refresh[][sizel]){
	for (int i=0; i<sizel; i++){
		for (int j=0; j<sizel; j++){
			refresh[i][j]=empty;
		}
	}
	refresh[sizel/2][sizel/2]=full;
}

void print_refresh (char refresh[][sizel]){
	for (int i=0; i<sizel; i++){
		for (int j=0; j<sizel; j++){
			cout<<refresh[i][j];
		}
		cout<<'\n';
	}
}
solo che c'ho un problema...non mi riesce bene dare l'input di movimento...lipperli avevo pensato con una cin.get...solo che se non premo invio non esegue il comando...
mi servirebbe qualcosa che non appena viene premuto un tasto..subito l'informazione viene passata in questo caso alla variabile move...
sapete mica aiutarmi?
un altra cosa...la sleep va bene usata così oppure c'è d meglio?
grazie per l'attenzione
M@


dopo un po' di ammattimenti...ecco il mio snake bello bello :P hahahahhha
Allegati
SNAKE.zip
(13.07 KiB) Scaricato 390 volte
Ultima modifica di m@ il lunedì 16 ottobre 2006, 18:16, modificato 1 volta in totale.
Avatar utente
paper0k
Rampante Reduce
Rampante Reduce
Messaggi: 7220
Iscrizione: lunedì 2 ottobre 2006, 13:39
Contatti:

Re: Snake in C++

Messaggio da paper0k »

Sull'input hai ragione... ho provato anche con getchar ma il risultato è lo stesso  :-[
Ma alcune possibili migliorie le ho trovate :)
Invece di:

system ("sleep 1");
usa

sleep(1);

per cancellare lo schermo usa questo:

cout << "\x1B[2J\x1B[?6h" << endl;
;)
Ultima modifica di paper0k il sabato 7 ottobre 2006, 10:05, modificato 1 volta in totale.
Chiunque può essere ragionevole, ma esser sani di mente è raro (Oscar Wilde)
Wiki|Blog|Twitter|Identi.ca|last.fm
Avatar utente
m@
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 476
Iscrizione: sabato 19 agosto 2006, 15:59
Località: Viareggio
Contatti:

Re: Snake in C++

Messaggio da m@ »

che farebbe di preciso la seconda?

Codice: Seleziona tutto

cout << "\x1B[2J\x1B[?6h" << endl;
e poi per la sleep...è vero che blocca il prog e da tutte le uscite a video alla fine....? mi pare di aver letto cosi in giro ???
M@
Avatar utente
paper0k
Rampante Reduce
Rampante Reduce
Messaggi: 7220
Iscrizione: lunedì 2 ottobre 2006, 13:39
Contatti:

Re: Snake in C++

Messaggio da paper0k »

Utilizza le sequenze esc per terminati vt100 per cancellare lo schermo e posizionarsi all'inizio della finestra
Qui ne trovi altre http://www.comptechdoc.org/os/linux/howlinuxworks/linux_hlvt100.html
Si lo sleep non è il massimo, spesso viene usato usleep come alternativa  ;)
Chiunque può essere ragionevole, ma esser sani di mente è raro (Oscar Wilde)
Wiki|Blog|Twitter|Identi.ca|last.fm
Avatar utente
TonT
Prode Principiante
Messaggi: 156
Iscrizione: venerdì 1 settembre 2006, 19:39
Località: là sui monti con annette

Re: Snake in C++

Messaggio da TonT »

per prendere subito l' informazione hai provato con getch() ?
...Ma io, senza legge, rubai in nome mio,
quegli altri, nel nome di dio...
Avatar utente
m@
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 476
Iscrizione: sabato 19 agosto 2006, 15:59
Località: Viareggio
Contatti:

Re: Snake in C++

Messaggio da m@ »

kuBN ..penso che la getch() sia proprio quello di cui ho bisogno...me l'aveva consigliato anche un mio amico...solo che non mi riesce inizializzarla...sotto che libreira dovrebbe stare?
M@
Avatar utente
TonT
Prode Principiante
Messaggi: 156
Iscrizione: venerdì 1 settembre 2006, 19:39
Località: là sui monti con annette

Re: Snake in C++

Messaggio da TonT »

dovrebbe stare in conio.h
...Ma io, senza legge, rubai in nome mio,
quegli altri, nel nome di dio...
Avatar utente
m@
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 476
Iscrizione: sabato 19 agosto 2006, 15:59
Località: Viareggio
Contatti:

Re: Snake in C++

Messaggio da m@ »

mi dice no such file or directory  >:(
M@
Avatar utente
TonT
Prode Principiante
Messaggi: 156
Iscrizione: venerdì 1 settembre 2006, 19:39
Località: là sui monti con annette

Re: Snake in C++

Messaggio da TonT »

girando un pò qua e là ( con google) ho visto che la libreria conio.h non esiste con il compilatore gcc
prova con ncurses.h
...Ma io, senza legge, rubai in nome mio,
quegli altri, nel nome di dio...
Avatar utente
m@
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 476
Iscrizione: sabato 19 agosto 2006, 15:59
Località: Viareggio
Contatti:

Re: Snake in C++

Messaggio da m@ »

nada :(
M@
Avatar utente
delta
Prode Principiante
Messaggi: 88
Iscrizione: lunedì 10 luglio 2006, 14:29
Località: Roma

Re: Snake in C++

Messaggio da delta »

si, getch() stà nella lib, che è solo per win....
forse puoi usare uno scanf con qualche controllo su cio' che ti viene inserito...
-la risposta non la devi cercare fuori la risposta è dentro di te-
-che però è: sbagliata!-
Giovanni
danlugli

Re: Snake in C++

Messaggio da danlugli »

Prova così:

Codice: Seleziona tutto

/* man 2 select
   man 2 select_tut
   man 2 read
   man 3 termios
*/
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>
#include <stdio.h>
#include <termios.h>
#include <iostream>
using namespace std;
int main () {
  
  termios before;
  tcgetattr (STDIN_FILENO, &before);
  termios after = before;
  after.c_lflag &= (~ICANON);
  after.c_lflag &= (~ECHO);
  tcsetattr (STDIN_FILENO, TCSANOW, &after);
  
  fd_set rfds0;
  FD_ZERO (&rfds0);
  FD_SET (STDIN_FILENO, &rfds0);
  int maxfd = STDIN_FILENO;
  
  cout << "premi 'z' per finire" << endl;
  
  for (;;) {
    struct timeval tv;
    tv.tv_sec = 10;
    tv.tv_usec = 0;
    fd_set rfds = rfds0;
    int nready = select (maxfd + 1, &rfds, 0, 0, &tv);
    if (nready == 0) cerr << "Allora lo premi sto tasto o no?" << endl;
    else if (nready < 0) cerr << "errore " << errno << endl;
    else if (FD_ISSET (STDIN_FILENO, &rfds)) {
      cout << "Hai premuto ";
      char c;
      read (STDIN_FILENO, &c, 1);
      if (isprint (c)) cout << c << endl;
      else cout << "un tasto non stampabile" << endl;
      if (c == 'z') {
        cout << "ciao" << endl;
        tcsetattr (STDIN_FILENO, TCSANOW, &before);
        break;
      }
    }
    else cerr << "boh?" << endl;
  }
  return 0;
}
saluti
Avatar utente
m@
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 476
Iscrizione: sabato 19 agosto 2006, 15:59
Località: Viareggio
Contatti:

Re: Snake in C++

Messaggio da m@ »

scusa ma che sarebbe? ???
M@
danlugli

Re: Snake in C++

Messaggio da danlugli »

E provare a compilarlo ed eseguirlo? Non dovrebbe esplodere.
Scherzi a parte, mi sembra di aver capito che cerchi un modo per leggere da tastiera ogni singolo tasto premuto.
Questo è un modo e, a quanto ne so, è l'unico: usare termios per cambiare le impostazioni di stdin (setvbuf non funziona su stdin).
La select in questo caso non è indispensabile (se non ti serve il timeout). Sarebbe indispensabile se dovessi leggere contemporaneamente da più canali (es. tastiera, socket, fifo etc): in questo caso consente di essere risvegliati quando succede qualcosa e non sprecare cpu in polling.
Saluti
Avatar utente
m@
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 476
Iscrizione: sabato 19 agosto 2006, 15:59
Località: Viareggio
Contatti:

Re: Snake in C++

Messaggio da m@ »

boia peso  :o ;D
M@
danlugli

Re: Snake in C++

Messaggio da danlugli »

suvvia, sono poche righe...
Avatar utente
m@
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 476
Iscrizione: sabato 19 agosto 2006, 15:59
Località: Viareggio
Contatti:

Re: Snake in C++

Messaggio da m@ »

ihihih grazie mille...era proprio quello di ccui avevo bisogno...ora vedo come integrarlo nel mio proggiettino...
stay tuned :)
M@
Avatar utente
m@
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 476
Iscrizione: sabato 19 agosto 2006, 15:59
Località: Viareggio
Contatti:

Re: Snake in C++

Messaggio da m@ »

una domanda...non è che potresti fare un commento alle righe del progrmma che hai scritto? perche senno non capisco bene cosa facciano..e dopo non saprei come integrarlo nel giochino...grazie mille...
M@
danlugli

Re: Snake in C++

Messaggio da danlugli »

Ecco qui

Codice: Seleziona tutto

/* Questo programma mostra l'impostazione di alcuni attributi del terminale
   e l'uso della select().

   Per ulteriori informazioni ed altri esempi:
   man 2 select
   man 2 select_tut
   man 2 read
   man 3 termios
   
   Daniele Lugli 2006
   Liberamente utilizzabile e modificabile
*/

#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>
#include <stdio.h>
#include <termios.h>
#include <iostream>

using namespace std;

int main () {
  
  // Dichiaro una struttura termios, che descrive le impostazioni del terminale
  termios before;
  
  // La riempio con i valori correnti
  tcgetattr (STDIN_FILENO, &before);
  
  // Ne faccio una copia da modificare
  termios after = before;
  
  // Disabilito il "modo canonico" che, tra altre cose, comprende il line buffering
  after.c_lflag &= (~ICANON);
  
  // Disabilito l'eco dei caratteri sullo schermo
  after.c_lflag &= (~ECHO);
  
  // Imposto i flag cosi' modificati
  tcsetattr (STDIN_FILENO, TCSANOW, &after);
  
  
  // Dichiaro una struttura per il "read file descriptors set" della select
  fd_set rfds0;
  
  // La inizializzo a zero
  FD_ZERO (&rfds0);
  
  // Imposto un flag per stdin (potrei impostarne anche per altri canali)
  FD_SET (STDIN_FILENO, &rfds0);
  
  // Tengo nota del piu' alto file descriptor, servira' alla select
  int maxfd = STDIN_FILENO;
  
  cout << "premi 'z' per finire" << endl;
  
  for (;;) {
    
    // Dichiaro una struttura per il timeout della select
    struct timeval tv;
    
    // 10 secondi
    tv.tv_sec = 10;
    
    // 0 microsecondi
    tv.tv_usec = 0;
    
    // Faccio una copia del read file descriptors set, select puo' modificarlo
    fd_set rfds = rfds0;
    
    // Chiamo la select e resto appeso qui, senza consumare cpu, finche' non
    // arriva qualcosa su uno dei canali che ho impostato (qui ho impostato
    // solo stdin) oppure finche' non va in timeout
    int nready = select (maxfd + 1, &rfds, 0, 0, &tv);
    
    if (nready == 0) {
      // select ritorna 0: nessun canale e' pronto, e' uscita per timeout
      cerr << "Allora lo premi sto tasto o no?" << endl;
    }
    else if (nready < 0) {
      // select ritorna <0: errore; il codice di errore lo trovo nella
      // variabile globale errno
      cerr << "errore " << errno << endl;
    }
    else if (FD_ISSET (STDIN_FILENO, &rfds)) {
      // nready>0, quindi uno o piu' canali sono leggibili.
      // Nel nostro caso c'e' solo stdin, ma comunque lo verifico
      // testando rfds
      cout << "Hai premuto ";
      char c;
      // Leggo un carattere (non mi blocco perche' sono sicuro che c'e')
      read (STDIN_FILENO, &c, 1);
      if (isprint (c)) {
        // se e' stampabile lo stampo
        cout << c << endl;
      }
      else {
        // altrimenti non voglio faccine
        cout << "un tasto non stampabile" << endl;
      }
      if (c == 'z') {
        // E' ora di andarsene
        cout << "ciao" << endl;
        break;
      }
    }
    else {
      // select() ha ritornato >0 ma STDIN_FILENO non risulta impostato.
      // Questo non dovrebbe succedere mai.
      cerr << "boh?" << endl;
    }
  }
  // Ripristino le impostazioni originali del terminale
  tcsetattr (STDIN_FILENO, TCSANOW, &before);
  return 0;
}
Saluti
Avatar utente
m@
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 476
Iscrizione: sabato 19 agosto 2006, 15:59
Località: Viareggio
Contatti:

Re: Snake in C++

Messaggio da m@ »

grazie..dopo mi documento...
una cosetta...qual'è il codice per la freccia destra sinistra..ec ecc?
tipo se volessi fare uno switch...come dovrei fare?

Codice: Seleziona tutto

case '\E[C' | '\EOC':
non me lo accetta...
any tricks?
M@
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 3 ospiti