2 * UCC 2012 Programming Competition Entry
13 #define TAG_BOARDSTATE 0x7342
21 typedef struct sSavedBoardState
25 char NormalisedBoard[];
29 tSavedBoardState *DB_int_ReadState(FILE *fp, off_t *offset);
30 void DB_int_AppendTag(FILE *fp, uint16_t Tag, uint16_t Size, void *Data);
33 char *DB_GetOpponentFile(const char *Opponent)
35 uint32_t checksum = 0;
39 const char *str = Opponent;
42 checksum ^= *str << ofs;
49 const char *filename = NULL;
52 const char *last_slash = NULL;
53 const char *last_dot = NULL;
54 const char *str = Opponent;
57 if(*str == '/') last_slash = str;
58 if(*str == '.') last_dot = str;
61 filename = last_slash + 1;
62 if( last_slash > last_dot )
63 filenamelen = str - filename;
65 filenamelen = last_dot - filename;
68 int len = snprintf(NULL, 0, "%08x_%.*s.ramen", checksum, filenamelen, filename);
69 char *ret = malloc(len+1);
70 snprintf(ret, len+1, "%08x_%.*s.ramen", checksum, filenamelen, filename);
71 // fprintf(stderr, "DB File = '%s'\n", ret);
75 void DB_LoadGuesses(const char *DBFile, enum eColours Colour)
79 tSavedBoardState *saved_board = NULL;
81 fp = fopen(DBFile, "r+");
84 // Read board states, checking for a same state
85 while( (saved_board = DB_int_ReadState(fp, &offset)) )
87 if( saved_board->W != giBoardWidth )
89 if( saved_board->H != giBoardHeight )
94 // TODO: Combine counts of how many times a state has been played
98 char bs[giBoardWidth*4];
102 if( Colour != COLOUR_RED )
104 ofs = giBoardHeight-4;
105 char *bs2 = saved_board->NormalisedBoard;
106 memcpy(bs + giBoardWidth*0, bs2 + giBoardWidth*(4-1), giBoardWidth);
107 memcpy(bs + giBoardWidth*1, bs2 + giBoardWidth*(4-2), giBoardWidth);
108 memcpy(bs + giBoardWidth*2, bs2 + giBoardWidth*(4-3), giBoardWidth);
109 memcpy(bs + giBoardWidth*3, bs2 + giBoardWidth*(4-4), giBoardWidth);
113 memcpy(bs, saved_board->NormalisedBoard, giBoardWidth*4);
115 // for( int i = 0; i < 4; i ++ ) {
116 // fprintf(stderr, "%.*s\n", giBoardWidth, bs + giBoardWidth*i);
120 for( int i = 0; i < giBoardWidth*4; i ++ )
122 tPiece *p = GetPieceByPos(i % giBoardWidth, i/giBoardWidth + ofs );
123 // fprintf(stderr, "%c", bs[i]);
124 // if(i % giBoardWidth == giBoardWidth-1)
125 // fprintf(stderr, "\n");
126 if( bs[i] == '\0' && p )
128 if( bs[i] != '\0' && !p )
131 p->GuessedRank = CharToRank(bs[i]);
138 void DB_WriteBackInitialState(const char *DBFile, enum eColours Colour, tPiece *Pieces)
140 char bs[giBoardHeight*giBoardWidth];
141 memset(bs, 0, sizeof(bs));
143 for( int i = 0; i < N_PIECES; i ++ )
145 if( Pieces[i].StartY < 0 ) continue ;
146 char *bp = &bs[ Pieces[i].StartY*giBoardWidth + Pieces[i].StartX ];
154 *bp = cRANK_CHARS[ Pieces[i].Rank ];
158 // Normalise board to RED
159 if( Colour != COLOUR_RED )
161 memcpy(bs + giBoardWidth*0, bs + giBoardWidth*(giBoardHeight-1), giBoardWidth);
162 memcpy(bs + giBoardWidth*1, bs + giBoardWidth*(giBoardHeight-2), giBoardWidth);
163 memcpy(bs + giBoardWidth*2, bs + giBoardWidth*(giBoardHeight-3), giBoardWidth);
164 memcpy(bs + giBoardWidth*3, bs + giBoardWidth*(giBoardHeight-4), giBoardWidth);
169 tSavedBoardState *saved_board;
170 FILE *fp = fopen(DBFile, "r+");
172 fp = fopen(DBFile, "w");
175 // Read board states, checking for a same state
176 while( (saved_board = DB_int_ReadState(fp, &offset)) )
178 // fprintf(stderr, "DBG: %i == %i? and %i == %i\n",
179 // saved_board->W, giBoardWidth, saved_board->H, giBoardHeight
182 if( saved_board->W != giBoardWidth )
184 if( saved_board->H != giBoardHeight )
187 BOOL b_different = false;
189 for( int i = 0; i < 4*giBoardWidth; i ++ )
191 if( saved_board->NormalisedBoard[i] == '#' || bs[i] == '#' )
193 if( saved_board->NormalisedBoard[i] != bs[i] ) {
194 fprintf(stderr, "DBG: '%c' != '%c'\n", saved_board->NormalisedBoard[i], bs[i]);
200 if( b_different ) continue ;
207 saved_board->Count ++;
208 fseek(fp, offset, SEEK_SET);
210 for( int i = 0; i < 4*giBoardWidth; i ++ )
212 if( saved_board->NormalisedBoard[i] == '#' )
213 saved_board->NormalisedBoard[i] = bs[i];
216 fwrite(saved_board, sizeof(*saved_board) + giBoardWidth*4, 1, fp);
220 saved_board = malloc( sizeof(*saved_board) + giBoardWidth*4 );
221 saved_board->W = giBoardWidth;
222 saved_board->H = giBoardHeight;
223 saved_board->Count = 1;
224 memcpy(saved_board->NormalisedBoard, bs, 4*giBoardWidth);
225 DB_int_AppendTag(fp, TAG_BOARDSTATE, sizeof(*saved_board) + giBoardWidth*4, saved_board);
232 tSavedBoardState *DB_int_ReadState(FILE *fp, off_t *offset)
235 tSavedBoardState *ret = NULL;
238 if( fread(&tag, sizeof(tag), 1, fp) != 1 )
240 if( tag.Tag == TAG_BOARDSTATE )
243 ret = malloc(tag.Length);
244 fread(ret, tag.Length, 1, fp);
246 fseek(fp, tag.Length, SEEK_CUR);
252 void DB_int_AppendTag(FILE *fp, uint16_t Tag, uint16_t Size, void *Data)
254 fseek(fp, 0, SEEK_END);
255 fwrite(&Tag, sizeof(uint16_t), 1, fp);
256 fwrite(&Size, sizeof(uint16_t), 1, fp);
257 fwrite(Data, Size, 1, fp);