first try of A* move sorting

This commit is contained in:
2022-04-05 13:20:13 +02:00
parent 49bbc2372c
commit 4dbcc30dc3

View File

@@ -60,6 +60,15 @@ typedef struct pos {
struct list_head list;
} 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 {
u64 zobrist; /* zobrist hash */
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)
{
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;
}
/* evaluate current position.
*
*
*/
static u32 eval(pos_t *pos, int amp, u32 from, u32 to)
/* evaluate current position :
* eval = cost + eval_to_dest
* cost is current cost
* eval is cost to join top of destination room
*/
static int room2room_dist[][4] = {
{ 4, 4, 6, 8}, { 4, 4, 4, 6}, { 6, 4, 4, 4}, { 8, 6, 4, 4}
};
/* static u64 eval_amp(pos_t *pos, int amp, u32 cell) */
/* { */
/* u32 bit = BIT(cell); */
/* int rows = popcount32(pos->amp[0]); */
/* int dist; */
/* int left = rows - popcount32(rooms[amp] & pos->final); */
/* if (ROOM(bit)) { /\* in a room *\/ */
/* 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)
{
log_f(1, "pos=%p amp=%d from=%u to=%u\n", pos, amp, from, to);
return 1;
}
u32 amp, tmp;
int cell;
int rows = popcount32(pos->amp[0]);
u64 eval = 0;
static char *int2bin(u32 mask)
{
static char ret[64];
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);
for (int i = 0; i < 32; ++i) {
ret[31-i] = mask & BIT(i)? '1': '0';
}
ret[32] = 0;
return ret;
}
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;
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;
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);
}
//printf("eval = %lu %lu\n", cost[amp] * dist, eval_amp(pos, amp, cell));
eval += cost[amp] * dist;
}
}
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#
@@ -529,7 +569,6 @@ static pos_t *get_pos(pos_t *from)
new->final = new->occupied = new->zobrist = 0;
new->cost = new->eval = 0;
new->moves = 0;
new->zobrist = 0;
} else {
*new = *from;
}
@@ -553,12 +592,26 @@ static void free_pos(pos_t *pos)
*/
static void push_pos(pos_t *pos)
{
if (pos) {
list_add(&pos->list, &pos_queue);
} else {
pos_t *cur;
if (!pos) {
log(1, "Fatal foo\n");
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
@@ -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
* (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)) {
// printf("Zobi Fuck1\n");
// exit(1);
@@ -763,6 +803,7 @@ static pos_t *newmove(pos_t *pos, amphipod_t amp, u32 from, u32 to)
// exit(1);
//}
//zobrist = hash1(pos);
zobrist = hash(&pos_tmp, amp, from, to);
if (ok < rows * 4 - 1) { /* */
if (zobrist == HASH_SEEN) {
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;
}
}
pos_tmp.eval = eval(&pos_tmp) + pos_tmp.cost;
if (!(newpos = get_pos(&pos_tmp)))
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);
push_pos(newpos);
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());
exit(0);
/* for flycheck */
eval(pos, 1, 1, 1);
/* dummy calls for flycheck */
eval(pos);
}