src/strategies/minimax2.c
// Returns and integer indicating the best mark you can get with a specific board state
// by testing the next n turns.
// This AI maximize and its enemy minimize.
Returns and integer indicating the best mark you can get with a specific board state
by testing the next n turns.
This AI maximize and its enemy minimize.
Returns and integer indicating the best mark you can get with a specific board state by testing the next n turns . This AI maximize and its enemy minimize .
void minimax(struct strat_board *b, int *mark, struct pos *pos, int n) {
    int p = b->current_player;
    if ((n == 0) || (b->players[p].l == ((p == 0) ? 0 : N - 1))) {
        *mark = board_value(b);
        return ;
    } else {
        if (p == get_current_player(&b->board)) {
            *mark = -1;
        } else {
            *mark = 200;
        }
        int moves_nb = 0;
        int t[N][N];
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                t[i][j] = 0;
            }
        }
        paths(b, t, b->players[p].c, b->players[p].l, 0, p);
        t[b->players[p].l][b->players[p].c] = -1;
        fprintf(stderr, "\n");
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                fprintf(stderr, "%d\t", t[i][j]);
            }
            fprintf(stderr, "\n");
        }
        fprintf(stderr, "\n");
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (t[i][j] == 1) {
                    struct strat_board b_cpy = *b;
                    move_pawn_strat(&b_cpy, j, i);
                    struct pos new_pos = {.c = j, .l = i, .d = -1};
                    int new_mark;
                    minimax(&b_cpy, &new_mark, &new_pos, n - 1);
                    if ((p == get_current_player(&b->board)) && new_mark > *mark) {
                        *mark = new_mark;
                        *pos = new_pos;
                        fprintf(stderr, "New best board\n");
                    } else if ((p == (get_current_player(&b->board) + 1) % 2) && new_mark < *mark) {
                        *mark = new_mark;
                        *pos = new_pos;
                        fprintf(stderr, "New best board\n");
                    }
                }
            }
        }
        /*
        // -- bridges -- //
        struct pos bridges[2 * N * N];
        int bridges_nb = 0;
        // Calculate the most profitable bridges.
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if(is_blockable_strat(b, j, i, 0)) {
                    bridges[bridges_nb].c = j;
                    bridges[bridges_nb].l = i;
                    bridges[bridges_nb].d = 0;
                    bridges_nb++;
                }
                if(is_blockable_strat(b, j, i, 1)) {
                    bridges[bridges_nb].c = j;
                    bridges[bridges_nb].l = i;
                    bridges[bridges_nb].d = 1;
                    bridges_nb++;
                }
            }
        }
        fprintf(stderr, "Ca va tourner pour les murs\n");
        for (int i = 0; i < bridges_nb; i++) {
            // if (is_blockable_strat(b, bridges[i].c, bridges[i].l, bridges[i].d)) {
                struct strat_board b_cpy = *b;
                place_wall_strat(&b_cpy, bridges[i].c, bridges[i].l, bridges[i].d);
                struct pos new_pos = {.c = bridges[i].c, .l = bridges[i].l, .d = bridges[i].d};
                int new_mark;
                minimax(&b_cpy, &new_mark, &new_pos, n - 1);
                if ((p == get_current_player(&b->board)) && new_mark > *mark) {
                    *mark = new_mark;
                    *pos = new_pos;
                    fprintf(stderr, "New best board\n");
                } else if ((p == (get_current_player(&b->board) + 1) % 2) && new_mark < *mark) {
                    *mark = new_mark;
                    *pos = new_pos;
                    fprintf(stderr, "New best board\n");
                }
            // }
        }
       */
    }
}
void minimax ( struct strat_board * b , int * mark , struct pos * pos , int n ) { int p = b -> current_player ; if ( ( n == 0 ) || ( b -> players [ p ] . l == ( ( p == 0 ) ? 0 : N - 1 ) ) ) { * mark = board_value ( b ) ; return ; } else { if ( p == get_current_player ( & b -> board ) ) { * mark = -1 ; } else { * mark = 200 ; } int moves_nb = 0 ; int t [ N ] [ N ] ; for ( int i = 0 ; i < N ; i ++ ) { for ( int j = 0 ; j < N ; j ++ ) { t [ i ] [ j ] = 0 ; } } paths ( b , t , b -> players [ p ] . c , b -> players [ p ] . l , 0 , p ) ; t [ b -> players [ p ] . l ] [ b -> players [ p ] . c ] = -1 ; fprintf ( stderr , " \n " ) ; for ( int i = 0 ; i < N ; i ++ ) { for ( int j = 0 ; j < N ; j ++ ) { fprintf ( stderr , " \t " , t [ i ] [ j ] ) ; } fprintf ( stderr , " \n " ) ; } fprintf ( stderr , " \n " ) ; for ( int i = 0 ; i < N ; i ++ ) { for ( int j = 0 ; j < N ; j ++ ) { if ( t [ i ] [ j ] == 1 ) { struct strat_board b_cpy = * b ; move_pawn_strat ( & b_cpy , j , i ) ; struct pos new_pos = { . c = j , . l = i , . d = -1 } ; int new_mark ; minimax ( & b_cpy , & new_mark , & new_pos , n - 1 ) ; if ( ( p == get_current_player ( & b -> board ) ) && new_mark > * mark ) { * mark = new_mark ; * pos = new_pos ; fprintf ( stderr , " \n " ) ; } else if ( ( p == ( get_current_player ( & b -> board ) + 1 ) % 2 ) && new_mark < * mark ) { * mark = new_mark ; * pos = new_pos ; fprintf ( stderr , " \n " ) ; } } } } } }
Returns and integer indicating the best mark you can get with a specific board state
by testing the next n turns.
Returns and integer indicating the best mark you can get with a specific board state by testing the next n turns .
/*
        // Initialize
        pos->c = -1;
        pos->l = -1;
        pos->d = -1;
        */ // play the possible moves from this state of the board // and keep in memory the best one. // --- moves --- // /* VERSION 1
        // there are 12 possible moves
        // 0..3 : normal moves ; 4..7 : jumps over ; 7..11 : diagonals.
        
        int col_move[12] = {-1, 0, 1, 0, -2, 0, 2, 0, -1, 1, 1, -1};
        int row_move[12] = {0, -1, 0, 1, 0, -2, 0, 2, -1, -1, 1, 1};

        fprintf(stderr, "Ca va tourner pour les mouvements\n");
        
        for (int i = 0; i < 12; i++) {
            
            //fprintf(stderr, "Et un petit tour\n");
            
            if (is_movement_allowed(b, b->players[p].c + col_move[i], b->players[p].l + row_move[i])) {
                
                struct strat_board b_cpy = *b;
                move_pawn_strat(&b_cpy, b->players[p].c + col_move[i], b->players[p].l + row_move[i]);
                struct pos new_pos = {.c = b->players[p].c + col_move[i], .l = b->players[p].l + row_move[i], .d = -1};
                int new_mark;
                minimax(&b_cpy, &new_mark, &new_pos, n - 1);
                if ((p == get_current_player(&b->board)) && new_mark > *mark) {
                    *mark = new_mark;
                    *pos = new_pos;
                    fprintf(stderr, "New best board\n");
                } else if ((p == (get_current_player(&b->board) + 1) % 2) && new_mark < *mark) {
                    *mark = new_mark;
                    *pos = new_pos;
                    fprintf(stderr, "New best board\n");
                }
                
            }
            
        }
         */ /* VERSION 2 */ // TEST // // ---- // // ------------- // /*
        // -- bridges -- //
        struct pos bridges[2 * N * N];
        int bridges_nb = 0;
        
        // Calculate the most profitable bridges.
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if(is_blockable_strat(b, j, i, 0)) {
                    bridges[bridges_nb].c = j;
                    bridges[bridges_nb].l = i;
                    bridges[bridges_nb].d = 0;
                    bridges_nb++;
                }
                if(is_blockable_strat(b, j, i, 1)) {
                    bridges[bridges_nb].c = j;
                    bridges[bridges_nb].l = i;
                    bridges[bridges_nb].d = 1;
                    bridges_nb++;
                }
            }
        }
        
        fprintf(stderr, "Ca va tourner pour les murs\n");
        
        for (int i = 0; i < bridges_nb; i++) {
            
            // if (is_blockable_strat(b, bridges[i].c, bridges[i].l, bridges[i].d)) {
                
                struct strat_board b_cpy = *b;
                place_wall_strat(&b_cpy, bridges[i].c, bridges[i].l, bridges[i].d);
                struct pos new_pos = {.c = bridges[i].c, .l = bridges[i].l, .d = bridges[i].d};
                int new_mark;
                minimax(&b_cpy, &new_mark, &new_pos, n - 1);
                if ((p == get_current_player(&b->board)) && new_mark > *mark) {
                    *mark = new_mark;
                    *pos = new_pos;
                    fprintf(stderr, "New best board\n");
                } else if ((p == (get_current_player(&b->board) + 1) % 2) && new_mark < *mark) {
                    *mark = new_mark;
                    *pos = new_pos;
                    fprintf(stderr, "New best board\n");
                }
                
            // }
            
        }
        // ------------- //
       */