#include #include #include /* Bob Weems - August 1994, derived from original Mastermind code */ /* Plays Super Mastermind - Available at most toy stores */ /* Uses move elimination + probability notions to find a move that is good on average */ /* Two-move openings are taken from The Official Mastermind Handbook by Leslie H. Alt, Signet, 1976, pp. 64-66 */ /* "xx" is for a blank in a guess, but not in hidden code */ char *color[9]={"bu","gn","yw","rd","bk","wh","or","bn","xx"}; /* opening1 contains patterns for first guess by program corresponding position in opening2 contains pattern for second guess. The negative values must be instantiated (randomly). The 8s correspond to blanks (unused positions). */ int opening1[7][5]={{-6,-1,-2,-3,-4},{-6,-7,-7,-8,-8}, {-4,-5,-6,-7,-8},{-6,-7,-8,-1,-2}, {-5,-5,-6,-7,-8},{-5,-6,-7,-8,8}, {-6,-6,-6,-7,-7}}; int opening2[7][5]={{-1,-2,-3,-4,-5},{-1,-2,-3,-4,-5}, {-1,-1,-2,-2,-3},{-1,-2,-3,-4,-5}, {-1,-2,-3,-4,-4},{-1,-2,-3,-4,8}, {-1,-2,-3,-4,-5}}; /* kpcMap is to avoid wasting space in keyPegCounts when recording how many uneliminated moves will get key pegs in a particular way. The first subscript corresponds to the number of black pegs, the second subscript to the number of white pegs. Thus, if we have 3 black key pegs and 2 white key pegs, kpcMap takes us to position 17 for the second subscript of keyPegCounts. Entries with -1 should NEVER be accessed, since they correspond to impossible key peg situations. */ int kpcMap[5][6]={{0,1,2,3,4,5},{6,7,8,9,10,-1},{11,12,13,14,-1,-1}, {15,16,17,-1,-1,-1},{18,-1,-1,-1,-1,-1}}; /*inverses of kpcMap*/ int inverseKPCmapBlack[19]={0,0,0,0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,4}; int inverseKPCmapWhite[19]={0,1,2,3,4,5,0,1,2,3,4,0,1,2,3,0,1,2,0}; int possibleMoves[32768][5]; /* stores the uneliminated possibilities */ int numberPossibleMoves; /* number of possibleMoves entries in use */ int keyPegCounts[32768][19]; /* see description for kpcMap */ void determineKeyPegs(keyPegs1,keyPegs2,blackOut,whiteOut) int keyPegs1[5],keyPegs2[5],*blackOut,*whiteOut; { /* Computes key pegs for two rows of code pegs. Recall that key pegging is symmetric - it does not matter which row is the hidden code. The loops are unrolled to reduce execution time by 1/2 */ int kpWork1[5],kpWork2[5]; int black,white; black=0; white=0; kpWork1[0]=keyPegs1[0]; kpWork1[1]=keyPegs1[1]; kpWork1[2]=keyPegs1[2]; kpWork1[3]=keyPegs1[3]; kpWork1[4]=keyPegs1[4]; kpWork2[0]=keyPegs2[0]; kpWork2[1]=keyPegs2[1]; kpWork2[2]=keyPegs2[2]; kpWork2[3]=keyPegs2[3]; kpWork2[4]=keyPegs2[4]; if (kpWork1[0]==kpWork2[0]) { black=1; kpWork1[0]=9; kpWork2[0]=9; } if (kpWork1[1]==kpWork2[1]) { black++; kpWork1[1]=9; kpWork2[1]=9; } if (kpWork1[2]==kpWork2[2]) { black++; kpWork1[2]=9; kpWork2[2]=9; } if (kpWork1[3]==kpWork2[3]) { black++; kpWork1[3]=9; kpWork2[3]=9; } if (kpWork1[4]==kpWork2[4]) { black++; kpWork1[4]=9; kpWork2[4]=9; } if (kpWork1[0]<9) if (kpWork1[0]==kpWork2[1]) { white++; kpWork2[1]=9; } else if (kpWork1[0]==kpWork2[2]) { white++; kpWork2[2]=9; } else if (kpWork1[0]==kpWork2[3]) { white++; kpWork2[3]=9; } else if (kpWork1[0]==kpWork2[4]) { white++; kpWork2[4]=9; } if (kpWork1[1]<9) if (kpWork1[1]==kpWork2[0]) { white++; kpWork2[0]=9; } else if (kpWork1[1]==kpWork2[2]) { white++; kpWork2[2]=9; } else if (kpWork1[1]==kpWork2[3]) { white++; kpWork2[3]=9; } else if (kpWork1[1]==kpWork2[4]) { white++; kpWork2[4]=9; } if (kpWork1[2]<9) if (kpWork1[2]==kpWork2[0]) { white++; kpWork2[0]=9; } else if (kpWork1[2]==kpWork2[1]) { white++; kpWork2[1]=9; } else if (kpWork1[2]==kpWork2[3]) { white++; kpWork2[3]=9; } else if (kpWork1[2]==kpWork2[4]) { white++; kpWork2[4]=9; } if (kpWork1[3]<9) if (kpWork1[3]==kpWork2[0]) { white++; kpWork2[0]=9; } else if (kpWork1[3]==kpWork2[1]) { white++; kpWork2[1]=9; } else if (kpWork1[3]==kpWork2[2]) { white++; kpWork2[2]=9; } else if (kpWork1[3]==kpWork2[4]) { white++; kpWork2[4]=9; } if (kpWork1[4]<9) if (kpWork1[4]==kpWork2[0] || kpWork1[4]==kpWork2[1] || kpWork1[4]==kpWork2[2] || kpWork1[4]==kpWork2[3]) white++; *blackOut=black; *whiteOut=white; } void zeroKeyPegCounts() { int i,j; for (i=0;i