← Back to contents
C source, ASCII text
— 5K bytes
— 1991-02-24
— PP20 compressed
/* 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;
}