home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume5
/
puzzle15
/
puzzle15.c
< prev
next >
Wrap
Text File
|
1988-08-31
|
4KB
|
180 lines
# include <curses.h>
# include <signal.h>
# define BLANK 0
# define UP 'k'
# define LEFT 'h'
# define DOWN 'j'
# define RIGHT 'l'
char *author = "(C) Copyright 1985, 1988 P. Knoppers";
char *release1 = "Permission to use and redistribute unmodified ";
char *release2 = "copies is granted to everyone";
char *malloc (); /* to satisfy lint */
die () /* nice exit on ctrl-C */
{
signal (SIGINT, SIG_IGN);
mvprintw (23, 0, "Goodbye. ");
refresh ();
endwin ();
exit (0);
}
main (argc, argv) /* plays a simple game "15 puzzle" */
char **argv; /* with variations in boardsize... */
{
register int i, j;
int size = 4; /* default size of the board */
int size2;
int *board;
int empty; /* position of empty field */
int out;
int m;
int swap;
int nswap = 0;
int movecnt = 0;
if (argc > 2)
argerr (argv[0]);
if (argc == 2)
if (sscanf (argv[1], "%d", &size) < 1)
argerr (argv[0]);
if ((size < 3) || (size > 6))
{
fprintf (stderr, "size must be 3, 4, 5, or 6\n");
exit (1);
}
size2 = size * size; /* surface area of the board */
board = (int *) malloc ((unsigned) size2 * sizeof (int));
if (board == NULL)
{
fprintf (stderr, "%s: malloc failed\n", argv[0]);
exit (1);
}
srand (getpid ()); /* initialize random number generator */
for (i = 1; i < size2; i++) /* put pieces on the board */
board[i - 1] = i;
for (i = size2 - 2; i > 0; i--)/* permutate pieces */
{
j = rand () % i;
swap = board[i];
board[i] = board[j];
board[j] = swap;
}
for (i = 0; i < size2 - 1; i++)/* is permutation a legal position ? */
for (j = 0; j < i; j++)
if (board[j] > board[i])
nswap++;
if (nswap % 2)
{ /* illegal position, swap two pieces */
swap = board[1];
board[1] = board[0];
board[0] = swap;
}
empty = size2 - 1; /* empty field starts in lower right corner */
signal (SIGINT, die);
initscr ();
crmode ();
noecho ();
while (1) /* until final position is reached */
{
printboard (size, board);
out = 1;
for (i = 0; i < size2 - 1; i++)
if (board[i] != i + 1)
out = 0;
if (out)
break; /* game ends */
while (1) /* until legal move is entered */
{
m = getch ();
if ((m != LEFT) && (m != UP) && (m != RIGHT) &&
(m != DOWN))
{
notmove ();
continue; /* not a move */
}
if (m == LEFT)
if (empty % size)
{
board[empty] = board[empty - 1];
board[empty - 1] = BLANK;
empty--;
movecnt++;
break;
}
if (m == UP)
if (empty >= size)
{
board[empty] = board[empty - size];
board[empty - size] = BLANK;
empty -= size;
movecnt++;
break;
}
if (m == RIGHT)
if ((empty + 1) % size)
{
board[empty] = board[empty + 1];
board[empty + 1] = BLANK;
empty++;
movecnt++;
break;
}
if (m == DOWN)
if (empty + size < size2)
{
board[empty] = board[empty + size];
board[empty + size] = BLANK;
empty += size;
movecnt++;
break;
}
}
}
mvprintw (22, 0, "You've reached the solution in %d moves.\n", movecnt);
refresh ();
endwin ();
}
argerr (s)
char *s;
{
fprintf (stderr, "usage: %s size\n", s);
exit (1);
}
printboard (size, board)
int *board;
{
register int i, j;
mvprintw (0, 0, "|"); /* print top edge of board */
for (j = 0; j < size; j++)
printw ("----|");
for (i = 0; i < size; i++)
{
mvprintw (i * 2 + 1, 0, "| ");
for (j = 0; j < size; j++)
if (board[size * i + j])
printw ("%2d | ", board[size * i + j]);
else
printw (" | ");
mvprintw (i * 2 + 2, 0, "|");
for (j = 0; j < size; j++)
printw ("----|");
}
mvprintw (16, 0, "\n"); /* erase error messages */
refresh (); /* put all this on the screen */
}
notmove ()
{
mvprintw (16, 0,
"use %c for up, %c for left, %c for right and %c for down",
UP, LEFT, RIGHT, DOWN);
refresh ();
}