예제 #1
0
// There are two types of command interfaces in the world of computing: good
// interfaces and user interfaces. -- Daniel J. Bernstein
//------------------------------------------------------------------------------
void repl() {
    Position *position = NULL;
    char command[128] = "";

    printf("Donna Vista v%s Copyright (c) 2014-2015 by Michael Dvorkin. All Rights Reserved.\nType ? for help.\n\n", VERSION);
    while (true) {
        printf("donna_vista> ");
        if (fgets(command, sizeof(command), stdin)) {
            // Strip trailing newline returned by fgets().
            int len = strlen(command);
            if (len > 0 && command[len - 1] == '\n') {
                command[len - 1] = '\0';
            }
            if (strlen(command)) {
                if (!strncmp(command, "bench", 5)) {
                    repl_bench(strtok(&command[5], " "));

                } else if (!strncmp(command, "book", 4)) {
                    repl_book(strtok(&command[4], " "));

                } else if (!strncmp(command, "perft", 5)) {
                    repl_perft(strtok(&command[5], " "));

                } else if (!strcmp(command, "go")) {
                    position = repl_think(repl_setup(position));

                } else if (!strcmp(command, "help") || !strcmp(command, "?")) {
                    repl_help();

                } else if (!strcmp(command, "new")) {
                    position = repl_setup(NULL);

                } else if (!strcmp(command, "undo")) {
                    position = repl_undo(position);

                } else if (!strcmp(command, "exit") || !strcmp(command, "quit")) {
                    break;

                } else {
                    Move move = new_move_from_string(position, command);
                    if (move) {
                        position = repl_think(make_move(repl_setup(position), move));
                    } else {
                        char buffer[256];
                        MoveGen *gen = new_move_gen(position);
                        valid_only(generate_all_moves(gen));
                        printf("%s appears to be an invalid move; valid moves are %s\n", command, all_moves(gen, buffer));
                    }
                }
            }
        } else {
            break; // Exit if fgets() errors out.
        }
    }
}
예제 #2
0
// Before returning the move make sure it is valid in current position.
//------------------------------------------------------------------------------
Move validate(Position *self, Move move) {
    if (move) {
        MoveGen *gen = new_move_gen(self);
        valid_only(generate_all_moves(gen));
        if (!among_valid(gen, move)) {
            return (Move)0;
        }
    }

    return move;
}
예제 #3
0
파일: board.c 프로젝트: juerkkil/chessai
/* Function returns 1 if opponent's king is checked
 * c = 1 (white) or -1 (black) */
int is_check(board * brd, int c) {
  move * t = malloc(sizeof(move));
  init_move(&t);
  generate_all_moves(c, brd, &t);
  move * t_ = t;
  while(t_->next != NULL) {
    if( t_->x * c == -6) {
      free_moves(&t);
      return 1;
    }
    t_=t_->next;
  }
  free_moves(&t);
  return 0;
}
예제 #4
0
파일: board.c 프로젝트: juerkkil/chessai
/* Returns 1 if player c has valid moves left.
 * c = 1 (white) or -1 (black)
 * If king is in check and no valid moves left, that implies checkmate */
