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 <stdbool.h>
#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;
}