home *** CD-ROM | disk | FTP | other *** search
- /* TURN.C
- * This module has the functions to get user moves
- */
-
- #include <proto/all.h>
- #include <intuition/intuition.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include "defns.h"
- #include "externs.h"
-
- USHORT fix; /*used to pass by reference auto variables*/
-
- VOID manturn(cp,np,pp,nhp)
- struct playerinfo *cp,*np,*pp; /* current, following, previous players */
- USHORT nhp; /*number of human players.*/
- {
- struct IntuiMessage *msg;
- struct card c;
- USHORT fin=0,code,exch=0,temp; /*flag showing whether a card has been dropped*/
- ULONG class,gid,fdpvis=0;
- struct Gadget *gaddr;
- /* deselect fup,fdp*/
- temp = RemoveGList(wind,&stdgad[FUPG],2);
- RefreshGList(&stdgad[FUPG],wind,NULL,2);
- stdgad[FUPG].Flags &= ~SELECTED;
- stdgad[FDPG].Flags &= ~SELECTED;
- DrawImage(wind->RPort,packim[0][0],FDPX,FDPY);
- TXTOUT(180,21,1,0,cp->name)
- if(nhp>1 && !cp->viewcard)
- {/* change players at keyboard*/
- OffMenu(wind,0x0020); /*reorder off*/
- OffMenu(wind,0xf862); /*modmem off*/
- OffMenu(wind,0x0040); /*about off*/
- TXTOUT(MESX,MESY,3,0,"Press Continue to display cards")
- WAITCONT;
- OnMenu(wind,0x0020); /*reorder on*/
- OnMenu(wind,0xf862); /*modmem on*/
- OnMenu(wind,0x0040); /*about on*/
- }
- AddGList(wind,&stdgad[FUPG],temp,2,NULL);
- disphand(cp);
- handgads(cp->nchld,cp->yc); /*place gadget over each card*/
- TXTOUT(MESX,MESY,1,0,"Select Move ")
- while(!fin && !exgm && !quit)
- {
- cont=0;
- Wait(1l<<mp->mp_SigBit);
- while(msg=(struct IntuiMessage *)GetMsg(mp))
- {
- class=msg->Class;
- code=msg->Code;
- gaddr=(struct Gadget *)(msg->IAddress);
- ReplyMsg((struct Message *)msg);
- switch(class)
- {
- case GADGETUP:
- gid=gaddr->GadgetID;
- if(gid>=HANDG1 && gid<=HANDG7 && gaddr->Flags&SELECTED && !exch)
- { /*card from selected*/
- if(stdgad[FUPG].Flags&SELECTED && !fdpvis)
- { /*exchange with top of fup*/
- gid = gid - HANDG1 +1;
- exch=1;
- c=NEXTFUP;
- PUTFUP((cp->hand[gid]));
- cp->hand[gid]=c;
- disphand(cp);
- RefreshGList(&hgads[1],wind,NULL,cp->nchld);
- DRAWFUP
- DrawImage(wind->RPort,packim[0][0],FDPX,FDPY);
- maintainmem(cp,pp,np,c,CURRPLRHOLDS);
- maintainmem(cp,pp,np,fup[fuptc],CURRPLRDROPD);
- TXTOUT(MESX,MESY,3,0,"Exchange made - hit continue")
- }
- else if(stdgad[FDPG].Flags&SELECTED)
- { /*exhange fdp top card*/
- exch=1;
- gid = gid - HANDG1 +1;
- maintainmem(cp,pp,np,fup[fuptc],GONEPAST);
- maintainmem(cp,pp,np,fup[fuptc],CURRPLRDROPD);
- c=NEXTFDP;
- PUTFUP((cp->hand[gid]));
- cp->hand[gid]=c;
- disphand(cp);
- RefreshGList(&hgads[1],wind,NULL,cp->nchld);
- DRAWFUP
- cp->mem[CARD2(c)] |= CURRPLRHOLDS;
- DrawImage(wind->RPort,packim[0][0],FDPX,FDPY);
- maintainmem(cp,pp,np,fup[fuptc],CURRPLRDROPD);
- TXTOUT(MESX,MESY,3,0,"Exchange made - hit continue")
- }
- }
- else if(gid==FDPG && !fdpvis && !exch)
- {/*make fdp visible*/
- DRAWFDP
- fdpvis=1; /*prevents use of fup*/
- }
- else if(gid>=SETGAD0 && gid<=SETGAD5) /*add to set*/
- if(addtofus(cp,gid-SETGAD0))
- {
- handgads(cp->nchld,cp->yc);
- REMHAND(cp)
- disphand(cp);
- if(!cp->nchld) fin=1; /*no card left*/
- }
- else ;
- else if(gid==SUBMITG) /*submit new set*/
- if(temp=submitset(cp))
- {
- handgads(cp->nchld,cp->yc);
- REMHAND(cp)
- disphand(cp);
- if(!cp->nchld) fin=1; /*no cards left*/
- TXTOUT(MESX,MESY,1,0,"Submission Accepted ");
- }
- else
- {
- TXTOUT(MESX,MESY,2,0,"Submission Rejected ");
- }
- else if(gid==FUPG && !exch && fdpvis)
- { /*do not take fdp card*/
- TXTOUT(MESX,MESY,3,0,"Exchange made - hit continue")
- maintainmem(cp,pp,np,fup[fuptc],GONEPAST);
- maintainmem(cp,pp,np,fup[fuptc],CURRPLRDROPD);
- c=NEXTFDP;
- PUTFUP(c);
- maintainmem(cp,pp,np,fup[fuptc],CURRPLRDROPD);
- exch=1;
- DrawImage(wind->RPort,packim[0][0],FDPX,FDPY);
- DRAWFUP;
- }
- else
- {
- if(cont && exch) fin=1; /*exchange must be made to finish move*/
- else if(cont && !exch && !fin)
- {
- TXTOUT(MESX,MESY,2,0,"No exchange made yet ")
- }
- }
- break;
- case MENUPICK:
- prgenmsg(class,code,(APTR)gaddr,cp);
- break;
- }
- }
- }
- handgads(0,0);
- if(!cp->viewcard) hidecards(cp);
- TXTOUT(180,21,1,0," ") /*remove name*/
- TXTOUT(MESX,MESY,3,0," ")
- }
-
-
- VOID disphand(struct playerinfo *p)
- {
- register USHORT i,x=HANDLEFT,y=p->yc+HANDTOP,v;
- char b[4];
- for(i=1,v=0;i<=p->nchld;i++) v += p->hand[i].n;
- TXTOUT(270,p->yc+HVTPY,1,0," ");
- stci_d(out,v);
- TXTOUT(270,p->yc+HVTPY,1,0,out);
- stci_d(b,p->turn);
- TXTOUT(270,p->yc+NWTPY+9,1,0,b);
- if(p->nchld)
- {
- DrawImage(wind->RPort,packim[0][CARD2(p->hand[1])],x,y);
- for(i=2;i<=p->nchld;i++)
- DrawImage(wind->RPort,packim[1][CARD2(p->hand[i])],x-(i-1)*17,y);
- }
- else REMHAND(p);
- }
-
- VOID compacthand(struct card h[],USHORT *n)
- {
- register USHORT s,d;
- for(d=1;d!=*n && !CDEQU(h[d],nulcard);d++); /*find first nulcard*/
- if(d!=*n)
- {
- for(s=d+1;s<=*n;s++)
- if(!CDEQU(h[s],nulcard)) h[d++]=h[s];
- *n=d-1;
- }
- if(CDEQU(h[*n],nulcard) && *n!=0) --*n;
- }
-
- VOID handgads(USHORT n,USHORT y)
- {/* put gadgets over users cards*/
- static USHORT num=0;
- register USHORT i;
- y+=HANDTOP;
- if(num)
- {
- RemoveGList(wind,&hgads[1],num);
- RefreshGList(&hgads[1],wind,NULL,num);
- }
- for(i=1;i<=n;i++)
- { /*initialise next gadget*/
- hgads[i-1].NextGadget = &hgads[i];
- hgads[i].TopEdge = y;
- hgads[i].Flags &= ~(SELECTED | GADGDISABLED);
- }
- hgads[i-1].NextGadget = NULL;
- if(i!=1) AddGList(wind,&hgads[1],~0,i-1,NULL);
- num=i-1;
- }
-
- VOID hidecards(struct playerinfo *p)
- {
- register USHORT i;
- char b[4];
- TXTOUT(270,p->yc+HVTPY,1,0," ");
- stci_d(b,p->turn);
- TXTOUT(270,p->yc+NWTPY+9,1,0,b);
- if(p->nchld)
- {
- DrawImage(wind->RPort,packim[0][0],HANDLEFT,p->yc+HANDTOP);
- for(i=2;i<=p->nchld;i++) DrawImage(wind->RPort,packim[1][0],HANDLEFT-(i-1)*17,p->yc+HANDTOP);
- }
- else REMHAND(p);
- }
-
- USHORT submitset(struct playerinfo *p)
- {/* submit set from user */
- struct card t[10];
- register USHORT i,d,n,samesuit=1,samenum=1;
- for(i=1,d=0;i<=p->nchld;i++)
- if(hgads[i].Flags&SELECTED) t[++d]=p->hand[i]; /*copy selected cards*/
- for(i=2;i<=d;i++)
- {
- if(t[i-1].n!=t[i].n) samenum=0; /*not same number*/
- if(t[i-1].s!=t[i].s) samesuit=0; /*not same suit*/
- }
- if(d<3 ||(!samesuit && !samenum)) return 0; /*rejected*/
- if(samesuit)
- {/*check set forms continuous sequence*/
- fix=d; /*cannot pass address of d*/
- ssortn(t,&fix); /*sort on number only*/
- d=fix;
- for(i=2;i<=d;i++)
- if((t[i-1].n!=t[i].n-1) && !(t[i-1].n==KING && t[i].n==ACE)) return 0; /*rejected*/
- }
- /*set accepted if this point reached*/
- for(i=1;i<=p->nchld;i++) if(hgads[i].Flags&SELECTED) p->hand[i]=nulcard;
- compacthand(p->hand,&p->nchld);
- for(i=0;i<=5 && fupset[i]->ncard!=0;i++) ;/*find empty set*/
- fupset[i]->ncard=d;
-
- if(samesuit)
- for(n=1;n<=d;n++)
- {
- fupset[i]->cards[n+t[1].n-1]=t[n];
- maintainmem(NULL,NULL,NULL,t[n],INFUPSET);
- }
- /*cards inserted so that card n is at fupset[i]->card[n] to simplify addition to both ends of the set*/
- else
- for(n=1;n<=d;n++)
- {
- fupset[i]->cards[n]=t[n];
- maintainmem(NULL,NULL,NULL,t[n],INFUPSET);
- }
- sortdispset();
- return 1; /*accepted...tells program to redo gadgets for cards*/
- }
-
- VOID sortdispset()
- {
- static USHORT num=0;
- register USHORT i,j,f,e=1;
- register ULONG l;
- struct set *s;
- if(num)
- { /*remove any gadgets already in place*/
- RemoveGList(wind,&setgads[0],num);
- RefreshGList(&setgads[0],wind,NULL,num);
- }
- while(e) /*ensure largest set comes first*/
- for(i=0,e=0;i<5;i++)
- {
- if(fupset[i]->ncard<fupset[i+1]->ncard)
- {
- e=1; /*exchange made*/
- s=fupset[i];fupset[i]=fupset[i+1];fupset[i+1]=s;
- }
- }
- num=0;
- for(i=0;i<=5;i++)
- if(fupset[i]->ncard!=0)
- {
- for(j=14;CDEQU(fupset[i]->cards[j],nulcard);j--) ;
- f=j;
- if(i<=2) l=566; else l=416;
- DrawImage(wind->RPort,packim[0][CARD2(fupset[i]->cards[j])],l,setpos[i]);
- j--;
- for(;!CDEQU(fupset[i]->cards[j],nulcard) && j;j--)
- DrawImage(wind->RPort,packim[1][CARD2(fupset[i]->cards[j])],l-(f-j)*17,setpos[i]);
- if(i!=0) setgads[i-1].NextGadget = &setgads[i];
- setgads[i].LeftEdge = l-17*(fupset[i]->ncard-1);
- setgads[i].Width = (fupset[i]->ncard-1)*17+64;
- setgads[i].NextGadget = NULL;
- num++; /*number of gadgets added*/
- }
- if(num) AddGList(wind,&setgads[0],~0,num,NULL);
- }
-
- VOID ssortn(struct card a[],USHORT *n)
- { /*selection sort a[] on card number only..Faster version for fupset*/
- register USHORT i,j,minpos;
- struct card t,minval;
- for(i=1;i<*n;i++)
- {
- minval.n=15;minpos=0;
- for(j=i;j<=*n;j++) if(a[j].n<=minval.n) minval=a[minpos=j];
- a[minpos]=a[i];
- a[i]=minval;
- }
- /*decide whether ace is high or low*/
- if(a[1].n==ACE && (a[2].n!=2 || a[3].n!=3) && a[*n].n==KING && a[(*n)-1].n==QUEEN)
- { /*put ace at end*/
- t=a[1];a[1]=nulcard;
- compacthand(a,n);
- a[++(*n)]=t;
- }
- }
-
- VOID hsort(struct card a[],USHORT n)
- { /* sort player cards.. sorts by number within suit */
- register USHORT i,j,maxpos,max;
- struct card maxval;
- for(i=1;i<n;i++)
- {
- maxval.n=0;maxval.s=0;maxpos=0;max=0;
- for(j=i;j<=n;j++) if(CARD2(a[j])>=max)
- {
- maxval=a[maxpos=j];
- max=CARD2(maxval);
- }
- a[maxpos]=a[i];
- a[i]=maxval;
- }
- }
-
-
-
- VOID maintainmem(cp,pp,np,card,flag)
- struct playerinfo *cp,*pp,*np;
- struct card card;
- USHORT flag;
- {
- register USHORT n=CARD2(card);
- switch(flag)
- {
- case CURRPLRHOLDS:
- if(cp) cp->mem[n] |= flag;
- if(pp) pp->mem[n] |= NEXTPLRHOLDS;
- if(np) np->mem[n] |= PREVPLRHOLDS;
- break;
- case CURRPLRDROPD:
- if(cp)
- {
- cp->mem[n] |= flag;
- cp->mem[n] &= ~CURRPLRHOLDS;
- }
- if(pp)
- {
- pp->mem[n] |= NEXTPLRDROPD;
- pp->mem[n] &= ~NEXTPLRHOLDS;
- }
- if(np)
- {
- np->mem[n] |= PREVPLRDROPD;
- np->mem[n] &= ~PREVPLRHOLDS;
- }
- break;
- case GONEPAST:
- case INFUPSET:
- plr[1]->mem[n] |= flag;
- plr[1]->mem[n] &= ~(CURRPLRHOLDS | PREVPLRHOLDS | NEXTPLRHOLDS);
- plr[2]->mem[n] |= flag;
- plr[2]->mem[n] &= ~(CURRPLRHOLDS | PREVPLRHOLDS | NEXTPLRHOLDS);
- plr[3]->mem[n] |= flag;
- plr[3]->mem[n] &= ~(CURRPLRHOLDS | PREVPLRHOLDS | NEXTPLRHOLDS);
- break;
- }
- }
-
-
- USHORT addtofus(struct playerinfo *p,ULONG set)
- {
- register struct card *fsc,*phc;
- register USHORT *fsn,phn,nomore,i,f,l,c=0; /*change made flag*/
- USHORT ncrd=p->nchld;
- char b[4];
- fsc=fupset[set]->cards;fsn=&fupset[set]->ncard;
- phc=p->hand;phn=p->nchld;
- for(f=1;CDEQU(fsc[f],nulcard);f++) ; /*find first card of set*/
- l=f+(*fsn)-1; /*position of last card of set*/
- if(fsc[f].s==fsc[f+1].s) /*same suit*/
- for(nomore=0;!nomore && !quit && !exgm;)
- {
- for(nomore=1,i=1;i<=phn && !quit && !exgm;i++)
- {
- if(hgads[i].Flags&SELECTED && !CDEQU(phc[i],nulcard))
- {
- if(fsc[f].n==phc[i].n+1 && fsc[f].s==phc[i].s)
- { /*add before first card of set*/
- fsc[--f]=phc[i];
- maintainmem(NULL,NULL,NULL,phc[i],INFUPSET);
- (*fsn)++;
- phc[i]=nulcard;
- c=1; /*change made*/
- nomore=0;
- }
- else if(((fsc[l].n==phc[i].n-1 && phc[i].n!=2) || (fsc[l].n==KING && phc[i].n==ACE))
- && fsc[l].s==phc[i].s)
- { /*add after last card*/
- fsc[++l]=phc[i];
- maintainmem(NULL,NULL,NULL,phc[i],INFUPSET);
- phc[i]=nulcard;
- c=1;
- (*fsn)++;
- nomore=0;
- }
- }
- }
- }
- else /*same number set*/
- for(i=1;i<=phn && !quit && !exgm;i++)
- if(hgads[i].Flags&SELECTED && !CDEQU(p->hand[i],nulcard))
- {
- if(fsc[l].n==phc[i].n)
- { /*insert after last card*/
- fsc[++l]=phc[i];
- maintainmem(NULL,NULL,NULL,phc[i],INFUPSET);
- (*fsn)++;
- phc[i]=nulcard;
- c=1;
- }
- }
- if(c)
- {
- sortdispset(); /*redisplay sets if changes made*/
- compacthand(p->hand,&p->nchld);
- ncrd-=p->nchld;
- stci_d(b,ncrd);
- TXTOUT(MESX,MESY,1,0," ");
- TXTOUT(MESX,MESY,1,0,b);
- TXTOUT(MESX+2*FWIDTH,MESY,1,0,"Cards Added ");
- }
- else
- {
- TXTOUT(MESX,MESY,2,0,"No cards added ");
- }
-
- return c;
- }
-