Suche
Suche Menü

Lösung Teil 1

Ein Lösungsvorschlag zur Aufgabe Snake, Konsolen-Spiel.

/*
	Snake, Console Game

	move the snake with w, a, s, d
	terminate with x
	
	Linux-System required!
 
	@author: www.c-howto.de
*/

#include<stdio.h>
#include<termio.h>
#define BLANK 0
#define HEAD 1
#define TAIL 2
#define FOOD 9
#define KEY_MOVE_UP 119
#define KEY_MOVE_LEFT 97
#define KEY_MOVE_DOWN 115
#define KEY_MOVE_RIGHT 100
#define WIDTH 60
#define HEIGHT 20
#define DEBUG 0

struct position {
	int x;
	int y;
} pos;

int field[WIDTH][HEIGHT];

static struct termio savemodes;
static int havemodes = 0;
int tty_break();
int tty_getchar();
int tty_fix();

void resetField();
void printField();
void setItem(int, int, int);
void move(int);

int main () {
	int key;
	resetField();

	pos.x=WIDTH/2;
	pos.y=HEIGHT/2;
	setItem(pos.x, pos.y, HEAD);
	tty_break();

	while(key!='x') {
		printField();
		key=tty_getchar();
		move(key);
		if(DEBUG) {
			printf(" %d %c |", key);
		}
	}

	printf("\n\n");
	return 0;
}

void move(int key) {

	setItem(pos.x, pos.y, TAIL);
	switch(key) {
		case KEY_MOVE_UP: pos.y--; break;
		case KEY_MOVE_LEFT: pos.x--; break;
		case KEY_MOVE_DOWN: pos.y++; break;
		case KEY_MOVE_RIGHT: pos.x++; break;
	}

	if(pos.y >= HEIGHT) pos.y=0;
	if(pos.y < 0) pos.y=HEIGHT-1;
	if(pos.x >= WIDTH) pos.x=0;
	if(pos.x < 0) pos.x=WIDTH-1;

	setItem(pos.x, pos.y, HEAD);
}

void setItem(int x, int y, int item) {
	field[x][y] = item;
}

void resetField() {
	int i,j;
	for(i=0;i<HEIGHT;i++) {
		for(j=0;j<WIDTH;j++) {
			field[i][j] = BLANK;
		}
	}
}

void printField() {
	//clear screen
	fprintf(stdout, "\033[2J");
	fprintf(stdout, "\033[1;1H");

	int i,j,x;
	for(i=0;i<HEIGHT+2;i++) {
		printf("\n");
		printf("|");
		for(j=0;j<WIDTH;j++) {
			if(i==0 || i==HEIGHT+1)  {
				printf("-");
			}
			else {
				x = field[j][i];
				switch(x) {
				case BLANK: printf(" "); break;
				case TAIL: printf("*"); break;
				case HEAD: printf("O"); break;
				}
			}
		}
		printf("|");
	}

	// print debug things
	if(DEBUG) {
		printf("\n\nX: %3d   Y: %3d", pos.x, pos.y);
		printf("\n\ni: %3d   j: %3d", i, j);
	}
}

int tty_break() {
	struct termio modmodes;
	if(ioctl(fileno(stdin), TCGETA, &savemodes) < 0)
		return -1;
	havemodes = 1;
	modmodes = savemodes;
	modmodes.c_lflag &= ~ICANON;
	modmodes.c_cc[VMIN] = 1;
	modmodes.c_cc[VTIME] = 0;
	return ioctl(fileno(stdin), TCSETAW, &modmodes);
}

int tty_getchar() {
	return getchar();
}

int tty_fix() {
	if(!havemodes)
		return 0;
	return ioctl(fileno(stdin), TCSETAW, &savemodes);
}