/* This program will draw a bridge hand in postscript. */
/* It has been used to make silkscreen source art for 
   T-shirt printing successfully several times.  */
/* It can do color separations (-s option).            */
/* It can't draw face cards well.  Put them in the middle, 
   not on the ends. */
/* To use this:  type
   cc shirtsource.c -o shirt
   Then shirt <data >outputfile.ps to run.

   Input is approximately:
	S: AK2
	H: Kq103
	D: T4x
	C: JQ3
*/

/* Author: Jeff Goldsmith.  All rights reserved.
   No warranty express or implied.  Use this at
   your own risk.  Please do not distribute
   without this header.  Please do not charge anyone
   money for this program. */


#include <stdio.h>
#define SPADE 1
#define HEART 2
#define DIAMOND 3
#define CLUB 4

main(argc,argv)
int argc;
char **argv;
{
char line[1000];	/* temp storage */
int hands;		/* hand number */
char *ptr;		/* to start looking */
char temp[100];		/* part of a line */
void nots(),card();
int nflag,sflag,eflag,wflag; /* do I print this hand */
int i,j;		/* counters */
int hand[2][13];	/* rank, suit */
FILE *file;
int readhand();
int args[26];
int seps;		/* flag to indicate color separations */

/* read command line flags */
clparse(argc,argv,args);
seps = 0;
if (args['s'-'a'] != 0) seps = 1;

/* header */
printf("%%!Postscript file\n");
printf("306 396 translate\n");
printf("90 rotate\n");
printf("306 306 scale\n");
printf(".25 .25 scale\n");
printf("6 306 div setlinewidth\n"); /* 1.5 pt lines are best */
printf("/d {lineto} def\n");
printf("/m {moveto} def\n");
printf("/tim { /Times-Roman findfont [100 306 div 0 0 150 306 div 0 0] makefont setfont } def\n");
printf("/sym { /Symbol findfont 140 306 div scalefont setfont } def\n");
printf("/bigsym { /Symbol findfont 280 306 div scalefont setfont } def\n");
printf("/club { sym (\247) show } def\n");
printf("/diamond { sym (\250) show } def\n");
printf("/heart { sym (\251) show } def\n");
printf("/spade { sym (\252) show } def\n");
printf("/bigclub { bigsym (\247) show } def\n");
printf("/bigdiamond { bigsym (\250) show } def\n");
printf("/bigheart { bigsym (\251) show } def\n");
printf("/bigspade { bigsym (\252) show } def\n");
printf("%%\n");

for (;;)		/* for many hands */
    {
    /* read in hand */
    file = stdin;
    i = readhand(file,hand);
    if (i == 0 || i == EOF) 		/* EOF encountered */
        {
        printf("stop\n");
        exit(0);
        }
    colorsort(hand);	/* alternating colors */
    
    for (j=0;j<=seps;j++)
        {
        /* thirteen cards */
        printf("75 rotate\n");
        for (i=0;i<13;i++)
            {
            /* build the card images */
            /* 3-1/16" by 2-3/16" */
            printf("%f %f translate\n",(2+3./16.)/2-.125, (3+1/16.)/2.);
            card(2.+3./16.,3+1./16.,.125,hand[0][i],hand[1][i],i==12,seps+j);
            printf("%f %f translate\n",-(2+3./16.)/2+.125, -(3+1/16.)/2.);
            printf("-110 13 div rotate\n");
            }

        printf("35 rotate\n");
        printf("%%\n");
        printf("copypage\n");
        printf("erasepage\n");
	printf("%%\n");
        }
    }
}

