first try of A* move sorting
This commit is contained in:
@@ -60,6 +60,15 @@ typedef struct pos {
|
|||||||
struct list_head list;
|
struct list_head list;
|
||||||
} pos_t;
|
} pos_t;
|
||||||
|
|
||||||
|
/* All possible moves between hallway and rooms
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint mask; /* blocking spaces */
|
||||||
|
uint dist;
|
||||||
|
} possible_move_t;
|
||||||
|
|
||||||
|
static possible_move_t moves[24][24];
|
||||||
|
|
||||||
typedef struct hash {
|
typedef struct hash {
|
||||||
u64 zobrist; /* zobrist hash */
|
u64 zobrist; /* zobrist hash */
|
||||||
u32 amp[4];
|
u32 amp[4];
|
||||||
@@ -145,6 +154,32 @@ static s32 room_exit[4][2][6] = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static char *int2bin(u32 mask)
|
||||||
|
{
|
||||||
|
static char ret[64];
|
||||||
|
|
||||||
|
for (int i = 0; i < 32; ++i) {
|
||||||
|
ret[31-i] = mask & BIT(i)? '1': '0';
|
||||||
|
}
|
||||||
|
ret[32] = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *int2pos(u32 mask)
|
||||||
|
{
|
||||||
|
static char res[1024];
|
||||||
|
char *p = res;
|
||||||
|
|
||||||
|
for (int i = 0; i < 32; ++i) {
|
||||||
|
if (mask & BIT(i)) {
|
||||||
|
*p++ = ' ';
|
||||||
|
strcpy(p, cells[i]);
|
||||||
|
p += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static void moves_print(move_t *moves, int nmoves)
|
static void moves_print(move_t *moves, int nmoves)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < nmoves; ++i)
|
for (int i = 0; i < nmoves; ++i)
|
||||||
@@ -422,72 +457,77 @@ static u64 hash(pos_t *pos, int amp, u32 from, u32 to)
|
|||||||
return zobrist;
|
return zobrist;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* evaluate current position.
|
/* evaluate current position :
|
||||||
*
|
* eval = cost + eval_to_dest
|
||||||
*
|
* cost is current cost
|
||||||
*/
|
* eval is cost to join top of destination room
|
||||||
static u32 eval(pos_t *pos, int amp, u32 from, u32 to)
|
*/
|
||||||
{
|
static int room2room_dist[][4] = {
|
||||||
log_f(1, "pos=%p amp=%d from=%u to=%u\n", pos, amp, from, to);
|
{ 4, 4, 6, 8}, { 4, 4, 4, 6}, { 6, 4, 4, 4}, { 8, 6, 4, 4}
|
||||||
return 1;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
static char *int2bin(u32 mask)
|
/* static u64 eval_amp(pos_t *pos, int amp, u32 cell) */
|
||||||
{
|
/* { */
|
||||||
static char ret[64];
|
/* u32 bit = BIT(cell); */
|
||||||
|
/* int rows = popcount32(pos->amp[0]); */
|
||||||
|
/* int dist; */
|
||||||
|
/* int left = rows - popcount32(rooms[amp] & pos->final); */
|
||||||
|
|
||||||
for (int i = 0; i < 32; ++i) {
|
/* if (ROOM(bit)) { /\* in a room *\/ */
|
||||||
ret[31-i] = mask & BIT(i)? '1': '0';
|
/* int curroom = cell / 4 - 2; */
|
||||||
|
|
||||||
|
/* dist = cell % 4; /\* distance to top of room *\/ */
|
||||||
|
/* dist += room2room_dist[curroom][amp]; */
|
||||||
|
/* dist += --left; /\* distance to final room *\/ */
|
||||||
|
/* log(1, "eval %c room(%s) = %d\n", amp + 'A', cells[cell], dist); */
|
||||||
|
/* } else { /\* in hallway *\/ */
|
||||||
|
/* int dest = (amp + 2) * 4; */
|
||||||
|
/* dist = moves[cell][dest].dist; */
|
||||||
|
/* dist += --left; /\* distance to final room *\/ */
|
||||||
|
/* log(1, "eval %c hallway(%s) = %d\n", amp + 'A', cells[cell], dist); */
|
||||||
|
/* } */
|
||||||
|
/* return cost[amp] * dist; */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
static u64 eval(pos_t *pos)
|
||||||
|
{
|
||||||
|
u32 amp, tmp;
|
||||||
|
int cell;
|
||||||
|
int rows = popcount32(pos->amp[0]);
|
||||||
|
u64 eval = 0;
|
||||||
|
|
||||||
|
for (amp = A; amp <= D; ++amp) {
|
||||||
|
u32 todo = pos->amp[amp] & ~pos->final; /* ignore finished ones */
|
||||||
|
int destroom = amp, dist;
|
||||||
|
int left = rows - popcount32(rooms[destroom] & pos->final);
|
||||||
|
|
||||||
|
printf("amp=%d %u final=%u\n", amp, pos->amp[amp], pos->final);
|
||||||
|
printf("amp=%c pos=%s\n", amp + 'A', int2bin(pos->amp[amp]));
|
||||||
|
printf("amp= tod=%s\n", int2bin(todo));
|
||||||
|
printf("amp= fin=%s\n", int2bin(pos->final));
|
||||||
|
bit_for_each32_2(cell, tmp, todo) {
|
||||||
|
u32 bit = BIT(cell);
|
||||||
|
if (ROOM(bit)) { /* in a room */
|
||||||
|
int curroom = cell / 4 - 2;
|
||||||
|
|
||||||
|
dist = cell % 4; /* distance to top of room */
|
||||||
|
dist += room2room_dist[curroom][destroom];
|
||||||
|
dist += --left; /* distance to final room */
|
||||||
|
log(1, "eval %c room(%s) = %d\n", amp + 'A', cells[cell], dist);
|
||||||
|
} else { /* in hallway */
|
||||||
|
int dest = (destroom + 2) * 4;
|
||||||
|
dist = moves[cell][dest].dist;
|
||||||
|
dist += --left; /* distance to final room */
|
||||||
|
log(1, "eval %c hallway(%s) = %d\n", amp + 'A', cells[cell], dist);
|
||||||
}
|
}
|
||||||
ret[32] = 0;
|
//printf("eval = %lu %lu\n", cost[amp] * dist, eval_amp(pos, amp, cell));
|
||||||
return ret;
|
eval += cost[amp] * dist;
|
||||||
}
|
|
||||||
|
|
||||||
static char *int2pos(u32 mask)
|
|
||||||
{
|
|
||||||
static char res[1024];
|
|
||||||
char *p = res;
|
|
||||||
|
|
||||||
for (int i = 0; i < 32; ++i) {
|
|
||||||
if (mask & BIT(i)) {
|
|
||||||
*p++ = ' ';
|
|
||||||
strcpy(p, cells[i]);
|
|
||||||
p += 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
//log_f(1, "pos=%p amp=%d from=%u to=%u\n", pos, amp, from, to);
|
||||||
|
return eval;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
H1 = BIT(_H1), H2 = BIT(_H2), H3 = (_H3), H4 = (_H4),
|
|
||||||
H5 = (_H5), H6 = (_H6), H7 = (_H7),
|
|
||||||
A1 = (_A1), A2 = (_A2), A3 = (_A3), A4 = (_A4),
|
|
||||||
B1 = (_B1), B2 = (_B2), B3 = (_B3), B4 = (_B4),
|
|
||||||
C1 = (_C1), C2 = (_C2), C3 = (_C3), C4 = (_C4),
|
|
||||||
D1 = (_D1), D2 = (_D2), D3 = (_D3), D4 = (_D4),
|
|
||||||
} space_t;
|
|
||||||
|
|
||||||
/* Steps to move to hallway
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
A1H = 1, A2H = 2, A3H = 3, A4H = 4
|
|
||||||
} out_t;
|
|
||||||
|
|
||||||
/* Mask which disallow moves to hallway
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
uint mask, dist;
|
|
||||||
} possible_move_t;
|
|
||||||
|
|
||||||
/* Steps to move from space outside room to hallway destination
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
AH1 = 2, AH2 = 1, AH3 = 1, AH4 = 3, AH5 = 5, AH6 = 7 , AH7 = 8,
|
|
||||||
BH1 = 4, BH2 = 3, BH3 = 1, BH4 = 1, BH5 = 3, BH6 = 5 , BH7 = 6,
|
|
||||||
CH1 = 6, CH2 = 5, CH3 = 3, CH4 = 1, CH5 = 1, CH6 = 3 , CH7 = 4,
|
|
||||||
DH1 = 8, DH2 = 7, DH3 = 5, DH4 = 3, DH5 = 1, DH6 = 1 , DH7 = 2
|
|
||||||
} steps_t;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #############
|
* #############
|
||||||
* #ab.c.d.e.fg#
|
* #ab.c.d.e.fg#
|
||||||
@@ -529,7 +569,6 @@ static pos_t *get_pos(pos_t *from)
|
|||||||
new->final = new->occupied = new->zobrist = 0;
|
new->final = new->occupied = new->zobrist = 0;
|
||||||
new->cost = new->eval = 0;
|
new->cost = new->eval = 0;
|
||||||
new->moves = 0;
|
new->moves = 0;
|
||||||
new->zobrist = 0;
|
|
||||||
} else {
|
} else {
|
||||||
*new = *from;
|
*new = *from;
|
||||||
}
|
}
|
||||||
@@ -553,12 +592,26 @@ static void free_pos(pos_t *pos)
|
|||||||
*/
|
*/
|
||||||
static void push_pos(pos_t *pos)
|
static void push_pos(pos_t *pos)
|
||||||
{
|
{
|
||||||
if (pos) {
|
pos_t *cur;
|
||||||
list_add(&pos->list, &pos_queue);
|
|
||||||
} else {
|
if (!pos) {
|
||||||
log(1, "Fatal foo\n");
|
log(1, "Fatal foo\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
if (!list_empty(&pos_queue)) {
|
||||||
|
//list_add_tail(&pos->list, &pos_queue);
|
||||||
|
//} else {
|
||||||
|
list_for_each_entry(cur, &pos_queue, list) {
|
||||||
|
if (cur->eval > pos->eval) {
|
||||||
|
log(1, "adding %lu before %lu\n", pos->eval, cur->eval);
|
||||||
|
list_add_tail(&pos->list, &cur->list);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
log(1, "not adding %lu before %lu\n", pos->eval, cur->eval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list_add_tail(&pos->list, &pos_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pop a position from stack
|
/* pop a position from stack
|
||||||
@@ -629,10 +682,6 @@ static void mask_print(u32 bits)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* generate possible moves between hallway and rooms
|
|
||||||
*/
|
|
||||||
static possible_move_t moves[24][24];
|
|
||||||
|
|
||||||
/* calculate distance and move mask for all possible moves
|
/* calculate distance and move mask for all possible moves
|
||||||
* (room -> hallway ans hallway -> room)
|
* (room -> hallway ans hallway -> room)
|
||||||
*/
|
*/
|
||||||
@@ -745,15 +794,6 @@ static pos_t *newmove(pos_t *pos, amphipod_t amp, u32 from, u32 to)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
if ((IN_HALLWAY(from) && !IN_ROOM(to)) ||
|
|
||||||
(IN_ROOM(from) && !IN_HALLWAY(to)) ||
|
|
||||||
(HALLWAY(bit_from) && !ROOM(bit_to)) ||
|
|
||||||
(ROOM(bit_from) && !HALLWAY(bit_to))) {
|
|
||||||
log(1, "BUG genmove!\n");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
zobrist = hash(&pos_tmp, amp, from, to);
|
|
||||||
//if (zobrist != zobrist_1(&pos_tmp)) {
|
//if (zobrist != zobrist_1(&pos_tmp)) {
|
||||||
// printf("Zobi Fuck1\n");
|
// printf("Zobi Fuck1\n");
|
||||||
// exit(1);
|
// exit(1);
|
||||||
@@ -763,6 +803,7 @@ static pos_t *newmove(pos_t *pos, amphipod_t amp, u32 from, u32 to)
|
|||||||
// exit(1);
|
// exit(1);
|
||||||
//}
|
//}
|
||||||
//zobrist = hash1(pos);
|
//zobrist = hash1(pos);
|
||||||
|
zobrist = hash(&pos_tmp, amp, from, to);
|
||||||
if (ok < rows * 4 - 1) { /* */
|
if (ok < rows * 4 - 1) { /* */
|
||||||
if (zobrist == HASH_SEEN) {
|
if (zobrist == HASH_SEEN) {
|
||||||
log(1, "collision, skipping move : ");
|
log(1, "collision, skipping move : ");
|
||||||
@@ -770,35 +811,10 @@ static pos_t *newmove(pos_t *pos, amphipod_t amp, u32 from, u32 to)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pos_tmp.eval = eval(&pos_tmp) + pos_tmp.cost;
|
||||||
if (!(newpos = get_pos(&pos_tmp)))
|
if (!(newpos = get_pos(&pos_tmp)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
//newpos->zobrist = zobrist;
|
|
||||||
//log(1, "Zobi6 %lu\n", newpos->zobrist);
|
|
||||||
//newpos->moves_list[newpos->moves].from = from;
|
|
||||||
//newpos->moves_list[newpos->moves].to = to;
|
|
||||||
//newpos->moves++;
|
|
||||||
//newpos->cost = newcost;
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (HALLWAY(bit_from)) {
|
|
||||||
newpos->final |= bit_to;
|
|
||||||
log(1, "Final destination %s, ok=%d, final=%s\n", cells[to],
|
|
||||||
popcount32(newpos->final), int2pos(newpos->final));
|
|
||||||
if (popcount32(newpos->final) == rows * 4) {
|
|
||||||
log(1, "found solution! cost=%lu\n", newpos->cost);
|
|
||||||
if (newpos->cost < result) {
|
|
||||||
result = newpos->cost;
|
|
||||||
log(1, "New best=%lu moves=%u List:", result, newpos->moves);
|
|
||||||
log(1, "\n");
|
|
||||||
}
|
|
||||||
free_pos(newpos);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
burrow_print_flat(newpos);
|
burrow_print_flat(newpos);
|
||||||
push_pos(newpos);
|
push_pos(newpos);
|
||||||
log(1, "New position: moves=%d cost=%lu\n", newpos->moves, newpos->cost);
|
log(1, "New position: moves=%d cost=%lu\n", newpos->moves, newpos->cost);
|
||||||
@@ -1023,6 +1039,6 @@ int main(int ac, char **av)
|
|||||||
printf("%s : res=%ld\n", *av, part == 1? part1(): part2());
|
printf("%s : res=%ld\n", *av, part == 1? part1(): part2());
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
/* for flycheck */
|
/* dummy calls for flycheck */
|
||||||
eval(pos, 1, 1, 1);
|
eval(pos);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user