-#include <stdio.h>
-#include <string.h>
-
-#include "block.h"
-#include "function.h"
-#include "type.h"
-
#include "constant.h"
/* constants */
-int height = 20;
-int minwidth = 8;
-int width = 10;
-int maxwidth = 15;
-
-int nbdigit = 5;
-int maxscor = 100000;
-int nbholes = 2;
-
int savelen = 12;
int xoffset = 1;
int yoffset = 1;
-/* blocks */
-
-#define _nb_blocks_std 12
-
-block_t _blocks_std[_nb_blocks_std] = {
- {3, 3, yellow, " .... . "}, // F
- {1, 5, blue, "...."}, // I
- {2, 4, lightmagenta, ". . . .."}, // L
- {2, 4, lightblue, " .... . "}, // N
- {2, 3, lightgreen, " ....."}, // P
- {3, 3, lightcyan, "... . . "}, // T
- {3, 2, magenta, ". ...."}, // U
- {3, 3, cyan, ". . ..."}, // V
- {3, 3, lightergreen, ". .. .."}, // W
- {3, 3, red, " . ... . "}, // X
- {2, 4, darkblue, " ... . ."}, // Y
- {3, 3, brown, ".. . .."}, // Z
-};
-
-block_t *getblocks (char *name, int *nb)
-{
- block_t *pt = NULL;
-
- if (strcmp (name, "std") == 0) {
- pt = _blocks_std;
- *nb = _nb_blocks_std;
- }
-
- return pt;
-}
-
-/* board */
-
-board_t *getboard (char *name)
-{
- board_t *board = NULL;
-
- if (strcmp (name, "6x10") == 0) {
- board = initboard (6, 10);
- } else if (strcmp (name, "5x12") == 0) {
- board = initboard (5, 12);
- } else if (strcmp (name, "4x15") == 0) {
- board = initboard (4, 15);
- } else if (strcmp (name, "3x20") == 0) {
- board = initboard (3, 20);
- } else if (strcmp (name, "list") == 0) {
- printf ("board: 6x10 5x12 4x15 3x20\n");
- board = (board_t *)(-1);
- }
-
- return board;
-}
-
/* vim: set ts=4 sw=4 et: */
#ifndef __CONSTANT_H__
#define __CONSTANT_H__
-#include "type.h"
-
/* global constants */
#ifndef __CONSTANT_C__
#endif /* __CONSTANT_C__ */
-/* block definitions */
-
-block_t *getblocks (char *name, int *nb);
-
-board_t *getboard (char *name);
-
#endif /* __CONSTANT_H__ */
/* vim: set ts=4 sw=4 et: */
}
}
-void displayblock (board_t *board, block_t *block, int x, int y)
+void displaysnake (board_t *board, snake_t *snake)
{
- int i, j;
-
- if (x == -1) {
- x = board->width / 2;
- }
-
- if (y == -1) {
- y = (board->height - block->height) / 2;
- }
+ int i;
- for (i = 0; i < block->width; i++) {
- for (j = 0; j < block->height; j++) {
- if (*getcell (block, i, j) != ' ') {
- _element (board, x - block->width / 2 + i, y + j, '0' + block->color);
- }
- }
+ int color = green;
+ for (i = 0; i < snake->length; i++) {
+ _element (board, snake->x[i], snake->y[i], color);
+ color = darkgreen;
}
}
return board;
}
-board_t *setscale (board_t *board, int scale)
+board_t *applyscale (board_t *board, int scale)
{
board->scale = scale;
switch (scale) {
case 0:
- board->xsize = board->width;
- board->ysize = board->height;
+ board->width = board->xsize;
+ board->height = board->ysize;
break;
case 1:
- board->xsize = board->width * 2;
- board->ysize = board->height;
+ board->width = board->xsize / 2;
+ board->height = board->ysize;
break;
case 2:
- board->xsize = board->width * 2;
- board->ysize = board->height * 2;
+ board->width = board->xsize / 2;
+ board->height = board->ysize / 2;
break;
case 3:
- board->xsize = board->width * 3;
- board->ysize = board->height * 2;
+ board->width = board->xsize / 3;
+ board->height = board->ysize / 2;
break;
}
return board;
return board;
}
-block_t *initblock (int width, int height)
+snake_t *initsnake (board_t *board)
{
- block_t *block = (block_t *) malloc (sizeof (block_t));
- CHECKALLOC (block);
- block->tab = (char *) calloc (1, width * height + 1);
- CHECKALLOC (block->tab);
- memset (block->tab, ' ', width * height);
- block->width = width;
- block->height = height;
- return block;
-}
+ snake_t *snake = (snake_t *) calloc (1, sizeof (snake_t));
+ CHECKALLOC (snake);
-block_t *changeblock (block_t *dest, block_t *src)
-{
- block_t *ret = NULL;
- if (dest && src) {
- free (dest->tab);
- memcpy (dest, src, sizeof (block_t));
- dest->tab = strdup (src->tab);
- CHECKALLOC (dest->tab);
- ret = dest;
- }
- return ret;
-}
+ snake->maxlength = board->width * board->height + 1;
-block_t *copyblock (block_t *block)
-{
- block_t *newblock = initblock (block->width, block->height);
- char *tab = newblock->tab;
- memcpy (newblock, block, sizeof (block_t));
- newblock->tab = tab;
- memcpy (newblock->tab, block->tab, block->width * block->height + 1);
- return newblock;
+ snake->x = (int *) calloc (snake->maxlength, sizeof (int));
+ CHECKALLOC (snake->x);
+
+ snake->y = (int *) calloc (snake->maxlength, sizeof (int));
+ CHECKALLOC (snake->y);
+
+ snake->x[0] = board->width / 2 + 1;
+ snake->y[0] = board->height / 2;
+ snake->x[1] = board->width / 2;
+ snake->y[1] = board->height / 2;
+
+ snake->length = 2;
+ snake->dir = 0;
+
+ return snake;
}
-void freeblock (block_t *block)
+void freesnake (snake_t *snake)
{
- if (block) {
- free (block->tab);
+ if (snake != NULL) {
+ free (snake->x);
+ free (snake->y);
}
- free (block);
+ free (snake);
}
-block_t *rotateblock (block_t *block, int rot)
+int movesnake (board_t *board, snake_t *snake, int dir)
{
- int i, j;
-
- rot = (rot > 0) ? rot % 4 : ((1 - rot / 4) * 4 + rot) % 4;
+ int i;
+ int ret = 0;
- block_t *newblock = NULL;
+ int x = snake->x[0];
+ int y = snake->y[0];
- switch (rot) {
+ switch (dir) {
case 0:
- newblock = copyblock (block);
+ y--;
break;
case 1:
- newblock = initblock (block->height, block->width);
- newblock->color = block->color;
- for (i = 0; i < block->width; i++) {
- for (j = 0; j < block->height; j++) {
- *getcell (newblock, block->height - 1 - j, i) = *getcell (block, i, j);
- }
- }
+ x--;
break;
case 2:
- newblock = initblock (block->width, block->height);
- newblock->color = block->color;
- for (i = 0; i < block->width; i++) {
- for (j = 0; j < block->height; j++) {
- *getcell (newblock, block->width - 1 - i, block->height - 1 - j) = *getcell (block, i, j);
- }
- }
+ y++;
break;
case 3:
- newblock = initblock (block->height, block->width);
- newblock->color = block->color;
- for (i = 0; i < block->width; i++) {
- for (j = 0; j < block->height; j++) {
- *getcell (newblock, j, block->width - 1 - i) = *getcell (block, i, j);
- }
- }
+ x++;
break;
}
- changeblock (block, newblock);
- freeblock (newblock);
+ if ((x >= 0) && (x < board->width) &&
+ (y >= 0) && (y < board->height)) {
+
+ char *cell = getcell (board, x, y);
+ switch (*cell) {
+ case '6': /* decrease size */
+ if (snake->length > 2) {
+ snake->length--;
+ snake->x[snake->length] = 0;
+ snake->y[snake->length] = 0;
+ }
+ /* fall through */
+ case ' ': /* only forward */
+ for (i = snake->length - 1; i > 0; i++) {
+ snake->x[i] = snake->x[i - 1];
+ snake->y[i] = snake->y[i - 1];
+ }
+ break;
+ case '5': /* increase size */
+ for (i = snake->length - 1; i >= 0; i++) {
+ snake->x[i + 1] = snake->x[i];
+ snake->y[i + 1] = snake->y[i];
+ }
+ snake->length++;
+ break;
+ }
+
+ snake->x[0] = x;
+ snake->y[0] = y;
+
+ snake->dir = dir;
- return block;
+ ret = 1;
+ }
+
+ return ret;
}
/* vim: set ts=4 sw=4 et: */
board_t *initboard (int width, int height);
-board_t *setscale (board_t *board, int scale);
+board_t *applyscale (board_t *board, int scale);
void freeboard (board_t *board);
board_t *loadboard (char *str);
-block_t *initblock (int width, int height);
+snake_t *initsnake (board_t *board);
-block_t *changeblock (block_t *dest, block_t *src);
+void freesnake (snake_t *snake);
-block_t *copyblock (block_t *block);
-
-void freeblock (block_t *block);
-
-block_t *rotateblock (block_t *block, int rot);
+int movesnake (board_t *board, snake_t *snake, int dir);
#endif /* __FUNCTION_H__ */
/* depend: */
/* cflags: */
-/* linker: block.o color.c constant.o debug.o display.o function.o -lcurses */
-/* doslnk: block.o color.c constant.o debug.o display.o function.o -lpdc~1 */
-/* winlnk: block.o color.c constant.o debug.o display.o function.o -lpdcurses */
+/* linker: block.o color.c constant.o debug.o display.o function.o time.o -lcurses */
+/* doslnk: block.o color.c constant.o debug.o display.o function.o time.o -lpdc~1 */
+/* winlnk: block.o color.c constant.o debug.o display.o function.o time.o -lpdcurses */
#include <curses.h>
#include <stdio.h>
char *version = "0.1";
char *filename = NULL;
-int scale = 1;
-char *boardname = "6x10";
+int scale = 0;
char *help =
"<i> Move up cursor\n"
"<j> Move left cursor\n"
"<k> Move down cursor\n"
"<l> Move right cursor\n"
- "<o> Hold/Release piece\n"
+ "<p> Pause\n"
"<q> Quit\n"
"<s> Save file\n"
;
int usage (int ret)
{
FILE *fd = ret ? stderr : stdout;
- fprintf (fd, "usage: %s [-b] [-f file] [-h] [-s int] [-v int]\n", progname);
- fprintf (fd, " -b: board form [6x10, 5x12, 4x15, 3x20] (%s)\n", boardname);
+ fprintf (fd, "usage: %s [-f file] [-h] [-s int] [-v int]\n", progname);
fprintf (fd, " -f: file name (%s)\n", (filename) ? filename : "none");
fprintf (fd, " -h: help message\n");
fprintf (fd, " -s: scale [0..3] (%d)\n", scale);
- fprintf (fd, " -v: verbose level (%d)\n", verbose);
+ fprintf (fd, " -v: verbose level [%d..%d] (%d)\n", ERROR, DEBUG, verbose);
fprintf (fd, "%s version %s\n", progname, version);
return ret;
}
char c = arg[1];
switch (c) {
- case 'b':
- arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
- if (arg == NULL) {
- VERBOSE (ERROR, fprintf (stderr, "%s: no board specified\n", progname));
- return usage (1);
- }
- boardname = arg;
- break;
case 'f':
arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
if (arg == NULL) {
return 1;
}
- /* load playground */
- board_t *board = NULL;
- if (filename) {
- char *buffer = readdata (filename);
- if (buffer == NULL) {
- VERBOSE (ERROR, fprintf (stderr, "can't read file (%s)\n", filename));
- return 1;
- }
- board = loadboard (buffer);
- free (buffer);
- if (board == NULL) {
- VERBOSE (ERROR, fprintf (stderr, "incorrect file (%s)\n", filename));
- return 1;
- }
- } else if (boardname) {
- board = getboard (boardname);
- if (board == (board_t *)(-1)) {
- return 0;
- }
- if (board == NULL) {
- VERBOSE (ERROR, fprintf (stderr, "unknown board (%s)\n", boardname));
- return 1;
- }
- }
- setscale (board, scale);
-
/* init curses window */
initscr ();
noecho ();
curs_set (0);
start_color ();
+ /* load playground */
+ int w0board = COLS - strmaxlen (help, '\n') - 2 * (xoffset + 1);
+ int h0board = LINES - 2 * (yoffset + 1);
+ board_t *board = initboard (w0board, h0board);
+ applyscale (board, scale);
+
/* window positions */
int xboard = board->xoffset = xoffset + 1;
- int yboard = board->yoffset = xoffset + 1;
- int xhelp = xboard + xoffset + 1 + board->xsize;
- int xcursor = 0;
- int ycursor = 0;
- int yhelp = yboard - 1;
+ int yboard = board->yoffset = yoffset + 1;
+ int xscore = xboard + xoffset + 1 + board->xsize;
+ int yscore = yboard - 1;
+ int xhelp = xscore;
+ int yhelp = yscore + 3 + xoffset;
+ int xcursor = board->width / 2;
+ int ycursor = board->height / 2;
int xsave = max (xboard + (board->xsize - savelen) / 2, 1);
int ysave = yboard + (board->ysize - 1) / 2;
char *savename = NULL;
- /* help window */
- int lhelp = helpwindow (help, xhelp, yhelp);
-
- /* window positions */
- int xmsg = xboard;
- int ymsg = max (yboard + xoffset + 1 + board->ysize, yhelp + lhelp + yoffset + 1);
- int lmsg = xhelp - xmsg + strmaxlen (help, '\n');
+ VERBOSE (DEBUG, printf ("width: %d\nheight: %d\n", board->width, board->height));
+ /* init snake */
+ snake_t *snake = initsnake (board);
+ /* help window */
+ helpwindow (help, xhelp, yhelp);
+
+ /* main loop */
+ int stop = 0;
+ int mode = 0;
+ int dir = 3;
+ timeval_t turn = {0, 0};
+ int speed = 3000;
+ while (!stop) {
+
+ boardwindow (board, 1);
+ if (isovertime (&turn)) {
+ setendtime (&turn, speed);
+ if (!movesnake (board, snake, snake->dir)) {
+ mode = 2;
+ }
+ }
+ int ch = getch ();
+
+ /* main controls */
+ switch (ch) {
+ case ' ':
+ case 'p':
+ if (mode == 0) {
+ mode = 1;
+ setendtime (&turn, speed);
+ } else if (mode == 1) {
+ mode = 0;
+ }
+ break;
+ case 'q':
+ stop = 1;
+ break;
+ case 's':
+ savename = savewindow (savelen, xsave, ysave);
+ if (savename != NULL) {
+ char *ptr = saveboard (board);
+ if (writedata (savename, ptr)) {
+ VERBOSE (WARNING, printf ("issue writing Board\n"));
+ }
+ free (ptr);
+ free (savename);
+ }
+ break;
+ }
+ if (mode != 1) {
+ continue;
+ }
+ /* game controls */
+ switch (ch) {
+ case KEY_UP:
+ case 'i':
+ if (!movesnake (board, snake, 0)) {
+ mode = 2;
+ }
+ break;
+ case KEY_LEFT:
+ case 'j':
+ if (!movesnake (board, snake, 1)) {
+ mode = 2;
+ }
+ break;
+ case KEY_DOWN:
+ case 'k':
+ if (!movesnake (board, snake, 2)) {
+ mode = 2;
+ }
+ break;
+ case KEY_RIGHT:
+ case 'l':
+ if (!movesnake (board, snake, 3)) {
+ mode = 2;
+ }
+ break;
+ }
+ }
endwin ();
--- /dev/null
+#include <stdlib.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "time.h"
+
+int newseed (int seed)
+{
+ if (seed == 0) {
+ seed = time (NULL);
+ }
+ srand (seed);
+ return seed;
+}
+
+void setendtime (timeval_t *t, int s)
+{
+ gettimeofday (t, NULL);
+ t->tv_usec += s * 1000l;
+ t->tv_sec += t->tv_usec / 1000000l;
+ t->tv_usec = t->tv_usec % 1000000l;
+}
+
+int isovertime (timeval_t *t)
+{
+ struct timeval _c;
+ struct timeval *c = &_c;
+ gettimeofday (c, NULL);
+ return ((t->tv_sec + t->tv_usec == 0) || (t->tv_sec < c->tv_sec) || ((t->tv_sec == c->tv_sec) && ( t->tv_usec < c->tv_usec)));
+}
+
+void msleep (int msec)
+{
+ usleep (msec * 1000);
+}
+
+/* vim: set ts=4 sw=4 et: */
--- /dev/null
+#ifndef __TIME_H__
+#define __TIME_H__
+
+#include <sys/time.h>
+
+typedef struct timeval timeval_t;
+
+int newseed (int seed);
+
+void setendtime (timeval_t *t, int s);
+
+int isovertime (timeval_t *t);
+
+void msleep (int msec);
+
+#endif /* __TIME_H__ */
+
+/* vim: set ts=4 sw=4 et: */
char *tab;
} block_t;
+typedef struct {
+ int dir;
+ int length;
+ int maxlength;
+ int *x;
+ int *y;
+} snake_t;
+
#endif /* __TYPE_H__ */
/* vim: set ts=4 sw=4 et: */