void card(sizex,sizey,fillet,suit,card,last,seps)
float sizex,sizey,fillet;	
int suit,card;
int last;		/* last card is different */
int seps;		/* 0 = both, 1 = only black, 2 = only red */
{
float x,y;
float w,h,c,h2,h3,h4,h5;
int insep();

static char *suits[5] = {"","spade","heart","diamond","club"};
static char *cards[14] = {"0","A","2","3","4","5","6","7","8","9","10","J","Q","K"};
static float error[14] = {0.,0.,.04,.04,.04,.04,.04,.04,.04,.04,-.04,.07,.01,.01};

x = sizex/2-fillet;
y = sizey/2-fillet;

/* card image */
if (seps != 2)
    {
    printf("newpath\n");
    printf("%f %f m\n",sizex/2,-y);
    printf("%f %f d\n",sizex/2,y);
    printf("%f %f %f %f %f arc\n",x,y,fillet,0.,90.);
    printf("%f %f d\n",-x,sizey/2);
    printf("%f %f %f %f %f arc\n",-x,y,fillet,90.,180.);
    printf("%f %f d\n",-sizex/2,-y);
    printf("%f %f %f %f %f arc\n",-x,-y,fillet,180.,270.);
    printf("%f %f d\n",x,-sizey/2);
    printf("%f %f %f %f %f arc\n",x,-y,fillet,270.,360.);
    printf("gsave 1 setgray fill grestore\n");
    printf("0 setgray stroke\n");
    }
/* characters in upper left corder of card */
if (insep(seps,suit))
    {
    printf("%f %f m\n",-x-.05+error[card],y-.33);
    printf("tim (%s) show\n",cards[card]);
    printf("%f %f m\n",-x-.1,y-.68);
    printf("%s\n",suits[suit]);
    }
if ((last == 1) && insep(seps,suit))
    {
    /* The other three corners */
    /* Three?  one.  */
    /* printf("%f %f m\n",x-.18+error[card],y-.33);
    printf("tim (%s) show\n",cards[card]);
    printf("%f %f m\n",x-.23,y-.68);
    printf("%s\n",suits[suit]); */
    printf("180 rotate\n"); 
    printf("%f %f m\n",-x-.05+error[card],y-.33);
    printf("tim (%s) show\n",cards[card]);
    printf("%f %f m\n",-x-.1,y-.68);
    printf("%s\n",suits[suit]);
    /* printf("%f %f m\n",x-.18+error[card],y-.33);
    printf("tim (%s) show\n",cards[card]);
    printf("%f %f m\n",x-.23,y-.68);
    printf("%s\n",suits[suit]); */
    printf("180 rotate\n"); 
    /* The pips */
    w = .33;   /* to account for char size */
    h = -.22;  /* to account for char size */
    c = .45;   /* for columns on 4s and up */
    h2 = .73;  /* for distance to top and bottom pips on 2s, etc. */
    h3 = .25;  /* for distance to middle of 8s */
    h4 = .33;  /* for distance to middle of 10s */
    h5 = .08;  /* for 10s */

    /* treat each spot card differently */
    switch (card)
	{
	case 1:
	    printf("2. 2. scale\n");
    	    printf("%f %f m\n",-w,h);
    	    printf("big%s\n",suits[suit]);
    	    printf(".5 .5 scale\n");
	    break;
	case 2:
    	    printf("%f %f m\n",-w,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("180 rotate\n");
    	    printf("%f %f m\n",-w,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("180 rotate\n"); 
	    break;
	case 3:
    	    printf("%f %f m\n",-w,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w,h);
    	    printf("big%s\n",suits[suit]);
    	    printf("180 rotate\n");
    	    printf("%f %f m\n",-w,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("180 rotate\n"); 
	    break;
	case 4:
    	    printf("%f %f m\n",-w-c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w+c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("180 rotate\n");

    	    printf("%f %f m\n",-w-c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w+c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("180 rotate\n");  
	    break;
	case 5:
    	    printf("%f %f m\n",-w-c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w+c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w,h3);
    	    printf("big%s\n",suits[suit]);
    	    printf("180 rotate\n");
	    
    	    printf("%f %f m\n",-w-c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w+c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("180 rotate\n");  
	    break;
	case 6:
    	    printf("%f %f m\n",-w-c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w+c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w-c,h);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w+c,h);
    	    printf("big%s\n",suits[suit]);
    	    printf("180 rotate\n");
	    
    	    printf("%f %f m\n",-w-c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w+c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("180 rotate\n");  
	    break;
	case 7:
    	    printf("%f %f m\n",-w-c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w+c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w-c,h);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w+c,h);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w,h3);
    	    printf("big%s\n",suits[suit]);
    	    printf("180 rotate\n");
	    
    	    printf("%f %f m\n",-w-c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w+c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("180 rotate\n");  
	    break;
	case 8:
    	    printf("%f %f m\n",-w-c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w+c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w-c,h);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w+c,h);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w,h3);
    	    printf("big%s\n",suits[suit]);
    	    printf("180 rotate\n");
	    
    	    printf("%f %f m\n",-w-c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w+c,h2);
    	    printf("big%s\n",suits[suit]);
    	    printf("%f %f m\n",-w,h3);
    	    printf("big%s\n",suits[suit]);
    	    printf("180 rotate\n");  
	    break;
	case 9:
     	    printf("%f %f m\n",-w-c,h2);
     	    printf("big%s\n",suits[suit]);
     	    printf("%f %f m\n",-w+c,h2);
     	    printf("big%s\n",suits[suit]);
     	    printf("%f %f m\n",-w-c,h5);
     	    printf("big%s\n",suits[suit]);
     	    printf("%f %f m\n",-w+c,h5);
     	    printf("big%s\n",suits[suit]);
     	    printf("%f %f m\n",-w,h);
     	    printf("big%s\n",suits[suit]);
     	    printf("180 rotate\n");

     	    printf("%f %f m\n",-w-c,h2);
     	    printf("big%s\n",suits[suit]);
     	    printf("%f %f m\n",-w+c,h2);
     	    printf("big%s\n",suits[suit]);
     	    printf("%f %f m\n",-w-c,h5);
     	    printf("big%s\n",suits[suit]);
     	    printf("%f %f m\n",-w+c,h5);
     	    printf("big%s\n",suits[suit]);
     	    printf("180 rotate\n"); 
	    break;
	case 10:
     	    printf("%f %f m\n",-w-c,h2);
     	    printf("big%s\n",suits[suit]);
     	    printf("%f %f m\n",-w+c,h2);
     	    printf("big%s\n",suits[suit]);
     	    printf("%f %f m\n",-w-c,h5);
     	    printf("big%s\n",suits[suit]);
     	    printf("%f %f m\n",-w+c,h5);
     	    printf("big%s\n",suits[suit]);
     	    printf("%f %f m\n",-w,h4);
     	    printf("big%s\n",suits[suit]);
     	    printf("180 rotate\n");

     	    printf("%f %f m\n",-w-c,h2);
     	    printf("big%s\n",suits[suit]);
     	    printf("%f %f m\n",-w+c,h2);
     	    printf("big%s\n",suits[suit]);
     	    printf("%f %f m\n",-w-c,h5);
     	    printf("big%s\n",suits[suit]);
     	    printf("%f %f m\n",-w+c,h5);
     	    printf("big%s\n",suits[suit]);
     	    printf("%f %f m\n",-w,h4);
     	    printf("big%s\n",suits[suit]);
     	    printf("180 rotate\n"); 
	    break;
	default:
	    break;
	}
/* for 2s and 3s (plus 5s, 7s, and 9s */
/*    printf("%f %f m\n",-w,h2);
    printf("big%s\n",suits[suit]);
    printf("%f %f m\n",-w,h);
    printf("big%s\n",suits[suit]);
    printf("180 rotate\n");
    printf("%f %f m\n",-w,h2);
    printf("big%s\n",suits[suit]);
    printf("180 rotate\n"); */

/* for 4s through 8s */
  /*  printf("%f %f m\n",-w-c,h2);
    printf("big%s\n",suits[suit]);
    printf("%f %f m\n",-w+c,h2);
    printf("big%s\n",suits[suit]);
    printf("%f %f m\n",-w-c,h);
    printf("big%s\n",suits[suit]);
    printf("%f %f m\n",-w+c,h);
    printf("big%s\n",suits[suit]);
    printf("%f %f m\n",-w,h3);
    printf("big%s\n",suits[suit]);
    printf("180 rotate\n");

    printf("%f %f m\n",-w-c,h2);
    printf("big%s\n",suits[suit]);
    printf("%f %f m\n",-w+c,h2);
    printf("big%s\n",suits[suit]);
    printf("%f %f m\n",-w,h3);
    printf("big%s\n",suits[suit]);
    printf("180 rotate\n");  */

/* for 9s and 10s */
/*    printf("%f %f m\n",-w-c,h2);
    printf("big%s\n",suits[suit]);
    printf("%f %f m\n",-w+c,h2);
    printf("big%s\n",suits[suit]);
    printf("%f %f m\n",-w-c,h5);
    printf("big%s\n",suits[suit]);
    printf("%f %f m\n",-w+c,h5);
    printf("big%s\n",suits[suit]);
    printf("%f %f m\n",-w,h4);
    printf("big%s\n",suits[suit]);
    printf("180 rotate\n");

    printf("%f %f m\n",-w-c,h2);
    printf("big%s\n",suits[suit]);
    printf("%f %f m\n",-w+c,h2);
    printf("big%s\n",suits[suit]);
    printf("%f %f m\n",-w-c,h5);
    printf("big%s\n",suits[suit]);
    printf("%f %f m\n",-w+c,h5);
    printf("big%s\n",suits[suit]);
    printf("%f %f m\n",-w,h4);
    printf("big%s\n",suits[suit]);
    printf("180 rotate\n");  */
    }
return;
}

/* test suit for being in right separation level */
int insep(seps,suit)
int seps,suit;
{
return((seps == 0) || 
      ((seps == 1) && (suit == 1)) ||
      ((seps == 1) && (suit == 4)) ||
      ((seps == 2) && (suit == 2)) ||
      ((seps == 2) && (suit == 3)));
}
/* This program reads in a hand in the format
	spades
	hearts
	diamonds
	clubs

	spades
	...

   So, different hands have blank lines between them.
   Voids are indicated ---.  Tens are "T".
   The result is an array 13 by 2, level 0 is suit:
	1 = spades
	2 = hearts
	3 = diamonds
	4 = clubs
   Level 1 is card: 1 = Ace, 2 = Deuce, ... , 13 = King.
*/

#include <stdio.h>

int readhand(file,hand)
FILE *file; 			/* file is open already */
int hand[2][13];
{
char line[30];			/* input buffer */
int i;				/* loop index   */
int h;				/* hand pointer: next free */
int s;				/* suit on which we are working (1=spades, ...) */

h = 0;
/* read spades, perhaps skipping blank line */
if (fgets(line,20,file) == (char *)0) return(EOF);
if (strlen(line) == 0) fgets(line,20,file);
for (s=1;s<=4;s++)
  {
  for (i=0;i<strlen(line);i++)
    {
    switch (line[i])
	{
	case '-':
	    break;
	case 'A':
	case 'a':
	    hand[0][h] = s;
	    hand[1][h++] = 1;
	    break;
	case 'K':
	case 'k':
	    hand[0][h] = s;
	    hand[1][h++] = 13;
	    break;
	case 'Q':
	case 'q':
	    hand[0][h] = s;
	    hand[1][h++] = 12;
	    break;
	case 'J':
	case 'j':
	    hand[0][h] = s;
	    hand[1][h++] = 11;
	    break;
	case '1':
	case 'T':
	case 't':
	    hand[0][h] = s;
	    hand[1][h++] = 10;
	    break;
	case '9':
	    hand[0][h] = s;
	    hand[1][h++] = 9;
	    break;
	case '8':
	    hand[0][h] = s;
	    hand[1][h++] = 8;
	    break;
	case '7':
	    hand[0][h] = s;
	    hand[1][h++] = 7;
	    break;
	case '6':
	    hand[0][h] = s;
	    hand[1][h++] = 6;
	    break;
	case '5':
	    hand[0][h] = s;
	    hand[1][h++] = 5;
	    break;
	case '4':
	    hand[0][h] = s;
	    hand[1][h++] = 4;
	    break;
	case '3':
	    hand[0][h] = s;
	    hand[1][h++] = 3;
	    break;
	case '2':
	    hand[0][h] = s;
	    hand[1][h++] = 2;
	    break;
	case '0':
	default:
	    break;
        }
    }
  fgets(line,20,file);
  }
if (h != 13) printf("Apparently corrupted hand; contains %d cards.\n",h);
return(1);
}

/* This routine sorts the hand by suits: spades hearts clubs diamonds.
   This is to alternate colors. 					*/

colorsort(hand)
int hand[2][13];
{
int hold[2][13];	/* temporary copy   */
int i,j;		/* counters 	    */
int h;			/* pointer	    */
int order[4];		/* order of the suits */

order[0] = 1;
order[1] = 2;
order[2] = 4;
order[3] = 3;

/* make a copy of the hand */
for (i=0;i<13;i++)
    {
    hold[0][i] = hand[0][i];
    hold[1][i] = hand[1][i];
    }

/* move cards into hand */
h = 0;
for (j=0;j<4;j++)
    for (i=0;i<13;i++)
        if (hold[0][i] == order[j])
	    {
	    hand[0][h] = hold[0][i];
	    hand[1][h] = hold[1][i];
	    h++;
 	    }
return;
}

int trans[13] = {0,12,11,10,9,8,7,6,5,4,3,2,1};

/* converts from hands in [2][13] form to [13] form */
h2toh1(handin,handout)
int handin[2][13];
int handout[13];
{
int i;
for (i=0;i<13;i++)
    handout[i] = 13 * (handin[0][i] - 1) + trans[handin[1][i]-1];
return;
}
/* This just parses a command line looking for -args */

clparse(argc,argv,args)
int argc;
char **argv;
int args[26];
{
int i;
int arg;

/* clear args to zero */
for (i=0;i<26;i++) args[i] = 0;

/* find any argument flags */
for (i=0;i<argc;i++)
   if (*(argv[i]) == '-')
	{
	arg = (int) *(argv[i] + 1);
	if ((arg >= (int) 'A') && (arg <= (int) 'Z')) 
		args[arg - (int)'A'] = i;
	if ((arg >= (int) 'a') && (arg <= (int) 'z')) 
		args[arg - (int)'a'] = i;
	}
return;
}
