/* MONEY MATCH */ /* by Richard Lenord Correa Jr. */ /* Copyright (c) 1988 */ /* All rights reserved */ #include /* puzzle array */ char puz_text[20][40] = { "PENNY WISE POUND FOOLISH", "CHIP OFF THE OLD BLOCK", "DONT BEAT AROUND THE BUSH", "CHUG A LUG", "ST ELMOS FIRE", "A PENNY SAVED IS A PENNY EARNED", "ONE FOOT IN THE GRAVE", "THATS ALL SHE WROTE", "SLEEP LIKE A TOP", "IN GOD WE TRUST", "KILROY WAS HERE", "GET THIS SHOW ON THE ROAD", "NICE GUYS FINISH LAST", "KEEP THE FAITH", EGG IN YOUR BEEEER", "ON THE FRITZ", "FIRE WHEN READY GRIDLEY", "STRAIGHT FROM THE HORSES MOUTH", "THE JIG IS UP", "BACK TO SQUARE ONE" }, *text_ptr[20], /* pointer to each puzzle */ save_word[10], /* array used for word placement in puzzle */ guess[30]; /* user guess array */ int line_ary[20], /* array to keep point information to draw boxes */ save_ary[15], /* array to store old line_ary point information */ placed[25], /* array to keep random generated numbers */ tracker[25], /* array to keep track of boxes on player screen */ old_pal[16], /* array to store old color palette information */ blk_pal[16], /* array used to black out screen */ copy[8], /* array used to copy puzzle, play, prize info */ choice, /* array used to choose which puzzle */ box_matched[20], /* array used to store info for matched boxes */ mse_form[37]; /* array to store mouse form info */ /* normal gem initiates */ int contrl[12], intin[256], intout[256], ptsin[256], ptsout[256], workin[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2}, workout[57], dummy, handle, rasters; /* raster variable for MFDB source and destin structures */ long *puzzle_scr,/* three */ *prize_scr, /* screen */ *play_scr, /* pointers */ puz, /* Malloc */ pri, /* dummys */ save_box[2100]; /* array to keep the cover box info */ */ usual MFDB skeleton structure */ struct mfdb { long *addr_scr; int box_width; int box_height; int wrd_wid_scr; int norm_rast; int colr_plane; int res_1; int res_2; int res_3; }; /* pointers for source and destination structures */ struct mfdb source; struct mfdb destin; main() { strt_appl(); /* set up application */ set_scrn(); /* set up screen displays drw_scrn(); /* draw player screen */ set_placement(); /* place prizes */ form_puzzle(); /* set up puzzle */ play_game(); /* play the game */ end_appl(); */ got back to desk top */ } strt_appl() { int loop; /* normal gem application opening commands */ appl_init(); handle = graf_handle(&dummy, &dummy, &dummy, &dummy); v_opnvwk(workin, &handle, workout); graf_mouse(256, mse_form); /* turn mouse off */ v_clrwk(handle); /* clear the screen */ for(loop = 0; loop < 16; loop++) { old_pal[loop] = Setcolor(loop, -1); /* save old color palette */ blk_pal[loop] = 0; /* load black screen colors */ text_ptr[loop] = puz_text[loop]; /* Set pointer to each puzzle */ box_matched[loop] = 0; /* set array to '0' */ } Setpalette(blk_pal); /* turn screen to black */ } set_scrn() { /* routine to set up all three screens and pointers */ puz = (long)Malloc(32767l); pri = (long)Malloc(32767l); play_scr = (long *)Physbase(); puzzle_scr = (long *)((0xffff00 & puz) + 0x0100); prize_scr = (long *)((0xffff00 & pri) + 0x0100); /* find out what type of raster format (rez) then save result in RASTERS */ rasters = workout[0]; rasters += 1; rasters = rasters / 16; vq_extnd(handle, 1, workout); /* Set up MFDB structure for source and destin */ source.wrd_wid_scr = rasters; /* word width */ source.norm_rast = 1; /* set to raster format not normal */ source.colr_plane = workout[4]; /* load color planes */ source.res_1 = 0; /* three */ source.res_2 = 0; /* dummy */ source.res_3 = 0; /* cells */ destin.wrd_wid_scr = rasters; destin.norm_rast = 1; destin.colr_plane = workout[4]; destin.res_1 = 0; destin.res_2 = 0; destin.res_3 = 0; } drw_scrn() { int loop, /* loop variable HA!/* colr_indx = 1, /* color index variable for each line drawn in the boxes */ draw_box; /* times to draw a box in a certain color */ /* set initial value of points for box drawing */ line_ary[0] = 35; line_ary[1] = 20; line_ary[2] = 85; line_ary[3] = 20; line_ary[4] = 85; line_ary[5] = 60; line_ary[6] = 35; line_ary[7] = 60; line_ary[8] = 35; line_ary[9] = 20; vsl_width(handle, 2); /* set line width */ vswr_mode(handle,1); /* set type of writing mode */ vsl_ends(handle, 0, 0); /* line end types */ vsl_type(handle, 1); /* set line style */ /* start the routine */ for(loop = 0; loop < 20; loop++) { /* draw twenty boxes */ /* If we have drawn the last box in the line reset the X coordinate to the beginning and move down to begin new row*/ if(loop == 5 || loop == 10 || loop == 15) { line_ary[0] = 35; line_ary[1] += 40; line_ary[2] = 85; line_ary[3] += 40; line_ary[4] = 85; line_ary[5] += 40; line_ary[6] = 35; line_ary[7] += 40; line_ary[8] = 35; line_ary[9] += 40; } /* save point information so we can reset after each box is drawn */ save_ary[0] = line_ary[0]; save_ary[1] = line_ary[1]; save_ary[2] = line_ary[2]; save_ary[3] = line_ary[3]; save_ary[4] = line_ary[4]; save_ary[5] = line_ary[5]; save_ary[6] = line_ary[6]; save_ary[7] = line_ary[7]; save_ary[8] = line_ary[8]; save_ary[9] = line_ary[9]; /* loop to draw the box */ for(colr_indx = 1; colr_indx <= 16; colr_indx++ ) { /* color */ for(draw_box = 0; draw_box < 2; draw_box++) { /* line to in this color */ vsl_color(handle, colr_indx); /* set line color */ v_pline(handle, 5, line_ary); /*draw the box*/ /* shrink the box size by one pixel width */ line_ary[0]++; line_ary[1]++; line_ary[2]--; line_ary[3]++; line_ary[4]--; line_ary[5]--; line_ary[6]++; line_ary[7]--; line_ary[8]++; line_ary[9]++; } } /* reset the box array information */ line_ary[0] = save_ary[0]; line_ary[1] = save_ary[1]; line_ary[2] = save_ary[2]; line_ary[3] = save_ary[3]; line_ary[4] = save_ary[4]; line_ary[5] = save_ary[5]; line_ary[6] = save_ary[6]; line_ary[7] = save_ary[7]; line_ary[8] = save_ary[8]; line_ary[9] = save_ary[9]; /* move to the right to draw the next box */ line_ary[0] += 50; line_ary[2] += 50; line_ary[4] += 50; line_ary[6] += 50; line_ary[8] += 50; } vst_color(handle, 7); /* set text color */ vst_height(handle, 14, &dummy, &dummy, &dummy, &dummy); /* set text height in points */ vst_effects(handle, 17); /* set text style */ v_gtext(handle, 48, 15, "Money***********Match"); /* write title */ /* set up array to copy the box form to the SAVE_BOX array that will hold it */ copy[0] = 35; copy[1] = 20; copy[2] = 85; copy[3] = 60; copy[4] = 0; copy[5] = 0; copy[6] = 50; copy[7] = 40; source.addr_scr = play_scr; /* set up source */ destin.addr_scr = save_box; /* destination */ vro_cpyfm(handle, 3, copy, &source, &destin); /* copy */ } set_placement() { int num, loop = 0, flag, index, across, down; Setscreen(prize_scr, prize_scr, -1); /* Set the screen to the puzzle screen */ v_clrwk(handle); for(index = 0; index < 20; index++) { /* Set the array that will hold the random numbers to zero */ placed[index] = 0; } do { flag = 0; /* Set FLAG to false */ num = rnd(20); /* Execute random routine passing the maximum number to the routine (20) */ /* Get twenty different numbers between 1 and 20 and store in the PLACED array */ for(index = 1; index < 20; index++) { /* loop counter */ if(num == placed[index]) { /* If the random number picked has already been stored */ flag = 1; /* Set the flag */ break; /* Break out of the routine */ } } if(flag != 1) { However, if we have a different that has not been stored in the array */ for(index = 1; index < 20; index++) { /* Then search the array for a zero */ if( placed[index] == 0) { /* Once we find the zero */ placed[index] = num; /* replace it with the new value */ loop++; /* increment the loop */ break; /* Break out of the routine */ } } } }while(loop < 19); vst_color(handle, 2); /* Set the text color */ vst_height(handle, 4, &dummy, &dummy, &dummy, &dummy); /* Set the height */ vst_effects(handle, 0); /* No effects */ /* Routine to place prizes in the puzzle */ across = 40; /* starting X position */ down = 40; /* starting Y position */ for(loop = 0; loop < 20; loop++) { /* loop counter for twenty placements */ /* This algorithm is fairly simple. We search each element of the array which has the random numbers stored in it. We then take that number and, using the CASE structure, we place the appropriate prize in the box. i.e. If the LOOP variable == 9 we are going to place the prize in BOX number nine. If the number in the PLACED array == 1 then we would put a $100 card in it. We also set the value in an array (TRACKER) that will help us decide if a match has been accomplished. i.e. If the user picks box number 6 and then picks box number 12 and they both hold the $200 prize, the value in both elements of the TRACKER array will be 2. Simple huh? */ if(loop == 5 || loop == 10 || loop == 15) { /* Reset the box if we have reached the far end of the screen */ across = 40; /* Reset across */ down += 40; /* Move down one row */ } /* Case structure to place the prize values and set the TRACKER array values*/ switch(placed[loop]) { case 0: v_gtext(handle, across, down, "$100"); tracker[loop] = 1; break; case 1: v_gtext(handle, across, down, "$100"); tracker[loop] = 1; break; case 2: v_gtext(handle, across, down, "$200"); tracker[loop] = 2; break; case 3: v_gtext(handle, across, down, "$200"); tracker[loop] = 2; break; case 4: v_gtext(handle, across, down, "$300"); tracker[loop] = 3; break; case 5: v_gtext(handle, across, down, "$300"); tracker[loop] = 3; break; case 6: v_gtext(handle, across, down, "$500"); tracker[loop] = 4; break; case 7: v_gtext(handle, across, down, "$500"); tracker[loop] = 4; break; case 8: v_gtext(handle, across, down, "520 ST"); tracker[loop] = 5; break; case 9: v_gtext(handle, across, down, "520 ST"); tracker[loop] = 5; break; case 10: v_gtext(handle, across, down, "1040 ST"); tracker[loop] = 6; break; case 11: v_gtext(handle, across, down, "1040 ST"); tracker[loop] = 6; break; case 12: v_gtext(handle, across, down, "XM 301"); tracker[loop] = 7; break; case 13: v_gtext(handle, across, down, "XM 301"); tracker[loop] = 7; break; case 14: v_gtext(handle, across, down, "130 XE"); tracker[loop] = 8; break; case 15: v_gtext(handle, across, down, "130 XE"); tracker[loop] = 8; break; case 16: v_gtext(handle, across, down, "WILD"); tracker[loop] = 9; break; case 17: v_gtext(handle, across, down, "WILD"); tracker[loop] = 9; break; case 18: v_gtext(handle, across, down, "MEGA ST"); tracker[loop] = 10; break; case 19: v_gtext(handle, across, down, "MEGA ST"); tracker[loop] = 10; break; default: break; } across += 50; /* move across one box */ } } rnd(num) { int rd = 0,/* Set random pick to zero */ mask = 0x000002; /* Set the mask to clear high bits */ --num; /* Set num to one lower than asked for because it will include '0' */ do { /* Access Random() function and AND it with RD until we have a number less than the maximum number size */ while (mask <= num) mask <<= 1; mask--; rd = Random() & mask; } while (rd > num); return(rd); /* Return the random number */ } form_puzzle() { int loop, points, style, color, counter = 0, tot_words = 0, inc_down, down; Setscreen(puzzle_scr, puzzle_scr, -1); /* Set the screnn to the puzzle screen */ v_clrwk(handle); /* Clear the screen */ choice = rnd(19); /* Which puzzle do we use */ /* Routine to set the puzzle */ for(loop = 0; loop < strlen(puz_text[choice]); loop++) { /* loop to find total words in string */ if(*text_ptr[choice] == 32) { /* Is the character a space ? */ tot_words++; /* Yes! increment the TOTAL WORDS in the puzzle */ } text_ptr[choice]++; /* increment the pointer */ } text_ptr[choice] = puz_text[choice]; /* Reset the pointer to the beginning of the string */ /* If a string has, for example, five words, we will only see three spaces so we add one more to TOTAL WORDS to get the correct amount of words. */ tot_words++; /* Algorithm to set the positioning of the puzzle */ inc_down = 160 / tot_words; /* We divide 160 ( the total pixels down we use in the play screen ), by the total words. i.e. If we have four words in the puzzle, each word would be allotted 40 pixels, and this value is stored in INC_DOWN. */ down = (inc_down / 2) + 30; /* We then cut this value in half (to find the center) and add 30 to center the text */ for(loop = 0; loop < strlen(puz_text[choice]); loop++) { /* loop to place each word of the puzzle */ if(*text_ptr[choice] == 32) { /* If we have a space */ save_word[counter] = '\0'; /* terminate the array (SAVE_WORD)that saves the word with the null character /* counter = 0; /* Reset the counter we use to load the SAVE_WORD array back to zero */ loop++; /* increment loop so we dont load the SPACE character */ text_ptr[choice]++; /* Increment the pointer * /* Routine to randomly pick text height */ do { points = rnd(14); }while(points < 5); style = rnd(16); /* Pick style of text randomly */ /* Rouitine to pick color for text randomly */ do { color = rnd(15); }while(color == 0); vst_color(handle, color); /* Set the color of the text */ vst_height(handle, points, &dummy, &dummy, &dummy, &dummy); /* Set the height of the text */ vst_effects(handle, style); /* Set effects */ /* This little command will center your text on the screen for you within a certain amount of pixels. handle = work station pointer 35 = x coordinate for where you want the justification to start down = y coordinate for where you want the justification to start save_word = pointer to text you want justified 250 = total pixels you want this text placed in 0 = set this if you want the text word justified 1 = set this if you want character justification */ v_justified(handle, 35, down, save_word, 250, 0, 1); down += inc_down; } save_word[counter] = *text_ptr[choice]; /* load the array that will save the word for you */ text_ptr[choice]++; /* increment the pointer */ counter++; /* increment the counteer */ } //* These commands are for the last word and to set the final text attributes */ save_word[counter] = '\0'; v_justified(handle, 35, down, save_word, 250, 0, 1); vst_color(handle, 2); vst_height(handle, 4, &dummy, &dummy, &dummy, &dummy); vst_effects(handle, 0); } play_game() { int player = 1, xcoord, ycoord, sav_xcoord, sav_ycoord, mult_x, mult_y, boxnum = 0, flag = 1, pick = 0, match = 0, button = 0, game_over = 0, used, loop, read, input, pos_cur; unsigned int which = 5, key, state; /* TIME TO PLAY!!!!! */ graf_mouse(257, mse_form); /* Turn on the mouse */ graf_mouse(0, mse_form); /* Set the mouse to the ever present arrow */ Setscreen(play_scr, play_scr, -1); /* Set the screen to the play screen */ Setpalette(old_pal); /* Reset the colors */ do { evnt_button(0, 0, 0, &xcoord, &ycoord, &button, &key); /* poll the mouse */ /* Routine to dispatch player action */ switch(button) { /* Left bnutton */ case 1: /* This is the algorithm that figures which box the user is in. First we take the the X and Y coordinate returned by the mouse and set to values relational to the actual playfield. We then divide the X coordinate by 50 (width of box) and the Y coordinate by 40 (height of box), and multiply the Y result by 5 (5 boxes per row) and add one to the X result (total boxes across) and then we add these two valuse together. We then\ check to see if the user, in his cute little way, has tried to use a box that has either already been matched, or was part of the first pick of the players turn. */ xcoord -= 35; /* Set the ycoord -= 20; relational screen */ boxnum = (xcoord / 50 + 1) + ((ycoord / 40) * 5); /* Find the box */ /* has the box already been used */ if(box_matched[(boxnum - 1)] == 1 || boxnum == used) { flag = 0; /* YES then set flag to FALSE */ } if(flag) { /*Everything is OK */ pick++; /* Increment the counter for how many boxes the user has picked this turn */ if(pick == 1) { /* If it is the first pick */ used = boxnum; /* Save the value of the first box picked */ sav_xcoord = xcoord; /* save the coordinates sav_ycoord = ycoord; as well */ } /* Routine to get the corner coordinates of the box picked */ /* This will be a little tough to explain, but here goes. We first use the X and Y relational coordinates to find out the box across value and the box down value. It uis then a simple matter to get the X and Y values for the particular value. i.e. If the mult_x value is a two then we know we are two boxes across, since each box is 50 pixels wide we multiply by 50 to get 100 (relational coordinate). Same holds true for the Y coordinate. If we are two rows down, then we multiply by 40 to get 80. To find the true value for the copy routine we must then add 35 to the X coordinate (because the play screen starts 35 pixels from the left) and add 20 to the Y coordinate (because the play screen starts 20 pixels from the top this is what I meant by relational!! Nice time to tell ya huh??) mult_x = (xcoord / 50) * 50; mult_y = (ycoord / 40) * 40; mult_x += 35; mult_y += 20; graf_mouse(256, mse_form); destin.addr_scr = play_scr; /* Set the source and source.addr_scr = prize_scr; destination pointers */ copy[0] = copy[4] = mult_x; /* load the COPY array copy[1] = copy[5] = mult_y; with our copy[2] = copy[6] = mult_x + 50; box copy[3] = copy[7] = mult_y + 40; coordinates */ vro_cpyfm(handle, 3, copy, &source, &destin); /* Do it!! */ graf_mouse(257, mse_form); if(pick == 2) { /* Is it the second pick */ /* If we have a wild card or a match then we set the BOX_MATCHED array element to true for that appropriate box */ if(tracker[(used - 1)] == tracker[(boxnum - 1)] || tracker[(used - 1)] == 9 || tracker[(boxnum - 1)] == 9) { box_matched[(used - 1)] = box_matched[(boxnum - 1)] = 1; source.addr_scr = puzzle_scr; /* Set the new source to reveal part of the puzzle */ graf_mouse(256, mse_form); vro_cpyfm(handle, 3, copy, &source, &destin); /* Do it !! */ /* Use the X and Y coordinates to do the same thing we did above for the first box picked */ mult_x = (sav_xcoord / 50) * 50; mult_y = (sav_ycoord / 40) * 40; mult_x += 35; mult_y += 20; copy[0] = copy[4] = mult_x; copy[1] = copy[5] = mult_y; copy[2] = copy[6] = mult_x + 50; copy[3] = copy[7] = mult_y + 40; vro_cpyfm(handle, 3, copy, &source, &destin); graf_mouse(257, mse_form); if(player == 1) { /* Set which player */ player = 2; } else { player = 1; } match++; } else { /* If we did not have a match */ Bconin(2); /* Let the player look until his heart is content then prees a key */ source.addr_scr = save_box; /* Set the source pointer to the array that has our cover box saved in it */ copy[0] = 0;/* use the copy[1] = 0; coordinates that copy[2] = 50; we used to save copy[3] = 40; the box with VERY IMPORTANT!! */ graf_mouse(256, mse_form); vro_cpyfm(handle, 3, copy, &source, &destin); /* Do it for the first p[ick as well */ mult_x = (sav_xcoord / 50) * 50; mult_y = (sav_ycoord / 40) * 40; mult_x += 35; mult_y += 20; copy[4] = mult_x; copy[5] = mult_y; copy[6] = mult_x + 50; copy[7] = mult_y + 40; vro_cpyfm(handle, 3, copy, &source, &destin); graf_mouse(257, mse_form); } pick = 0; /* Rest the PICK counter */ /* Check to see if the players have matched every thing, if so thne end the game */ if(match == 10) { game_over = 1; /* Set the game over flag */ } if(player == 1) { /*Reset player flag */ player = 2; } else { player = 1; } } } flag = 1; break; case 2: /* Take a guess routine */ if(! pick) { /* It must be done before a box is picked */ v_curhome(handle); /* Set the cursor for(pos_cur = 0; pos_cur < 23; pos_cur++) { to the v_curdown(handle); lower right hand corner */ } v_eeol(handle); /* Erase anything there */ v_gtext(handle, 0, 190, "->"); /* Show prompt */ v_curright(handle); /* Move cursor 2 characters v_curright(handle); to the right */ gets(guess); /* What is the guess */ /* Convert the guess to upper case */ for(read = 0; read < strlen(guess); read++) { input = toupper(guess[read]); guess[read] = input; } /* Reposition cursor */ v_curhome(handle); for(pos_cur = 0; pos_cur < 23; pos_cur++) { v_curdown(handle); } v_eeol(handle); /* Compare the guess to the puzzle */ if(! strcmp(guess, puz_text[choice])) { /* If the user is right */ finish_game(); /* Finish game routine */ game_over = 1; /* Set game over flag */ Bconin(2); /* Stare at the screen */ } } break; default: break; } /* Routine to p[rint which players' turn it is */ v_curhome(handle); for(pos_cur = 0; pos_cur < 23; pos_cur++) { v_curdown(handle); } printf("PLAYER-->> %d\n", player); }while(flag && ! game_over); } finish_game() /* This will be a surprise for you!!!*/ { int colr_indx = 0, loop, draw_box; v_clrwk(handle); line_ary[0] = 0; line_ary[1] = 0; line_ary[2] = 319; line_ary[3] = 0; line_ary[4] = 319; line_ary[5] = 199; line_ary[6] = 0; line_ary[7] = 199; line_ary[8] = 0; line_ary[9] = 0; for(loop = 1; loop <= 100; loop++, colr_indx++ ) { if(colr_indx > 15) { colr_indx = 0; } vsl_color(handle, colr_indx); v_pline(handle, 5, line_ary); line_ary[0]++; line_ary[1]++; line_ary[2]--; line_ary[3]++; line_ary[4]--; line_ary[5]--; line_ary[6]++; line_ary[7]--; line_ary[8]++; line_ary[9]++; } vst_height(handle, 14, &dummy, &dummy, &dummy, &dummy); v_gtext(handle, 95, 110, "YOU WIN!!!"); } end_appl() /* Back to desk top */ { v_clsvwk(handle); appl_exit(); }