This is ComputerPlayer.m in view mode; [Download] [Up]
// ComputerPlayer.m // Project: Cribbage // Stephan Wacker // 93-09-16 #import "deck.h" #import "cribbage.h" #import "ComputerPlayer.h" #import "Deck.h" #import "ScoreBoard.h" @implementation ComputerPlayer - (char *) pronoun { return "I"; } - (char *) possessivePronoun { return "my"; } - (char *) reflexivePronoun { return "me"; } - (int) selectCardForBestScore // // Return index of card to play for best score. // Return -1 if no card scores. // { int i, j, k, l; j = -1; k = 0; for (i = 0; i < FULLHAND; i++) { /* maximize score */ if( face[i] != FACE_NONE ) { l = [table score: hand[i]]; if (l > k) { k = l; j = i; } } } return j; } - (int) findVal: (int) v { int i; for( i = 0; i < FULLHAND; i++ ) { if( face[i] != FACE_NONE ) { if( VAL( hand[i].rank ) == v ) return( i ); } } return( -1 ); } - (int) numOfVal: (int) v { int i, j; for( i = 0, j = 0; i < FULLHAND; i++ ) { if( face[i] != FACE_NONE ) { if( VAL( hand[i].rank ) == v ) ++ j; } } return( j ); } - (int) selectCardNonscoring { int i, j, l; int s = [table sumPlayed]; #define NTV 10 /* number scores to test */ /* score to test reachability of, and order to test them in */ static int tv[ NTV ] = { 8, 7, 9, 6, 11, 12, 13, 14, 10, 5 }; if( s < 4 ) { /* try for good value */ if( ( j = [self findVal: 4-s] ) >= 0 ) return( j ); if( ( j = [self findVal: 3-s] ) >= 0 && s == 0 ) return( j ); } if( s > 0 && s < 20 ) { for( i = 1; i <= 10; i++ ) { /* try for retaliation to 31 */ if( ( j = [self findVal: 21-i-s] ) >= 0 ) { if( ( l = [self numOfVal: i] ) > 0 ) { if( l > 1 || VAL( hand[j].rank ) != i ) return( j ); } } } } if( s < 15 ) { for( i = 0; i < NTV; i++ ) { /* for retaliation after 15 */ if( ( j = [self findVal: tv[i]-s] ) >= 0 ) { if( ( l = [self numOfVal: 15-tv[i]] ) > 0 ) { if( l > 1 || VAL( hand[j].rank ) != 15-tv[i] ) return( j ); } } } } j = -1; for( i = FULLHAND-1; i >= 0; --i ) { /* remember: h is sorted */ if( face[i] != FACE_NONE ) { l = s + VAL( hand[i].rank ); if( l > 31 ) continue; if( l != 5 && l != 10 && l != 21 ) { j = i; break; } } } if( j >= 0 ) return( j ); for( i = FULLHAND-1; i >= 0; --i ) { if( face[i] != FACE_NONE ) { l = s + VAL( hand[i].rank ); if( l > 31 ) continue; if( j < 0 ) j = i; if( l != 5 && l != 21 ) { j = i; break; } } } return( j ); } - (int) selectCard // // Return index of card to be played next. // { int result; result = [self selectCardForBestScore]; if (result < 0) /* if nothing scores */ result = [self selectCardNonscoring]; return result; } - playOneCard { if( [self canPlay] ) { [self playCardAt: [self selectCard]]; } else { [self go]; } return self; } - emptyHand { [super emptyHand]; knownum = 0; return self; } - chooseDiscard { CARD d[ CARDS ], h[ FULLHAND ], cb[ 2 ]; register int i, j, k; int nc, ns; long sums[ 15 ]; static int undo1[15] = {0,0,0,0,0,1,1,1,1,2,2,2,3,3,4}; static int undo2[15] = {1,2,3,4,5,2,3,4,5,3,4,5,4,5,5}; makedeck( d ); nc = CARDS; for( i = 0; i < knownum; i++ ) { /* get all other cards */ remove_card( known[i], d, nc-- ); } for( i = 0; i < 15; i++ ) sums[i] = 0L; ns = 0; for( i = 0; i < (FULLHAND - 1); i++ ) { cb[0] = hand[i]; for( j = i + 1; j < FULLHAND; j++ ) { cb[1] = hand[j]; for( k = 0; k < FULLHAND; k++ ) h[k] = hand[k]; remove_card( hand[i], h, FULLHAND ); remove_card( hand[j], h, FULLHAND - 1 ); for( k = 0; k < nc; k++ ) { sums[ns] += scorehand( h, d[k], CINHAND, TRUE, FALSE ); if( [deck isCompCrib] ) sums[ns] += adjust( cb, d[k] ); else sums[ns] -= adjust( cb, d[k] ); } ++ns; } } j = 0; for( i = 1; i < 15; i++ ) if( sums[i] > sums[j] ) j = i; for( k = 0; k < FULLHAND; k++ ) h[k] = hand[k]; remove_card( h[ undo1[j] ], hand, FULLHAND ); remove_card( h[ undo2[j] ], hand, FULLHAND - 1 ); hand[4] = h[ undo1[j] ]; hand[5] = h[ undo2[j] ]; return self; } - discard { int i; CARD card; [self chooseDiscard]; /* puts best discard at end */ for( i = CINHAND; i < FULLHAND; i++ ) { card = hand[i]; face[i] = FACE_NONE; hand[i].rank = hand[i].suit = EMPTY; [self displayCardAt: i]; [deck putIntoCrib: card]; } return self; } - (BOOL) faceUp // // Computer's cards are displayed face down. // { return NO; } - sortHand { [super sortHand]; [self makeknown: hand num: FULLHAND]; return self; } - makeknown: (CARD *) cards num: (int) n { register int i; for( i = 0; i < n; i++ ) { known[ knownum++ ] = cards[i]; } return self; } - makeknown: (CARD) card { known[ knownum++ ] = card; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.