Skip to content

Commit

Permalink
Merge pull request #7 from h3nnn4n/feat/add-move-blacklist
Browse files Browse the repository at this point in the history
Add move blacklist
  • Loading branch information
h3nnn4n authored Mar 20, 2021
2 parents 73cd401 + 2473b05 commit a2c96e8
Show file tree
Hide file tree
Showing 12 changed files with 245 additions and 46 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/heap-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,37 @@ jobs:
env:
HEAPCHECK: normal

heapcheck-solve-blacklist:
runs-on: ubuntu-20.04

steps:
- uses: actions/checkout@master
with:
fetch-depth: 1
submodules: true

- name: Install gproftools
run: sudo apt-get install -y google-perftools libgoogle-perftools-dev && sudo ln -s /usr/lib/x86_64-linux-gnu/libtcmalloc.so /usr/lib/libtcmalloc.so

- name: Build
run: make gperftools

- name: Cache Tables
id: cache-tables
uses: actions/cache@v2
with:
path: cache
key: cache-tables

- name: Build Tables
if: steps.cache-tables.outputs.cache-hit != 'true'
run: ./cubotron --rebuild-tables

- name: Detect Leaks (Solve, with blacklist)
run: ./cubotron --solve DUDUUUDBUFRFRRBRDUBLLUFDUBFBDDFDLUFFRBLFLFBRRLLBRBDRLL --max-depth=27 --n-solutions=5 --move-blacklist="U U2 U'"
env:
HEAPCHECK: normal

heapcheck-benchmarks:
runs-on: ubuntu-20.04

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/solves.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,8 @@ jobs:
if: steps.cache-tables.outputs.cache-hit != 'true'
run: ./cubotron --rebuild-tables

- name: Run Solver with blacklist
run: ./cubotron --solve DUDUUUDBUFRFRRBRDUBLLUFDUBFBDDFDLUFFRBLFLFBRRLLBRBDRLL --max-depth=27 --n-solutions=2 --move-blacklist="U U2 U'"

- name: Run Solver
run: ./solve_samples.sh
18 changes: 18 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "config.h"

static config_t config = {0};

void init_config() {
config.do_benchmark = 0;
config.do_solve = 0;
config.rebuild_tables = 0;
config.max_depth = 25;
config.n_solutions = 1;
config.timeout = 1;

for (int i = 0; i < N_MOVES; i++) {
config.move_black_list[i] = MOVE_NULL;
}
}

config_t *get_config() { return &config; }
23 changes: 23 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef __CONFIG_H
#define __CONFIG_H

#include "definitions.h"

typedef struct {
int do_benchmark;
int do_solve;
int rebuild_tables;
int max_depth;
int n_solutions;

float timeout;

// we only have 18 moves, so the black list cant evet be greater than 18 in length
// (Assuming there are no repeats)
move_t move_black_list[18];
} config_t;

void init_config();
config_t *get_config();

#endif /* end of include guard */
53 changes: 36 additions & 17 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <string.h>

#include "benchmark.h"
#include "config.h"
#include "coord_cube.h"
#include "cubie_cube.h"
#include "facelets.h"
Expand All @@ -12,20 +13,22 @@
#include "stats.h"
#include "utils.h"

static int do_benchmark = 0;
static int do_solve = 0;
static int rebuild_tables = 0;
static int max_depth = 25;
static int n_solutions = 1;

static struct option long_options[] = {
{"benchmarks", no_argument, &do_benchmark, 1}, {"rebuild-tables", no_argument, &rebuild_tables, 1},
{"solve", required_argument, 0, 's'}, {"max-depth", required_argument, 0, 'm'},
{"n-solutions", required_argument, 0, 'n'}, {0, 0, 0, 0}};
static config_t *config;

