static void search_done(position_t* pos, move_t move) { //FIXME: enter critical section if (!ModeAnalyze && InGame && move != MOVE_NONE) { position_move(pos, move); position_print(pos, C_WHITE); send_line("move %s", move_format(move)); } }
void loop_xboard(void) { position_t* pos = position_new(); color_t engineColor = C_BLACK; IF.info_depth = info_depth; IF.info_pv = info_pv; IF.info_curmove = info_curmove; IF.search_done = search_done; log_set_mode(MODE_GUI); log_line("xboard mode"); threads_init(pos); while (1) { char* line = get_line(); char* token = arg_start(line); if (!strcmp(token, "new")) { position_reset(pos); TT_clear(); engineColor = C_BLACK; InGame = 1; } else if (!strcmp(token, "quit")) { InGame = 0; threads_search_stop(); break; } else if (!strcmp(token, "protover")) { char* v = arg_next(); if (v && atoi(v) == 2) { send_line("feature myname=\"Walce\""); send_line("feature setboard=1 usermove=1 sigint=0 sigterm=0"); send_line("feature playother=1 ping=1 time=1 colors=0 name=1"); send_line("feature ics=1 analyze=1"); send_line("feature option=\"Search Depth -spin %d 0 20\"", 0); send_line("feature option=\"Thinking Time -spin %d 0 600000\"", 0); send_line("feature done=1"); } } else if (!strcmp(token, "random") || !strcmp(token, "bk") || !strcmp(token, "ics") || !strcmp(token, "name") || !strcmp(token, "accepted") || !strcmp(token, "computer") ) { ; // IGNORE } else if (!strcmp(token, "variant") || !strcmp(token, "rejected") || !strcmp(token, "draw") || !strcmp(token, "hint") || !strcmp(token, "hard") || !strcmp(token, "easy") || !strcmp(token, "rating") || !strcmp(token, "pause") || !strcmp(token, "resume") || !strcmp(token, "memory") || !strcmp(token, "cores") || !strcmp(token, "egtpath") ) { send_line("Error (not implemented yet): %s", token); } else if (!strcmp(token, "?")) { threads_search_stop(); } else if (!strcmp(token, "st")) { token = arg_next(); if (token) TC.l_time = atoi(token) * 1000; } else if (!strcmp(token, "level")) { char* moves = arg_next(); char* min = arg_next(); char* inc = arg_next(); char* sec = min ? strchr(min, ':') : NULL; if (sec) *sec++ = 0; if (inc) { int t = atoi(min) * 60 + (sec ? atoi(sec) : 0); TC.togo = atoi(moves); TC.ctime[0] = TC.otime[0] = t * 1000; TC.ctime[1] = TC.otime[1] = atoi(inc) * 1000; } } else if (!strcmp(token, "time")) { token = arg_next(); if (token) TC.ctime[0] = atoi(token) * 10; } else if (!strcmp(token, "otim")) { token = arg_next(); if (token) TC.otime[0] = atoi(token) * 10; } else if (!strcmp(token, "analyze")) { ModeAnalyze = 1; TC.infinite = 1; engineColor = pos->to_move; threads_search(); } else if (ModeAnalyze && !strcmp(token, "exit")) { threads_search_stop(); ModeAnalyze = 0; TC.infinite = 0; } else if (ModeAnalyze && !strcmp(token, ".")) { //send_line("Error (not implemented yet): %s", token); } else if (!strncmp(line, "result", 6)) { InGame = 0; threads_search_stop(); } else if (!strncmp(line, "force", 5)) { engineColor = C_NONE; } else if (!strcmp(token, "go")) { engineColor = pos->to_move; threads_search(); } else if (!strcmp(token, "playother")) { engineColor = 1 ^ pos->to_move; } else if (!strcmp(token, "white")) { pos->to_move = C_WHITE; engineColor = C_BLACK; } else if (!strcmp(token, "black")) { pos->to_move = C_BLACK; engineColor = C_WHITE; } else if (!strcmp(token, "sd")) { char* d = arg_next(); if (d) TC.l_depth = atoi(d); } else if (!strcmp(token, "ping")) { char* a = arg_rest(); if (a) send_line("pong %s", a); else send_line("pong"); } else if (!strcmp(token, "edit")) { send_line("Error (command not implemented): %s", token); } else if (!strcmp(token, "undo")) { if (!position_unmove(pos)) send_line("Error (command not legal now): %s", token); } else if (!strcmp(token, "remove")) { if (!position_unmove(pos) || !position_unmove(pos)) send_line("Error (command not legal now): %s", token); } else if (!strcmp(token, "setboard")) { char* b = arg_rest(); if (!b) send_line("Error (missing argument): %s", token); else position_set(pos, b); } else if (!strcmp(token, "post")) { ModePost = 1; } else if (!strcmp(token, "nopost")) { ModePost = 1; } else if (!strcmp(token, "option")) { char* o = arg_next_sep('='); char* v = arg_next(); if (!o) log_line("missing option"); else if (!strcmp(o, "Thinking Time")) { if (v) TC.l_time = atoi(v); } else if (!strcmp(o, "Search Depth")) { if (v) TC.l_depth = atoi(v); } else log_line("unknown option: %s", o); } else { if (!strcmp(token, "usermove")) token = arg_next(); threads_search_stop(); move_t move = parse_move(pos, token); if (!move) { send_line("Illegal move: %s", token); } else { position_move(pos, move); position_print(pos, C_WHITE); if (ModeAnalyze || engineColor == pos->to_move) threads_search(); } } } threads_exit(); position_destroy(pos); }
int execute_step (struct world *world, int display, int move_forward) { struct position new_pos; struct cell *cell; int ret; enum ant_action action; int new_direction, direction; int new_marker; if (!world->cursor) { fprintf (stderr, "Internal error: cursor is NULL\n"); return -1; } if (move_forward) { skip_round_markers (world, 1); if (!world->cursor->next) { fprintf (stderr, "Already at the end of simulation\n"); return -1; } } else { if (!world->cursor->prev) { fprintf (stderr, "Already at the beginning of simulation\n"); return -1; } world->cursor = world->cursor->prev; skip_round_markers (world, 0); if (!world->cursor->ant) { fprintf (stderr, "Already at the beginning of simulation (file starts with round marker)\n"); world->round--; return -1; } world->step--; } if (!world->cursor) { fprintf (stderr, "Internal error: cursor is NULL\n"); return -1; } cell = cell_at (world, &world->cursor->ant->pos); if (world->cursor->ant != cell->ant) { fprintf (stderr, "Error in internal data structure: Ant not at cell.\n"); return -1; } if (move_forward) { world->cursor->old_ant_state = cell->ant->state; cell->ant->state = world->cursor->new_ant_state; } else { cell->ant->state = world->cursor->old_ant_state; } action = world->cursor->action; if (!move_forward) { if (world->cursor->action_had_no_side_effects) { if (warnings) { fprintf (stderr, "Stepping back an action without side effects.\n"); } return 0; } action=reverse_action[action]; } switch (action) { case MOVE_FORWARD: case MOVE_BACKWARD: new_pos = world->cursor->ant->pos; direction = world->cursor->ant->direction; if (action == MOVE_BACKWARD) direction+=3; position_move (&new_pos, direction); if ((ret = verify_ant_position (world, &new_pos)) != 0) { if (warnings) { fprintf (stderr, "Ant crashing into another ant or rock!\n"); } if (move_forward) { world->cursor->action_had_no_side_effects = 1; } break; /* this is a valid condition. */ } if (display) { if ((ret=v_move_ant (world->cursor->ant, &new_pos, world->cursor->ant->direction)) != 0) { return ret; } } cell->ant = NULL; if (!display) cell->ant_needs_update = 1; world->cursor->ant->pos = new_pos; cell = cell_at (world, &new_pos); cell->ant = world->cursor->ant; if (!display) cell->ant_needs_update = 1; if ((ret=handle_dead_ants_around (&new_pos))!=0) return ret; break; case TURN_LEFT: case TURN_RIGHT: new_direction = world->cursor->ant->direction; if (action == TURN_RIGHT) { new_direction++; } else { new_direction--; } if (new_direction < 0) new_direction+=6; if (new_direction > 5) new_direction-=6; if (display) { if ((ret=v_move_ant (world->cursor->ant, &world->cursor->ant->pos, new_direction)) != 0) { return ret; } } world->cursor->ant->direction = new_direction; if (!display) cell->ant_needs_update = 1; break; case PICKUP_FOOD: if (world->cursor->ant->carries_food) { if (warnings) { fprintf (stderr, "Ant carriing food attempts to pick up food.\n"); } if (move_forward) { world->cursor->action_had_no_side_effects = 1; } break; } if (cell->food == 0) { if (warnings) { fprintf (stderr, "Ant attepmts to pick up food but there is none.\n"); } if (move_forward) { world->cursor->action_had_no_side_effects = 1; } world->cursor->action_had_no_side_effects = 1; break; } if (display) { if ((ret=v_ant_picks_up_food (world->cursor->ant, cell->food, cell->food-1)) != 0) { return ret; } } cell->food--; if (!display) cell->food_needs_update = 1; world->cursor->ant->carries_food++; break; case DROP_FOOD: if (!world->cursor->ant->carries_food) { if (warnings) { fprintf (stderr, "Ant carriing no food attempts to drop food.\n"); } if (move_forward) { world->cursor->action_had_no_side_effects = 1; } world->cursor->action_had_no_side_effects = 1; break; } cell = cell_at (world, &world->cursor->ant->pos); if (display) { if ((ret=v_ant_drops_food (world->cursor->ant, cell->food, cell->food+1)) != 0) { return ret; } } cell->food++; if (!display) cell->food_needs_update = 1; world->cursor->ant->carries_food--; break; case SET_MARKER: case CLEAR_MARKER: new_marker = cell->markers[world->cursor->ant->colony]; if (action == SET_MARKER) { new_marker |= (1<<world->cursor->marker); } else { new_marker &= ~(1<<world->cursor->marker); } if (new_marker == cell->markers[world->cursor->ant->colony]) { if (warnings) { fprintf (stderr, "Ant setting/clearing marker but it is already set/cleared.\n"); } if (move_forward) { world->cursor->action_had_no_side_effects = 1; } break; } if (display) { if ((ret=v_ant_changes_marker (world->cursor->ant, cell->markers[world->cursor->ant->colony], new_marker)) != 0) { return ret; } } cell->markers[world->cursor->ant->colony] = new_marker; if (!display) cell->markers_need_update = 1; break; default: fprintf (stderr, "Illegal ant action\n"); return -1; } if (move_forward) { if (world->cursor->next) world->cursor = world->cursor->next; world->step++; } /* when moving backwards this already has been done at the beginning. */ return 0; }