games@tekred.TEK.COM (09/01/88)
Submitted by: "Peter Knoppers, Delft Univ. of Technology" <uunet.uu.net!mcvax!dutesta!knop> Comp.sources.games: Volume 5, Issue 59 Archive-name: puzzle15 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: README Makefile puzzle15.c # Wrapped by billr@saab on Wed Aug 31 10:35:26 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(919 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' XThis is a small program that plays the 15-puzzle game X(is that the correct name of this game ?), similar to the one Xin the desktop of some famous personal computers. X XThe size of the game can be set with an optional argument, Xdefault is 4, other sizes are 3, 5 and 6. Moves are made with Xthe 'h', 'j', 'k' and 'l' keys (like in vi). Any other key Xprints a diagnostic, your local interrupt key aborts the Xgame. When all pieces are sorted the program printes the Xnumber of moves that were used and exits. X XThe program is copyrighted to prevent creation and distribution of Xa zillion different versions and/or trojan horses. If you have Xsuggestions for improvements please mail them to me. X XWe compile the program by Xcc -O puzzle15.c -lcurses -ltermilb -o puzzle15 X XEnjoy! X-- XPeter Knoppers, Delft Univ. of Technology X.--. . - . .-. -.- -. --- .--. .--. . .-. ... X...!mcvax!dutrun!dutesta!knop X or Xknop@dutesta.UUCP X END_OF_FILE if test 919 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(101 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# simple makefile for puzzle15 Xpuzzle15: puzzle15.c X cc -o puzzle15 -O puzzle15.c -lcurses -ltermcap END_OF_FILE if test 101 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'puzzle15.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'puzzle15.c'\" else echo shar: Extracting \"'puzzle15.c'\" \(4059 characters\) sed "s/^X//" >'puzzle15.c' <<'END_OF_FILE' X# include <curses.h> X# include <signal.h> X# define BLANK 0 X# define UP 'k' X# define LEFT 'h' X# define DOWN 'j' X# define RIGHT 'l' X Xchar *author = "(C) Copyright 1985, 1988 P. Knoppers"; Xchar *release1 = "Permission to use and redistribute unmodified "; Xchar *release2 = "copies is granted to everyone"; X Xchar *malloc (); /* to satisfy lint */ X Xdie () /* nice exit on ctrl-C */ X{ X signal (SIGINT, SIG_IGN); X mvprintw (23, 0, "Goodbye. "); X refresh (); X endwin (); X exit (0); X} X Xmain (argc, argv) /* plays a simple game "15 puzzle" */ Xchar **argv; /* with variations in boardsize... */ X{ X register int i, j; X int size = 4; /* default size of the board */ X int size2; X int *board; X int empty; /* position of empty field */ X int out; X int m; X int swap; X int nswap = 0; X int movecnt = 0; X if (argc > 2) X argerr (argv[0]); X if (argc == 2) X if (sscanf (argv[1], "%d", &size) < 1) X argerr (argv[0]); X if ((size < 3) || (size > 6)) X { X fprintf (stderr, "size must be 3, 4, 5, or 6\n"); X exit (1); X } X size2 = size * size; /* surface area of the board */ X board = (int *) malloc ((unsigned) size2 * sizeof (int)); X if (board == NULL) X { X fprintf (stderr, "%s: malloc failed\n", argv[0]); X exit (1); X } X X srand (getpid ()); /* initialize random number generator */ X for (i = 1; i < size2; i++) /* put pieces on the board */ X board[i - 1] = i; X for (i = size2 - 2; i > 0; i--)/* permutate pieces */ X { X j = rand () % i; X swap = board[i]; X board[i] = board[j]; X board[j] = swap; X } X for (i = 0; i < size2 - 1; i++)/* is permutation a legal position ? */ X for (j = 0; j < i; j++) X if (board[j] > board[i]) X nswap++; X if (nswap % 2) X { /* illegal position, swap two pieces */ X swap = board[1]; X board[1] = board[0]; X board[0] = swap; X } X empty = size2 - 1; /* empty field starts in lower right corner */ X X signal (SIGINT, die); X initscr (); X crmode (); X noecho (); X X while (1) /* until final position is reached */ X { X printboard (size, board); X out = 1; X for (i = 0; i < size2 - 1; i++) X if (board[i] != i + 1) X out = 0; X if (out) X break; /* game ends */ X while (1) /* until legal move is entered */ X { X m = getch (); X if ((m != LEFT) && (m != UP) && (m != RIGHT) && X (m != DOWN)) X { X notmove (); X continue; /* not a move */ X } X if (m == LEFT) X if (empty % size) X { X board[empty] = board[empty - 1]; X board[empty - 1] = BLANK; X empty--; X movecnt++; X break; X } X if (m == UP) X if (empty >= size) X { X board[empty] = board[empty - size]; X board[empty - size] = BLANK; X empty -= size; X movecnt++; X break; X } X if (m == RIGHT) X if ((empty + 1) % size) X { X board[empty] = board[empty + 1]; X board[empty + 1] = BLANK; X empty++; X movecnt++; X break; X } X if (m == DOWN) X if (empty + size < size2) X { X board[empty] = board[empty + size]; X board[empty + size] = BLANK; X empty += size; X movecnt++; X break; X } X } X } X mvprintw (22, 0, "You've reached the solution in %d moves.\n", movecnt); X refresh (); X endwin (); X} X Xargerr (s) Xchar *s; X{ X fprintf (stderr, "usage: %s size\n", s); X exit (1); X} X Xprintboard (size, board) Xint *board; X{ X register int i, j; X mvprintw (0, 0, "|"); /* print top edge of board */ X for (j = 0; j < size; j++) X printw ("----|"); X for (i = 0; i < size; i++) X { X mvprintw (i * 2 + 1, 0, "| "); X for (j = 0; j < size; j++) X if (board[size * i + j]) X printw ("%2d | ", board[size * i + j]); X else X printw (" | "); X mvprintw (i * 2 + 2, 0, "|"); X for (j = 0; j < size; j++) X printw ("----|"); X } X mvprintw (16, 0, "\n"); /* erase error messages */ X refresh (); /* put all this on the screen */ X} X Xnotmove () X{ X mvprintw (16, 0, X "use %c for up, %c for left, %c for right and %c for down", X UP, LEFT, RIGHT, DOWN); X refresh (); X} END_OF_FILE if test 4059 -ne `wc -c <'puzzle15.c'`; then echo shar: \"'puzzle15.c'\" unpacked with wrong size! fi # end of 'puzzle15.c' fi echo shar: End of shell archive. exit 0