void else_of_player_one(t_all *a) { a->nb1 = 0; my_printf("\033[31mChoisissez une ligne valide\033[0m\n"); print_allum(a); player_one(a); }
int zz::map::solomax( int iterations, bool use_heuristic ) { #ifdef DEBUG_MAP fprintf( stderr, "%*s(%d,%d) vs (%d,%d) solomax:\n", ( 10 - iterations ) * 2, "", player_one().x( ), player_one().y( ), player_two().x( ), player_two().y( ) ); #endif _max = INT_MIN; for( int i = 0; i < 4; ++i ) { zz::map::location player_one = _player_one.adjacent( i ); if( is_wall( player_one ) ) { _mins[i] = INT_MIN; } else { if( iterations > 0 ) { // look ahead at the next solomax int result = 0; // save the current state int max = _max; int mins[4]; for( int k = 0; k < 4; ++k ) { mins[k] = _mins[k]; } zz::map::location player_one_original( _player_one ); // update the map set_player_one( player_one ); // get the next solomax result = solomax( iterations - 1, use_heuristic ) * 0.999; // restore the current state set_player_one( player_one_original ); set_is_wall( player_one, false ); _max = max; for( int k = 0; k < 4; ++k ) { _mins[k] = mins[k]; } _mins[i] = result; } else { ++__minimax_leafs; if( use_heuristic ) { _mins[i] = area_available_from( player_one ) * 128; } else { _mins[i] = 0; } } } if( _mins[i] > _max ) { _max = _mins[i]; } } #ifdef DEBUG_MAP fprintf( stderr, "%*s(%d,%d) vs (%d,%d) solomax.mins(): [", ( 10 - iterations ) * 2, "", player_one().x( ), player_one().y( ), player_two().x( ), player_two().y( ) ); for( int i = 0; i < 4; ++i ) { fprintf( stderr, "%d:%d", i, _mins[i] ); if( i != 3 ) fprintf( stderr, ", " ); } fprintf( stderr, "] (%d)\n", _max ); #endif return _max; }
int zz::map::minimax( int iterations, bool use_heuristic ) { #ifdef DEBUG_MAP fprintf( stderr, "%*s(%d,%d) vs (%d,%d) minimax:\n", ( 10 - iterations ) * 2, "", player_one().x( ), player_one().y( ), player_two().x( ), player_two().y( ) ); #endif // calculate the outcome of all possible moves of player_one and player_two _max = INT_MIN; for( int i = 0; i < 4; ++i ) { _mins[i] = INT_MAX; for( int j = 0; j < 4; ++j ) { if( _mins[i] < _max ) break; zz::map::location player_one = _player_one.adjacent( i ); zz::map::location player_two = _player_two.adjacent( j ); bool player_one_dies = is_wall( player_one ); bool player_two_dies = is_wall( player_two ); int result = 0; if( player_one == player_two || ( player_two_dies && player_one_dies ) ) { // draw result = -64; } else if( player_two_dies && !player_one_dies ) { // win result = INT_MAX; } else if( !player_two_dies && player_one_dies ) { // loss result = INT_MIN; } else if( !use_heuristic && iterations <= 0 ) { result = 0; ++__minimax_leafs; } else { // nothing interesting enough to end the game happened yet // save the current state int max = _max; int mins[4]; for( int k = 0; k < 4; ++k ) { mins[k] = _mins[k]; } zz::map::location player_one_original( _player_one ); zz::map::location player_two_original( _player_two ); // update the map set_player_one( player_one ); set_player_two( player_two ); if( iterations > 0 ) { // get the next minimax result = minimax( iterations - 1, use_heuristic ) * 0.999; } else { // get the voronoi_territory result = territory() * 128; ++__minimax_leafs; } // restore the current state set_player_one( player_one_original ); set_player_two( player_two_original ); set_is_wall(player_one, false); set_is_wall(player_two, false); _max = max; for( int k = 0; k < 4; ++k ) { _mins[k] = mins[k]; } } if( result < _mins[i] ) _mins[i] = result; } if( _mins[i] > _max ) { _max = _mins[i]; } } #ifdef DEBUG_MAP fprintf( stderr, "%*s(%d,%d) vs (%d,%d) minimax.mins(): [", ( 10 - iterations ) * 2, "", player_one().x( ), player_one().y( ), player_two().x( ), player_two().y( ) ); for( int i = 0; i < 4; ++i ) { fprintf( stderr, "%d:%d", i, _mins[i] ); if( i != 3 ) fprintf( stderr, ", " ); } fprintf( stderr, "] (%d)\n", _max ); #endif return _max; }
int zz::map::territory( ) const { int player_one_territory = 0; int player_two_territory = 0; int player_one_distances[width() * height()]; int player_two_distances[width() * height()]; for( int* i = player_one_distances; i < player_one_distances + width() * height(); ) { ( *i++ ) = -1; } for( int* i = player_two_distances; i < player_two_distances + width() * height(); ) { ( *i++ ) = -1; } int todo[width() * height()]; int counted_locations[width() * height()]; // initialize everything for player_one for( int* i = counted_locations; i < counted_locations + width() * height(); ) { ( *i++ ) = false; } int* current_todo = todo; int* todo_end = todo; (*todo_end++) = player_one().x() + width() * player_one().y(); counted_locations[player_one().x( ) + width( ) * player_one().y( )] = true; player_one_distances[player_one().x( ) + width( ) * player_one().y( )] = 0; // find the distance to every location player_one can reach while( current_todo < todo_end ) { zz::map::location current( *current_todo % width( ), *current_todo / width( ) ); ++player_one_territory; // everything will belong to player one, until we start counting player_two int current_index = current.x( ) + width() * current.y( ); int distance = player_one_distances[current_index]; for( int i = 0; i < 4; ++i ) { // add all accessible neighbors of this location to the todo list zz::map::location neighbor = current.adjacent( i ); int neighbor_index = neighbor.x( ) + width( ) * neighbor.y( ); if( !counted_locations[neighbor_index] && !is_wall(neighbor_index) ) { player_one_distances[neighbor_index] = distance + 1; counted_locations[neighbor_index] = true; ( *todo_end++ ) = neighbor_index; } } ++current_todo; } // re-init for player_two for( int* i = counted_locations; i < counted_locations + width() * height(); ) { ( *i++ ) = false; } current_todo = todo; todo_end = todo; (*todo_end++) = player_two().x() + width() * player_two().y(); counted_locations[player_two().x( ) + width( ) * player_two().y( )] = true; player_two_distances[player_two().x( ) + width( ) * player_two().y( )] = 0; // find the distance to every location player_one can reach and adjust ownership of contested locations while( current_todo < todo_end ) { zz::map::location current( *current_todo % width( ), *current_todo / width( ) ); int current_index = current.x( ) + width() * current.y( ); int distance = player_two_distances[current_index]; int player_one_distance = player_one_distances[current_index]; if( player_one_distance == -1 || distance < player_one_distance ) { ++player_two_territory; // everything will belong to player one, until we start counting player_two } if ( distance < player_one_distance || distance == player_one_distance) { --player_one_territory; // everything will belong to player one, until we start counting player_two } for( int i = 0; i < 4; ++i ) { // add all accessible neighbors of this location to the todo list zz::map::location neighbor = current.adjacent( i ); int neighbor_index = neighbor.x( ) + width( ) * neighbor.y( ); if( !counted_locations[neighbor_index] && !is_wall(neighbor_index) ) { player_two_distances[neighbor_index] = distance + 1; counted_locations[neighbor_index] = true; ( *todo_end++ ) = neighbor_index; } } ++current_todo; } return player_one_territory - player_two_territory; }