Esempio n. 1
0
int test_scout() {
	Board b, orig;
	Move *moves, *omoves;
	int status, i, j, n, m;
	status = WIN;
	
	printf("testing scout\n");
	setup(&b);
	setup(&orig);
	printb(&b);

	moves = gen_moves(&b, &n);
	for(i=0; i<n && i<5; i++) {
		printf("=============================================\napplying move %d\n", i+1);
		apply_move(&b, moves[i]);
		
		omoves = gen_moves(&b, &m);
		for(j=0; j<m && j<5; j++) {
			
			printf("second move %d\n", j+1);
			apply_move(&b, omoves[j]);
			printb(&b);
			printf("eval = %d\n", eval(&b));
			undo_move(&b, omoves[j]);
			
		}
		free(omoves);
		
		undo_move(&b, moves[i]);
	}
	free(moves);
	
	return status;
}
Esempio n. 2
0
File: battle.cpp Progetto: ejrh/hex
void Battle::make_move(Participant& participant) {
    std::vector<const MoveType *> move_types = combat_model->get_available_move_types(*this, participant);

    const MoveType *best = NULL;
    int best_target = -1;
    float best_value = 0;
    int num_considered = 0;
    for (auto iter = participants.begin(); iter != participants.end(); iter++) {
        const Participant& target = *iter;
        for (auto iter2 = move_types.begin(); iter2 != move_types.end(); iter2++) {
            const MoveType *type = *iter2;
            if (!type->is_viable(*this, participant, target))
                continue;

            num_considered++;

            float expected_value = type->expected_value(*this, participant, target) * type->repeats();

            if (expected_value > best_value) {
                best = type;
                best_target = target.id;
                best_value = expected_value;
            }
        }
    }

    if (best != NULL && best_target != -1) {
        BOOST_LOG_TRIVIAL(trace) << boost::format("Considered %d moves and chose: ") % num_considered << *best << boost::format(" (with value %0.1f)") % best_value;
        Participant& target = participants[best_target];
        for (int i = 0; i < best->repeats(); i++) {
            // It's possible the move is no longer viable
            if (!best->is_viable(*this, participant, target))
                break;

            // Make the move
            Move move = best->generate(*this, participant, target);
            moves.push_back(move);
            apply_move(move);

            // Riposte
            MoveType *riposte_type = combat_model->move_types[Riposte];
            if (riposte_type != NULL && riposte_type->is_viable(*this, target, participant)) {
                Move riposte = riposte_type->generate(*this, target, participant);
                moves.push_back(riposte);
                apply_move(riposte);
            }
        }
    } else {
        BOOST_LOG_TRIVIAL(trace) << "Considered no moves";
    }
}
Esempio n. 3
0
/* Naively choose the move that will shrink the most dots. */
mask_t choose_move_greedy(grid_t grid, int allow_shrinkers, int *no_moves) {
    mask_t move = EMPTY_MASK;
    int i, num_dots, max_dots = -1;

    int num_moves;
    move_list_t moves;
    get_moves(grid, allow_shrinkers, &num_moves, moves);

    *no_moves = 0;
    if (SHOULD_SHRINK_RANDOM(num_moves, allow_shrinkers)) {
        *no_moves = 1;
        return random_mask();
    }

    for (i = 0; i < num_moves; i++) {
        grid_t new_grid;
        memcpy(new_grid, grid, sizeof(grid_t));
        num_dots = apply_move(new_grid, moves[i]);
        if (num_dots > max_dots) {
            max_dots = num_dots;
            move = moves[i];
        }
    }
    return move;
}
Esempio n. 4
0
File: move.c Progetto: jes/zoe
/* return 1 if the move is valid and 0 otherwise, printing an appropriate
 * message if print is non-zero.
 */
int is_valid_move(Game game, Move m, int print) {
    Board *board = &(game.board);
    Game game2 = game;
    uint64_t beginbit, endbit;
    char *strmove = xboard_move(m);

    beginbit = 1ull << m.begin;
    endbit = 1ull << m.end;

    /* ensure that the piece belongs to the current player */
    if(!(board->b[game.turn][OCCUPIED] & beginbit)) {
        if(print)
            printf("Illegal move (%s): that is not your piece.\n", strmove);
        return 0;
    }

    /* ensure that the end tile can be moved to from the begin tile */
    if(!(generate_moves(&game, m.begin) & endbit)) {
        if(print)
            printf("Illegal move (%s): that piece can't move like that.\n",
                    strmove);
        return 0;
    }

    /* ensure that pawns reaching the eighth rank promote */
    if(!m.promote && ((m.end / 8) == 0 || (m.end / 8) == 7)
            && board->mailbox[m.begin] == PAWN) {
        if(print)
            printf("Illegal move (%s): pawns reaching the eighth rank must "
                    "promote.\n", strmove);
        return 0;
    }

    /* ensure that no other pieces promote */
    if(m.promote && (board->mailbox[m.begin] != PAWN
                || ((m.end / 8) != 0 && (m.end / 8) != 7))) {
        if(print)
            printf("Illegal move (%s): that piece may not promote at this "
                    "time.\n", strmove);
        return 0;
    }

    /* ensure that the king is not left in check
     * NOTE: we apply_move() here, so the state of the game is changed; this
     * check must be done last
     */
    apply_move(&game2, m);
    if(king_in_check(&(game2.board), game.turn)) {
        if(print)
            printf("Illegal move (%s): king is left in check.\n", strmove);
        return 0;
    }

    /* hasn't failed any validation, must be a valid move */
    return 1;
}
Esempio n. 5
0
File: ai.c Progetto: ejrh/ejrh
void evaluate_move(GAME *game, MOVE move, int *vector, int to_depth)
{
    GAME *game2 = clone_game(game);
    int window[MAX_PLAYERS];
    
    memset(window, 0, sizeof(window));
    apply_move(game2, move);
    search_tree(game2, vector, to_depth, window, game2->current_player);

    stack_pop(&game_stack, game2);
}
Esempio n. 6
0
static void tick(int *len, char *buf, struct per_session_data *data) {
    int path_length = 0;
    path_t path;

    mask_t random_dots = EMPTY_MASK;

    json_object *result;
    const char *s;

    /* If it's a new game, only send the grid and don't compute a move. */
    if (data->new_game) {
        data->new_game = 0;
    } else {
        struct timeval tv;
        long ms;
        mask_t move;
        int no_moves;

        gettimeofday(&tv, NULL);
        ms = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
        if ((ms - data->last_updated) < MIN_UPDATE_INTERVAL) {
            return;
        }
        data->last_updated = ms;

        move = choose_move(data->grid, 0, 100, &no_moves);
        apply_move(data->grid, move);
        fill_grid(data->grid, GET_CYCLE_COLOR(move));
        if (no_moves) {
            random_dots = move;
        } else {
            mask_to_path(move, &path_length, path);
        }
    }

    result = json_object_new_object();
    json_object_object_add(result, "grid", json_grid(data->grid));
    if (path_length == 0 && random_dots == EMPTY_MASK) {
        json_object_object_add(result, "newGrid", json_object_new_boolean(TRUE));
    }
    if (random_dots) {
        json_object_object_add(result, "shrinkRandom", json_shrink_random(random_dots));
    }
    if (path_length) {
        json_object_object_add(result, "path", json_path(path_length, path));
    }

    s = json_object_to_json_string(result);
    *len = strlen(s);
    memcpy(buf, s, *len);
    buf[*len] = 0;

    json_object_put(result);
}
Esempio n. 7
0
void Group::buildTransitionTable()
{
    transition_table = TransitionTable(state_count);
    std::vector<int> arr(piece_count);

    for (int index = 0; index < state_count; index++)
    {
        for (int move = 0; move < 6; move++)
        {
            index_to_array(index, arr);
            apply_move(arr, move);
            transition_table[index][move] = array_to_index(arr);
        }
    }
}
Esempio n. 8
0
/* heuristic = score ** uncertainty_of_board
 *   where uncertainty_of_board = (sum of certainty_of_dots) / num_dots
 *         uncertainty_of_dot | 1/4 if shrunk by cycle
 *                            | 1/5 if shrunk by a regular move
 *                            | 1   otherwise
 */
