@ -17,7 +17,6 @@ enum api_function_t {ia_lib_init, ia_start_match, ia_start_game, ia_end_game , i
struct player_t {
enum bool play ;
size_t branch ;
unsigned int error ;
void * ia_lib_p ;
@ -92,7 +91,7 @@ enum bool ia_call_function(const struct player_t player, enum api_function_t api
/* pour associer une branche de l'étoile à un joueur */
size_t star_branch ( unsigned int nb_player , size_t index ) {
return ( ( nb_player % 2 & & index > nb_player / 2 ) | | ( ! ( nb_player % 2 ) & & index > = nb_player / 2 ) ) ? index - nb_player + ( nb_player > 3 ? nb_player > = 6 ? 2 : 1 : 0 ) + 4 : index ;
return ( nb_player = = 4 ) ? 1 + index + ( index > = 2 ? 1 : 0 ) : ( 6 / nb_player ) * index ;
}
ssize_t move_calculation ( size_t index , enum direction_t move ) {
@ -149,9 +148,45 @@ ssize_t move_calculation(size_t index, enum direction_t move) {
}
}
enum bool valid_move ( const struct move_t move , const struct player_t player , const struct game_state_t game ) {
enum bool search ( const size_t * tab , size_t length , size_t value ) {
size_t first , last , middle ;
first = 0 ;
last = length - 1 ;
while ( first < = last ) {
middle = ( last - first ) / 2 ;
if ( tab [ middle ] = = value )
return true ;
if ( tab [ middle ] < value )
first = middle + 1 ;
else
last = middle - 1 ;
}
return false ;
}
enum bool valid_move ( const struct move_t move , const struct move_t previous_move , const struct player_t player , const struct game_state_t game , const size_t start_position [ 6 ] [ 10 ] , const enum bool last_move ) {
size_t j ;
ssize_t dest , dest2 ;
/* on considère que c'est le premier saut (pas de vérification du collage) si le previous_move = (-1,-1) */
if ( previous_move . start_pos = = - 1 & & previous_move . end_pos = = - 1 ) {
if ( move . start_pos = = - 1 & & move . end_pos = = - 1 ) /* on regarde si on a -1 -1 */
return true ;
if ( game . board [ move . start_pos ] ! = ( player . branch ) + 1 ) /* on vérifie que la case appartient au joueur */
return false ;
} else {
/* on vérifie le collage */
if ( move . start_pos ! = previous_move . end_pos )
return false ;
}
if ( last_move ) {
/* si c'est le dernier mouvement, on ne stationne pas sur une branche */
for ( j = ( ( player . branch % 3 ) + 1 ) % 6 ; j ! = ( player . branch % 3 ) ; j = ( j + ( j = = ( player . branch % 3 ) + 2 ? 2 : 1 ) ) % 6 ) /* ne pas faire les branches de départ et d'arrivée */
if ( search ( start_position [ j ] , 10 , move . end_pos ) )
return false ;
}
/* on regarde si la case de départ appartient au joueur + collage */
if ( ( game . board [ move . start_pos ] ! = ( player . branch ) + 1 ) | | move . start_pos = = - 1 | | move . end_pos = = - 1 )
return false ; /* la case de départ ne comporte pas le pion du joueur */
/* on regarde autour */
@ -182,7 +217,7 @@ enum bool valid_move(const struct move_t move, const struct player_t player, con
enum bool winner ( struct player_t player , const size_t start_position [ 6 ] [ 10 ] , const struct game_state_t game ) {
size_t final_branch , j ;
final_branch = player . branch + ( player . branch > 2 ? - 3 : 3 ) ;
final_branch = ( player . branch + 3 ) % 6 ;
j = 0 ;
do
if ( game . board [ start_position [ final_branch ] [ j ] ] ! = ( player . branch ) + 1 )
@ -213,13 +248,13 @@ int main(int argc, char** argv) {
/* on lit le nombre de parties */
if ( ! char_to_int ( argv [ 1 ] , & nb_game ) | | nb_game < = 0 ) {
fprintf ( stderr , " %s must be a positive number. \n " , argv [ 1 ] ) ;
fprintf ( stderr , " nb_game ( %s) must be a positive number.\n " , argv [ 1 ] ) ;
return 2 ;
}
/* on lit le nombre de joueurs */
if ( ! char_to_int ( argv [ 2 ] , & nb_player ) | | nb_player < = 0 ) {
fprintf ( stderr , " %s must be a positive number .\n " , argv [ 2 ] ) ;
if ( ! char_to_int ( argv [ 2 ] , & nb_player ) | | nb_player < 2 | | nb_player > 6 | | nb_player = = 5 ) {
fprintf ( stderr , " nb_player (%s) must be 2, 3, 4 or 6 .\n " , argv [ 2 ] ) ;
return 3 ;
}
@ -286,35 +321,38 @@ int main(int argc, char** argv) {
/* initialisation : on place les pions */
for ( i = 0 ; i < nb_player ; i + + ) {
player_state [ i ] . error = 0 ;
player_state [ i ] . play = true ;
player_state [ i ] . branch = star_branch ( nb_player , i ) ;
for ( j = 0 ; j < 10 ; j + + )
game_state . board [ start_position [ player_state [ i ] . branch ] [ j ] ] = ( player_state [ i ] . branch ) + 1 ;
}
# ifdef debug
for ( i = 0 ; i < 121 ; i + + )
if ( game_state . board [ i ] )
printf ( " %d %d \n " , i , game_state . board [ i ] ) ;
# endif
/* chaque joueur joue */
nb_player_end = 0 ;
i = 0 ;
nb_player_end = 0 ;
while ( nb_player_end < nb_player - 1 ) {
+ + i ;
i % = nb_player ;
/* si le joueur peut jouer */
if ( player_state [ i ] . play ) {
if ( player_state [ i ] . error < 3 ) {
game_state_copy = game_state ;
first_move = 1 ;
do { /* on demande la suite de coup */
movement . start_pos = - 1 ;
movement . end_pos = - 1 ;
previous_movement . start_pos = - 1 ;
previous_movement . end_pos = - 1 ;
game_state_ia_copy = game_state_copy ;
/* on suppose qu'on a une stratégie */
ia_call_function ( player_state [ i ] , ia_next_move , & next_move , & game_state_ia_copy , first_move , & movement ) ;
/* on cherche à valider le coup */
if ( ( ! first_move & & previous_movement . end_pos = = movement . start_pos & & valid_move ( movement , player_state [ i ] , game_state_copy ) ) | | ( first_move & & movement . start_pos = = movement . end_pos ) | | ( first_move & & valid_move ( movement , player_state [ i ] , game_state_copy ) ) ) {
if ( valid_move ( movement , previous_ movement, player_state [ i ] , game_state_copy , start_position , next_move ) ) {
/* on effectue le mouvement */
game_state_copy . board [ movement . start_pos ] = none ;
game_state_copy . board [ movement . end_pos ] = ( player_state [ i ] . branch ) + 1 ;
@ -323,22 +361,16 @@ int main(int argc, char** argv) {
else {
game_state = game_state_copy ; /* commit */
if ( winner ( player_state [ i ] , start_position , game_state ) ) {
player_state [ i ] . play = false ;
nb_player_end + + ;
nb_player_end = nb_player - 1 /* la partie se termine */ ;
puts ( " le joueur a gagné " ) ;
ia_call_function ( player_state [ i ] , ia_end_game , NULL ) ;
}
}
} else {
if ( + + player_state [ i ] . error = = 3 ) {
player_state [ i ] . play = false ;
if ( + + ( player_state [ i ] . error ) = = 3 ) {
nb_player_end + + ;
puts ( " perdu " ) ;
ia_call_function ( player_state [ i ] , ia_end_game , NULL ) ;
/* on enleve les pions du joueur */
for ( j = 0 ; j < 121 ; j + + ) /* mauvais */
if ( game_state . board [ j ] = = ( player_state [ i ] . branch ) + 1 )
game_state . board [ j ] = none ;
}
next_move = 0 ;
}
@ -347,8 +379,10 @@ int main(int argc, char** argv) {
}
}
puts ( " fin de la partie " ) ;
/* pour le dernier joueur */
ia_call_function ( player_state [ ( ( + + i ) % nb_player ) ] , ia_end_game , NULL ) ;
/* pour les joueurs qui n'ont pas perdus */
for ( i = 0 ; i < nb_player ; i + + )
if ( player_state [ i ] . error < 3 )
ia_call_function ( player_state [ ( ( + + i ) % nb_player ) ] , ia_end_game , NULL ) ;
}