/*********************************************************************** * * Yachtc * Yes, Friends, it My First Amiga Program * Copyright 1985 by Sheldon Leemon * Feel free to copy and distribute the program and * source code, but don't try to sell, license, or * otherwise commercially exploit it. * * If you have questions or comments, you may contact * the author through Delphi (username = DRX) * or Compuserve ID 72705,1355. No late-night phone calls, * please. * ************************************************************************/ /* Version 2.0 modifications by Mark Schretlen of Calgary,Alberta 86-03-16 ( some fixes & Steve Bennett's "scales" incorporated with calls to Happy,Bomb, and YahtzeeSound). Version 3.0 further modifications by M. Schretlen for multitasking "scales" 87-12-30. */ #include "bones.h" /***************** Image and other data structs ****************/ /* Image data for dice spots. All 48 bits are used for the image. We move this data down to CHIP memory, just in case (later versions will lets us allocate structures in CHIP memory--so they say)*/ unsigned short SpotData [] [57] ={ /* one spot */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07E0, 0x0000, 0x0000, 0x1FF8, 0x0000, 0x0000, 0x1FF8, 0x0000, 0x0000, 0x1FF8, 0x0000, 0x0000, 0x07E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* two spots*/ 0x1F80, 0x0000, 0x0000, 0x7FE0, 0x0000, 0x0000, 0x7FE0, 0x0000, 0x0000, 0x7FE0, 0x0000, 0x0000, 0x1F80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01F8, 0x0000, 0x0000, 0x07FE, 0x0000, 0x0000, 0x07FE, 0x0000, 0x0000, 0x07FE, 0x0000, 0x0000, 0x01F8, /* three spots */ 0x1F80, 0x0000, 0x0000, 0x7FE0, 0x0000, 0x0000, 0x7FE0, 0x0000, 0x0000, 0x7FE0, 0x0000, 0x0000, 0x1F80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07E0, 0x0000, 0x0000, 0x1FF8, 0x0000, 0x0000, 0x1FF8, 0x0000, 0x0000, 0x1FF8, 0x0000, 0x0000, 0x07E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01F8, 0x0000, 0x0000, 0x07FE, 0x0000, 0x0000, 0x07FE, 0x0000, 0x0000, 0x07FE, 0x0000, 0x0000, 0x01F8, /* four spots */ 0x1F80, 0x0000, 0x01F8, 0x7FE0, 0x0000, 0x07FE, 0x7FE0, 0x0000, 0x07FE, 0x7FE0, 0x0000, 0x07FE, 0x1F80, 0x0000, 0x01F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F80, 0x0000, 0x01F8, 0x7FE0, 0x0000, 0x07FE, 0x7FE0, 0x0000, 0x07FE, 0x7FE0, 0x0000, 0x07FE, 0x1F80, 0x0000, 0x01F8, /* five spots */ 0x1F80, 0x0000, 0x01F8, 0x7FE0, 0x0000, 0x07FE, 0x7FE0, 0x0000, 0x07FE, 0x7FE0, 0x0000, 0x07FE, 0x1F80, 0x0000, 0x01F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07E0, 0x0000, 0x0000, 0x1FF8, 0x0000, 0x0000, 0x1FF8, 0x0000, 0x0000, 0x1FF8, 0x0000, 0x0000, 0x07E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F80, 0x0000, 0x01F8, 0x7FE0, 0x0000, 0x07FE, 0x7FE0, 0x0000, 0x07FE, 0x7FE0, 0x0000, 0x07FE, 0x1F80, 0x0000, 0x01F8, /* six spots */ 0x1F80, 0x0000, 0x01F8, 0x7FE0, 0x0000, 0x07FE, 0x7FE0, 0x0000, 0x07FE, 0x7FE0, 0x0000, 0x07FE, 0x1F80, 0x0000, 0x01F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F80, 0x0000, 0x01F8, 0x7FE0, 0x0000, 0x07FE, 0x7FE0, 0x0000, 0x07FE, 0x7FE0, 0x0000, 0x07FE, 0x1F80, 0x0000, 0x01F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F80, 0x0000, 0x01F8, 0x7FE0, 0x0000, 0x07FE, 0x7FE0, 0x0000, 0x07FE, 0x7FE0, 0x0000, 0x07FE, 0x1F80, 0x0000, 0x01F8, }; USHORT (*SpotData_chip)[57]; SHORT boardlines[] = { HLINR,VLINT, HLINR,VLINB, HLINL-1,VLINB, HLINL-1,VLINT, HLINL,VLINT, HLINL,VLINB, HLINR-1,VLINB, HLINR-1,VLINT }; static USHORT colormap [8] = { WHITE, /* background color */ #define BGRP 0 RED, /* color of window-close box */ #define REDP 1 GREEN, /* color of menu title */ #define GRNP 2 YELLOW, /* color of window-close dot */ #define YELP 3 AQUA, #define AQUP 4 PURPLE, #define PURP 5 BLUE, #define BLUP 6 BLACK #define BLKP 7 }; extern void init_sound(); extern void do_sound(); #include "endless.h" /* *************************Program Begins Here******************* */ main() { USHORT bones [6]; /* The array for dice values */ USHORT cats; int scores [MAXPLAYERS] [SCORECATS]; USHORT IMsg(), flag; USHORT players, cur_player, turns; init_sound(); do_sound(YAHSOUND,7); init_scr(); /* do one-time initialization of screen */ for (;;) { /* get number of players */ while( (flag=IMsg()) < 64); /* wait til new game menu item selected */ /* initialize the scores */ for(players=cur_player=0;players24) ); /* wait til button pushed */ changed = Shake(bones); /* shake if any are changed */ } OffGadget(&ButtonGadget,BdWdw,NULL); for(dieno = 0; dieno < DICE ; dieno++) /* turn gadgets off */ DieGadg[dieno].Activation = NULL; if( (bones[0] == bones[1]) && (bones[1] == bones[2]) && (bones[2] == bones[3]) && (bones[3] == bones[4]) ) do_sound(YAHSOUND,5); }/* end of roll_ */ score_turn(scores,bones,cur_player) int scores[]; USHORT bones[]; USHORT cur_player; { USHORT IMsg(); unsigned int Evaluate(),score; USHORT row,values[7],count; /********************************************************************/ /* This routine evaluates the current dice values in the bones array in terms of the score they produce for the scoring category passed in row for the function "Evaluate"(returns the score). */ for(count=0;count<7;count++) values[count]=0; /* zero out temporarily sort array */ for(count=0;count<5;count++) /* sort dice by number of spots */ { values[bones[count]]++; values[6]+=(1+bones[count]); /* add die to total */ } /********************************************************************/ /* position score gadget */ ScoreGadget.LeftEdge = VLINL + (VLINS*cur_player) + 4; /* AddGadget(BdWdw,&ScoreGadget,-1); */ /* show possible scores to let player select */ for (row = 0; row <17; row ++) if (scores[row] == -1) { SetAPen (BdRp,BGRP); /* erase dots with bg pen */ ShowDots (row,cur_player); SetAPen (BdRp,REDP); /* possible scores in green */ score = Evaluate(values,row); ShowScore (score,row,cur_player); } /* wait until user clicks on a score of an unused category */ while( ( (row=IMsg()) > 17) || (scores[row] != -1 ) ); SetAPen (BdRp,BLKP); /* selected scores in black */ score = Evaluate(values,row); /* evaluate row selected */ ShowScore (scores[row]=score,row,cur_player); /* print in black */ /*********Steve Bennett's "scales" sounds.******/ if ((score < 3) || ((score < 6) && (row > 2)) ) do_sound(BOMBSOUND,5); else if ( ((score > 18) && (row < 6)) || ((score > 25) && (row > 8)) ) do_sound(HAPPYSOUND,5); else if ((score < 20) && (row > 8) ) do_sound(HAPPYSOUND,1); /***********************************************/ if (row<7) { ClearRow(7,cur_player); ShowScore (scores[7]+=score,7,cur_player); /* do upper sub-total */ } else { ClearRow(18,cur_player); ShowScore (scores[18]+=score,18,cur_player); /* or else lower total */ } if (scores[7] > BONUS) { ClearRow(8,cur_player); ShowScore (scores[8] = 35, 8, cur_player); /* check for bonus */ } /*add sub-totals to total and display */ ClearRow(20,cur_player); ShowScore (scores[20]=scores[7]+scores[8]+scores[18],20,cur_player); for (row = 0; row <17; row ++) if (scores[row] == -1) { SetAPen (BdRp,BGRP); /* erase scores with bg pen */ score = Evaluate(values,row); ShowScore (score,row,cur_player); SetAPen (BdRp,BLKP); /* draw dots in black pen */ ShowDots (row,cur_player); } } USHORT IMsg() { struct IntuiMessage *BdMsg; /* Intuition message structure */ ULONG Mclass; /* Message class */ USHORT Mcode,flag; /* Message code */ APTR Maddress; /* Address of structure that caused message */ SHORT Mmx, Mmy ; /* Message mouse x and y */ flag = 35; Wait (1 << BdWdw->UserPort->mp_SigBit); while (BdMsg = (struct IntuiMessage *)GetMsg(BdWdw->UserPort)) { Mclass = BdMsg->Class; Mcode = BdMsg->Code; Maddress = BdMsg->IAddress; Mmx = BdMsg->MouseX; Mmy = BdMsg->MouseY; ReplyMsg(BdMsg); switch (Mclass) { case CLOSEWINDOW: Cleanup(); exit(TRUE); break; case GADGETUP: flag = (Mmy-29)/8; break; case MENUPICK: switch (MENUNUM(Mcode)){ case 0: flag = 64 + ITEMNUM(Mcode); break; case 1: switch (ITEMNUM(Mcode)){ case 0: AutoRequest (BdWdw,&InstructText[13],NULL,&OKText,0,0,515,180); flag = 32; break; case 1: AutoRequest (BdWdw,&AboutText[10],NULL,&OKText,0,0,515,148); flag = 32; break; } /* end of Item switch */ break; } /* end of MenuNum switch */ break; } /* end of Class switch */ }/* while */ return(flag); } USHORT Shake(bones) USHORT bones[]; { USHORT dieno,changed,Rollrep(); for(dieno=changed=0;dieno 2) flagg = 1; return( (flagg) ? values[6] : 0); /* 4 of a kind */ case 11: for(count=flagg=0;count<6;count++) if(values[count] > 3) flagg = 1; return( (flagg) ? values[6] : 0); /* full house */ case 12: for(count=flagg=0;count<6;count++) if(values[count] > 1) flagg+=values[count]; return((unsigned int) ((flagg == 5) ? 25 : 0)); /* small straight */ case 13: flagg = 0; save = 100; for (count = 0;count < 6;count++) { if(values[count] > 1) /* are there more than one pair */ { flagg = flagg + values[count]; save = count; } } if (flagg > 2) return(0); if (save != 100) values[save] = values[save] - 1; flagg = 0; if (((values[0] == 1) && (values[1] == 1) && (values[2] == 1) && (values[3] == 1) ) || ((values[1] == 1) && (values[2] == 1) && (values[3] == 1) && (values[4] == 1) ) || ((values[2] == 1) && (values[3] == 1) && (values[4] == 1) && (values[5] == 1) )) flagg = 30; /* whew! */ if(save != 100) values[save] = values[save] + 1; return(flagg); /* large straight */ case 14: flagg = 0; for (count = 0;count < 6;count++) { if(values[count] > 1) return(0); } if (values[0] == values[1] == values[2] == values[3] == values[4] == 1 || values[1] == values[2] == values[3] == values[4] == values[5] == 1 ) return(40); /* if five in a row, score */ return(0); /* yacht */ case 15: for(count=flagg=0;count<6;count++) if(values[count] == 5) flagg = 50; return(flagg); /* yarboro */ case 16: return((unsigned int)values[6]); /* better not get here! */ default: return(0); } } ShowScore(score,row,player) USHORT score,row,player; { int length; char *score_str = "0000"; SetDrMd(BdRp,JAM1); Move (BdRp,DOTL + (DOTS*player), (row*TEXTS)+DOTT ); Text (BdRp, " ",4); length = stcu_d (score_str,score,4); Move (BdRp, DOTL + (DOTS*player + ((4-length)*SPACEW) ), (row*TEXTS)+DOTT ); Text (BdRp, score_str, length); } ShowDots (row,player) USHORT row,player; { Move (BdRp,DOTL + (DOTS*player), (row*TEXTS)+DOTT ); SetDrMd(BdRp,JAM1); Text (BdRp, "....",4); } ClearRow (row,player) USHORT row,player; { Move (BdRp,DOTL + (DOTS*player), (row*TEXTS)+DOTT ); SetDrMd(BdRp,JAM2); Text (BdRp, " ",4); } Name (player) USHORT player; { Move(BdRp, DOTL -(2*SPACEW) + (DOTS*player), TEXTT+2); Text(BdRp, textline[MAXLINES+player], 8); } init_scr() { /* move image data to chip memory*/ if (InitImages() != TRUE) { printf("Not enough chip memory for images.\n"); FreeImages(); Exit(FALSE); } /* Open the Intuition and Graphics libraries. * Get pointer to WCS routines, and if = 0, libraries aren't available. */ IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",INTUITION_REV); if (IntuitionBase == NULL) exit(FALSE); GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", GRAPHICS_REV); if (GfxBase == NULL) { CloseLibrary(IntuitionBase); exit(FALSE); } /* Open the Screen and Windows. If they = 0, they weren't opened. */ if ((NewBoardWindow.Screen = BackWindow.Screen = BdScr = (struct Screen *)OpenScreen(&NewBdScr)) == NULL) exit(FALSE); if (( BackWdw = (struct Window *)OpenWindow(&BackWindow)) == NULL) exit(FALSE); if (( BdWdw = (struct Window *)OpenWindow(&NewBoardWindow)) == NULL) exit(FALSE); SetMenuStrip(BdWdw,&BdMenu); init_pad(); /* draw the score pad */ } /* end of init_scr */ init_pad() { /* Set up the board outline */ ULONG Seconds,Micros; int count, column; WVPort = (struct ViewPort *)ViewPortAddress(BdWdw); /* find the viewport */ LoadRGB4(WVPort,&colormap,8); /* load our new set of colors */ SetAPen (BdRp,BLKP); Move(BdRp,0,VLINT); SetDrMd (BdRp,JAM2); /* JAM2 substituted */ PolyDraw(BdRp,8,&boardlines); /* Put in text and horizontal lines for board */ Move(BdRp,TEXTL,TEXTT+2); Text(BdRp,textline[0],strlen(textline[0]) ); for(count = 1; count