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 <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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue