commit 11fb66043d316e1a6c6867e0feb5cbdfa5635ef6
parent 1b195e5460cb4e090fca849e0c2bd968a4f18fa1
Author: Claudio Alessi <smoppy@gmail.com>
Date: Fri, 26 Oct 2012 19:51:21 +0200
worm2.1 -> worm
Diffstat:
D | worm2.1.c | | | 472 | ------------------------------------------------------------------------------- |
1 file changed, 0 insertions(+), 472 deletions(-)
diff --git a/worm2.1.c b/worm2.1.c
@@ -1,472 +0,0 @@
-/*
- * Copyright (c) 2006
- * Claudio M. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * TODO
- * o fix: eat the numbers with the body too
- * o fix: eat the numbers from any digit
- * o fix: the numbers with 2 digits are out of borders
- * o Create the '?' key which show the help and the commands
- * o Ehm.. ehm.. Add the colors :-) Any volunteer?
-*/
-
-#include <stdio.h>
-#include <curses.h>
-#include <time.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define HEAD 'o' /* normal head */
-#define WORM 'w' /* worm's body */
-#define EATH 'O' /* eating head */
-
-#define MINROW 21
-#define MINCOL 80
-
-#define LEVEAT 5 /* Food eated befor to increment the level */
-#define LEVMAX 9 /* Max speed (to preserve the refresh delay in auto-mode) */
-
-/* Recursive list */
-typedef struct list_t {
- int x;
- int y;
- struct list_t *next;
-} List;
-
-/* Routes */
-enum { R_UP = 1, R_LEFT, R_DOWN, R_RIGHT } route;
-
-/*
- * Prototypes
-*/
-void newnode(List **listp, int y, int x);
-void wormshow(List *worm, char ch, char chhead);
-void moveworm(List **worm, int way);
-int isout(List *worm);
-int isbite(List *worm);
-int iseat(List *worm, int row, int col);
-void killworm(List **worm);
-
-/* The main function */
-int main(int argc, char **argv)
-{
- int ch = 0, n, eating, trick = 0;
- int erow, ecol; /* eat position */
- int level, tricks, moves, score;
-
- WINDOW *wstat, *wpos, *wepos; /* Status and positions windows */
- List *worm = NULL, *current; /* THe LiST */
-
- int auto_mode = 0; /* Play without user interaction */
-
- level = tricks = moves = score = 0;
- srand( time(NULL) );
-
- /* check the flag for auto-mode */
- if( argc == 2 && argv[1][0] == '-' && argv[1][1] == 'a' )
- auto_mode = 1;
-
- initscr(); /* start of session */
- curs_set(0); /* hide the cursor */
- keypad(stdscr, TRUE); /* enable the function keys */
- cbreak();
- noecho();
- nodelay(stdscr, TRUE); /* unlock getch(3) */
-
- /* Check the terminal size */
- if( LINES < MINROW || COLS < MINCOL ) {
- endwin();
- printf("This game require a terminal size of %dx%d pixel.\n",
- MINROW, MINCOL);
- printf("Your terminal size is: %dx%d\n", LINES, COLS);
- return -1;
- }
-
- /* Create the windows */
- wstat = subwin(stdscr, 3, COLS - COLS / 3, 2, COLS / 6); /* status */
- wpos = subwin(stdscr, 3, 9, 2, 3); /* worm position */
- wepos = subwin(stdscr, 3, 9, 2, COLS - 9 - 3); /* eat position */
-
- /* Add the first position */
- newnode(&worm, 1 + rand() % (COLS - 2), 6 + rand() % (LINES - 7));
-
- /* start point for the eat */
- erow = 6 + rand() % (LINES - 7);
- ecol = 1 + rand() % (COLS - 2);
-
- /* choose a random route */
- route = 1 + rand() % 4;
-
- wormshow(worm, WORM, HEAD); /* put the first WORM */
- mvprintw(erow, ecol, "%d", n = 1); /* put the first eat */
-
- /* main loop */
- while( (auto_mode ? getch() : (ch = getch())) != 'q' ) {
- /*
- * Auto-mode play
- *
- * NOTE: the worm can to bite himself losing the
- * game which will be auto-restarted again.
- *
- */
- if( auto_mode ) {
- ch = 0; /* don't touch the user moves */
-
- /* choose the route, if needed */
- if( worm->x < erow ) {
- if( route != R_DOWN )
- ch = 'j';
- }
- else if( worm->x > erow ) {
- if( route != R_UP )
- ch = 'k';
- }
- else if( worm->y < ecol ) {
- if( route != R_RIGHT )
- ch = 'l';
- }
- else {
- if( route != R_LEFT )
- ch = 'h';
- }
- }
-
- switch(ch) {
- case 'h':
- case KEY_LEFT:
- route = R_LEFT;
- ++moves;
- break;
- case 'j':
- case KEY_DOWN:
- route = R_DOWN;
- ++moves;
- break;
- case 'k':
- case KEY_UP:
- route = R_UP;
- ++moves;
- break;
- case 'l':
- case KEY_RIGHT:
- route = R_RIGHT;
- ++moves;
- break;
- case 'p':
- case ' ': /* space bar */
- /* Pause */
- nodelay(stdscr, FALSE); /* lock the getch() */
-
- mvprintw(LINES / 2, COLS / 2, "Pause!");
- while( (ch = getch()) ) {
- if( ch == 'p' || ch == ' ' )
- break;
-
- clear();
- mvprintw(LINES / 2, COLS / 2, "Pause!");
- }
-
- nodelay(stdscr, TRUE); /* unlock the getch() */
- clear();
-
- break;
- case 't': /* Tricks */
- if( trick ) {
- nodelay(stdscr, TRUE);
- trick = 0;
- }
- else {
- nodelay(stdscr, FALSE);
- trick = 1;
- ++tricks;
- }
- break;
- case KEY_RESIZE: /* Terminal resize */
- nodelay(stdscr, FALSE);
-
- /* Check the terminal size */
- while( LINES < MINROW || COLS < MINCOL ) {
- clear();
- mvprintw(LINES / 2, COLS / 2 - 12, "Terminal size too small!");
- mvprintw(LINES / 2 + 1, COLS / 2 - 16,
- "Please, enlarge it and press a key");
- getch();
- }
-
- nodelay(stdscr, TRUE);
- clear();
-
- break;
- } /* eof switch() */
- moveworm(&worm, route); /* move the worm */
-
- /*
- * Check if the "new" position is already
- * busy or it's out of the window.
- */
- if( isout(worm) || isbite(worm) || (auto_mode && level >= LEVMAX) ) {
-
- if( level >= LEVMAX )
- mvprintw(LINES / 2, COLS / 2 - 5, "Too fast!");
- else
- mvprintw(LINES / 2, COLS / 2 - 5, "You lose!");
-
- mvprintw(LINES / 2 + 1, COLS / 2 - 10, "Your scores are: %.3d", score);
-
- if( auto_mode ) {
- mvprintw(LINES / 2 + 3, COLS / 2 - 6, "Restarting..");
- refresh();
-
- /* reset the game */
- killworm(&worm);
- newnode(&worm, 1 + rand() % (COLS - 2), 6 + rand() % (LINES - 7));
- erow = 6 + rand() % (LINES - 7);
- ecol = 1 + rand() % (COLS - 2);
- score = level = eating = tricks = moves = 0;
- n = 1;
-
- sleep(2); /* leave that the user tastes the messsage :-) */
- continue;
- }
- else {
- mvprintw(LINES / 2 + 2, COLS / 2 - 10, "Press a key to exit..");
-
- nodelay(stdscr, FALSE);
- getch(); /* wait for input */
-
- break;
- }
- }
-
- eating = n; /* needed for the wormshow() call */
-
- /* If it's eating */
- while( iseat(worm, erow, ecol) ) {
- /* Add a node on the top of worm (new head) */
- current = worm;
- while( current->next != NULL )
- current = current->next;
- newnode(¤t->next, worm->y, worm->x);
-
- /* Change the eat's position */
- erow = 6 + rand() % (LINES - 7);
- ecol = 1 + rand() % (COLS - 2);
- ++n; /* Change the eat's number */
-
- score += level + 1; /* increment the points */
-
- /* Increase the level */
- if( !(n % LEVEAT) ) {
- ++level;
- }
- }
-
- erase(); /* clear the screen */
- box(stdscr, ACS_VLINE, ACS_HLINE); /* create the borders */
- mvprintw(erow, ecol, "%d", n); /* draw the eat */
-
- /* Show the status window (and its elemets) */
- mvwprintw(stdscr, 1, COLS / 2 - 37 / 2, /* Copy */
- "The Hermit worm - (C) 2006 Claudio M."); /* left */
- box(wstat, ACS_VLINE, ACS_HLINE); /* status box */
- mvwhline(stdscr, 5, 1, ACS_HLINE, COLS - 2); /* new top limit */
-
- /* Show the worm position */
- box(wepos, ACS_VLINE, ACS_HLINE); /* status box */
- mvwprintw(stdscr, 1, 3, "Worm Curs");
- mvwprintw(wepos, 1, 2, "%.2dx%.2d", erow, ecol);
-
- /* Show the eat position */
- box(wpos, ACS_VLINE, ACS_HLINE); /* status box */
- mvwprintw(stdscr, 1, COLS - 12, "Eat Curs");
- mvwprintw(wpos, 1, 2, "%.2dx%.2d", worm->x, worm->y);
-
- /* Show the informations */
- mvwprintw(wstat, 1, 3,
- "TS:%.2dx%.2d | " /* Terminal size */
- "SL:%.2d | " /* Speed level */
- "EM:%.2d | " /* Eats missing */
- "UM:%.3d | " /* User moves */
- "UT:%.2d | " /* User tricks */
- "Ss:%.3d", /* Scores */
- LINES, COLS, level + 1, LEVEAT - (n % LEVEAT),
- moves, tricks, score);
-
- /*
- * Show the whole "new" worm
- * NOTE: this statement is not optimized - trash statement :-)
- */
- if( iseat(worm, erow + 1, ecol) || iseat(worm, erow - 1, ecol) ||
- iseat(worm, erow, ecol + 1) || iseat(worm, erow, ecol - 1) ) {
- wormshow(worm, WORM, EATH);
- }
- else
- wormshow(worm, WORM, HEAD);
-
- usleep( 100000 - level * 10000 );
- }
-
- endwin(); /* end of session */
-
- puts("\nEnd of game.");
-
- return 0;
-} /* E0F main */
-
-/*
- * Returns if the worm is out of the window
-*/
-int isout(List *worm)
-{
- if( worm->x <= 5 || !worm->y || worm->x >= LINES - 1 || worm->y >= COLS - 1)
- return 1;
-
- return 0;
-} /* eof isout() */
-
-/*
- * Return if the worm is eating
-*/
-int iseat(List *worm, int row, int col)
-{
- return (worm->x == row && worm->y == col);
-} /* eof iseat() */
-
-/*
- * Check if the worm is biting itself
-*/
-int isbite(List *worm)
-{
- List *current = worm;
-
- while( (current = current->next) != NULL ) {
- if( worm->x == current->x && worm->y == current->y )
- return 1;
- }
-
- return 0;
-} /* eof isbite() */
-
-/*
- * Show the worm (call refresh(3))
-*/
-void wormshow(List *worm, char ch, char chhead)
-{
- List *current = worm->next;
-
- /* show the worm */
- while( current != NULL ) {
- mvprintw(current->x, current->y, "%c", ch);
- current = current->next;
- }
- mvprintw(worm->x, worm->y, "%c", chhead); /* show the head */
-
- refresh(); /* print the changes */
-
-} /* eof wormshow() */
-
-/*
- * Add a new node to the list
-*/
-void newnode(List **listp, int y, int x)
-{
- List *newPtr;
-
- /* Allocate the memory */
- if( (newPtr = malloc( sizeof(List) )) == NULL ) {
- printf("Not enough memory to allocate the \"%d.%d\" element\n", x, y);
- return;
- }
- newPtr->next = *listp;
- newPtr->x = x;
- newPtr->y = y;
-
- *listp = newPtr;
-
-} /* eof newnode() */
-
-/*
- * Move the whole worm
-*/
-void moveworm(List **worm, int way)
-{
- List *current = *worm;
- int n = 1, i;
-
- /* count the nodes */
- while( (current = current->next) != NULL )
- ++n;
-
- current = *worm; /* come back to the start point */
- while( --n ) {
-
- current = *worm;
- i = n;
-
- while( --i )
- current = current->next;
-
- /* update the position */
- current->next->x = current->x;
- current->next->y = current->y;
- }
-
- /* move the head */
- switch(way) {
- case R_UP:
- --( *worm )->x;
- break;
- case R_LEFT:
- --( *worm )->y;
- break;
- case R_DOWN:
- ++( *worm )->x;
- break;
- case R_RIGHT:
- ++( *worm )->y;
- break;
- }
-
-} /* eof moveworm() */
-
-/*
- * Kill the worm: free the whole worm's memory
-*/
-void killworm(List **worm)
-{
- List *current;
-
- while(*worm != NULL) {
- current = *worm;
- *worm = (*worm)->next;
- free(current);
- }
-
-} /* eof killworm() */
-