void _choose_move(grid_t grid, int allow_shrinkers, int turns_remaining, int certainty, float *value, mask_t *move, int *no_moves) {
    float best_value = -1;
    mask_t best_move = EMPTY_MASK;

    int i, num_moves;
    move_list_t moves;

    get_moves(grid, allow_shrinkers, &num_moves, moves);

    if (certainty == 720 && SHOULD_SHRINK_RANDOM(num_moves, allow_shrinkers)) {
        *move = random_mask();
        *value = num_dots(*move);
        *no_moves = 1;
        return;
    }

    for (i = 0; i < num_moves; i++) {
        int score;
        float value;
        grid_t new_grid;

        if (turns_remaining > 1 || HAS_CYCLE(moves[i])) {
            memcpy(new_grid, grid, sizeof(grid_t));
            score = apply_move(new_grid, moves[i]);
        } else {
            score = num_dots(moves[i]);
        }

        value = pow(score, certainty / 720.0);

        if (turns_remaining > 1) {
            int next_certainty = certainty - score * (HAS_CYCLE(moves[i]) ? 15 : 16);
            float next_value;
            mask_t next_move;
            _choose_move(new_grid, allow_shrinkers, turns_remaining - 1, next_certainty, &next_value, &next_move, NULL);
            value += next_value;
        }

        if (value > best_value) {
            best_value = value;
            best_move = moves[i];
        }
    }

    *value = best_value;
    *move = best_move;
}
Esempio n. 9
0
/* 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;
}
Esempio n. 10
0
int test_apply_move() {
	int status, num_moves, i;
	Board board;
	Move *moves;
	status = WIN;
	num_moves = 0;
	setup(&board);
	printb(&board);
	moves = gen_moves(&board, &num_moves);
	printf("found %d moves\n", num_moves);
	for(i=0; i<35 && i<num_moves; i++) {
		printf("move %d: %d is moving from %d to %d, capturing %d\n",
			i, moving_type(moves[i]), moves[i].from,
			moves[i].to, capturing_type(moves[i]));
		printf("board after move %d looks like:\n", i+1);
		apply_move(&board, moves[i]);
		printb(&board);
		undo_move(&board, moves[i]);
	}
	
	return status;
}
Esempio n. 11
0
File: ai.c Progetto: 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);
}
Esempio n. 12
0
File: ai.c Progetto: ejrh/ejrh
MOVE search_tree(GAME *game, int *best_vector, int to_depth, int *window_vector, int window_player)
{
    MOVE moves[MAX_MOVES];
    int num_moves;
    int i;
    MOVE best_move = MOVE_INVALID;
    int player;
    unsigned int hash;

    if (to_depth <= 0 || game_is_over(game))
    {
        evaluate_game_immediate(game, best_vector);
        return best_move;
    }

#ifdef USE_TRANSPOSITION_TABLE_SEARCH
    hash = hash_game(game) % TRANSPOSITION_TABLE_SIZE;

    if (transposition_table[hash][0] != TABLE_UNUSED)
    {
        memcpy(best_vector, transposition_table[hash], sizeof(int)*MAX_PLAYERS);
        hit_count++;
        return best_move;
    }
#endif
    
    num_moves = generate_valid_moves(game, moves);

    player = game->current_player;

    for (i = 0; i < num_moves; i++)
    {
        GAME *game2 = clone_game(game);
        int vector[MAX_PLAYERS];
        MOVE move;

        apply_move(game2, moves[i]);
        node_count++;
        move = search_tree(game2, vector, to_depth - 1, best_vector, player);
        if (move == MOVE_INVALID)
            move = moves[i];

        if (i == 0 || vector[player] > best_vector[player])
        {
            memcpy(best_vector, vector, sizeof(vector));
            best_move = moves[i];
        }

        stack_pop(&game_stack, game2);
        
        /* Prune if this move is so good for the current player that
           the potential value for the window player is less than
           the window. */
        if (vector[player] > parameters.total_score - window_vector[window_player])
        {
            break;
        }
    }

#ifdef USE_TRANSPOSITION_TABLE_SEARCH
    memcpy(transposition_table[hash], best_vector, sizeof(int)*MAX_PLAYERS);
#endif

    return best_move;
}
Esempio n. 13
0
void BorderList::removeLine(int i)