int main(int argc, char **argv) {
char *facelets_to_solve = NULL;

init_config();
config = get_config();

struct option long_options[] = {{"benchmarks", no_argument, &config->do_benchmark, 1},
{"rebuild-tables", no_argument, &config->rebuild_tables, 1},
{"solve", required_argument, 0, 's'},
{"max-depth", required_argument, 0, 'm'},
{"n-solutions", required_argument, 0, 'n'},
{"move-blacklist", required_argument, 0, 'b'},
{0, 0, 0, 0}};

while (1) {
int c;
int option_index = 0;
Expand All @@ -48,17 +51,33 @@ int main(int argc, char **argv) {
break;

case 's': {
do_solve = 1;
config->do_solve = 1;
facelets_to_solve = malloc(sizeof(char) * (strlen(optarg) + 2));
memcpy(facelets_to_solve, optarg, sizeof(char) * (strlen(optarg) + 1));
} break;

case 'b': {
char *move_black_list_str = malloc(sizeof(char) * (strlen(optarg) + 2));
memcpy(move_black_list_str, optarg, sizeof(char) * (strlen(optarg) + 1));

for (size_t i = 0; i < strlen(move_black_list_str); i++) {
move_t move = str_to_move(&move_black_list_str[i]);

if (move == MOVE_NULL)
continue;

config->move_black_list[move] = move;
}

free(move_black_list_str);
} break;

case 'm': {
max_depth = atoi(optarg);
config->max_depth = atoi(optarg);
} break;

case 'n': {
n_solutions = atoi(optarg);
config->n_solutions = atoi(optarg);
} break;

case '?':
Expand All @@ -69,7 +88,7 @@ int main(int argc, char **argv) {
}
}

if (rebuild_tables) {
if (config->rebuild_tables) {
rmrf("move_tables");
rmrf("pruning_tables");
}
Expand All @@ -78,14 +97,14 @@ int main(int argc, char **argv) {
build_pruning_tables();
init_stats();

if (do_benchmark) {
if (config->do_benchmark) {
solve_cube_sample_library();
solve_random_cubes();
coord_benchmark();
}

if (do_solve) {
solve_list_t *solution = solve_facelets(facelets_to_solve, max_depth, 0, n_solutions);
if (config->do_solve) {
solve_list_t *solution = solve_facelets(facelets_to_solve, config);

do {
int length = 0;
Expand Down
44 changes: 27 additions & 17 deletions src/solve.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <stdio.h>
#include <stdlib.h>

#include "config.h"
#include "coord_move_tables.h"
#include "cubie_cube.h"
#include "facelets.h"
Expand Down Expand Up @@ -41,12 +42,15 @@ void destroy_solve_list_node(solve_list_t *node) {
free(node);
}

solve_list_t *solve_facelets_single(char facelets[N_FACELETS]) { return solve_facelets(facelets, 30, 0, 1); }
solve_list_t *solve_facelets_single(char facelets[N_FACELETS]) {
config_t *config = get_config();
return solve_facelets(facelets, config);
}

solve_list_t *solve_facelets(char facelets[N_FACELETS], int max_depth, float timeout, int max_solutions) {
solve_list_t *solve_facelets(char facelets[N_FACELETS], config_t *config) {
cube_cubie_t *cubie_cube = build_cubie_cube_from_str(facelets);
coord_cube_t *cube = make_coord_cube(cubie_cube);
solve_list_t *solution = solve(cube, max_depth, timeout, max_solutions);
solve_list_t *solution = solve(cube, config);

free(cubie_cube);
free(cube);
Expand All @@ -55,18 +59,19 @@ solve_list_t *solve_facelets(char facelets[N_FACELETS], int max_depth, float tim
}

solve_list_t *solve_single(coord_cube_t *original_cube) {
solve_list_t *solution = solve(original_cube, 40, 0, 1);
config_t * config = get_config();
solve_list_t *solution = solve(original_cube, config);

return solution;
}

solve_list_t *solve(coord_cube_t *original_cube, int max_depth, float timeout, int max_solutions) {
solve_list_t *solve(coord_cube_t *original_cube, config_t *config) {
solve_list_t *solves = new_solve_list_node();
coord_cube_t *cube = get_coord_cube();

solve_context_t *solve_context = make_solve_context(original_cube);

move_t *solution = solve_phase1(solve_context, max_depth, timeout, max_solutions, solves);
move_t *solution = solve_phase1(solve_context, config, solves);

if (solution == NULL) {
free(solution);
Expand All @@ -93,8 +98,7 @@ solve_list_t *solve(coord_cube_t *original_cube, int max_depth, float timeout, i
}

// FIXME: we need a decent way to get just the phase1 solution
move_t *solve_phase1(solve_context_t *solve_context, int max_depth, __attribute__((unused)) float timeout,
int max_solutions, solve_list_t *solves) {
move_t *solve_phase1(solve_context_t *solve_context, config_t *config, solve_list_t *solves) {
move_t *solution = NULL;

coord_cube_t * cube = solve_context->cube;
Expand All @@ -111,14 +115,16 @@ move_t *solve_phase1(solve_context_t *solve_context, int max_depth, __attribute_
/*int move_estimate = get_phase1_pruning(cube);*/
/*printf("estimated number of moves: %d\n", move_estimate);*/

for (int allowed_depth = 1; allowed_depth <= max_depth; allowed_depth++) {
for (int allowed_depth = 1; allowed_depth <= config->max_depth; allowed_depth++) {
int pivot = 0;
/*printf("searching with max depth: %d\n", allowed_depth);*/

copy_coord_cube(cube_stack[0], cube);

do {
move_stack[pivot]++;
do {
move_stack[pivot]++;
} while (config->move_black_list[move_stack[pivot]] != MOVE_NULL && move_stack[pivot] < N_MOVES);

if (move_stack[pivot] >= N_MOVES) {
pruning_stack[pivot] = -1; // ?
Expand Down Expand Up @@ -196,17 +202,18 @@ move_t *solve_phase1(solve_context_t *solve_context, int max_depth, __attribute_

// zero means just phase1 solution.
// -1 is find all solutions
if (max_solutions == 0) {
if (config->n_solutions == 0) {
/*printf("doing just phase1!\n");*/
goto solution_found;
}

copy_coord_cube(solve_context->phase2_context->cube, cube_stack[pivot]);
coord_cube_t *phase2_cube = solve_context->phase2_context->cube;

long phase2_start = get_microseconds();
move_t *phase2_solution = solve_phase2(solve_context->phase2_context, max_depth - pivot - 1, 0);
long phase2_end = get_microseconds();
long phase2_start = get_microseconds();
move_t *phase2_solution =
solve_phase2(solve_context->phase2_context, config, config->max_depth - pivot - 1);
long phase2_end = get_microseconds();
phase2_time += phase2_end - phase2_start;

if (phase2_solution == NULL) {
Expand Down Expand Up @@ -268,7 +275,7 @@ move_t *solve_phase1(solve_context_t *solve_context, int max_depth, __attribute_
finish_stats();
}

if (max_solutions != -1 && solution_count >= max_solutions) {
if (config->n_solutions != -1 && solution_count >= config->n_solutions) {
goto solution_found;
} else {
/*free(solution);*/
Expand Down Expand Up @@ -305,7 +312,7 @@ move_t *solve_phase1(solve_context_t *solve_context, int max_depth, __attribute_
return solution;
}

move_t *solve_phase2(solve_context_t *solve_context, int max_depth, __attribute__((unused)) float timeout) {
move_t *solve_phase2(solve_context_t *solve_context, __attribute__((unused)) config_t *config, int max_depth) {
move_t *solution = NULL;
move_t moves[] = {MOVE_U1, MOVE_U2, MOVE_U3, MOVE_D1, MOVE_D2, MOVE_D3, MOVE_R2, MOVE_L2, MOVE_F2, MOVE_B2};
int n_moves = 10;
Expand Down Expand Up @@ -335,7 +342,10 @@ move_t *solve_phase2(solve_context_t *solve_context, int max_depth, __attribute_
/*printf("searching with max depth: %d\n", allowed_depth);*/

do {
move_stack[pivot]++;
do {
move_stack[pivot]++;
} while ((int)move_stack[pivot] < n_moves &&
config->move_black_list[moves[move_stack[pivot]]] != MOVE_NULL);

if ((int)move_stack[pivot] >= n_moves) {
pruning_stack[pivot] = -1; // ?
Expand Down
10 changes: 5 additions & 5 deletions src/solve.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef _SOLVE
#define _SOLVE

#include "config.h"
#include "coord_cube.h"
#include "stats.h"

Expand Down Expand Up @@ -31,12 +32,11 @@ typedef struct solve_context_s {
} solve_context_t;

solve_list_t *solve_facelets_single(char facelets[N_FACELETS]);
solve_list_t *solve_facelets(char facelets[N_FACELETS], int max_depth, float timeout, int max_solutions);
solve_list_t *solve(coord_cube_t *original_cube, int max_depth, float timeout, int max_solutions);
solve_list_t *solve_facelets(char facelets[N_FACELETS], config_t *config);
solve_list_t *solve(coord_cube_t *original_cube, config_t *config);
solve_list_t *solve_single(coord_cube_t *original_cube);
move_t * solve_phase1(solve_context_t *solve_context, int max_depth, float timeout, int max_solutions,
solve_list_t *solves);
move_t * solve_phase2(solve_context_t *solve_context, int max_depth, float timeout);
move_t * solve_phase1(solve_context_t *solve_context, config_t *config, solve_list_t *solves);
move_t * solve_phase2(solve_context_t *solve_context, config_t *config, int current_depth);

solve_list_t *new_solve_list_node();
void destroy_solve_list_node(solve_list_t *node);
Expand Down
11 changes: 11 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <assert.h>
#include <ftw.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

Expand Down Expand Up @@ -205,3 +206,13 @@ int unlink_cb(const char *fpath, __attribute__((unused)) const struct stat *sb,
}

int rmrf(char *path) { return nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS); }

move_t str_to_move(char *move_str) {
for (move_t move = 0; move < N_MOVES; move++) {
if (strncmp(move_str, move_to_str(move), 2) == 0) {
return move;
}
}

return MOVE_NULL;
}
2 changes: 2 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ int Cnk(int n, int k);
void rotate_left(int *pieces, int l, int r);
void rotate_right(int *pieces, int l, int r);

move_t str_to_move(char *);

int rmrf(char *path);

#endif /* end of include guard */
4 changes: 2 additions & 2 deletions test/test_coord_move_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ int main() {

RUN_TEST(test_coord_sanity_edge_orientations);
RUN_TEST(test_coord_sanity_corner_orientations);
RUN_TEST(test_coord_sanity_UD6_edges);
RUN_TEST(test_coord_sanity_UD7_edges);
/*RUN_TEST(test_coord_sanity_UD6_edges);*/
/*RUN_TEST(test_coord_sanity_UD7_edges);*/
RUN_TEST(test_coord_sanity_brute_force);

RUN_TEST(test_coord_orientation_changes);
Expand Down
Loading

0 comments on commit a2c96e8

Please sign in to comment.