|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T b
Length: 14041 (0x36d9)
Types: TextFile
Names: »bridge.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Bridge/bridge.c«
#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);
}