HW3: refactor complete

This commit is contained in:
Claudio Maggioni 2019-12-13 09:23:45 +01:00
parent 8b59fedabd
commit 1e1a51c9f6

View file

@ -17,6 +17,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#define DEBUG 0
#if DEBUG #if DEBUG
char* NAMES[] = { "KING", "QUEEN", "ROOK", "BISHOP", "KNIGHT", "PAWN" }; 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) { unsigned row) {
return (value_at(c, col, row) ^ (('C'|'a') << 24 | ('r'|'z') << 16 | return (value_at(c, col, row) ^ (('C'|'a') << 24 | ('r'|'z') << 16 |
('a'|'n') << 8 | ('i'|'g'|'a'))) ('a'|'n') << 8 | ('i'|'g'|'a')))
% table_total_size(c); % table_total_size(c);
} }
visit_table* table_new(const struct chessboard* 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) { 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->found = true;
s->column = column; s->column = column;
s->row = row; 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 BISHOP: bishop_positions(s, p); break;
case QUEEN: queen_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, unsigned int path_len(const struct chessboard* c,
@ -266,7 +271,6 @@ unsigned int path_len(const struct chessboard* c,
visit_table* table) { visit_table* table) {
unsigned int hops = 0; unsigned int hops = 0;
bool has_next = true;
#if DEBUG #if DEBUG
printf("board r=%u c=%u\n", rows(c), columns(c)); 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; struct search_status status;
search_status_init(&status, p, better, c, table); search_status_init(&status, p, better, c, table);
while (has_next) { while (true) {
status.found = false;
consider_positions(&status, p); 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->column = status.column;
p->row = status.row; p->row = status.row;
if (status.table != NULL) {
table_visit(c, table, p->column, p->row);
}
#if DEBUG #if DEBUG
print_p_position(p); print_p_position(p);
#endif #endif
@ -288,106 +306,43 @@ unsigned int path_len(const struct chessboard* c,
hops++; hops++;
} }
return hops - 1; return hops;
} }
bool better_inc(struct search_status* s, unsigned column, unsigned row) { bool better_inc(struct search_status* s, unsigned column, unsigned row) {
return value_at(s->chessboard, s->column, s->row) > return value_at(s->chessboard, column, row) >
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) { bool better_dec(struct search_status* s, unsigned column, unsigned row) {
return value_at(s->chessboard, s->column, s->row) < return value_at(s->chessboard, column, row) <
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) { bool better_simple(struct search_status* s, unsigned column, unsigned row) {
return !table_visited(s->chessboard, s->table, column, row) && return !table_visited(s->chessboard, s->table, column, row) &&
(!s->found || (value_at(s->chessboard, s->column, s->row) > (!s->found || value_at(s->chessboard, column, row) >
value_at(s->chessboard, column, row))); value_at(s->chessboard, s->column, s->row));
} }
unsigned int increasing_path_len(const struct chessboard* c, unsigned int increasing_path_len(const struct chessboard* c,
struct piece_position* p) { struct piece_position* p) {
return path_len(c, p, better_inc, NULL);
} }
unsigned int decreasing_path_len(const struct chessboard* c, unsigned int decreasing_path_len(const struct chessboard* c,
struct piece_position* p) { struct piece_position* p) {
return path_len(c, p, better_dec, NULL);
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;
} }
unsigned int simple_path_len(const struct chessboard* c, unsigned int simple_path_len(const struct chessboard* c,
struct piece_position* p) { struct piece_position* p) {
visit_table* v = table_new(c); visit_table* v = table_new(c);
table_visit(c, v, p->column, p->row); table_visit(c, v, p->column, p->row);
#if DEBUG unsigned int len = path_len(c, p, better_simple, v);
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++;
}
table_destroy(c, v); table_destroy(c, v);
return hops - 1; return len;
} }