home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_09_04
/
9n04040a
< prev
next >
Wrap
Text File
|
1991-02-19
|
6KB
|
309 lines
/*
* puzzle.c: This QNX Windows program creates a
* moving tile puzzle, with 15 numbered tiles in a
* 4 X 4 enclosure.
*
* It is reproduced here by permission of Quantum Software Systems, Ltd
* of Kanata, Canada.
*/
#include <stdio.h>
#include <windows.h>
#define RECT_HEIGHT 250
#define RECT_WIDTH 360
#define PANE_BORDER 140
#define PANE_HEIGHT ((rows)*RECT_HEIGHT + 120)
#define PANE_WIDTH ((rows)*RECT_WIDTH + 120)
#define CASE(str) (((str)[0] << 8) | (str)[1])
EVENT_MSG msg;
int rows = 4, max_num;
int b[20][20], old[20][20];
int mv;
èmain()
{
int go = YES, wid, pid;
/* connect to QWindows */
if ( !GraphicsOpen (NULL) )
exit ( -1 );
SetName("Puzzle", NULL); /* Optional */
pid = PictureOpen ( "pict", NULL, NULL, LIGHT_GRAY, NULL, NULL, NULL );
PictureHighlightOptions( NULL, 'N', 0, 0 );
init();
display();
wid = WindowOpen ("Puzzle", PANE_HEIGHT, PANE_WIDTH,
"MT480-r;s", NULL, NULL, pid);
/*
* Put control button in top frame.
*/
WindowBarCurrent( TOP, NULL );
SetButton( NULL, WHITE, NULL );
DrawAt( 300, 120 );
AttachDialog("Options", NULL,
"Scramble;Size|@(Easy|03;The Famous 4 x 4|04;Hard|05;Very Hard|06;You've got to be Kidding|10)^R",
NULL, "MD", NULL, NULL);
DrawButton( "Options", NULL, "Ns;D", "op");
Draw();
WindowBarCurrent( NULL, NULL );
load_icon( "/windows/apps/puzzle" );
DrawStart(NULL, 0);
while ( go )
{
GetEvent ( 0, &msg, sizeof(msg));
switch ( Event ( &msg ) )
{
case QUIT:
WindowClose( 0, NULL );
go = NO;
break;
case TERMINATED:
go = NO;
break;
case CLICK:
if (msg.hdr.code == 'S') {
/* game piece selected */è move(atoi(msg.hdr.key) - 1);
mv++;
win ();
}
break;
case DIALOG:
switch(CASE(msg.hdr.key)) {
case '03': case '04': case '05': case '06':
case '07': case '10':
rows = atoi(msg.hdr.key);
case 'Sc':
new_game();
break;
}
}
}
GraphicsClose( );
exit (0);
}
init() {
int i, j, r, loop;
max_num = rows*rows;
for (i = 0; i < rows; i++)
for (j = 0; j < rows; j++) {
b[i][j] = ( i * rows + j);
old[i][j] = -1;
}
i = j = rows - 1;
srand(get_ticks());
r = rand() % 200 + 500;
for (loop = 0; loop < 5000; ++loop) {
switch (rand() % 4) {
case 0:
if (i != 0) {
b[i][j] = b[i - 1][j];
b[i - 1][j] = max_num;
--i;
}
break;
case 1:
if (i != rows - 1) {
b[i][j] = b[i + 1][j];
b[i + 1][j] = max_num;
i++;
}
break;
è case 2:
if (j != 0) {
b[i][j] = b[i][j - 1];
b[i][j - 1] = max_num;
--j;
}
break;
case 3:
if (j != rows - 1) {
b[i][j] = b[i][j + 1];
b[i][j + 1] = max_num;
j++;
}
break;
}
}
}
display() {
int i, j;
for (i = 0; i < rows; i++)
if (memcmp(b[i], old[i], rows)) {
for (j = 0; j < rows; j++)
if (b[i][j] != max_num)
draw_number(i, j, b[i][j] + 1);
memcpy(old[i], b[i], rows);
}
}
draw_number( row, col, number)
int row, col, number;
{
char tbuf[4];
tsprintf(tbuf, "%2d", number);
SetColor ( "T", BLACK );
DrawAt (PANE_BORDER + (row*RECT_HEIGHT) + CHARH/2,
PANE_BORDER + (col*RECT_WIDTH ));
DrawText( tbuf, 0, 0, 0, "Sem", tbuf);
Draw ( );
}
move_number( row, col, number)èint row, col, number;
{
char buffer[7];
tsprintf(buffer, "%2d", number);
ShiftTo( buffer, PANE_BORDER + (row*RECT_HEIGHT) + CHARH/2,
PANE_BORDER + (col*RECT_WIDTH ));
}
move(m)
int m;
{
int i1, j1, i, j, i2, j2, c;
i1 = j1 = -1;
for (i = 0; i1 == -1 && i < rows; i++)
for (j = 0; j < rows; j++)
if (b[i][j] == m) {
i1 = i;
j1 = j;
break;
}
if (i1 != -1) {
i2 = j2 = -1;
for (i = 0; i < rows; i++)
if (b[i][j1] == max_num) {
i2 = i;
j2 = j1;
break;
}
if (i2 == -1)
for (j = 0; j < rows; j++)
if (b[i1][j] == max_num) {
i2 = i1;
j2 = j;
break;
}
if (i2 == -1)
return;
}
else
return;
/* Hold picture for smoother updates */
PictureHold( );
if (i1 == i2)
if (j1 < j2)
for (j = j2 - 1; j >= j1; --j) {
b[i1][j + 1] = b[i1][j];
move_number(i1, j+1, b[i1][j]+1);è }
else
for (j = j2; j < j1; j++) {
b[i1][j] = b[i1][j + 1];
move_number(i1, j, b[i1][j+1]+1);
}
else
if (i1 < i2)
for (i = i2 - 1; i >= i1; --i) {
b[i + 1][j1] = b[i][j1];
move_number(i+1, j1, b[i][j1]+1);
}
else
for (i = i2; i < i1; i++) {
b[i][j1] = b[i + 1][j1];
move_number(i, j1, b[i+1][j1]+1);
}
b[i1][j1] = max_num;
/* update current picture */
PictureContinue( );
}
win() {
int c = 0, i, j;
char buf[50];
for (i = 0; i < rows; i++)
for (j = 0; j < rows; j++)
if (b[i][j] < c)
return( 0 );
else
c = (int) b[i][j];
tsprintf(buf, "You got it in %d moves!", mv);
Notice( NULL, "You Win", NULL, "W", buf);
return( 1 );
}
new_game() {
RECT_AREA area;
WindowInfo(NULL,&area,NULL,NULL,NULL,NULL);
/* erase all elements in the picture */
WindowHold( );
Erase( ALL );
area.height = PANE_HEIGHT;
area.width = PANE_WIDTH;
è init( );
display( );
mv = 0;
WindowChange( &area, NULL, KEEP, NULL, "!" );
WindowContinue( );
}