From cc307a968ef1036d6cd96ce38c64cc195950ea46 Mon Sep 17 00:00:00 2001 From: Ian C Date: Thu, 18 Sep 2008 21:34:06 +0000 Subject: Initial checkin --- dbox.c | 1081 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ depend.mak | 1 + level0 | 5 + level1 | 10 + level14 | 9 + level15 | 9 + level4 | 10 + level5 | 10 + level73 | 14 + levelA | 6 + levelB | 5 + levelC | 7 + levelD | 9 + levelE | 12 + makefile | 57 ++++ mktar | 11 + 16 files changed, 1256 insertions(+) create mode 100644 dbox.c create mode 100644 depend.mak create mode 100644 level0 create mode 100644 level1 create mode 100644 level14 create mode 100644 level15 create mode 100644 level4 create mode 100644 level5 create mode 100644 level73 create mode 100644 levelA create mode 100644 levelB create mode 100644 levelC create mode 100644 levelD create mode 100644 levelE create mode 100644 makefile create mode 100644 mktar diff --git a/dbox.c b/dbox.c new file mode 100644 index 0000000..a0cb31c --- /dev/null +++ b/dbox.c @@ -0,0 +1,1081 @@ +/* + + dbox - Sokoban level solver + + Copyright (C) 2001 Ian Cowburn (ianc@noddybox.demon.co.uk) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------- + +*/ +static const char cvs_id[]="$Id$"; + +#include +#include +#include +#include +#include + +#if (USECURSES == ncurses) +# include +#else +# include +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +static const int DEBUG=TRUE; +static char *name; + +/* Stop the program once this much memory is allocated. + Set to -1 to disable the check +*/ +#define MAXMB -1 + +#define MEGABYTE (1024*1024) + +/* ---------------------------------------- TYPES +*/ +typedef signed char PosInt; +typedef unsigned char Byte; +typedef Byte Bool; + +typedef char Route[1024]; + +typedef enum {SPACE_GL=' ', + WALL_GL='#', + PLAYER_GL='@', + BOX_GL='B', + TARGET_GL='.', + BOX_TARGET_GL='X'} Glyph; + +typedef enum {SPACE, WALL} MapChar; + +typedef enum {QUIET,CSV,VERBOSE} LogMode; + +#define DIR_NONE -1 +#define DIR_LEFT 0 +#define DIR_UP 1 +#define DIR_RIGHT 2 +#define DIR_DOWN 3 + +typedef struct + { + PosInt x; + PosInt y; + } Pos; + +static const Pos move_dir[4]={{-1,0},{0,-1},{1,0},{0,1}}; + +typedef struct State + { + Pos player; + Pos *box; + Bool path; + Byte dir; + Bool pushed; + int hash; + struct State *left; + struct State *right; + struct State *up; + struct State *down; + struct State *parent; + struct State *next; + } State; + +typedef struct + { + char *name; + int width,height; + int no; + Pos *target; + MapChar *map; + State *state; + } Level; + +#define STATE_HASH 0x10000 + +typedef struct StateMap + { + State *s; + struct StateMap *next; + } StateMap; + +static StateMap *state_map[STATE_HASH]={NULL}; +static int state_map_no=0; + +#define AT(l,x,y) ((l)->map[(l)->width*(y)+(x)]) + + +/* ---------------------------------------- PROTOS +*/ +static void *Grab(size_t l); + +static void Interactive(Level *l, int play); + +static Level *Load(const char *path); +static void FreeLevel(Level *l); +static void Display(Level *level, State *state); +static char GetGlyph(Level *level, State *state, int x, int y); +static State *CreateState(Byte dir, Bool must_push, Level *l, State *s, + Bool check_possible); +static void Solve(Level *level, Route route, int max_depth, LogMode log); + + +/* ---------------------------------------- MAIN +*/ +int main(int argc, char *argv[]) +{ + int interact=FALSE; + int play=FALSE; + int base; + int f; + LogMode mode=VERBOSE; + + name=argv[0]; + + if (argc<2) + { + fprintf(stderr,"%s: usage %s [-i|-p] file [file2 ...]\n",name,name); + return EXIT_FAILURE; + } + + if (strcmp(argv[1],"-i")==0) + { + interact=TRUE; + base=2; + } + else if (strcmp(argv[1],"-p")==0) + { + interact=TRUE; + play=TRUE; + base=2; + } + else if (strcmp(argv[1],"-c")==0) + { + interact=FALSE; + mode=CSV; + base=2; + } + else + base=1; + + if (argc<=base) + { + fprintf(stderr,"%s: usage %s [-c|-i|-p] file [file2 ...]\n",name,name); + return EXIT_FAILURE; + } + + for(f=base;fname); + + Display(level,level->state); + + Solve(level,route,999,mode); + + printf("\nRoute = '%s'\n",route); + } + + FreeLevel(level); + } + } + + return EXIT_SUCCESS; +} + + +/* ---------------------------------------- UTIL +*/ +static size_t grab_tot=0; +static int grab_last_mb=0; +static int grab_mb=0; + +static void *Grab(size_t l) +{ + size_t *p; + + p=malloc(l+sizeof(size_t)); + + if (!p) + { + fprintf(stderr,"%s: malloc(%d) failed\n",name,l); + exit(EXIT_FAILURE); + } + + *p=l; + + grab_tot+=l; + + grab_mb=grab_tot/MEGABYTE; + + if (grab_last_mb!=grab_mb) + { + grab_last_mb=grab_mb; + + if (grab_mb==MAXMB) + { + fprintf(stderr,"Quitting: Allocated %d Mb\n",grab_mb); + exit(EXIT_FAILURE); + } + } + + return p+1; +} + + +static void Release(void *p) +{ + size_t *pp; + + pp=p; + + pp--; + + grab_tot-=*pp; + + free(pp); +} + + +static int GrabSize(void) +{ + return grab_mb; +} + + +static Pos *FindPos(Pos *p, int no, int x, int y) +{ + int f; + + for (f=0;fname=Grab(strlen(line)+1); + strcpy(new->name,line); + + new->no=atoi(GetLine(fp)); + + /* Calc sizes + */ + new->width=strlen(GetLine(fp)); + new->height=1; + + while((line=GetLine(fp))) + { + new->height++; + + if (strlen(line)!=new->width) + { + fprintf(stderr,"%s: '%s' (line %d) too short " + "(should be %d wide)\n", + name,line,new->height,new->width); + exit(EXIT_FAILURE); + } + } + + /* Rewind file and skip first two lines + */ + rewind(fp); + GetLine(fp); + GetLine(fp); + + new->target=Grab(sizeof(Pos)*new->no); + new->map=Grab(sizeof(MapChar)*(new->width*new->height)); + + new->state=Grab(sizeof(State)); + new->state->parent=NULL; + new->state->next=NULL; + new->state->box=Grab(sizeof(Pos)*new->no); + new->state->left=new->state->right=new->state->up=new->state->down=NULL; + new->state->dir=DIR_NONE; + + tno=0; + bno=0; + pno=0; + + for(y=0;yheight;y++) + { + line=GetLine(fp); + + if (strlen(line)width) + { + fprintf(stderr,"%s: line '%s' too short " + "(should be %d wide)\n",name,line,new->width); + exit(EXIT_FAILURE); + } + + for(x=0;xwidth;x++) + switch(line[x]) + { + case WALL_GL: + AT(new,x,y)=WALL; + break; + + case SPACE_GL: + AT(new,x,y)=SPACE; + break; + + case BOX_TARGET_GL: + case TARGET_GL: + if (tno==new->no) + { + fprintf(stderr,"%s: too many " + "targets in %s\n",name,path); + + exit(EXIT_FAILURE); + } + + AT(new,x,y)=SPACE; + new->target[tno].x=x; + new->target[tno].y=y; + tno++; + + /* NOTE: Runs into following case + */ + if (line[x]==TARGET_GL) + break; + + case BOX_GL: + if (bno==new->no) + { + fprintf(stderr,"%s: too many " + "boxes in %s\n",name,path); + + exit(EXIT_FAILURE); + } + + AT(new,x,y)=SPACE; + new->state->box[bno].x=x; + new->state->box[bno].y=y; + bno++; + break; + + case PLAYER_GL: + if (pno++==1) + { + fprintf(stderr,"%s: too many " + "players in %s\n",name,path); + + exit(EXIT_FAILURE); + } + + AT(new,x,y)=SPACE; + new->state->player.x=x; + new->state->player.y=y; + break; + } + } + + fclose(fp); + + if (pno==0) + { + fprintf(stderr,"%s: no player definied in %s\n",name,path); + + exit(EXIT_FAILURE); + } + + return new; +} + + +static void FreeLevel(Level *l) +{ +} + + +static void Display(Level *level, State *state) +{ + int x,y; + + for(y=0;yheight;y++) + { + for(x=0;xwidth;x++) + putchar(GetGlyph(level,state,x,y)); + + putchar('\n'); + } +} + + +static char GetGlyph(Level *level, State *state, int x, int y) +{ + if (AT(level,x,y)==WALL) + return WALL_GL; + else if (FindPos(&state->player,1,x,y)) + return PLAYER_GL; + else if (FindPos(state->box,level->no,x,y) && + FindPos(level->target,level->no,x,y)) + return BOX_TARGET_GL; + else if (FindPos(state->box,level->no,x,y)) + return BOX_GL; + else if (FindPos(level->target,level->no,x,y)) + return TARGET_GL; + else + return SPACE_GL; + +} + + +/* ---------------------------------------- SOLVER +*/ +static void FreeState(State *s) +{ + Release(s->box); + Release(s); +} + + +static void ClearStates(void) +{ + int f; + + state_map_no=0; + + for(f=0;fnext; + Release(state_map[f]); + state_map[f]=p; + } +} + + +static Bool AddNewState(Level *l, State *s) +{ + StateMap *p; + int hash; + + hash=s->hash%STATE_HASH; + + p=state_map[hash]; + + while(p) + { + if (s->player.x==p->s->player.x && s->player.y==p->s->player.y) + { + int f; + int ok; + + ok=FALSE; + + for(f=0;fno && !ok;f++) + if (s->box[f].x!=p->s->box[f].x || s->box[f].y!=p->s->box[f].y) + ok=TRUE; + + if (!ok) + return FALSE; + } + + p=p->next; + } + + p=Grab(sizeof *p); + + p->s=s; + p->next=state_map[hash]; + state_map[hash]=p; + + state_map_no++; + + return TRUE; +} + + +static int GetStateNum(void) +{ + return state_map_no; +} + + +static const char *NoMoveReason(char *fmt,...) +{ + static char r[512]; + va_list va; + + va_start(va,fmt); + + if (fmt) + vsprintf(r,fmt,va); + + va_end(va); + + return r; +} + + +static Bool CheckImpossible(Level *l, State *s) +{ + int f; + + for(f=0;fno;f++) + { + int x,y; + + x=s->box[f].x; + y=s->box[f].y; + + if (!FindPos(l->target,l->no,x,y)) + { + int d; + int any_move; + + /* Check that the box can be pushed at all for the next go + (Simple wall based check) + */ + any_move=FALSE; + + for(d=0;d<4 && !any_move;d++) + { + int nx,ny; + + nx=x+move_dir[d].x; + ny=y+move_dir[d].y; + + if (AT(l,nx,ny)!=WALL) + { + int ox,oy; + + ox=x+move_dir[(d+2)%4].x; + oy=y+move_dir[(d+2)%4].y; + + if (AT(l,ox,oy)!=WALL) + any_move=TRUE; + } + } + + if (!any_move) + { + NoMoveReason("Couldn't push block at %d,%d",x,y); + return TRUE; + } + + /* Four blocks together is impossible + */ + if (FindPos(s->box,l->no,x+1,y) && FindPos(s->box,l->no,x,y+1) && + FindPos(s->box,l->no,x+1,y+1)) + { + NoMoveReason("Group of 4 boxes at %d,%d",x,y); + return TRUE; + } + } + } + + return FALSE; +} + + +static State *CreateState(Byte dir, Bool must_push, + Level *l, State *s, Bool check_possible) +{ + State *new; + Pos *p; + int x,y; + int push; + int dx,dy; + int f; + + dx=move_dir[dir].x; + dy=move_dir[dir].y; + + push=FALSE; + + x=s->player.x+dx; + y=s->player.y+dy; + + /* Check for walls + */ + if (AT(l,x,y)==WALL) + return NULL; + + /* Check for boxes + */ + if ((p=FindPos(s->box,l->no,x,y))) + { + int bx,by; + + /* Can the box be pushed? + */ + bx=p->x+dx; + by=p->y+dy; + + if (AT(l,bx,by)==WALL) + return NULL; + + if (FindPos(s->box,l->no,bx,by)) + return NULL; + + push=TRUE; + } + + if (!push && must_push) + return NULL; + + new=Grab(sizeof *new); + new->box=Grab(sizeof(Pos)*l->no); + memcpy(new->box,s->box,sizeof(Pos)*l->no); + + new->player.x=x; + new->player.y=y; + + if (push) + { + p=FindPos(new->box,l->no,x,y); + + p->x+=dx; + p->y+=dy; + + /* (Very) basic checks to see if the move has made the level impossible + */ + if (check_possible && CheckImpossible(l,new)) + { + FreeState(new); + return NULL; + } + } + + + new->left=NULL; + new->right=NULL; + new->up=NULL; + new->down=NULL; + + new->parent=s; + new->next=NULL; + + new->path=FALSE; + new->pushed=push; + new->dir=dir; + + /* Calculate a hash based on box and player positions + */ + new->hash=0; + + for(f=0;fno;f++) + new->hash+=new->box[f].x+new->box[f].y*l->height; + + new->hash+=(STATE_HASH>>2)+new->box[f].x+new->box[f].y*l->height; + + if (!AddNewState(l,new)) + { + NoMoveReason("State matches previous"); + FreeState(new); + return NULL; + } + + return new; +} + + +static void SetChain(State **first, State **curr, State *new) +{ + if (new) + { + if (!*first) + { + *first=new; + *curr=*first; + } + else + { + (*curr)->next=new; + (*curr)=new; + } + } +} + + +static void SubSolve(Level *level, State *state,int depth, + int max_depth, LogMode log) +{ + static time_t last=0; + State *first; + State *curr; + State *new; + State *s; + int ok; + int f; + + if (depth>=max_depth) + return; + + if (depth==1) + last=time(NULL); + + switch(log) + { + case QUIET: + break; + case VERBOSE: + printf("Searching %d moves deep " + "(%ld secs, used %dMb - %d unique states)\n", + depth,time(NULL)-last,GrabSize(),GetStateNum()); + break; + case CSV: + printf("%d,%ld,%d,%d\n", + depth,time(NULL)-last,GrabSize(),GetStateNum()); + break; + } + + last=time(NULL); + + /* Loop across all states at this depth + */ + s=state; + first=NULL; + curr=NULL; + + while(s) + { + /* Check to see whether the level is solved + */ + ok=TRUE; + + for(f=0;(fno) && ok;f++) + if (!FindPos(s->box,level->no, + level->target[f].x,level->target[f].y)) + ok=FALSE; + + if (ok) + { + s->path=TRUE; + s=s->parent; + + while(s) + { + s->path=TRUE; + s=s->parent; + } + return; + } + + /* Check moves + */ + if (s->dir==DIR_RIGHT) + s->left=new=CreateState(DIR_LEFT,!s->pushed,level,s,TRUE); + else + s->left=new=CreateState(DIR_LEFT,FALSE,level,s,TRUE); + + SetChain(&first,&curr,new); + + if (s->dir==DIR_LEFT) + s->right=new=CreateState(DIR_RIGHT,!s->pushed,level,s,TRUE); + else + s->right=new=CreateState(DIR_RIGHT,FALSE,level,s,TRUE); + + SetChain(&first,&curr,new); + + if (s->dir==DIR_DOWN) + s->up=new=CreateState(DIR_UP,!s->pushed,level,s,TRUE); + else + s->up=new=CreateState(DIR_UP,FALSE,level,s,TRUE); + + SetChain(&first,&curr,new); + + if (s->dir==DIR_UP) + s->down=new=CreateState(DIR_DOWN,!s->pushed,level,s,TRUE); + else + s->down=new=CreateState(DIR_DOWN,FALSE,level,s,TRUE); + + SetChain(&first,&curr,new); + + s=s->next; + } + + if (first) + SubSolve(level,first,++depth,max_depth,log); +} + + +static void Solve(Level *level, Route route, int max_depth, LogMode log) +{ + State *s; + + route[0]=0; + ClearStates(); + + SubSolve(level,level->state,1,max_depth,log); + + s=level->state; + + while(s) + { + if (s->left && s->left->path) + { + strcat(route,"L"); + s=s->left; + } + else if (s->right && s->right->path) + { + strcat(route,"R"); + s=s->right; + } + else if (s->up && s->up->path) + { + strcat(route,"U"); + s=s->up; + } + else if (s->down && s->down->path) + { + strcat(route,"D"); + s=s->down; + } + else + s=NULL; + } +} + + +/* ---------------------------------------- INTERACTIVE MODE +*/ +static void CursesDisplay(Level *l, State *s, int play) +{ + int x,y,f; + char allow[80]; + + for(x=0;xwidth;x++) + { + char num[20]; + + sprintf(num,"%d",x); + + f=0; + while(num[f]) + mvaddch(3+f,3+x,num[f++]); + + for(y=0;yheight;y++) + { + if (x==0) + mvprintw(6+y,0,"%d",y); + + mvaddch(6+y,3+x,GetGlyph(l,s,x,y)); + } + } + + strcpy(allow,"Moves: "); + + if (s->left) + strcat(allow,"left "); + + if (s->right) + strcat(allow,"right "); + + if (s->up) + strcat(allow,"up "); + + if (s->down) + strcat(allow,"down "); + + if (s->parent) + strcat(allow,"back"); + + while(strlen(allow)<70) + strcat(allow," "); + + mvaddstr(l->height+11,0,allow); + + if (!play) + { + if (s->path) + mvaddstr(l->height+10,0,"On solved path: YES"); + else + mvaddstr(l->height+10,0,"On solved path: NO "); + } + else + { + int depth=0; + + while(s) + { + depth++; + s=s->parent; + } + + mvprintw(l->height+10,0,"Depth: %d ",depth); + } + + mvprintw(LINES-3,0,"Last reason: %-40.40s",NoMoveReason(NULL)); + + refresh(); +} + + +static void Interactive(Level *l, int play) +{ + int quit; + Route route; + State *s; + + if (!play) + Solve(l,route,999,VERBOSE); + + initscr(); + cbreak(); + noecho(); + nonl(); + intrflush(stdscr,FALSE); + keypad(stdscr,TRUE); + + quit=FALSE; + s=l->state; + + clear(); + mvaddstr(0,0,l->name); + + mvaddstr(LINES-1,0,"Cursors to move, P to follow path, " + "Q to quit, Backspace/B to step back"); + + if (!play) + mvprintw(l->height+9,0,"Route:%s",route); + + while(!quit) + { + int key; + + CursesDisplay(l,s,play); + + key=getch(); + + if (key=='p' || key=='P') + { + if (s->left && s->left->path) + key=KEY_LEFT; + + if (s->right && s->right->path) + key=KEY_RIGHT; + + if (s->up && s->up->path) + key=KEY_UP; + + if (s->down && s->down->path) + key=KEY_DOWN; + } + + switch(key) + { + case KEY_BACKSPACE: + case 'b': + case 'B': + if (s->parent) + s=s->parent; + break; + + case KEY_LEFT: + if (play && !s->left) + s->left=CreateState(DIR_LEFT,FALSE,l,s,TRUE); + + if (s->left) + s=s->left; + break; + + case KEY_RIGHT: + if (play && !s->right) + s->right=CreateState(DIR_RIGHT,FALSE,l,s,TRUE); + + if (s->right) + s=s->right; + break; + + case KEY_DOWN: + if (play && !s->down) + s->down=CreateState(DIR_DOWN,FALSE,l,s,TRUE); + + if (s->down) + s=s->down; + break; + + case KEY_UP: + if (play && !s->up) + s->up=CreateState(DIR_UP,FALSE,l,s,TRUE); + + if (s->up) + s=s->up; + break; + + case 'q': + case 'Q': + quit=TRUE; + break; + + default: + break; + } + } + + endwin(); +} + + +/* END OF FILE */ diff --git a/depend.mak b/depend.mak new file mode 100644 index 0000000..65af7b3 --- /dev/null +++ b/depend.mak @@ -0,0 +1 @@ +dbox.o: dbox.c diff --git a/level0 b/level0 new file mode 100644 index 0000000..cb06798 --- /dev/null +++ b/level0 @@ -0,0 +1,5 @@ +Test Level +2 +####### +#.B@B.# +####### diff --git a/level1 b/level1 new file mode 100644 index 0000000..e6fe633 --- /dev/null +++ b/level1 @@ -0,0 +1,10 @@ +Level 1 +4 + ### + #.# + # #### +###B B.# +#. B@### +####B# + #.# + ### diff --git a/level14 b/level14 new file mode 100644 index 0000000..e38d7d5 --- /dev/null +++ b/level14 @@ -0,0 +1,9 @@ +Level 14 +6 +######## +# # # +# B..B # +#@B.X ## +# B..B # +# # # +######## diff --git a/level15 b/level15 new file mode 100644 index 0000000..39f7093 --- /dev/null +++ b/level15 @@ -0,0 +1,9 @@ +Level 15 +6 + ####### +## # +# B BB # +#......# +# BB B # +### @### + #### diff --git a/level4 b/level4 new file mode 100644 index 0000000..a02581b --- /dev/null +++ b/level4 @@ -0,0 +1,10 @@ +Level 4 +5 + #### +## # +#@B # +##B ## +## B # +#.B # +#..X.# +###### diff --git a/level5 b/level5 new file mode 100644 index 0000000..1295ffe --- /dev/null +++ b/level5 @@ -0,0 +1,10 @@ +Level 5 +3 + ##### + #@ ### + # B # +### # ## +#.# # # +#.B # # +#. B # +######## diff --git a/level73 b/level73 new file mode 100644 index 0000000..703c7f8 --- /dev/null +++ b/level73 @@ -0,0 +1,14 @@ +Level 73 +12 + ######## + # # # + ####### BB...# + # #...# + # ######B#...# +## # #...# +# # #B B ##### +# # B B B # +# @ B # # +#####B BB # + # # + ####### diff --git a/levelA b/levelA new file mode 100644 index 0000000..4c5f7e8 --- /dev/null +++ b/levelA @@ -0,0 +1,6 @@ +Test Level +2 +##### +#@B.# +# B.# +##### diff --git a/levelB b/levelB new file mode 100644 index 0000000..cb06798 --- /dev/null +++ b/levelB @@ -0,0 +1,5 @@ +Test Level +2 +####### +#.B@B.# +####### diff --git a/levelC b/levelC new file mode 100644 index 0000000..36ee80b --- /dev/null +++ b/levelC @@ -0,0 +1,7 @@ +Test Level +1 +######### +##### # +#@B # +#####.### + ### diff --git a/levelD b/levelD new file mode 100644 index 0000000..d418434 --- /dev/null +++ b/levelD @@ -0,0 +1,9 @@ +Test Level +3 +######### +#@ # +# # # # +# #BB# # +# # # # +#.B. .# +######### diff --git a/levelE b/levelE new file mode 100644 index 0000000..b8660f0 --- /dev/null +++ b/levelE @@ -0,0 +1,12 @@ +Test Level +2 +########## +#@ # +# # # +# B # +# # # +# B # +# . # +# # # +# .# +########## diff --git a/makefile b/makefile new file mode 100644 index 0000000..9cc2e62 --- /dev/null +++ b/makefile @@ -0,0 +1,57 @@ +# +# +# dbox - Sokoban solver +# +# Copyright (C) 2001 Ian Cowburn (ianc@noddybox.demon.co.uk) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# ------------------------------------------------------------------------- +# + + +TARGET = dbox + +SOURCES = dbox.c + +HEADERS = + +OBJECTS = $(SOURCES:.c=.o) + +LIBS = -lncurses + +FLAGS = -O2 -g -Wall -pedantic -ansi + +DEPEND = depend.mak + +$(TARGET): $(OBJECTS) + $(CC) $(FLAGS) -o $(TARGET) $(OBJECTS) $(LIBS) + +%.o: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) $(FLAGS) $(TRACE) -c $< -o $@ + +-include depend.mak + +clean: + -rm $(TARGET) $(TARGET).exe core *.stackdump *.o depend.mak + +depend: $(DEPEND) + @echo Dependencies updated.... + +$(DEPEND): $(SOURCES) $(HEADERS) + $(CC) -MM $(SOURCES) > $(DEPEND) + + +# END OF FILE diff --git a/mktar b/mktar new file mode 100644 index 0000000..6847060 --- /dev/null +++ b/mktar @@ -0,0 +1,11 @@ +#!/bin/bash + +FILE=dbox.tar.gz + +make clean +tar cvfz $FILE level* makefile mktar *.c + +if [ `uname` != "Linux" ] ; +then + mv $FILE ~/desktop +fi -- cgit v1.2.3