#include #include #include #include #include #include #define debug #ifdef DEBUG #undef debug #define debug printf #endif typedef struct Card { char number; char type; } card; void Initializehands( card phand[][14], card chand[][14] ); void Createdeck( card * deck ); void Shuffle( card * deck ); void Dealcards( card * deck, card * discard, card phand[][14], card chand[][14] ); void Playersturn( card * deck, card * discard, card phand[][14], int * pnumcards, int cnumcards ); void Computersturn( card * deck, card * discard, card chand[][14], int * cnumcards, int pnumcards ); void Scoring( int pnumcards, int cnumcards, card phand[][14], card chand[][14] ); int typetorow( card * cards, int index ); int numtopos( card * cards, int index ); int Isgreater( int row1, int row2, card chand[][14] ); char Sub( int row, card chand[][14] ); char Add( int row, card chand[][14] ); int Isvalid( card play, card * discard ); int Longsuit( int size, card chand[][14] ); int top = 51, topd = 0, deadlock = 0; void main(void) { card deck[52], discard[52], phand[4][14], chand[4][14]; int newgame = 1, notover = 1, pnumcards = 7, cnumcards = 7; char again[3] = "y"; while ( newgame ) { srandom( time(NULL) ); Initializehands( phand, chand ); Createdeck( deck ); Shuffle( deck ); Dealcards( deck, discard, phand, chand ); while ( notover ) { Playersturn( deck, discard, phand, &pnumcards, cnumcards ); if ( deadlock == 2 ) { printf( "\n\nApparently neither player can move or is willing to move.\n" ); printf( "The game is a stalemate.\n\n" ); break; } notover = pnumcards; if ( ! notover ) continue; Computersturn( deck, discard, chand, &cnumcards, pnumcards ); if ( deadlock == 2 ) { printf( "\n\nApparently neither player can move or is willing to move.\n" ); printf( "The game is a stalemate.\n\n" ); break; } notover = cnumcards; } if ( deadlock != 2 ) Scoring( pnumcards, cnumcards, phand, chand ); printf( "Do you want to play again [y or n]? " ); fgets( again, 3, stdin ); if ( ( *again == 'y' ) || ( *again == 'Y' ) ) { top = 51; topd = 0; pnumcards = 7; cnumcards = 7; deadlock = 0; notover = 1; } if ( ( *again == 'n' ) || ( *again == 'N' ) ) newgame = 0; } } void Initializehands( card phand[][14], card chand[][14] ) { register int i, j; for( i = 0; i < 4; i++ ) for( j = 0; j < 14; j++ ) { phand[i][j].number = '0'; chand[i][j].number = '0'; phand[i][j].type = 'N'; if ( j == 0 ) switch( i ) { case 0: chand[i][j].type = 'H'; break; case 1: chand[i][j].type = 'S'; break; case 2: chand[i][j].type = 'C'; break; default: chand[i][j].type = 'D'; } else chand[i][j].type = 'N'; } } void Createdeck( card * deck ) { char types[] = { 'H', 'S', 'C', 'D' }; register int i, j, count = 0; for( i = 0; i < 4; i++ ) for( j = 0; j < 14; j++ ) { deck[count].type = types[i]; if ( j == 0 ) continue; switch( j ) { case 1: deck[count].number = 'A'; break; case 10: deck[count].number = 'T'; break; case 11: deck[count].number = 'J'; break; case 12: deck[count].number = 'Q'; break; case 13: deck[count].number = 'K'; break; default: deck[count].number = j + 48; } count++; } } void Shuffle( card * deck ) { register int i; int count, position; card temp; for( i = 0; i < 52; i++ ) { position = random() % 52; temp.number = deck[position].number; temp.type = deck[position].type; deck[position].number = deck[i].number; deck[position].type = deck[i].type; deck[i].number = temp.number; deck[i].type = temp.type; } } void Dealcards( card * deck, card * discard, card phand[][14], card chand[][14] ) { register int i; int row, column; for( i = 0; i < 7; i++ ) { row = typetorow( deck, top ); column = numtopos( deck, top ); phand[row][column].number = deck[top].number; phand[row][column].type = deck[top].type; top--; } for ( i = 0; i < 7; i++ ) { row = typetorow( deck, top ); column = numtopos( deck, top ); chand[row][column].number = deck[top].number; chand[row][column].type = deck[top].type; top--; chand[row][0].number = Add( row, chand ); } discard[topd].number = deck[top].number; discard[topd].type = deck[top].type; top--; } void Playersturn( card * deck, card * discard, card phand[][14], int * pnumcard, int cnumcards ) { int notendofturn = 1, row, column, incorrectsuit = 1, pnumcards; register int i, j; char dorp[3], suit[3], temp[4]; card play; pnumcards = *pnumcard; putchar( '\n' ); while ( notendofturn ) { printf( "Your cards:\n" ); for( i = 0; i < 4; i++ ) { for ( j = 1; j < 14; j++ ) { if ( phand[i][j].type == 'N' ) continue; printf( "%c%c ", phand[i][j].number, phand[i][j].type ); } putchar( '\n' ); } putchar( '\n' ); printf( "The computer has %d cards\n", cnumcards ); printf( "Discard is %c%c\n\n", discard[topd].number, discard[topd].type ); if ( top > -1 ) printf( "Do you want to (d)raw or (p)lay? " ); else printf( "Do you want to (p)lay or (s)kip? " ); fgets( dorp, 3, stdin ); if ( ( ( *dorp == 'd' ) || ( *dorp == 'D' ) ) && ( top > -1 ) ) { row = typetorow( deck, top ); column = numtopos( deck, top ); phand[row][column].number = deck[top].number; phand[row][column].type = deck[top].type; pnumcards++; deadlock = 0; top--; printf( "\n\n" ); continue; } if ( ( *dorp == 'p' ) || ( *dorp == 'P' ) ) { putchar( '\n' ); printf( "Which card do you want to play? " ); fgets( temp, 4, stdin ); play.number = temp[0]; play.type = temp[1]; play.type = toupper( play.type ); if ( Isvalid( play, discard ) ) { row = typetorow( &play, 0 ); column = numtopos( &play, 0 ); if ( phand[row][column].type == 'N' ) { printf( "\n\n" ); printf( "You do not have that card\n\n" ); continue; } phand[row][column].number = '0'; phand[row][column].type = 'N'; pnumcards--; topd++; discard[topd].number = toupper( play.number ); discard[topd].type = play.type; if ( discard[topd].number == '8' ) while ( incorrectsuit ) { printf( "What suit is this? " ); fgets( suit, 3, stdin ); putchar( '\n' ); *suit = toupper( *suit ); if ( ( *suit == 'H' ) || ( *suit == 'S' ) || ( *suit == 'C' ) || ( *suit == 'D' ) ) { incorrectsuit = 0; discard[topd].type = *suit; } } notendofturn = 0; deadlock = 0; continue; } printf( "\n\nThat is not a valid choice\n\n" ); continue; } if ( ( ( *dorp == 's' ) || ( *dorp == 'S' ) ) && ( top == -1 ) ) { notendofturn = 0; deadlock++; } } *pnumcard = pnumcards; } void Computersturn( card * deck, card * discard, card chand[][14], int * cnumcard, int pnumcards ) { int notendofturn = 1, row, column, switchsuit = 0, rowtemp, cnumcards, i, j, pos, bestpos = -1; char size, best = '0'; cnumcards = *cnumcard; while( notendofturn ) { #ifdef DEBUG printf( "Computer's cards:\n" ); printf( "Discard is %c%c\n\n", discard[topd].number, discard[topd].type ); for( i = 0; i < 4; i++ ) { for ( j = 1; j < 14; j++ ) { if ( chand[i][j].type == 'N' ) continue; printf( "%c%c ", chand[i][j].number, chand[i][j].type ); } putchar( '\n' ); } putchar( '\n' ); #endif row = typetorow( discard, topd ); if ( chand[row][0].number != '0' ) { for( i = 13; i > 0; i-- ) { if ( ( chand[row][i].type == 'N' ) || ( i == 8 ) ) continue; rowtemp = row; switchsuit = 1; column = i; for( j = 0; j < 4; j++ ) if ( chand[j][i].number == discard[topd].number ) { if ( Isgreater( j, row, chand ) ) rowtemp = j; } if ( switchsuit ) break; } if ( switchsuit ) { topd++; discard[topd].number = chand[rowtemp][column].number; discard[topd].type = chand[rowtemp][column].type; chand[rowtemp][column].number = '0'; chand[rowtemp][column].type = 'N'; chand[rowtemp][0].number = Sub( rowtemp, chand ); cnumcards--; deadlock = 0; notendofturn = 0; break; } for ( j = 0; j < 4; j++ ) { pos = numtopos(discard, topd); if ( chand[j][pos].type != 'N' ) { size = chand[j][0].number; if ( size > best ) { best = size; bestpos = j; } } } if ( ( bestpos != -1 ) && ( bestpos != 8 ) ) { topd++; discard[topd].number = chand[bestpos][pos].number; discard[topd].type = chand[bestpos][pos].type; chand[bestpos][pos].number = '0'; chand[bestpos][pos].type = 'N'; cnumcards--; deadlock = 0; notendofturn = 0; chand[bestpos][0].number = Sub( bestpos, chand ); break; } topd++; discard[topd].number = '8'; chand[row][8].number = '0'; chand[row][8].type = 'N'; cnumcards--; deadlock = 0; chand[row][0].number = Sub( row, chand ); for( j = 0; j < 4; j++ ) { if ( !j ) rowtemp = 0; else if ( Isgreater( j, rowtemp, chand ) ) rowtemp = j; } discard[topd].type = chand[rowtemp][0].type; notendofturn = 0; break; } if ( !notendofturn ) continue; debug( "This is where I'll either draw or play a card from another hand\n" ); for ( j = 0; j < 4; j++ ) { pos = numtopos(discard, topd); if ( chand[j][pos].type != 'N' ) { debug( "I've found a card to use\n" ); size = chand[j][0].number; if ( size > best ) { best = size; bestpos = j; } } } debug( "This is size: %c\n", size ); debug( "This is best: %c\n", best ); debug( "This is bestpos: %d\n", bestpos ); if ( ( bestpos != -1 ) && ( bestpos != 8 ) ) { topd++; discard[topd].number = chand[bestpos][pos].number; discard[topd].type = chand[bestpos][pos].type; chand[bestpos][pos].number = '0'; chand[bestpos][pos].type = 'N'; cnumcards--; deadlock = 0; notendofturn = 0; chand[bestpos][0].number = Sub( bestpos, chand ); } if ( !notendofturn ) { continue; } rowtemp = -1; for( j = 0; j < 4; j++ ) { if ( ( ( ( cnumcards > 4 ) && ( Longsuit( 2, chand ) ) && ( pnumcards > 4 ) ) || ( ( cnumcards < 5 ) || ( pnumcards < 5 ) ) ) && ( chand[j][8].number == '8' ) ) { topd++; discard[topd].number = '8'; chand[j][8].number = '0'; chand[j][8].type = 'N'; chand[j][0].number = Sub( j, chand ); cnumcards--; deadlock = 0; for( i = 0; i < 4; i++ ) if ( !i ) rowtemp = i; else if ( Isgreater( i, rowtemp, chand ) ) rowtemp = i; discard[topd].type = chand[rowtemp][0].type; notendofturn = 0; break; } } if( !notendofturn ) continue; if ( top > -1 ) { row = typetorow( deck, top ); column = numtopos( deck, top ); chand[row][column].number = deck[top].number; chand[row][column].type = deck[top].type; chand[row][0].number = Add( row, chand ); top--; cnumcards++; deadlock = 0; continue; } notendofturn = 0; deadlock++; } *cnumcard = cnumcards; } int typetorow( card * cards, int index ) { int row; if ( cards[index].type == 'H' ) row = 0; else if ( cards[index].type == 'S' ) row = 1; else if ( cards[index].type == 'C' ) row = 2; else row = 3; return( row ); } int numtopos( card * cards, int index ) { int pos; char val[2]; val[1] = '\0'; if ( ( cards[index].number == 'K' ) || ( cards[index].number == 'k' ) ) pos = 13; else if ( ( cards[index].number == 'Q' ) || ( cards[index].number == 'q' ) ) pos = 12; else if ( ( cards[index].number == 'J' ) || ( cards[index].number == 'j' ) ) pos = 11; else if ( ( cards[index].number == 'T' ) || ( cards[index].number == 't' ) ) pos = 10; else if ( ( cards[index].number == 'A' ) || ( cards[index].number == 'a' ) ) pos = 1; else { val[0] = cards[index].number; pos = atoi( val ); } return( pos ); } int Isgreater( int row1, int row2, card chand[][14] ) { if ( ( int ) chand[row1][0].number > ( int ) chand[row2][0].number ) return( 1 ); return( 0 ); } char Sub( int row, card chand[][14] ) { char number; if ( ( int ) chand[row][0].number == 65 ) number = 57; else number = chand[row][0].number - 1; return( number ); } char Add( int row, card chand[][14] ) { char number; if ( ( int ) chand[row][0].number == 57 ) number = 65; else number = chand[row][0].number + 1; return( number ); } void Scoring( int pnumcards, int cnumcards, card phand[][14], card chand[][14] ) { register int i, j; int score = 0; if ( pnumcards == 0 ) { for ( i = 0; i < 4; i++ ) for ( j = 1; j < 14; j++ ) { if ( chand[i][j].type == 'N' ) continue; else if ( chand[i][j].number == 'A' ) score++; else if ( chand[i][j].number == '8' ) score += 50; else if ( ( chand[i][j].number == 'T' ) || ( chand[i][j].number == 'J' ) || ( chand[i][j].number == 'Q' ) || ( chand[i][j].number == 'K' ) ) score += 10; else score += ( int ) ( chand[i][j].number - 48 ); } printf( "\n\n\nYour score is %d\n\n", score ); } else { for ( i = 0; i < 4; i++ ) for ( j = 1; j < 14; j++ ) { if ( phand[i][j].type == 'N' ) continue; else if ( phand[i][j].number == 'A' ) score++; else if ( phand[i][j].number == '8' ) score += 50; else if ( ( phand[i][j].number == 'T' ) || ( phand[i][j].number == 'J' ) || ( phand[i][j].number == 'Q' ) || ( phand[i][j].number == 'K' ) ) score += 10; else score += ( int ) ( phand[i][j].number - 48 ); } printf( "\n\n\nThe computer's score is %d\n\n", score ); } } int Isvalid( card play, card * discard ) { if ( ( play.type == discard[topd].type ) || ( (char) toupper( play.number ) == discard[topd].number ) || ( play.number == '8' ) ) return( 1 ); else return( 0 ); } int Longsuit( int size, card chand[][14] ) { register int i; int longsuit = 0; for( i = 0; i < 4; i++ ) if ( chand[i][0].number >= size ) { longsuit = 1; break; } return( longsuit ); }