DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T b

⟦823fd8a23⟧ TextFile

    Length: 14041 (0x36d9)
    Types: TextFile
    Names: »bridge.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/Bridge/bridge.c« 

TextFile

#include <stdio.h>

#define EQ ==
#define NEQ !=
#define NOT !
#define AND &&
#define OR ||
#define TRUE 1
#define FALSE 0

#define SIDE(i) ((i)%2)
#define NEXT(i) ((i+1)%4)
#define PARTNER(i) ((i+2)%4)
#define IC(i) (i+'0')
#define ALLp p=0;p<=3;++p

FILE *f1;
char scr[16][80];
int  r[4]={1,6,11,6},c[4]={18,32,18,4};
int hand= -1,decl,dummy,trump,dbl,ld,ldd,win[2],HBR,HBS,HBB,rs,ts[2]={0,0};
int vt[2]={0,0},part[2]={0,0};
int eofg,eofp,eofr=0;
int card[52],C[4][52],NS[4][4],LS[4];
int TV[5]={20,20,30,30,30};
int VUL[2][16]={0,1,0,1,1,0,1,0,0,1,0,1,1,0,1,0,
                0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,1};
char CBR,CBS,CPR,CPS;
extern char player[4][20];
char str[80],inp[80],num[6];
char FV[13]={'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
char SV[5]={'C','D','H','S','N'};
char P[4]={'N','E','S','W'};
extern long seed;

init()
{  int p,t;

   f1=fopen("bridge.log","w");
   for(ALLp){player[p][0]=P[p];player[p][1]=':';}
   for(ALLp){
      str[1]='\0';
      str[0]=P[PARTNER(p)];
      rput(p,13,4,29,str);
      str[0]=P[t=NEXT(p)];
      rput(p,13,8,20,str);
      str[0]=P[PARTNER(t)];
      rput(p,13,8,38,str);
      str[0]=P[p];
      rput(p,13,12,29,str);
      rput(p,13,17,5,player[(p+2)%4]);
      rput(p,13,17,25,player[(p+1)%4]);
      rput(p,13,17,45,player[p]);
      rput(p,13,17,65,player[(p+3)%4]);
   }
   srandom(seed);
}
rinit()
{  int tvt,p,i,j;
   char *d;

   for(i=0;i<16;i++){
      d=(char *)&scr[i][0];
      for(j=0;j<80;++j) *d++ =' ';
   }
   sput("Hand:",0,0);sput("Vul.:",1,0);
   sput("Bid",0,51);sput("=N==E==S==W==",1,46);
   sput("Play",0,66);sput("=N===E===S===W===",1,60);
   sput("--------------",5,17);
   sput("|     N      |",6,17);
   sput("|W          E|",7,17);
   sput("|            |",8,17);
   sput("|     S      |",9,17);
   sput("--------------",10,17);
   sput("Result:",15,47);
   itos((++hand)+1);
   sput(num+3,0,6);
   for(ALLp)rput(p,8,0,0,num+3);

/* for duplicate bridge
   sput("Score:",15,62);
   tvt=VUL[0][hand%16]*2+VUL[1][hand%16];
*/
/* for rubber */
   tvt=vt[0]*2+vt[1];
   for(ALLp){ clearw(p,11); clearw(p,10);}
   str[1]='\0';
   switch(tvt){
      case 0: for(ALLp)rput(p,8,1,0,"NONE");sput("NONE",1,6);break;
      case 1: for(ALLp){
                 rput(p,8,1,0,"E-W ");
                 str[0]=45+SIDE(p)*79;
                 rput(p,10,3,8,str);
              }
              sput("E-W",1,6);
              break;
      case 2: for(ALLp){
                 rput(p,8,1,0,"N-S ");
                 str[0]=124-SIDE(p)*79;
                 rput(p,10,3,8,str);
              }
              sput("N-S",1,6);
              break;
      case 3: str[0]='+';
              for(ALLp){
                 rput(p,8,1,0,"BOTH");
                 rput(p,10,3,8,str);
              }
              sput("BOTH",1,6);
              break;
   }
   for(ALLp){
      rput(p,9,0,0,"    0");
      rput(p,9,0,6,"    0");
      clearw(p,0);clearw(p,1);clearw(p,2);clearw(p,3);
      clearw(p,4);clearw(p,5);clearw(p,6);clearw(p,7);
   }
}
pscr()
{   int i,j;
    char *d;

    for(i=0;i<16;++i){
       d=(char *)&scr[i][0];
       for(j=0;j<80;++j)fprintf(f1,"%c",*d++);
       fprintf(f1,"\n");
    }
    fprintf(f1,"\n\n\n\n");
    fflush(f1);
}

sput(s,r,c)
char *s;
int r,c;
{   char *d;

    d=(char *)&scr[r][c];
    while(*s) *d++ = *s++;
}
deal()
{  int i,j,rr,cc;
   char *d;

   for(i=0;i<52;++i){
      card[i]=i;
      for(j=0;j<4;++j)C[j][i]=0;
   }
   for(i=0;i<4;++i){
      LS[i]=0;
      for(j=0;j<4;++j) NS[i][j]=0;
   }
   i=52;
   while(i>1){
      j=random()%i--;
      C[i/13][card[j]]=1;
      NS[i/13][card[j]/13]++;
      if(NS[i/13][card[j]/13]>LS[i/13]) LS[i/13]++;
      card[j]=card[i];
   }
   C[0][card[0]]=1;
   NS[0][card[0]/13]++;
   for(i=0;i<4;++i) printhand(i,i);
   for(i=0;i<4;++i){
      rr=r[i]-1;cc=c[i]; if(i EQ 3) cc=cc+10-LS[i];
      for(j=51;j>=0;--j){
         if(j%13 EQ 12){ d=(char *)&scr[++rr][cc];*d++ =SV[j/13]; *d++ = ' ';}
         if(C[i][j] EQ 1)*d++ = FV[j%13];
      }
   }
}
bid()
{  int i,j,p,rb,eofb,legalbid,NP,OB;
   int PFBS[2][5];

   for(ALLp){
      rput(p,10,2,0,"-----------");
      rput(p,10,4,6,"-----------");
      for(i=0;i<=3;++i) rput(p,10,i,11,"|");
      for(i=0;i<=3;++i) rput(p,10,i+3,5,"|");
   }
   for(i=0;i<2;++i)for(j=0;j<5;++j)PFBS[i][j]= -1;
   rb=HBR=NP=0;
   eofb=eofg=FALSE;
   HBS= -1;
   for(i=OB=hand%4;NOT eofb;i=NEXT(i)){
      legalbid=FALSE;
      do{
         if(readbid(i)<0)continue;
         if(CBS EQ 6){
            if((dbl NEQ 1) OR (SIDE(i) NEQ SIDE(HBB)) OR (HBR<1))continue;
            dbl=2;ldd=i;
         }
         if(CBS EQ 5){
            if((dbl NEQ 0) OR (SIDE(i) EQ SIDE(HBB)) OR (HBR<1))continue;
            dbl=1;ld=i;
         }
         if(CBR<HBR)continue;
         if(CBR>=HBR AND CBR<8){
            if ((CBR EQ HBR) AND (CBS<=HBS))continue;
            dbl=0;HBR=CBR;HBS=CBS;HBB=i;
            if(PFBS[SIDE(i)][CBS] EQ -1)PFBS[SIDE(i)][CBS]=i;
         }
         if(CBS EQ 7) NP++; else NP=0;
         legalbid=TRUE;
      }while(NOT legalbid);
      if(NP EQ 4){eofb=eofg=TRUE;inp[0]=inp[1]='=';}
      if((NP EQ 3) AND (HBR>0)) {eofb=TRUE;inp[0]=inp[1]='=';}
      printbid(rb,i);
      sput(inp,2+rb+(i<OB),47+3*(i%4));
      if(NEXT(i) EQ OB) rb++;
   }
   decl=PFBS[SIDE(HBB)][HBS];
   dummy=PARTNER(decl);
   trump=HBS;
   if(NOT eofg){
      strcpy(str,"CONTRACT: ");
      str[10]=HBR+'0'; str[11]=SV[HBS]; str[12]='/'; str[13]=P[decl]; j=14;
      if(dbl>0){str[j++]=' ';str[j++]='X';str[j++]='/';str[j++]=P[ld];}
      if(dbl>1)
         {str[j++]=' ';str[j++]='X';str[j++]='X';str[j++]='/';str[j++]=P[ldd];}
      str[j]='\0';
      for(ALLp)rput(p,11,0,0,str);
      sput(str+10,4+rb,47);
   }
}
play()
{  int r,i,ss,legalplay,winner,FL,FPS,HPR,HPS,p;

   FL=NEXT(decl);
   win[0]=win[1]=0;
   for(r=1;r<=13;++r){
      i=FL;
      do{
         legalplay=FALSE;
         do{
            if(readplay(i EQ dummy ? decl : i,i)<0)continue;
            if(CPS EQ 5){
               if(SIDE(i) NEQ SIDE(decl))continue;
               if(CPR<0 OR CPR>13-win[0]-win[1])continue;
               printhand(NEXT(decl),decl);
               printhand(NEXT(decl),NEXT(dummy));
               printhand(NEXT(dummy),decl);
               printhand(NEXT(dummy),NEXT(decl));
               strcpy(inp,"Declarer asks    more tricks.  Agree?");
               if(CPR>9) inp[14]='1';
               inp[15]=CPR%10+'0';
               rget((1<<NEXT(decl))|(1<<NEXT(dummy)),inp);
               if(inp[0] NEQ 'Y'){
                  clearw(NEXT(decl),0);
                  clearw(NEXT(decl),1);
                  clearw(NEXT(dummy),3);
                  clearw(NEXT(dummy),0);
                  continue;
               }
               printhand(decl,NEXT(decl));
               printhand(decl,NEXT(dummy));
               win[SIDE(decl)]+=CPR;
               win[1-SIDE(decl)]=13-win[SIDE(decl)];
               itos(win[0]);for(ALLp)rput(p,9,0,0,num);
               itos(win[1]);for(ALLp)rput(p,9,0,6,num);
               for(ALLp){clearw(p,4);clearw(p,5);clearw(p,6);clearw(p,7);}
               return;
            }
            if(i EQ FL){
               if(CPS EQ 4) continue;
               if(CPS EQ 6){
		   if (r < 13) continue;
                   else{
                      for(ss=0;C[i][ss]<1;++ss);
                      inp[0]=SV[CPS=ss/13];inp[1]=FV[CPR=ss%13];
                   }
	       }
               if(NOT inhand(CPS,CPR,i))continue;
               if(r EQ 1){
                  for(ALLp) clearw(p,10);
                  for(p=NEXT(dummy);p NEQ dummy;p=NEXT(p))printhand(p,dummy);
                  printhand(dummy,decl);
               }
               winner=FL;
               HPR=CPR;
               FPS=HPS=CPS;
            }
            else{
               if(CPS EQ 6){
                  for(ss=NS[i][FPS]?FPS*13:0;C[i][ss]<1;++ss);
                  inp[0]=SV[CPS=ss/13];inp[1]=FV[CPR=ss%13];
               }
               if(CPS EQ 4) {CPS=FPS;inp[1]=inp[0];inp[0]=SV[FPS];}
               if((CPS NEQ FPS) AND (NS[i][FPS] NEQ 0))continue;
               if(NOT inhand(CPS,CPR,i))continue;
               if(CPS EQ HPS){
                  if(CPR>HPR){winner=i;HPR=CPR;}
               }
               else {if(CPS EQ trump){winner=i;HPR=CPR;HPS=CPS;}}
            }
            printplay(i);
            printsuit(i,i,CPS);
            sput(inp,1+r,61+4*i);
            sput("!",1+r,63+4*FL);
            if(i EQ dummy)
               for(p=NEXT(dummy);p NEQ dummy;p=NEXT(p))printsuit(p,i,CPS);
            if(i EQ decl) printsuit(dummy,decl,CPS);
            legalplay=TRUE;
         }while(NOT legalplay);
         i=NEXT(i);
      }while(i NEQ FL);
      itos(++win[SIDE(FL=winner)]);
      for(ALLp) rput(p,9,0,6*SIDE(FL),num);
      sput("*",r+1,63+4*winner);
      if(r<13){
         waitkey("Press return to pause.");
         for(ALLp){clearw(p,4);clearw(p,5);clearw(p,6);clearw(p,7);}
      }
   }
}
score()
{  int vt,over,otv,winside;

   vt=VUL[winside=SIDE(decl)][hand%16];
   over=win[winside]-6-HBR;
   otv=TV[HBS];
   if(dbl>0) otv=100*dbl*(vt+1);
   if(over>=0){
      rs=HBR*TV[HBS];
      if(HBS EQ 4) rs+=10;
      if(dbl NEQ 0) rs=rs*2*dbl;
      if(rs>=100)rs+=(250+200*vt);
      rs+=(50+over*otv);
      if(dbl NEQ 0)rs+=50; 
      if(HBR EQ 6)rs+=500+250*vt;
      if(HBR EQ 7)rs+=1000+500*vt;
   }
   else{
      if(dbl EQ 0)rs=50*over*(vt+1);
      else rs=((200*over+100)+100*over*vt)*dbl;
   }
   if(rs<0){winside=1-winside;rs= -rs;}
   ts[winside]+=rs;
   printscore(winside);
   itos(over);sput(num+3,15,55);
   waitkey("Press return to pause.");
}
rscore()
{  int over,otv,winside,p;

   winside=SIDE(decl);
   over=win[winside]-6-HBR;
   otv=TV[HBS];
   if(dbl>0) otv=100*dbl*(vt[winside]+1);
   if(over>=0){
      rs=HBR*TV[HBS];
      if(HBS EQ 4) rs+=10;
      if(dbl NEQ 0) rs=rs*2*dbl;
      ts[winside]+=rs;
      ts[winside]+=(over*otv);
      if(dbl NEQ 0)ts[winside]+=50; 
      if(HBR EQ 6)ts[winside]+=500+250*vt[winside];
      if(HBR EQ 7)ts[winside]+=1000+500*vt[winside];
      part[winside]+=rs;
      if(part[winside]>=100){
         if(vt[winside]){
            ts[winside]+=700-200*vt[1-winside]; vt[0]=vt[1]=0;
            eofr=1;
         }
         else{vt[winside]+=1;}
         part[0]=part[1]=0; for(ALLp)rput(p,9,1,0,"    0     0");
      }
      else{itos(part[winside]);for(ALLp)rput(p,9,1,6*winside,num);}
      itos(ts[winside]);for(ALLp)rput(p,9,2,6*winside,num);
   }
   else{
      if(dbl EQ 0)rs=50*over*(vt[winside]+1);
      else rs=((200*over+100)+100*over*vt[winside])*dbl;
      ts[1-winside]-=rs;
      itos(ts[1-winside]);for(ALLp)rput(p,9,2,6-6*winside,num);
   }
   itos(over);sput(num+3,15,55);
   waitkey("Press return to pause.");
}
readbid(i)
int i;
{   
   strcpy(inp,"It's your turn to bid ");
   rget(1<<i,inp);
   inp[2]='\0'; 
   CBR=inp[0]-'0';
   if(CBR>0 AND CBR <8) return(CBS=lookup(inp[1],SV,5));
   CBR=8;
   switch(inp[0]){
      case '\n':
      case 'P': inp[0]=inp[1]='-';CBS=7;return(CBS);
      case 'X': if(inp[1] EQ 'X'){CBS=6;return(CBS);}
                else{inp[1]='\0';CBS=5;return(CBS);}
      default:  return(-1);
   }
}
readplay(i,j)
int i,j;
{
   if (j EQ dummy) strcpy(inp,"It's dummy's turn to play ");
   else strcpy(inp,"It's your turn to play ");
   rget(1<<i,inp);
   if(inp[0] EQ 'F'){
     CPS=5;CPR=inp[1]-'0';
     if(inp[2]>='0' AND inp[2]<='9') CPR=CPR*10+inp[2]-'0';
     if(inp[1]=='\n') CPR=13-win[0]-win[1];
     return(0);
     }
   inp[2]='\0'; 
   if((CPR=lookup(inp[0],FV,13))>=0) {CPS=4;return(0);}
   if(inp[0] EQ '\n'){CPS=6;return(0);}
   CPS=lookup(inp[0],SV,4);
   CPR=lookup(inp[1],FV,13);
   if(CPS<0 OR CPR<0) return(-1);
   else return(0);
}
lookup(ch,t,i)
int i;
char ch,*t;

{  int j;
 
   for(j=i-1;j>=0;j--)if(ch EQ t[j]) return(j);
   return(-1);
}
inhand(s,r,i)
int s,r,i;

{  int j;

   j=s*13+r;
   if(C[i][j] NEQ 1)return(FALSE);
   C[i][j]=0;
   NS[i][s]--;
   return(TRUE);
}
itos(i)
int i;

{  int j,f;
   char t;

   if(i EQ 0) {num[0]=num[1]=num[2]=num[3]=' ';num[4]='0';num[5]=0;return;}
   f=0;if(i<0){f=1;i= -i;}
   num[0]='\0';
   for(j=1;j<=5;j++)
      if(i>0){
         num[j]=i%10+'0';
         i/=10;
      }
      else{ if(f){num[j]='-';f=0;} else num[j]=' ';}
   for(i=0;i<=2;++i){
      t=num[i];
      num[i]=num[5-i];
      num[5-i]=t;
   }
}
printhand(p,h)
int p,h;

{  int s;

   for(s=0;s<4;++s)printsuit(p,h,s);
}
printsuit(p,h,s)
int p,h,s;

{  int i,j=2,offset=0;
   str[0]=SV[s];
   str[1]=' ';
   for(i=12;i>=0;--i)if(C[h][s*13+i] EQ 1)str[j++]=FV[i];
   str[j++]=' ';str[j]='\0';
   if((j=(6+h-p)%4) EQ 3) offset=11-LS[h];
   rput(p,j,3-s,offset,str);
}
printplay(h)
int h;

{  int p;

   for(ALLp) rput(p,(6+h-p)%4+4,0,0,inp);
}
printscore(winside)
int winside;

{ int p;

  itos(rs);for(ALLp){rput(p,9,1,6*winside,num);rput(p,9,1,6-6*winside,"    0");}
  sput(num,15,69);
  itos(ts[winside]);for(ALLp)rput(p,9,2,6*winside,num);
}
printbid(rb,i)
int rb,i;
{  int p;
 
   p=i;
   rput(p,10,5+rb/4,6+3*(rb%4),inp); p=NEXT(p);
   rput(p,10,3-rb%4,12+3*(rb/4),inp); p=NEXT(p);
   rput(p,10,1-rb/4,9-3*(rb%4),inp); p=NEXT(p);
   rput(p,10,3+rb%4,3-3*(rb/4),inp); p=NEXT(p);
}
waitkey(c)
char *c;
{  int p;
   char t[40];
   do {strcpy(t,c);}
   while(rwait((1<<decl)|(1<<NEXT(decl))|(1<<NEXT(dummy)),t,2)>0);
   for(ALLp) clearw(p,12);
}
clearw(p,wn)
int p,wn;

{  
   str[0]='Z';
   str[1]='\0';
   rput(p,wn,0,0,str);
}
/*
rput(p,w,r,c,s)
int p,w,r,c;
char *s;

{   printf("p=%d, w=%d, r=%d, c=%d, s=%s",p,w,r,c,s);
}
rget(p,s)
int p;
char *s;
{   scanf("%s",s);
}
*/
more()
{  int p;
/*
   if(NOT eofr) return;
   strcpy(inp,"You like another rubber?");
   rwait(15,inp,5);
   if(inp[0] NEQ 'Y'){for(ALLp)rput(p,0,0,0,"\\"); exit();}
   for(ALLp)clearw(p,12);
   eofr=0;
*/
   return;
}
bridge()
{  int p;

   init();
   eofp=FALSE;
   do{
      rinit();
      deal();
      bid();
      if(NOT eofg){
         play();
         rscore();
      }
      else for(ALLp) clearw(p,10);
      pscr();
      more();
   }while(NOT eofp);
}