{
    
    
   class is_equal_to_i
   {
      int m_i;
      public:
        is_equal_to_i(int i) {
           m_i = i;
        }
        bool operator() (Figure& fig) {
         if (fig.ypos == m_i && fig.ypos != 640)
           return true;
         else
           return false;

    }

   };


   class apply_move
   {
      int m_i;
      public:
       apply_move(int i) {
           m_i = i;
        }
        void operator() (Figure& fig) {
         if (fig.ypos != m_i && fig.ypos < m_i)
           fig.ypos += 32;

    }

   };


    std::vector<Figure>::iterator iter;

    std::vector<Figure> newfence;

    if (i != -1)
    {
    //        std::cout << "10 elements found, ret = " << i << std::endl;
   //     for (iter=fence.begin(); iter!=fence.end(); iter++ )
   //     {
   //         if ((*iter).ypos != i || (*iter).ypos == 640)
   //         {
   //             newfence.push_back(*iter);
   //         }
   //     }


     std::vector<Figure>::iterator newend = std::remove_if(fence.begin(), fence.end(), is_equal_to_i(i));
     fence.erase(newend, fence.end());
   


 //     for (iter=fence.begin(); iter!=fence.end(); iter++ )
 //     {
 //          if ((*iter).ypos != 640 && (*iter).ypos < i)
 //          {
 //              (*iter).ypos += 32;
 //          }


 //     }


     std::for_each(fence.begin(), fence.end(), apply_move(i));

      // fence = newfence;
     }

}
Esempio n. 14
0
File: move.c Progetto: jes/zoe
/* apply the given move to the given game */
void apply_move(Game *game, Move m) {
    Board *board = &(game->board);
    int beginpiece, endpiece;
    int begincolour, endcolour;
    uint64_t beginbit, endbit;
    int eptile;
    uint64_t epbit;
    Move m2;

    /* check board consistency */
    /*if(!consistent_board(&(game->board))) {
        printf("!!! Inconsistent board at start of apply_move!\n");
        draw_board(&(game->board));
        printf("occupied:\n");
        draw_bitboard(game->board.occupied);
        printf("black occupied:\n");
        draw_bitboard(game->board.b[BLACK][OCCUPIED]);
        printf("white occupied:\n");
        draw_bitboard(game->board.b[WHITE][OCCUPIED]);
        exit(1);
    }*/

    /* find the piece from the mailbox */
    beginpiece = board->mailbox[m.begin];
    endpiece = board->mailbox[m.end];

    /* find the bits to use */
    beginbit = 1ull << m.begin;
    endbit = 1ull << m.end;

    /* find out if this move is quiet */
    if(board->occupied & endbit)
        game->quiet_moves = 0;
    else
        game->quiet_moves++;

    /* find the colour from white's occupied bitboard */
    begincolour = !(board->b[WHITE][OCCUPIED] & beginbit);
    endcolour = !(board->b[WHITE][OCCUPIED] & endbit);

    /* delete a pawn if taken en passant */
    if(beginpiece == PAWN && ((m.end / 8) == (5 - begincolour * 3))
                && ((m.end % 8) == game->ep)) {
        eptile = (4 - begincolour) * 8 + game->ep;
        game->eval += piece_square_score(PAWN, eptile, !game->turn);
        epbit = 1ull << eptile;
        board->mailbox[eptile] = EMPTY;
        board->occupied ^= epbit;
        board->b[!begincolour][OCCUPIED] ^= epbit;
        board->b[!begincolour][PAWN] ^= epbit;
    }

    /* update en passant availability */
    if(beginpiece == PAWN && abs(m.begin - m.end) == 16)
        game->ep = m.begin % 8;
    else
        game->ep = 9;

    /* remove the piece from the begin square */
    game->eval -= piece_square_score(beginpiece, m.begin, game->turn);
    board->mailbox[m.begin] = EMPTY;
    board->occupied ^= beginbit;
    board->b[begincolour][beginpiece] ^= beginbit;
    board->b[begincolour][OCCUPIED] ^= beginbit;
    board->zobrist ^= zobrist[beginpiece][m.begin];
    board->zobrist ^= zobrist[EMPTY][m.begin];

    /* remove the piece from the end square if necessary */
    if(endpiece != EMPTY) {
        game->eval += piece_square_score(endpiece, m.end, !game->turn);
        board->b[endcolour][endpiece] ^= endbit;
        board->b[endcolour][OCCUPIED] ^= endbit;
    }
    board->zobrist ^= zobrist[endpiece][m.end];

    /* change the piece to it's promotion if appropriate */
    if(m.promote)
        beginpiece = m.promote;

    /* insert the piece at the end square */
    game->eval += piece_square_score(beginpiece, m.end, game->turn);
    board->mailbox[m.end] = beginpiece;
    board->occupied |= endbit;
    board->b[begincolour][beginpiece] |= endbit;
    board->b[begincolour][OCCUPIED] |= endbit;
    board->zobrist ^= zobrist[beginpiece][m.end];

    /* can't castle on one side if a rook was moved from it's original place */
    if(beginpiece == ROOK) {
        /* queenside */
        if((m.begin == 0 && begincolour == WHITE)
                || (m.begin == 56 && begincolour == BLACK))
            game->can_castle[begincolour][QUEENSIDE] = 0;

        /* kingisde */
        if((m.begin == 7 && begincolour == WHITE)
                || (m.begin == 63 && begincolour == BLACK))
            game->can_castle[begincolour][KINGSIDE] = 0;
    }

    /* can't castle on one side if that rook is taken */
    if(endpiece == ROOK) {
        /* queenside */
        if((m.end == 0 && endcolour == WHITE)
                || (m.end == 56 && endcolour == BLACK))
            game->can_castle[endcolour][QUEENSIDE] = 0;

        /* kingisde */
        if((m.end == 7 && endcolour == WHITE)
                || (m.end == 63 && endcolour == BLACK))
            game->can_castle[endcolour][KINGSIDE] = 0;
    }

    if(beginpiece == KING) {
        /* can no longer castle on either side if the king is moved */
        game->can_castle[begincolour][QUEENSIDE] = 0;
        game->can_castle[begincolour][KINGSIDE] = 0;

        /* move the rook for castling */
        if(abs(m.begin - m.end) == 2) {
            if(m.begin > m.end) {/* queenside */
                m2.begin = m.begin - 4;
                m2.end = m.end + 1;
            }
            else {/* kingside */
                m2.begin = m.begin + 3;
                m2.end = m.end - 1;
            }

            /* make sure we don't try to promote */
            m2.promote = 0;

            /* apply the rook move */
            apply_move(game, m2);

            /* undo the turn toggle */
            game->turn = !game->turn;
            game->eval = -game->eval;
        }
    }

    /* toggle current player */
    game->turn = !game->turn;
    game->eval = -game->eval;

    /* check board consistency */
    /*if(!consistent_board(&(game->board))) {
        printf("!!! Inconsistent board at end of apply_move!\n");
        draw_board(&(game->board));
        printf("occupied:\n");
        draw_bitboard(game->board.occupied);
        printf("black occupied:\n");
        draw_bitboard(game->board.b[BLACK][OCCUPIED]);
        printf("white occupied:\n");
        draw_bitboard(game->board.b[WHITE][OCCUPIED]);
        exit(1);
    }*/
}
Esempio n. 15
0
File: battle.cpp Progetto: ejrh/hex
void Battle::replay_move(const Move& move) {
    apply_move(move);
}
Esempio n. 16
0
///////////////////////////////////
// MAIN (only for internal test) //
///////////////////////////////////
int
main ()
{
  // Valgrind run
  init_chess_library ();
  int i, from, to;

  for (i = 0; i < 1000; i++)
    {
      Game *g = init_game ();
      Board *board;
      char *fen;

      // 1. e4 a6 2. Bc4 a5 3. Qh5 a4 4. Qxf7#
      board = current_board (g);
      get_coord (board, 'P', "e", "e4", 0, &from, &to);
      pseudo_legal_move (board, from, to);
      apply_move (g, from, to, 0);
      fen = to_fen (board);
      free (fen);

      board = current_board (g);
      get_coord (board, 'P', "a", "a6", 0, &from, &to);
      pseudo_legal_move (board, from, to);
      apply_move (g, from, to, 0);
      fen = to_fen (current_board (g));
      free (fen);

      board = current_board (g);
      get_coord (board, 'B', "", "c4", 0, &from, &to);
      pseudo_legal_move (board, from, to);
      apply_move (g, from, to, 0);
      fen = to_fen (current_board (g));
      free (fen);

      board = current_board (g);
      get_coord (board, 'P', "a", "a5", 0, &from, &to);
      pseudo_legal_move (board, from, to);
      apply_move (g, from, to, 0);
      fen = to_fen (current_board (g));
      free (fen);

      board = current_board (g);
      get_coord (board, 'Q', "", "h5", 0, &from, &to);
      pseudo_legal_move (board, from, to);
      apply_move (g, from, to, 0);
      fen = to_fen (current_board (g));
      free (fen);

      board = current_board (g);
      get_coord (board, 'P', "a", "a4", 0, &from, &to);
      pseudo_legal_move (board, from, to);
      apply_move (g, from, to, 0);
      fen = to_fen (current_board (g));
      free (fen);

      board = current_board (g);
      get_coord (board, 'Q', "", "f7", 0, &from, &to);
      pseudo_legal_move (board, from, to);
      apply_move (g, from, to, 0);
      fen = to_fen (current_board (g));
      free (fen);

      free_game (g);
    }
  return 0;
}