h #1

Closed
spv00 wants to merge 1 commits from fix-shit-formatting into master
3 changed files with 405 additions and 837 deletions

473
board.c
View File

@ -4,11 +4,10 @@
* Created by Gabriel Tofvesson * Created by Gabriel Tofvesson
*/ */
#include "board.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "board.h"
/** /**
* Raises an error by printing it to stderr and stopping execution * Raises an error by printing it to stderr and stopping execution
@ -19,7 +18,6 @@
abort(); \ abort(); \
} }
/** /**
* Raises an error if the given condition is not met * Raises an error if the given condition is not met
* The error will be the given reason * The error will be the given reason
@ -29,55 +27,40 @@
#else #else
#define ASSERT(cond, reason) \ #define ASSERT(cond, reason) \
{ \ { \
if (! cond) ERROR ((reason)); \ if (!cond) \
ERROR((reason)); \
} }
#endif #endif
/** /**
* Check if a given xy-pair is in bounds of a Sudoku board * Check if a given xy-pair is in bounds of a Sudoku board
*/ */
static inline bool static inline bool is_in_bounds(board_pos x, board_pos y) {
is_in_bounds (board_pos x, board_pos y)
{
#ifdef OPTIMIZE #ifdef OPTIMIZE
return true; return true;
#else #else
return x >= 0 && return x >= 0 && x < 9 && y >= 0 && y < 9;
x < 9 &&
y >= 0 &&
y < 9 ;
#endif #endif
} }
/** /**
* Check if a given element value is within acceptable bounds * Check if a given element value is within acceptable bounds
*/ */
static inline bool static inline bool is_valid_value(element_value value) {
is_valid_value (element_value value)
{
#ifdef OPTIMIZE #ifdef OPTIMIZE
return true; return true;
#else #else
return value >= 0 && return value >= 0 && value < 9;
value < 9 ;
#endif #endif
} }
void meta_init(struct metadata *meta) {
void
meta_init (struct metadata *meta)
{
memset(meta, 0, sizeof(struct metadata)); memset(meta, 0, sizeof(struct metadata));
} }
void board_make_links(struct board *board) {
void
board_make_links (struct board *board)
{
for (board_pos y = 0; y < 9; ++y) for (board_pos y = 0; y < 9; ++y)
for (board_pos x = 0; x < 9; ++x) for (board_pos x = 0; x < 9; ++x) {
{
unsigned pos = ELEM_POS(x, y); unsigned pos = ELEM_POS(x, y);
unsigned link_count = -1; unsigned link_count = -1;
@ -98,84 +81,60 @@ board_make_links (struct board *board)
for (board_pos lqy = 0; lqy < 3; ++lqy) for (board_pos lqy = 0; lqy < 3; ++lqy)
for (board_pos lqx = 0; lqx < 3; ++lqx) for (board_pos lqx = 0; lqx < 3; ++lqx)
if ((lqx + qx) != x && (lqy + qy) != y) if ((lqx + qx) != x && (lqy + qy) != y)
board->links[pos][++link_count] = BOARD_ELEM (board, lqx + qx, lqy + qy); board->links[pos][++link_count] =
BOARD_ELEM(board, lqx + qx, lqy + qy);
} }
} }
void board_init(struct board *board) {
void
board_init (struct board *board)
{
struct board_element defval; struct board_element defval;
defval.has_value = false; defval.has_value = false;
defval.potential = 0x1FF; defval.potential = 0x1FF;
defval.complexity = 9; defval.complexity = 9;
for (board_pos y = 0; y < 9; ++y) for (board_pos y = 0; y < 9; ++y)
for (board_pos x = 0; x < 9; ++x) for (board_pos x = 0; x < 9; ++x) {
{
struct board_element *elem = BOARD_ELEM(board, x, y); struct board_element *elem = BOARD_ELEM(board, x, y);
/* Set default state */ /* Set default state */
memcpy(elem, &defval, sizeof(struct board_element)); memcpy(elem, &defval, sizeof(struct board_element));
} }
board_make_links(board); board_make_links(board);
board->complexity = 9; board->complexity = 9;
for (unsigned i = 0; i < 9; ++i) for (unsigned i = 0; i < 9; ++i) {
{
meta_init(&board->meta_quad[i]); meta_init(&board->meta_quad[i]);
meta_init(&board->meta_row[i]); meta_init(&board->meta_row[i]);
meta_init(&board->meta_col[i]); meta_init(&board->meta_col[i]);
} }
} }
bool meta_has_value(const struct metadata *meta, element_value value) {
bool
meta_has_value (const struct metadata *meta, element_value value)
{
return ((meta->marked >> value) & 1) == 1; return ((meta->marked >> value) & 1) == 1;
} }
void meta_set_value(struct metadata *meta, element_value value) {
void
meta_set_value (struct metadata *meta, element_value value)
{
meta->marked |= 1 << value; meta->marked |= 1 << value;
} }
void meta_clear_values(struct metadata *meta) { meta->marked = 0; }
void static inline void meta_mark(struct metadata *meta, element_value value,
meta_clear_values (struct metadata *meta) unsigned index) {
{
meta->marked = 0;
}
static inline void
meta_mark (struct metadata *meta, element_value value, unsigned index)
{
meta_set_value(meta, value); meta_set_value(meta, value);
unsigned char count = meta->unique[value].count; unsigned char count = meta->unique[value].count;
if (count == 0) if (count == 0) {
{
meta->unique[value].count = 1; meta->unique[value].count = 1;
meta->unique[value].index = index; meta->unique[value].index = index;
} } else {
else
{
meta->unique[value].count = 2; meta->unique[value].count = 2;
} }
} }
void board_meta_quad_refresh(struct board *board, board_pos qx, board_pos qy) {
void
board_meta_quad_refresh (struct board *board, board_pos qx, board_pos qy)
{
struct metadata *meta = BOARD_QUAD(board, qx * 3, qy * 3); struct metadata *meta = BOARD_QUAD(board, qx * 3, qy * 3);
board_pos quad_base_x = qx * 3; board_pos quad_base_x = qx * 3;
board_pos quad_base_y = qy * 3; board_pos quad_base_y = qy * 3;
@ -183,8 +142,7 @@ board_meta_quad_refresh (struct board *board, board_pos qx, board_pos qy)
meta_clear_values(meta); meta_clear_values(meta);
for (board_pos off_y = 0; off_y < 3; ++off_y) for (board_pos off_y = 0; off_y < 3; ++off_y)
for (board_pos off_x = 0; off_x < 3; ++off_x) for (board_pos off_x = 0; off_x < 3; ++off_x) {
{
struct board_element *elem = struct board_element *elem =
BOARD_ELEM(board, quad_base_x + off_x, quad_base_y + off_y); BOARD_ELEM(board, quad_base_x + off_x, quad_base_y + off_y);
@ -193,16 +151,12 @@ board_meta_quad_refresh (struct board *board, board_pos qx, board_pos qy)
} }
} }
void board_meta_row_refresh(struct board *board, board_pos y) {
void
board_meta_row_refresh (struct board *board, board_pos y)
{
struct metadata *meta = BOARD_ROW(board, y); struct metadata *meta = BOARD_ROW(board, y);
meta_clear_values(meta); meta_clear_values(meta);
for (board_pos x = 0; x < 9; ++x) for (board_pos x = 0; x < 9; ++x) {
{
struct board_element *elem = BOARD_ELEM(board, x, y); struct board_element *elem = BOARD_ELEM(board, x, y);
if (elem->has_value) if (elem->has_value)
@ -210,16 +164,12 @@ board_meta_row_refresh (struct board *board, board_pos y)
} }
} }
void board_meta_col_refresh(struct board *board, board_pos x) {
void
board_meta_col_refresh (struct board *board, board_pos x)
{
struct metadata *meta = BOARD_COL(board, x); struct metadata *meta = BOARD_COL(board, x);
meta_clear_values(meta); meta_clear_values(meta);
for (board_pos y = 0; y < 9; ++y) for (board_pos y = 0; y < 9; ++y) {
{
struct board_element *elem = BOARD_ELEM(board, x, y); struct board_element *elem = BOARD_ELEM(board, x, y);
if (elem->has_value) if (elem->has_value)
@ -227,106 +177,56 @@ board_meta_col_refresh (struct board *board, board_pos x)
} }
} }
bool board_meta_can_set(const struct board *board, board_pos x, board_pos y,
bool element_value value) {
board_meta_can_set ( if (is_in_bounds(x, y) && is_valid_value(value)) {
const struct board *board, return !(meta_has_value(BOARD_ROW(board, y), value) ||
board_pos x,
board_pos y,
element_value value
)
{
if (is_in_bounds (x, y) && is_valid_value (value))
{
return ! (
meta_has_value (BOARD_ROW (board, y), value) ||
meta_has_value(BOARD_COL(board, x), value) || meta_has_value(BOARD_COL(board, x), value) ||
meta_has_value (BOARD_QUAD (board, x, y), value) meta_has_value(BOARD_QUAD(board, x, y), value));
); } else
} ERROR("Invalid parameters to function board_meta_can_set()");
else ERROR("Invalid parameters to function board_meta_can_set()");
} }
void board_set(struct board *board, board_pos x, board_pos y,
void element_value value) {
board_set ( if (is_in_bounds(x, y) && is_valid_value(value)) {
struct board *board, ASSERT(board_meta_can_set(board, x, y, value),
board_pos x, "Attempt to set impossible value on board");
board_pos y,
element_value value
)
{
if (is_in_bounds (x, y) && is_valid_value (value))
{
ASSERT (
board_meta_can_set (board, x, y, value),
"Attempt to set impossible value on board"
);
struct board_element *elem = BOARD_ELEM(board, x, y); struct board_element *elem = BOARD_ELEM(board, x, y);
elem->has_value = true; elem->has_value = true;
elem->value = value; elem->value = value;
} } else
else ERROR("Invalid parameters to function board_set()"); ERROR("Invalid parameters to function board_set()");
} }
void board_mark(struct board *board, board_pos x, board_pos y,
void element_value value) {
board_mark ( if (is_in_bounds(x, y) && is_valid_value(value)) {
struct board *board, ASSERT(!board_has_value(board, x, y), "Attempt to mark element with value");
board_pos x,
board_pos y,
element_value value
)
{
if (is_in_bounds (x, y) && is_valid_value (value))
{
ASSERT (
! board_has_value (board, x, y),
"Attempt to mark element with value"
);
struct board_element *elem = BOARD_ELEM(board, x, y); struct board_element *elem = BOARD_ELEM(board, x, y);
if (! board_is_marked (board, x, y, value)) if (!board_is_marked(board, x, y, value)) {
{
elem->potential |= 1 << value; elem->potential |= 1 << value;
++(elem->complexity); ++(elem->complexity);
} }
} } else
else ERROR("Invalid parameters to function board_mark()"); ERROR("Invalid parameters to function board_mark()");
} }
bool board_unmark(struct board *board, board_pos x, board_pos y,
bool element_value value) {
board_unmark ( if (is_in_bounds(x, y) && is_valid_value(value)) {
struct board *board, ASSERT(!board_has_value(board, x, y), "Attempt to mark element with value");
board_pos x,
board_pos y,
element_value value
)
{
if (is_in_bounds (x, y) && is_valid_value (value))
{
ASSERT (
! board_has_value (board, x, y),
"Attempt to mark element with value"
);
return elem_unmark(BOARD_ELEM(board, x, y), value); return elem_unmark(BOARD_ELEM(board, x, y), value);
} } else
else ERROR("Invalid parameters to function board_unmark()"); ERROR("Invalid parameters to function board_unmark()");
} }
bool elem_unmark(struct board_element *elem, element_value value) {
bool if (elem_is_marked(elem, value)) {
elem_unmark (
struct board_element *elem,
element_value value
)
{
if (elem_is_marked (elem, value))
{
/* Shift bit to correct place and then invert first 9 bits */ /* Shift bit to correct place and then invert first 9 bits */
elem->potential ^= (1 << value); elem->potential ^= (1 << value);
--(elem->complexity); --(elem->complexity);
@ -335,86 +235,44 @@ elem_unmark (
return elem->potential != 0; return elem->potential != 0;
} }
bool board_has_value(const struct board *board, board_pos x, board_pos y) {
bool if (is_in_bounds(x, y)) {
board_has_value (
const struct board *board,
board_pos x,
board_pos y
)
{
if (is_in_bounds (x, y))
{
return BOARD_ELEM(board, x, y)->has_value; return BOARD_ELEM(board, x, y)->has_value;
} } else
else ERROR("Invalid parameters to function board_has_value()"); ERROR("Invalid parameters to function board_has_value()");
} }
element_value board_get_value(const struct board *board, board_pos x,
element_value board_pos y) {
board_get_value ( if (is_in_bounds(x, y)) {
const struct board *board,
board_pos x,
board_pos y
)
{
if (is_in_bounds (x, y))
{
return BOARD_ELEM(board, x, y)->value; return BOARD_ELEM(board, x, y)->value;
} } else
else ERROR("Invalid parameters to function board_get_value()"); ERROR("Invalid parameters to function board_get_value()");
} }
bool board_is_marked(const struct board *board, board_pos x, board_pos y,
bool element_value value) {
board_is_marked ( if (is_in_bounds(x, y) && is_valid_value(value)) {
const struct board *board,
board_pos x,
board_pos y,
element_value value
)
{
if (is_in_bounds (x, y) && is_valid_value (value))
{
return elem_is_marked(BOARD_ELEM(board, x, y), value); return elem_is_marked(BOARD_ELEM(board, x, y), value);
} } else
else ERROR("Invalid parameters to function board_is_marked()"); ERROR("Invalid parameters to function board_is_marked()");
} }
bool elem_is_marked(const struct board_element *elem, element_value value) {
bool
elem_is_marked (
const struct board_element *elem,
element_value value
)
{
return elem->potential & (1 << value); return elem->potential & (1 << value);
} }
bool board_is_valid(struct board *board) {
bool
board_is_valid (struct board *board)
{
for (board_pos y = 0; y < 9; ++y) for (board_pos y = 0; y < 9; ++y)
for (board_pos x = 0; x < 9; ++x) for (board_pos x = 0; x < 9; ++x)
if ( if (!board_has_value(board, x, y) &&
!board_has_value (board, x, y) && BOARD_ELEM(board, x, y)->potential == 0)
BOARD_ELEM (board, x, y)->potential == 0
)
return false; return false;
return true; return true;
} }
void board_update_marks(struct board *board, board_pos x, board_pos y) {
void if (is_in_bounds(x, y)) {
board_update_marks (
struct board *board,
board_pos x,
board_pos y
)
{
if (is_in_bounds (x, y))
{
struct board_element *elem = BOARD_ELEM(board, x, y); struct board_element *elem = BOARD_ELEM(board, x, y);
/* Mark all values as impossible */ /* Mark all values as impossible */
@ -431,27 +289,18 @@ board_update_marks (
/* Count marked bits */ /* Count marked bits */
unsigned short potential = elem->potential; unsigned short potential = elem->potential;
while (potential != 0) while (potential != 0) {
{
if ((potential & 1) == 1) if ((potential & 1) == 1)
++(elem->complexity); ++(elem->complexity);
potential >>= 1; potential >>= 1;
} }
} } else
else ERROR("Invalid parameters to function board_update_marks()"); ERROR("Invalid parameters to function board_update_marks()");
} }
bool board_can_quad_set_value(struct board *board, board_pos x, board_pos y,
bool element_value value) {
board_can_quad_set_value ( if (is_in_bounds(x, y) && is_valid_value(value)) {
struct board *board,
board_pos x,
board_pos y,
element_value value
)
{
if (is_in_bounds (x, y) && is_valid_value (value))
{
/* Compute quadrant bases */ /* Compute quadrant bases */
board_pos quad_x = TO_QUAD(x); board_pos quad_x = TO_QUAD(x);
board_pos quad_y = TO_QUAD(y); board_pos quad_y = TO_QUAD(y);
@ -460,36 +309,25 @@ board_can_quad_set_value (
board_pos simp_x = x % 3; board_pos simp_x = x % 3;
board_pos simp_y = y % 3; board_pos simp_y = y % 3;
bool next = false; bool next = false;
/* Check along x-axis */ /* Check along x-axis */
for (board_pos base_x = 0; base_x < 9; base_x += 3) for (board_pos base_x = 0; base_x < 9; base_x += 3) {
{
next = false; next = false;
if (base_x != quad_x) if (base_x != quad_x) {
{
for (board_pos check_y = 0; check_y < 3 && !next; ++check_y) for (board_pos check_y = 0; check_y < 3 && !next; ++check_y)
if (check_y != simp_y) if (check_y != simp_y)
for (board_pos check_x = 0; check_x < 3 && ! next; ++check_x) for (board_pos check_x = 0; check_x < 3 && !next; ++check_x) {
{
board_pos target_x = base_x + check_x; board_pos target_x = base_x + check_x;
board_pos target_y = quad_y + check_y; board_pos target_y = quad_y + check_y;
bool has_value = board_has_value(board, target_x, target_y); bool has_value = board_has_value(board, target_x, target_y);
/* Check if a quadrant can contain the given value */ /* Check if a quadrant can contain the given value */
if ( if ((has_value &&
( BOARD_ELEM(board, target_x, target_y)->value == value) ||
has_value && (!has_value &&
BOARD_ELEM (board, target_x, target_y)->value == value board_is_marked(board, target_x, target_y, value))) {
) ||
(
! has_value &&
board_is_marked (board, target_x, target_y, value)
)
)
{
next = true; next = true;
break; break;
} }
@ -500,32 +338,22 @@ board_can_quad_set_value (
} }
/* Check along y-axis */ /* Check along y-axis */
for (board_pos base_y = 0; base_y < 9; base_y += 3) for (board_pos base_y = 0; base_y < 9; base_y += 3) {
{
next = false; next = false;
if (base_y != quad_y) if (base_y != quad_y) {
{
for (board_pos check_x = 0; check_x < 3 && !next; ++check_x) for (board_pos check_x = 0; check_x < 3 && !next; ++check_x)
if (check_x != simp_x) if (check_x != simp_x)
for (board_pos check_y = 0; check_y < 3 && ! next; ++check_y) for (board_pos check_y = 0; check_y < 3 && !next; ++check_y) {
{
board_pos target_x = quad_x + check_x; board_pos target_x = quad_x + check_x;
board_pos target_y = base_y + check_y; board_pos target_y = base_y + check_y;
bool has_value = board_has_value(board, target_x, target_y); bool has_value = board_has_value(board, target_x, target_y);
/* Check if a quadrant can contain the given value */ /* Check if a quadrant can contain the given value */
if ( if ((has_value &&
( BOARD_ELEM(board, target_x, target_y)->value == value) ||
has_value && (!has_value &&
BOARD_ELEM (board, target_x, target_y)->value == value board_is_marked(board, target_x, target_y, value))) {
) ||
(
! has_value &&
board_is_marked (board, target_x, target_y, value)
)
)
{
next = true; next = true;
break; break;
} }
@ -536,64 +364,42 @@ board_can_quad_set_value (
} }
return true; return true;
} } else
else ERROR("Invalid parameters to function board_can_quad_set_value()"); ERROR("Invalid parameters to function board_can_quad_set_value()");
} }
static inline bool field_is_potential(unsigned short field,
static inline bool element_value value) {
field_is_potential (unsigned short field, element_value value)
{
return ((field >> (value * 2)) & 3) < 2; return ((field >> (value * 2)) & 3) < 2;
} }
static inline void field_invalidate(unsigned short *field,
static inline void element_value value) {
field_invalidate (unsigned short *field, element_value value)
{
*field |= 2 << (value * 2); *field |= 2 << (value * 2);
} }
static inline void field_increment(unsigned short *field, element_value value) {
static inline void
field_increment (unsigned short *field, element_value value)
{
if (field_is_potential(*field, value)) if (field_is_potential(*field, value))
*field += (1 << (value * 2)); *field += (1 << (value * 2));
} }
void board_update_all_marks(struct board *board) {
void
board_update_all_marks (struct board *board)
{
for (board_pos y = 0; y < 9; ++y) for (board_pos y = 0; y < 9; ++y)
for (board_pos x = 0; x < 9; ++x) for (board_pos x = 0; x < 9; ++x)
if (!board_has_value(board, x, y)) if (!board_has_value(board, x, y))
board_update_marks(board, x, y); board_update_marks(board, x, y);
} }
bool board_place(struct board *board, board_pos x, board_pos y,
bool element_value value) {
board_place ( if (is_in_bounds(x, y) && is_valid_value(value)) {
struct board *board, if (board_meta_can_set(board, x, y, value)) {
board_pos x,
board_pos y,
element_value value
)
{
if (is_in_bounds (x, y) && is_valid_value (value))
{
if (board_meta_can_set (board, x, y, value))
{
unsigned pos = ELEM_POS(x, y); unsigned pos = ELEM_POS(x, y);
/* Unmark all adjacent elements */ /* Unmark all adjacent elements */
for (unsigned i = 0; i < 20; ++i) for (unsigned i = 0; i < 20; ++i)
if ( if (!board->links[pos][i]->has_value &&
! board->links[pos][i]->has_value && !elem_unmark(board->links[pos][i], value)) {
! elem_unmark (board->links[pos][i], value)
)
{
/* Unmarking potential caused element to have no potential */ /* Unmarking potential caused element to have no potential */
return false; return false;
} }
@ -607,27 +413,19 @@ board_place (
meta_set_value(BOARD_COL(board, x), value); meta_set_value(BOARD_COL(board, x), value);
return true; return true;
} } else
else return false; return false;
} } else
else ERROR("Invalid parameters to function board_place()"); ERROR("Invalid parameters to function board_place()");
} }
struct board *board_place_speculative(const struct board *board,
struct board *
board_place_speculative (
const struct board *board,
struct board *board_duplicate, struct board *board_duplicate,
board_pos x, board_pos x, board_pos y,
board_pos y, element_value value) {
element_value value if (is_in_bounds(x, y) && is_valid_value(value)) {
)
{
if (is_in_bounds (x, y) && is_valid_value (value))
{
/* Ensure value can be placed*/ /* Ensure value can be placed*/
if (board_meta_can_set (board, x, y, value)) if (board_meta_can_set(board, x, y, value)) {
{
/* Create duplicate and place value */ /* Create duplicate and place value */
board_copy(board, board_duplicate); board_copy(board, board_duplicate);
@ -637,24 +435,19 @@ board_place_speculative (
board_refresh_complexity(board_duplicate); board_refresh_complexity(board_duplicate);
return board_duplicate; return board_duplicate;
} } else
else return NULL; return NULL;
} } else
else ERROR("Invalid parameters to function board_place_speculative()"); ERROR("Invalid parameters to function board_place_speculative()");
} }
bool board_refresh_complexity(struct board *board) {
bool
board_refresh_complexity (struct board *board)
{
board->complexity = 10; board->complexity = 10;
for (board_pos y = 0; y < 9; ++y) for (board_pos y = 0; y < 9; ++y)
for (board_pos x = 0; x < 9; ++x) for (board_pos x = 0; x < 9; ++x)
if (! board_has_value (board, x, y)) if (!board_has_value(board, x, y)) {
{
struct board_element *elem = BOARD_ELEM(board, x, y); struct board_element *elem = BOARD_ELEM(board, x, y);
if (elem->complexity < board->complexity) if (elem->complexity < board->complexity) {
{
/* If complexity is somehow 0, we have an invalid board state */ /* If complexity is somehow 0, we have an invalid board state */
if (elem->complexity == 0) if (elem->complexity == 0)
return false; return false;
@ -674,14 +467,8 @@ board_refresh_complexity (struct board *board)
return true; return true;
} }
void board_copy(const struct board *board_from, struct board *board_to) {
void
board_copy (const struct board *board_from, struct board *board_to)
{
/* Copy everything except the links */ /* Copy everything except the links */
memcpy ( memcpy(board_to, board_from,
board_to, sizeof(struct board) - sizeof(((struct board *)0)->links));
board_from,
sizeof(struct board) - sizeof (((struct board *)0)->links)
);
} }

170
board.h
View File

@ -6,7 +6,6 @@
#include <stdbool.h> #include <stdbool.h>
#define ELEM_POS(x, y) (((y)*9) + (x)) #define ELEM_POS(x, y) (((y)*9) + (x))
/** /**
@ -17,7 +16,8 @@
/** /**
* Get a `struct metadata`-entry from a specified location on the quadrand grid * Get a `struct metadata`-entry from a specified location on the quadrand grid
*/ */
#define BOARD_QUAD(board_ptr, x, y) (&(board_ptr)->meta_quad[TO_QUAD ((y)) + ((x) / 3)]) #define BOARD_QUAD(board_ptr, x, y) \
(&(board_ptr)->meta_quad[TO_QUAD((y)) + ((x) / 3)])
/** /**
* Get a `struct metadata`-entry from a specified row value * Get a `struct metadata`-entry from a specified row value
@ -29,7 +29,6 @@
*/ */
#define BOARD_COL(board_ptr, x) (&(board_ptr)->meta_col[(x)]) #define BOARD_COL(board_ptr, x) (&(board_ptr)->meta_col[(x)])
/** /**
* Convert any valid board position to a quadrant base position (lowest index) * Convert any valid board position to a quadrant base position (lowest index)
*/ */
@ -82,212 +81,133 @@ struct board {
struct metadata meta_row[9]; /* Row metadata */ struct metadata meta_row[9]; /* Row metadata */
struct metadata meta_col[9]; /* Column metadata */ struct metadata meta_col[9]; /* Column metadata */
struct board_element
struct board_element *links [81][20];/* All "connected", "adjacent" elements */ *links[81][20]; /* All "connected", "adjacent" elements */
}; };
/** /**
* Initialize metadata to a blank state * Initialize metadata to a blank state
*/ */
void void meta_init(struct metadata *meta);
meta_init (struct metadata *meta);
/* /*
* Just generate board element adjacency links * Just generate board element adjacency links
*/ */
void void board_make_links(struct board *board);
board_make_links (struct board *board);
/** /**
* Initialize a board to a blank state with maximum complexity * Initialize a board to a blank state with maximum complexity
*/ */
void void board_init(struct board *board);
board_init (struct board *board);
/** /**
* Check if a metadata structure has marked a given value * Check if a metadata structure has marked a given value
*/ */
bool bool meta_has_value(const struct metadata *meta, element_value value);
meta_has_value (const struct metadata *meta, element_value value);
/** /**
* Set value as marked for the given metadata structure * Set value as marked for the given metadata structure
*/ */
void void meta_set_value(struct metadata *meta, element_value value);
meta_set_value (struct metadata *meta, element_value value);
/** /**
* Clear all marked values for the given metadata structure * Clear all marked values for the given metadata structure
*/ */
void void meta_clear_values(struct metadata *meta);
meta_clear_values (struct metadata *meta);
/** /**
* Refresh metadata for a given quadrant * Refresh metadata for a given quadrant
*/ */
void void board_meta_quad_refresh(struct board *board, board_pos qx, board_pos qy);
board_meta_quad_refresh (struct board *board, board_pos qx, board_pos qy);
/** /**
* Refresh metadata for a given row * Refresh metadata for a given row
*/ */
void void board_meta_row_refresh(struct board *board, board_pos y);
board_meta_row_refresh (struct board *board, board_pos y);
/** /**
* Refresh metadata for a given column * Refresh metadata for a given column
*/ */
void void board_meta_col_refresh(struct board *board, board_pos x);
board_meta_col_refresh (struct board *board, board_pos x);
/** /**
* Check if a value can be set at a given position on the board based on * Check if a value can be set at a given position on the board based on
* analysing the metadata structures of `board` * analysing the metadata structures of `board`
*/ */
bool bool board_meta_can_set(const struct board *board, board_pos x, board_pos y,
board_meta_can_set ( element_value value);
const struct board *board,
board_pos x,
board_pos y,
element_value value
);
/** /**
* Set the value of an element on the board * Set the value of an element on the board
* *
* NOTE: This marks an element as having a decided value * NOTE: This marks an element as having a decided value
*/ */
void void board_set(struct board *board, board_pos x, board_pos y,
board_set ( element_value value);
struct board *board,
board_pos x,
board_pos y,
element_value value
);
/** /**
* Mark a potential value of an element on the board * Mark a potential value of an element on the board
* *
* NOTE: Marking an element with a decided value is undefined * NOTE: Marking an element with a decided value is undefined
*/ */
void void board_mark(struct board *board, board_pos x, board_pos y,
board_mark ( element_value value);
struct board *board,
board_pos x,
board_pos y,
element_value value
);
/** /**
* Removes a marking of a potential value of an element on the board * Removes a marking of a potential value of an element on the board
* *
* NOTE: Unmarking an element with a decied value is undefined * NOTE: Unmarking an element with a decied value is undefined
*/ */
bool bool board_unmark(struct board *board, board_pos x, board_pos y,
board_unmark ( element_value value);
struct board *board,
board_pos x,
board_pos y,
element_value value
);
/** /**
* Removes a marking of a potential value of an element * Removes a marking of a potential value of an element
*/ */
bool bool elem_unmark(struct board_element *elem, element_value value);
elem_unmark (
struct board_element *elem,
element_value value
);
/** /**
* Get whether or not an element has a decided value * Get whether or not an element has a decided value
*/ */
bool bool board_has_value(const struct board *board, board_pos x, board_pos y);
board_has_value (
const struct board *board,
board_pos x,
board_pos y
);
/** /**
* Get definite value of a board element * Get definite value of a board element
* *
* NOTE: Getting the definite value of an element without a value is undefined * NOTE: Getting the definite value of an element without a value is undefined
*/ */
element_value element_value board_get_value(const struct board *board, board_pos x,
board_get_value ( board_pos y);
const struct board *board,
board_pos x,
board_pos y
);
/** /**
* Get whether or not a board element is marked with a particular value * Get whether or not a board element is marked with a particular value
* *
* NOTE: Getting the mark state of an element with a value is undefined * NOTE: Getting the mark state of an element with a value is undefined
*/ */
bool bool board_is_marked(const struct board *board, board_pos x, board_pos y,
board_is_marked ( element_value value);
const struct board *board,
board_pos x,
board_pos y,
element_value value
);
/** /**
* Get whether or not a given element is marked with a particular value * Get whether or not a given element is marked with a particular value
*/ */
bool bool elem_is_marked(const struct board_element *elem, element_value value);
elem_is_marked (
const struct board_element *elem,
element_value value
);
/** /**
* Checks if there are any pairs of board elements that share a value and * Checks if there are any pairs of board elements that share a value and
* also share either a row or a column * also share either a row or a column
*/ */
bool bool board_is_valid(struct board *board);
board_is_valid (struct board *board);
/** /**
* Check row and column of given position and mark potential values that could * Check row and column of given position and mark potential values that could
* be set at that position and still leave the board in a valid state * be set at that position and still leave the board in a valid state
*/ */
void void board_update_marks(struct board *board, board_pos x, board_pos y);
board_update_marks (
struct board *board,
board_pos x,
board_pos y
);
/** /**
* Refreshes marks of all board elements without a value * Refreshes marks of all board elements without a value
*/ */
void void board_update_all_marks(struct board *board);
board_update_all_marks (struct board *board);
/** /**
* Attempt to set value at the given position * Attempt to set value at the given position
@ -296,14 +216,8 @@ board_update_all_marks (struct board *board);
* the addition of this value and returns true * the addition of this value and returns true
* If value cannot be placed, just return false * If value cannot be placed, just return false
*/ */
bool bool board_place(struct board *board, board_pos x, board_pos y,
board_place ( element_value value);
struct board *board,
board_pos x,
board_pos y,
element_value value
);
/** /**
* Place a speculative value. This allocates a duplicate board with the element * Place a speculative value. This allocates a duplicate board with the element
@ -312,26 +226,18 @@ board_place (
* *
* NOTE: If element cannot be placed, this returns NULL * NOTE: If element cannot be placed, this returns NULL
*/ */
struct board * struct board *board_place_speculative(const struct board *board,
board_place_speculative (
const struct board *board,
struct board *board_duplicate, struct board *board_duplicate,
board_pos x, board_pos x, board_pos y,
board_pos y, element_value value);
element_value value
);
/** /**
* Recomputes board complexity by searching all elements on board for the * Recomputes board complexity by searching all elements on board for the
* lowest complexity * lowest complexity
*/ */
bool bool board_refresh_complexity(struct board *board);
board_refresh_complexity (struct board *board);
/** /**
* Copy a board layout to another board * Copy a board layout to another board
*/ */
void void board_copy(const struct board *board_from, struct board *board_to);
board_copy (const struct board *board_from, struct board *board_to);

283
main.c
View File

@ -1,3 +1,4 @@
#include "board.h"
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
@ -6,8 +7,6 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include "board.h"
/** /**
* ANSI control codes * ANSI control codes
@ -16,7 +15,6 @@
#define COLOUR_RESET "\e[0m" #define COLOUR_RESET "\e[0m"
#define CLEAR "\033[2J" #define CLEAR "\033[2J"
/** /**
* How many boards to allocate by default for board spec * How many boards to allocate by default for board spec
* Average depth for highly complex boards is between 10 and 12 * Average depth for highly complex boards is between 10 and 12
@ -29,26 +27,20 @@
*/ */
#define DEPTH_INCREMENT 3 #define DEPTH_INCREMENT 3
struct args { struct args {
bool valid; bool valid;
unsigned verbosity : 2; unsigned verbosity : 2;
char *file_name; char *file_name;
}; };
struct boards_table { struct boards_table {
struct board **board_specs; struct board **board_specs;
unsigned long long max_depth; unsigned long long max_depth;
}; };
void tables_ensure_depth(struct boards_table *board_spec,
void unsigned long long depth) {
tables_ensure_depth (struct boards_table *board_spec, unsigned long long depth) if (board_spec->max_depth <= depth) {
{
if (board_spec->max_depth <= depth)
{
/* Compute new max depth */ /* Compute new max depth */
unsigned long long new_max; unsigned long long new_max;
if (board_spec->max_depth == 0) if (board_spec->max_depth == 0)
@ -57,14 +49,11 @@ tables_ensure_depth (struct boards_table *board_spec, unsigned long long depth)
new_max = board_spec->max_depth + DEPTH_INCREMENT; new_max = board_spec->max_depth + DEPTH_INCREMENT;
/* Disregard NULL return value. What's it gonna do, segfault? :P */ /* Disregard NULL return value. What's it gonna do, segfault? :P */
board_spec->board_specs = realloc ( board_spec->board_specs =
board_spec->board_specs, realloc(board_spec->board_specs, sizeof(struct board *) * new_max);
sizeof (struct board *) * new_max
);
/* Allocate boards */ /* Allocate boards */
for (unsigned long long l = board_spec->max_depth; l < new_max; ++l) for (unsigned long long l = board_spec->max_depth; l < new_max; ++l) {
{
board_spec->board_specs[l] = malloc(sizeof(struct board)); board_spec->board_specs[l] = malloc(sizeof(struct board));
board_make_links(board_spec->board_specs[l]); board_make_links(board_spec->board_specs[l]);
} }
@ -74,42 +63,26 @@ tables_ensure_depth (struct boards_table *board_spec, unsigned long long depth)
} }
} }
bool bool simplify(struct boards_table *board_spec, unsigned long long depth,
simplify ( unsigned long long *counter, unsigned verbosity);
struct boards_table *board_spec,
unsigned long long depth,
unsigned long long *counter,
unsigned verbosity
);
struct board_file {
struct board_file
{
int fd; int fd;
void *data; void *data;
}; };
/** /**
* Determines if the given char is a valid character for defining * Determines if the given char is a valid character for defining
* a board element * a board element
*/ */
static inline bool static inline bool is_valid_def(char def) {
is_valid_def (char def) return def == ' ' || (def >= '0' && def <= '9');
{
return def == ' ' ||
(
def >= '0' &&
def <= '9'
);
} }
/** /**
* Load a board-definition file and return file descriptor * Load a board-definition file and return file descriptor
*/ */
static struct board_file static struct board_file load_board_file(const char *path) {
load_board_file (const char *path)
{
struct board_file file; struct board_file file;
file.fd = -1; file.fd = -1;
file.data = NULL; file.data = NULL;
@ -121,8 +94,7 @@ load_board_file (const char *path)
/* Map 89 bytes of file to memory */ /* Map 89 bytes of file to memory */
void *region = mmap(NULL, 89, PROT_READ, MAP_SHARED, fd, 0); void *region = mmap(NULL, 89, PROT_READ, MAP_SHARED, fd, 0);
if (region == (void*)-1) if (region == (void *)-1) {
{
close(fd); close(fd);
return file; return file;
} }
@ -134,8 +106,7 @@ load_board_file (const char *path)
*/ */
char *data = region; char *data = region;
for (unsigned i = 1; i <= 89; ++i) for (unsigned i = 1; i <= 89; ++i)
if (!((i % 10) == 0) && !is_valid_def (data[i - 1])) if (!((i % 10) == 0) && !is_valid_def(data[i - 1])) {
{
munmap(region, 89); munmap(region, 89);
close(fd); close(fd);
return file; return file;
@ -151,23 +122,18 @@ load_board_file (const char *path)
/** /**
* Free all resources linked to an opened board definition file * Free all resources linked to an opened board definition file
*/ */
static void static void close_board_file(struct board_file file) {
close_board_file (struct board_file file)
{
close(file.fd); close(file.fd);
munmap(file.data, 89); munmap(file.data, 89);
} }
static void static void copy_to_board(struct board_file file, struct board *board) {
copy_to_board (struct board_file file, struct board *board)
{
// Clear board // Clear board
board_init(board); board_init(board);
char *data = file.data; char *data = file.data;
for (unsigned i = 1; i <= 89; ++i) for (unsigned i = 1; i <= 89; ++i)
if ((i % 10) != 0) if ((i % 10) != 0) {
{
board_pos x = i % 10; board_pos x = i % 10;
board_pos y = i / 10; board_pos y = i / 10;
@ -176,44 +142,25 @@ copy_to_board (struct board_file file, struct board *board)
} }
} }
static void ansi_set_cursor(unsigned y, unsigned x) {
static void
ansi_set_cursor (unsigned y, unsigned x)
{
printf("\033[%u;%uH", x + 1, y + 1); printf("\033[%u;%uH", x + 1, y + 1);
} }
static void ansi_clear_screen() { puts(CLEAR); }
static void void ansi_cursor_show(bool show) {
ansi_clear_screen ()
{
puts (CLEAR);
}
void
ansi_cursor_show (bool show)
{
if (show) if (show)
fputs("\e[?25h", stdout); fputs("\e[?25h", stdout);
else else
fputs("\e[?25l", stdout); fputs("\e[?25l", stdout);
} }
static void static void print_board_verbose(const struct board *board, unsigned whence_x,
print_board_verbose ( unsigned whence_y) {
const struct board *board, for (board_pos y = 0; y < 9; ++y) {
unsigned whence_x, for (board_pos x = 0; x < 9; ++x) {
unsigned whence_y
)
{
for (board_pos y = 0; y < 9; ++y)
{
for (board_pos x = 0; x < 9; ++x)
{
for (element_value vy = 0; vy < 3; ++vy) for (element_value vy = 0; vy < 3; ++vy)
for (element_value vx = 0; vx < 3; ++vx) for (element_value vx = 0; vx < 3; ++vx) {
{
element_value check = vx + (vy * 3); element_value check = vx + (vy * 3);
ansi_set_cursor(whence_x + (x * 4) + vx, whence_y + (y * 4) + vy); ansi_set_cursor(whence_x + (x * 4) + vx, whence_y + (y * 4) + vy);
@ -231,8 +178,7 @@ print_board_verbose (
} }
ansi_set_cursor(0, (y * 4) + 3); ansi_set_cursor(0, (y * 4) + 3);
if (y != 8) if (y != 8) {
{
for (unsigned i = 0; i < (4 * 9) - 1; ++i) for (unsigned i = 0; i < (4 * 9) - 1; ++i)
if ((i + 1) % 4 == 0) if ((i + 1) % 4 == 0)
fputs("+", stdout); fputs("+", stdout);
@ -244,26 +190,21 @@ print_board_verbose (
fflush(stdout); fflush(stdout);
} }
static void print_board(const struct board *board, const struct board *compare,
static void unsigned whence_x, unsigned whence_y) {
print_board (const struct board *board, const struct board *compare, unsigned whence_x, unsigned whence_y) for (board_pos y = 0; y < 9; ++y) {
{
for (board_pos y = 0; y < 9; ++y)
{
/* Print row */ /* Print row */
for (board_pos x = 0; x < 9; ++x) for (board_pos x = 0; x < 9; ++x) {
{
ansi_set_cursor(whence_x + (x * 2), whence_y + (y * 2)); ansi_set_cursor(whence_x + (x * 2), whence_y + (y * 2));
/* Print board element */ /* Print board element */
if (board_has_value (board, x, y)) if (board_has_value(board, x, y)) {
{
if (compare != NULL && !board_has_value(compare, x, y)) if (compare != NULL && !board_has_value(compare, x, y))
printf (COLOUR_RED "%u" COLOUR_RESET, board_get_value (board, x, y) + 1); printf(COLOUR_RED "%u" COLOUR_RESET,
board_get_value(board, x, y) + 1);
else else
printf("%u", board_get_value(board, x, y) + 1); printf("%u", board_get_value(board, x, y) + 1);
} } else
else
fputs(" ", stdout); fputs(" ", stdout);
/* Print column element delimiter */ /* Print column element delimiter */
@ -272,10 +213,8 @@ print_board (const struct board *board, const struct board *compare, unsigned wh
} }
/* Print row element delimiter */ /* Print row element delimiter */
if (y < 8) if (y < 8) {
{ for (board_pos x = 0; x < 17; ++x) {
for (board_pos x = 0; x < 17; ++x)
{
ansi_set_cursor(whence_x + x, whence_y + (y * 2 + 1)); ansi_set_cursor(whence_x + x, whence_y + (y * 2 + 1));
if ((x & 1) == 0) if ((x & 1) == 0)
fputs("-", stdout); fputs("-", stdout);
@ -286,16 +225,13 @@ print_board (const struct board *board, const struct board *compare, unsigned wh
} }
} }
/** /**
* Compute first potential value of a given element * Compute first potential value of a given element
*/ */
element_value element_value first_potential_value(struct board_element *element,
first_potential_value (struct board_element *element, struct board *board, bool *error) struct board *board, bool *error) {
{
unsigned short potential = element->potential; unsigned short potential = element->potential;
if (potential == 0) if (potential == 0) {
{
*error = true; *error = true;
return 0; return 0;
} }
@ -303,8 +239,7 @@ first_potential_value (struct board_element *element, struct board *board, bool
*error = false; *error = false;
element_value value = 0; element_value value = 0;
while (potential != 0) while (potential != 0) {
{
if ((potential & 1) == 1) if ((potential & 1) == 1)
return value; return value;
++value; ++value;
@ -315,34 +250,22 @@ first_potential_value (struct board_element *element, struct board *board, bool
abort(); abort();
} }
/** /**
* Reduce away all elements on board with complexity=1 until none remain * Reduce away all elements on board with complexity=1 until none remain
*/ */
#ifdef NOVERB #ifdef NOVERB
bool bool simplify(struct boards_table *board_specs, unsigned long long depth)
simplify (
struct boards_table *board_specs,
unsigned long long depth
)
#else #else
bool bool simplify(struct boards_table *board_specs, unsigned long long depth,
simplify ( unsigned long long *counter, unsigned verbosity)
struct boards_table *board_specs,
unsigned long long depth,
unsigned long long *counter,
unsigned verbosity
)
#endif #endif
{ {
/* Get current table */ /* Get current table */
struct board *board = board_specs->board_specs[depth]; struct board *board = board_specs->board_specs[depth];
#ifndef NOVERB #ifndef NOVERB
if (verbosity > 0) if (verbosity > 0) {
{ if (((*counter) & (0xFFFF >> (4 * (4 - verbosity)))) == 0) {
if (((*counter) & (0xFFFF >> (4 * (4 - verbosity)))) == 0)
{
print_board_verbose(board, 0, 0); print_board_verbose(board, 0, 0);
ansi_set_cursor(0, 35); ansi_set_cursor(0, 35);
printf("Iteration: %llu", *counter); printf("Iteration: %llu", *counter);
@ -351,23 +274,20 @@ simplify (
} }
#endif #endif
bool error; bool error;
unsigned count = 0; unsigned count = 0;
/* Reduce using low-complexity computation */ /* Reduce using low-complexity computation */
while (board->complexity == 1) while (board->complexity == 1) {
{
for (board_pos y = 0; y < 9; ++y) for (board_pos y = 0; y < 9; ++y)
for (board_pos x = 0; x < 9; ++x) for (board_pos x = 0; x < 9; ++x)
if (! board_has_value (board, x, y)) if (!board_has_value(board, x, y)) {
{
struct board_element *elem = BOARD_ELEM(board, x, y); struct board_element *elem = BOARD_ELEM(board, x, y);
if (elem->complexity == 1) if (elem->complexity == 1) {
{
element_value value = first_potential_value(elem, board, &error); element_value value = first_potential_value(elem, board, &error);
if (error) return false; if (error)
return false;
++count; ++count;
@ -380,35 +300,21 @@ simplify (
} }
/* Attempt to reduce with speculative placement */ /* Attempt to reduce with speculative placement */
if (board->complexity > 1) if (board->complexity > 1) {
{
for (board_pos y = 0; y < 9; ++y) for (board_pos y = 0; y < 9; ++y)
for (board_pos x = 0; x < 9; ++x) for (board_pos x = 0; x < 9; ++x) {
{
struct board_element *elem = BOARD_ELEM(board, x, y); struct board_element *elem = BOARD_ELEM(board, x, y);
/* Find a simplest element on the board */ /* Find a simplest element on the board */
if ( if (!elem->has_value && elem->complexity == board->complexity)
! elem->has_value && for (element_value value = 0; value < 9; ++value) {
elem->complexity == board->complexity
)
for (element_value value = 0; value < 9; ++value)
{
/* Try speculative placement of each potential value and recurse */ /* Try speculative placement of each potential value and recurse */
tables_ensure_depth(board_specs, depth + 1); tables_ensure_depth(board_specs, depth + 1);
if (elem_is_marked (elem, value)) if (elem_is_marked(elem, value)) {
{ struct board *board_spec = board_place_speculative(
struct board *board_spec = board, board_specs->board_specs[depth + 1], x, y, value);
board_place_speculative (
board,
board_specs->board_specs[depth + 1],
x,
y,
value
);
/* If speculative placement failed, try another value */ /* If speculative placement failed, try another value */
if (board_spec == NULL) if (board_spec == NULL) {
{
if (!elem_unmark(elem, value)) if (!elem_unmark(elem, value))
return false; return false;
continue; continue;
@ -418,26 +324,16 @@ simplify (
if ( if (
#ifdef NOVERB #ifdef NOVERB
simplify ( simplify(board_specs, depth + 1) &&
board_specs,
depth + 1
) &&
#else #else
simplify ( simplify(board_specs, depth + 1, counter, verbosity) &&
board_specs,
depth + 1,
counter,
verbosity
) &&
#endif #endif
board_spec->complexity == 0) board_spec->complexity == 0) {
{
board_copy(board_spec, board); board_copy(board_spec, board);
x = 9; x = 9;
y = 9; y = 9;
value = 9; value = 9;
} } else if (!elem_unmark(elem, value))
else if (! elem_unmark (elem, value))
return false; return false;
} }
} }
@ -446,25 +342,19 @@ simplify (
return true; return true;
} }
struct args argparse(int argc, char **argv) {
struct args
argparse (int argc, char **argv)
{
struct args result; struct args result;
result.file_name = NULL; result.file_name = NULL;
result.valid = true; result.valid = true;
result.verbosity = 0; result.verbosity = 0;
if (argc < 2) if (argc < 2) {
{
result.valid = false; result.valid = false;
return result; return result;
} }
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
if (strncmp (argv[i], "-", 1) == 0) if (strncmp(argv[i], "-", 1) == 0) {
{ if (result.verbosity != 0) {
if (result.verbosity != 0)
{
result.valid = false; result.valid = false;
return result; return result;
} }
@ -472,31 +362,24 @@ argparse (int argc, char **argv)
result.verbosity = 1; result.verbosity = 1;
else if (strcmp(argv[i], "-vv") == 0) else if (strcmp(argv[i], "-vv") == 0)
result.verbosity = 2; result.verbosity = 2;
else else {
{
result.valid = false; result.valid = false;
return result; return result;
} }
} } else if (result.file_name == NULL)
else if (result.file_name == NULL)
result.file_name = argv[i]; result.file_name = argv[i];
else else {
{
result.valid = false; result.valid = false;
return result; return result;
} }
return result; return result;
} }
int main(int argc, char **argv, char **env) {
int
main (int argc, char **argv, char **env)
{
struct args args = argparse(argc, argv); struct args args = argparse(argc, argv);
if (! args.valid) if (!args.valid) {
{ fputs("Badly formatted arguments! Usage:\n\t./sudoku [-v[v]] {file name}\n",
fputs ("Badly formatted arguments! Usage:\n\t./sudoku [-v[v]] {file name}\n", stderr); stderr);
return 1; return 1;
} }
@ -521,12 +404,9 @@ main (int argc, char **argv, char **env)
close_board_file(file); close_board_file(file);
ansi_clear_screen(); ansi_clear_screen();
if (! board_is_valid (root_board)) if (!board_is_valid(root_board)) {
{
fputs("Supplied board is not valid!\n", stderr); fputs("Supplied board is not valid!\n", stderr);
ansi_cursor_show(true); ansi_cursor_show(true);
@ -534,11 +414,9 @@ main (int argc, char **argv, char **env)
return 1; return 1;
} }
if (args.verbosity == 0) if (args.verbosity == 0)
puts("Simplifying..."); puts("Simplifying...");
board_refresh_complexity(root_board); board_refresh_complexity(root_board);
/* Profiler start time */ /* Profiler start time */
@ -553,19 +431,16 @@ main (int argc, char **argv, char **env)
ansi_clear_screen(); ansi_clear_screen();
if (root_board->complexity == 0) if (root_board->complexity == 0) {
{
print_board(&original, NULL, 0, 0); print_board(&original, NULL, 0, 0);
print_board(root_board, &original, 21, 0); print_board(root_board, &original, 21, 0);
ansi_set_cursor(0, 18); ansi_set_cursor(0, 18);
} } else {
else
{
print_board_verbose(root_board, 0, 0); print_board_verbose(root_board, 0, 0);
ansi_set_cursor(0, 36); ansi_set_cursor(0, 36);
} }
printf ("Simplification took %Lf seconds\n", ((long double)(end_clk - start_clk))/CLOCKS_PER_SEC); printf("Simplification took %Lf seconds\n",
((long double)(end_clk - start_clk)) / CLOCKS_PER_SEC);
ansi_cursor_show(true); ansi_cursor_show(true);