diff --git a/chess_paths/chess_paths.c b/chess_paths/chess_paths.c index 181545b..5670a20 100644 --- a/chess_paths/chess_paths.c +++ b/chess_paths/chess_paths.c @@ -17,6 +17,8 @@ #include #include +#define DEBUG 0 + #if DEBUG char* NAMES[] = { "KING", "QUEEN", "ROOK", "BISHOP", "KNIGHT", "PAWN" }; @@ -61,7 +63,7 @@ inline unsigned long table_hash(const struct chessboard* c, unsigned col, unsigned row) { return (value_at(c, col, row) ^ (('C'|'a') << 24 | ('r'|'z') << 16 | ('a'|'n') << 8 | ('i'|'g'|'a'))) - % table_total_size(c); + % table_total_size(c); } visit_table* table_new(const struct chessboard* c) { @@ -154,7 +156,13 @@ void search_status_init(struct search_status* s, struct piece_position* p, */ void consider(struct search_status* s, unsigned column, unsigned row) { - if (s->better(s, column, row)) { + const bool b = s->better(s, column, row); + +#if DEBUG + printf("consider c=%u r=%u better=%u\n", column, row, b); +#endif + + if (b) { s->found = true; s->column = column; s->row = row; @@ -255,9 +263,6 @@ void consider_positions(struct search_status* s, struct piece_position* p) { case BISHOP: bishop_positions(s, p); break; case QUEEN: queen_positions(s, p); break; } -#if DEBUG - print_poss(poss, p); -#endif } unsigned int path_len(const struct chessboard* c, @@ -266,7 +271,6 @@ unsigned int path_len(const struct chessboard* c, visit_table* table) { unsigned int hops = 0; - bool has_next = true; #if DEBUG printf("board r=%u c=%u\n", rows(c), columns(c)); @@ -275,12 +279,26 @@ unsigned int path_len(const struct chessboard* c, struct search_status status; search_status_init(&status, p, better, c, table); - while (has_next) { + while (true) { + status.found = false; consider_positions(&status, p); - has_next = status.found; + +#if DEBUG + printf("consideration c=%u r=%u\n", status.column, status.row); + print_p_position(p); +#endif + + if (status.column == p->column && status.row == p->row) { + break; + } + p->column = status.column; p->row = status.row; + if (status.table != NULL) { + table_visit(c, table, p->column, p->row); + } + #if DEBUG print_p_position(p); #endif @@ -288,106 +306,43 @@ unsigned int path_len(const struct chessboard* c, hops++; } - return hops - 1; + return hops; } bool better_inc(struct search_status* s, unsigned column, unsigned row) { - return value_at(s->chessboard, s->column, s->row) > - value_at(s->chessboard, column, row); + return value_at(s->chessboard, column, row) > + value_at(s->chessboard, s->column, s->row); } bool better_dec(struct search_status* s, unsigned column, unsigned row) { - return value_at(s->chessboard, s->column, s->row) < - value_at(s->chessboard, column, row); + return value_at(s->chessboard, column, row) < + value_at(s->chessboard, s->column, s->row); } bool better_simple(struct search_status* s, unsigned column, unsigned row) { return !table_visited(s->chessboard, s->table, column, row) && - (!s->found || (value_at(s->chessboard, s->column, s->row) > - value_at(s->chessboard, column, row))); + (!s->found || value_at(s->chessboard, column, row) > + value_at(s->chessboard, s->column, s->row)); } unsigned int increasing_path_len(const struct chessboard* c, struct piece_position* p) { - + return path_len(c, p, better_inc, NULL); } unsigned int decreasing_path_len(const struct chessboard* c, struct piece_position* p) { - - unsigned int hops = 0; - bool has_next = true; - -#if DEBUG - puts("decreasing"); - printf("board r=%u c=%u\n", rows(c), columns(c)); -#endif - - struct search_status status; - search_status_init(&status, p, better_inc, c, NULL); - - while (has_next) { - consider_positions(&status, p); - has_next = status.found; - p->column = status.column; - p->row = status.row; - -#if DEBUG - print_p_position(p); -#endif - - hops++; - } - - return hops - 1; + return path_len(c, p, better_dec, NULL); } + unsigned int simple_path_len(const struct chessboard* c, struct piece_position* p) { - visit_table* v = table_new(c); table_visit(c, v, p->column, p->row); -#if DEBUG - print_visited(c, v); -#endif - - bool has_next = true; - unsigned hops = 0; - - while(has_next) { - struct position* poss = get_positions(c, p); - has_next = false; - unsigned int base_v = 0, next_v; - -#if DEBUG - puts("simple"); - print_p_position(p); -#endif - - while(poss != NULL) { - if (!table_visited(c, v, poss->column, poss->row)) { - next_v = value_at(c, poss->column, poss->row); - if (!has_next || next_v > base_v) { - has_next = true; - p->row = poss->row; - p->column = poss->column; - base_v = next_v; - } - } - struct position* del = poss; - poss = poss->next; - free(del); - } - - table_visit(c, v, p->column, p->row); -#if DEBUG - print_visited(c, v); -#endif - hops++; - } + unsigned int len = path_len(c, p, better_simple, v); table_destroy(c, v); - return hops - 1; + return len; } -