home *** CD-ROM | disk | FTP | other *** search
- /* move.c for PUZZ Martin Round. January 1990 */
-
- unsigned char work [MAXACROSS] [MAXDOWN];
- int scorex,scorey,scoreapen,scorebpen;
-
- extern char line[MAXLINE];
- extern int sqrsacross,sqrsdown;
- extern unsigned char goal [MAXACROSS] [MAXDOWN];
- extern unsigned char grid [MAXACROSS] [MAXDOWN];
- extern unsigned char movelist [MAXPIECES] [4];
-
- extern int topleftx,toplefty;
- extern int sqrwidth,sqrheight;
- extern int slide;
-
- extern int moves;
- extern int dmapwidth,dmapheight;
- extern int audio;
-
- extern struct RastPort *dbuff;
-
- extern void play_note(int,int);
-
- void off () /* turn off any sounds currently playing */
- {
- if (audio)
- {
- play_note (100,0);
- play_note (100,1);
- play_note (100,2);
- play_note (100,3);
- }
- }
-
- void tune()
- {
- if (audio)
- {
- off();
- play_note (48,0);
- play_note (48,1);
- Delay (16);
- off();
- Delay (8);
- play_note (43,2);
- Delay (8);
- play_note (42,3);
- play_note (100,2);
- Delay (8);
- play_note (43,2);
- play_note (100,3);
- Delay (8);
- play_note (45,3);
- play_note (100,2);
- Delay (24);
- play_note (43,2);
- play_note (100,3);
- Delay (24);
- off();
- Delay (16);
- play_note (47,0);
- play_note (47,1);
- Delay (16);
- off();
- Delay (16);
- play_note (48,0);
- play_note (48,1);
- play_note (52,2);
- play_note (52,3);
- Delay (16);
- off();
- }
- }
-
- void movesquare(rp,x,y,width,height,dx,dy)
- struct RastPort *rp;
- int x,y,width,height,dx,dy;
- {
- ClipBlit
- (
- rp,topleftx + x,toplefty + y, /* source posn */
- dbuff,x+dx,y+dy, /* dest posn */
- width,height, /* size */
- 0xc0 /* direct copy */
- );
- }
-
- int canmove(int piece, int direction) /* returns 0 if it can't */
- {
- int i,j,old;
-
- for (j=0; j<sqrsdown; j++)
- for (i=0; i<sqrsacross; i++)
- if (piece == grid [i] [j])
- {
- switch (direction)
- {
- case 1:
- if (i == (sqrsacross - 1)) return(0);
- old = grid [i+1] [j];
- break;
- case 2:
- if (j == 0) return(0);
- old = grid [i] [j-1];
- break;
- case 3:
- if (i == 0) return(0);
- old = grid [i-1] [j];
- break;
- default:
- if (j == (sqrsdown - 1)) return(0);
- old = grid [i] [j+1];
- break;
- }
-
- if (old && (old != piece)) return (0);
- }
- return (1);
- }
-
- void sortlist (int piece, int move)
- {
- int i;
-
- if ((move+=2) > 4) move -=4; /* opposite direction of move */
-
- for (i=0; i<3; i++)
- if (move == movelist [piece] [i])
- {
- while (i < 3)
- {
- movelist [piece] [i] = movelist [piece] [i+1];
- i++;
- }
- movelist [piece] [3] = move; /* last in new list */
- return;
- }
- }
-
- int suggestmove(int piece) /* 1 left, 2 up, 3 right, 4 down, 0 can't */
- {
- int i,move;
-
- for (i=0; i<4; i++) /* look through move list */
- {
- if (canmove(piece,(move = movelist [piece] [i])))
- {
- sortlist (piece,move);
- return (move);
- }
- }
-
- return (0);
- }
-
- void moveonepiece(struct RastPort *rp,int piece,int direction)
- {
- int i,j,finished;
- /* prepare double buffer */
- ClipBlit
- (
- rp,topleftx,toplefty, /* source posn */
- dbuff,0,0, /* dest posn */
- dmapwidth,dmapheight, /* size */
- 0xc0 /* direct copy */
- );
-
- for (j=0; j<sqrsdown; j++)
- for (i=0; i<sqrsacross; i++)
- if((work [i] [j] = grid [i] [j]) == piece)
- {
- work [i] [j] = 0;
- SetDrMd(dbuff,JAM1);
- SetAPen(dbuff,0);
- RectFill
- (
- dbuff,
- i*sqrwidth,
- j*sqrheight,
- i*sqrwidth+sqrwidth-1,
- j*sqrheight+sqrheight-1
- );
- }
-
- for (j=0; j<sqrsdown; j++)
- {
- for (i=0; i<sqrsacross; i++)
- {
- if (piece == grid [i] [j])
- {
- switch (direction)
- {
- case 1:
- work [i+1] [j] = piece;
- movesquare
- (
- rp,
- i*sqrwidth,
- j*sqrheight,
- sqrwidth,
- sqrheight,
- sqrwidth,
- 0
- );
- break;
-
- case 2:
- work [i] [j-1] = piece;
- movesquare
- (
- rp,
- i*sqrwidth,
- j*sqrheight,
- sqrwidth,
- sqrheight,
- 0,
- -sqrheight
- );
- break;
-
- case 3:
- work [i-1] [j] = piece;
- movesquare
- (
- rp,
- i*sqrwidth,
- j*sqrheight,
- sqrwidth,
- sqrheight,
- -sqrwidth,
- 0
- );
- break;
-
- case 4:
- work [i] [j+1] = piece;
- movesquare
- (
- rp,
- i*sqrwidth,
- j*sqrheight,
- sqrwidth,
- sqrheight,
- 0,
- sqrheight
- );
- break;
- }
- }
- }
- }
-
- ClipBlit
- (
- dbuff,0,0, /* source posn */
- rp,topleftx,toplefty, /* dest posn */
- dmapwidth,dmapheight, /* size */
- 0xc0 /* direct copy */
- );
-
- for (j=0; j<sqrsdown; j++)
- for (i=0; i<sqrsacross; i++)
- grid [i] [j] = work [i] [j];
-
- finished = 1;
-
- for (j=0; finished && j<sqrsdown; j++)
- for (i=0; i<sqrsacross; i++)
- if (goal [i] [j] && (grid [i] [j] != goal [i] [j]))
- finished = 0;
-
- if (finished)
- tune();
- }
-
- void updatescore(struct RastPort *rp)
- {
- if (audio)
- play_note (48,0);
-
- moves++;
-
- if (scorex || scorey)
- {
- Move(rp,scorex,scorey+6);
- SetDrMd(rp,JAM2);
- SetAPen(rp,scoreapen);
- SetBPen(rp,scorebpen);
- sprintf(line,"Moves:%5d",moves);
- Text(rp,line,11);
- }
- }
-
- int movepiece(struct RastPort *rp,int piece)
- {
- int direction;
-
- if ((direction = suggestmove(piece)) != 0)
- {
- updatescore(rp);
-
- do
- {
- moveonepiece(rp,piece,direction);
- } while (slide && canmove(piece,direction));
- }
- return (direction);
- }
-
- void slidepieces(struct RastPort *rp,int piece)
- {
- int i,j,x,y,zx,zy,direction;
-
- int flag = 1;
-
- for (j=0; flag && j<sqrsdown; j++)
- for (i=0; flag && i<sqrsacross; i++)
- if (piece == grid [i] [j])
- {
- x = i;
- y = j;
- flag = 0;
- }
-
- for (i=0; i<sqrsacross; i++)
- if (grid [i] [y] == 0)
- {
- flag = 1;
- zx = i;
- zy = y;
- }
-
- if (flag == 0)
- for(i=0; i<sqrsdown; i++)
- if (grid [x] [i] == 0)
- {
- flag = 1;
- zx = x;
- zy = i;
- }
-
- if (flag == 0) return;
-
- if (x == zx)
- {
- if (y > zy)
- {
- for (i=zy+1; i<y; i++)
- if (255 == grid [x] [i])
- return;
- direction = 2;
- }
- else
- {
- for (i=y+1; i<zy; i++)
- if (255 == grid [x] [i])
- return;
- direction = 4;
- }
- }
- else
- {
- if (x > zx)
- {
- for (i=zx+1; i<x; i++)
- if (255 == grid [i] [y])
- return;
- direction = 3;
- }
- else
- {
- for (i=x+1; i<zx; i++)
- if (255 == grid [i] [y])
- return;
- direction = 1;
- }
- }
-
- piece = 0;
-
- if (x == zx)
- {
- if (y > zy)
- {
- for (i=zy+1; i<=y; i++)
- if ((grid [x] [i]) && (piece != grid [x] [i]))
- {
- if (canmove(piece = grid [x] [i],direction))
- {
- if (flag)
- {
- flag = 0;
- updatescore(rp);
- }
- moveonepiece(rp,piece,direction);
- }
- else return;
- }
- }
- else
- {
- for (i=zy-1; i>=y; i--)
- if ((grid [x] [i]) && (piece != grid [x] [i]))
- {
- if (canmove(piece = grid [x] [i],direction))
- {
- if (flag)
- {
- flag = 0;
- updatescore(rp);
- }
- moveonepiece(rp,piece,direction);
- }
- else return;
- }
- }
- }
- else
- {
- if (x > zx)
- {
- for (i=zx+1; i<=x; i++)
- if ((grid [i] [y]) && (piece != grid [i] [y]))
- {
- if (canmove(piece = grid [i] [y],direction))
- {
- if (flag)
- {
- flag = 0;
- updatescore(rp);
- }
- moveonepiece(rp,piece,direction);
- }
- else return;
- }
- }
- else
- {
- for (i=zx-1; i>=x; i--)
- if ((grid [i] [y]) && (piece != grid [i] [y]))
- {
- if (canmove(piece = grid [i] [y],direction))
- {
- if (flag)
- {
- flag = 0;
- updatescore(rp);
- }
- moveonepiece(rp,piece,direction);
- }
- else return;
- }
- }
- }
- }
-
- void clicked(struct RastPort *rp,int xclick,int yclick)
- {
- int x,y,piece;
- if ((xclick<topleftx) || (yclick<toplefty)) return;
- if ((x = ((xclick-topleftx)/sqrwidth)) >= sqrsacross) return;
- if ((y = ((yclick-toplefty)/sqrheight)) >= sqrsdown) return;
- if ((piece = grid [x] [y]) == 0) return;
- if (piece == 255) return;
-
- if (slide == 2)
- {
- if (movepiece(rp,piece) == 0)
- slidepieces(rp,piece);
- }
- else
- movepiece(rp,piece);
-
- if (audio)
- play_note(100,0);
-
- }
-