#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
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
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@
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
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@
/* 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;
}
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?