int has_moves(board * brd, int c) {
  move * t = malloc(sizeof(move));
  init_move(&t);
  generate_all_moves(c, brd, &t);
  move * t_ = t;
  while(t_->next != NULL) {
    if(apply_move(brd, &t_, c)) {
      undo_move(brd, &t_);
      free_moves(&t);
      return 1;

    }
    t_ = t_->next;
  }
  free_moves(&t);
  return 0;
}
예제 #5
0
파일: ai.c 프로젝트: ejrh/ejrh
int generate_valid_moves(GAME *game, MOVE *moves)
{
    DECKP hand = game->players[game->current_player].hand;
    int i;
    int num = 0;
    MOVE all_moves[MAX_MOVES];
    int num_moves;

    num_moves = generate_all_moves(hand, all_moves);
    
    /* Special case: put highest move first, just in case it helps pruning. */
    if (num_moves >= 1 && is_valid_move(game, all_moves[num_moves-1]))
       moves[num++] = all_moves[num_moves-1];
    
    for (i = 0; i < num_moves-1; i++)
        if (is_valid_move(game, all_moves[i]))
            moves[num++] = all_moves[i];

    return num;
}
예제 #6
0
파일: ai.c 프로젝트: ejrh/ejrh
void test(void)
{
    GAME game;
    MOVE moves[MAX_MOVES];
    int vector[MAX_PLAYERS];
    int num_moves;
    int i;
    MOVE chosen_move;
    clock_t start_time, end_time;
    int centiseconds, rate;

    printf("Rankoids AI test\n");

    clear_transposition_table();
    init_stack(&game_stack, 100*sizeof(GAME));

    initialise_game(&game);
    game.num_players = 3;
    game.players[0].hand[0] = 1;
    game.players[0].hand[1] = 3;
    game.players[0].hand[3] = 2;
    game.players[1].hand[4] = 1;
    game.players[0].hand[6] = 4;
    game.players[0].hand[7] = 3;
    game.players[0].hand[10] = 2;
    game.players[0].hand[JOKER_VALUE] = 1;
    game.players[1].hand[1] = 1;
    game.players[1].hand[2] = 3;
    game.players[1].hand[3] = 1;
    game.players[1].hand[4] = 1;
    game.players[1].hand[5] = 1;
    game.players[1].hand[9] = 3;
    game.players[1].hand[12] = 1;
    game.players[1].hand[5] = 2;
    game.players[2].hand[0] = 3;
    game.players[2].hand[2] = 1;
    game.players[2].hand[3] = 1;
    game.players[1].hand[4] = 2;
    game.players[2].hand[5] = 2;
    game.players[2].hand[9] = 1;
    game.players[2].hand[11] = 4;
    game.current_player = 0;
    game.pile_owner = 0;

    printf("Current game:\n");
    print_game(&game);

    printf("All moves for player 1:\n");
    num_moves = generate_all_moves(game.players[0].hand, moves);
    for (i = 0; i < num_moves; i++)
        print_move(moves[i]);
    printf("\n");

    evaluate_game_immediate(&game, vector);
    printf("Game vector is: [%d,%d,%d]\n", vector[0], vector[1], vector[2]);

    printf("All valid moves for player 1:\n");
    num_moves = generate_valid_moves(&game, moves);
    for (i = 0; i < num_moves; i++)
        print_move(moves[i]);
    printf("\n");

    chosen_move = MAKE_MOVE(3, 2);
    printf("Apply move ");
    print_move(chosen_move);
    printf(", game is:\n");
    apply_move(&game, chosen_move);
    print_game(&game);

    evaluate_game_immediate(&game, vector);
    printf("Game vector is: [%d,%d,%d]\n", vector[0], vector[1], vector[2]);

    printf("All valid moves for player 2:\n");
    num_moves = generate_valid_moves(&game, moves);
    for (i = 0; i < num_moves; i++)
    {
        print_move(moves[i]);
        clear_transposition_table();
        evaluate_move(&game, moves[i], vector, parameters.depth);
        printf(", with vector [%d,%d,%d]\n", vector[0], vector[1], vector[2]);
    }

    node_count = 0;
    clear_transposition_table();

    start_time = clock();
    chosen_move = choose_move(&game, vector, parameters.depth+5);
    end_time = clock();
    centiseconds = (end_time - start_time)*100 / CLOCKS_PER_SEC;
    if (centiseconds != 0)
    {
        rate = (int) (100.0*node_count/centiseconds);
    }
    else
    {
        rate = 0;
    }
    printf("%d nodes examined (%d hits), time was: %0.2f seconds, rate is: %d nodes/sec\n", node_count, hit_count, centiseconds/100.0, rate);
    printf("Chosen move was:");
    print_move(chosen_move);
    printf(", with vector [%d,%d,%d]\n", vector[0], vector[1], vector[2]);

    free_stack(&game_stack);
}