HW3: refactor complete
This commit is contained in:
parent
8b59fedabd
commit
1e1a51c9f6
1 changed files with 38 additions and 83 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue