memoize
このコミットが含まれているのは:
コミット
56c1ac73e1
55
uttt.c
55
uttt.c
|
@ -916,10 +916,55 @@ struct ut_move ut_minimax(int (*value)(const struct ut_state *state), const stru
|
|||
return best_move;
|
||||
}
|
||||
|
||||
struct ut_statevalue
|
||||
{
|
||||
unsigned char tilesxo[21];
|
||||
char value;
|
||||
};
|
||||
struct ut_statevalue ut_rolloutCache[16777216];
|
||||
void ut_statetokey(struct ut_statevalue *sv, const struct ut_state *state)
|
||||
{
|
||||
memset(sv->tilesxo, 0, sizeof(sv->tilesxo));
|
||||
char *tiles = (char *)state->tiles;
|
||||
for(int i = 0; i < sizeof(state->tiles); i++)
|
||||
sv->tilesxo[i / 4] |= ((tiles[i] == 'X') * (1 << ((i % 4) * 2))) |
|
||||
((tiles[i] == 'O') * (1 << ((i % 4) * 2 + 1)));
|
||||
}
|
||||
unsigned long ut_keytoidx(struct ut_statevalue *sv)
|
||||
{
|
||||
//djb2 hash
|
||||
unsigned long hash = 5831;
|
||||
for(int i = 0; i < sizeof(sv->tilesxo); i++)
|
||||
{
|
||||
hash = ((hash << 5) + hash) ^ sv->tilesxo[i];
|
||||
}
|
||||
return hash % (sizeof(ut_rolloutCache) / sizeof(ut_rolloutCache[0]));
|
||||
}
|
||||
int ut_memValue(int value, const struct ut_state *state)
|
||||
{
|
||||
struct ut_statevalue sv;
|
||||
sv.value = value;
|
||||
ut_statetokey(&sv, state);
|
||||
ut_rolloutCache[ut_keytoidx(&sv)] = sv;
|
||||
return value;
|
||||
}
|
||||
int ut_getValue(const struct ut_state *state, int *value)
|
||||
{
|
||||
struct ut_statevalue sv;
|
||||
ut_statetokey(&sv, state);
|
||||
struct ut_statevalue *entry = &ut_rolloutCache[ut_keytoidx(&sv)];
|
||||
if(memcmp(sv.tilesxo, entry->tilesxo, sizeof(sv.tilesxo))) {return 1;}
|
||||
*value = entry->value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define UT_RDEPTH 2
|
||||
#define UT_RTURNS 2
|
||||
#define UT_RTURNS 9
|
||||
int ut_rollout(const struct ut_state *state)
|
||||
{
|
||||
// memoization
|
||||
int value;
|
||||
if(!ut_getValue(state, &value)) {return value;}
|
||||
|
||||
struct ut_state rstate = *state;
|
||||
int moves = 0;
|
||||
|
@ -933,12 +978,12 @@ int ut_rollout(const struct ut_state *state)
|
|||
}
|
||||
moves++;
|
||||
}
|
||||
return (winner == 'X') ? (UT_VALUEMAX - moves) :
|
||||
(winner == 'O') ? (UT_VALUEMIN + moves) :
|
||||
(winner == ' ') ? 0 : ut_value(&rstate);
|
||||
return ut_memValue((winner == 'X') ? (UT_VALUEMAX - moves) :
|
||||
(winner == 'O') ? (UT_VALUEMIN + moves) :
|
||||
(winner == ' ') ? 0 : ut_value(&rstate), state);
|
||||
}
|
||||
|
||||
#define UT_DEPTH 5
|
||||
#define UT_DEPTH 4
|
||||
int ut_agentgetmove(const struct ut_state *state, const struct ut_game *game, struct ut_move *move)
|
||||
{
|
||||
*move = ut_minimax(ut_rollout, state, UT_DEPTH);
|
||||
|
|
読み込み中…
新しいイシューから参照