Browse Source

Adaptation pour les nouvelles règles

master
Bastien 8 years ago
committed by Squiz
parent
commit
a854102fb6
1 changed files with 110 additions and 106 deletions
  1. +110
    -106
      main.c

+ 110
- 106
main.c View File

@ -17,6 +17,7 @@
enum bool {false, true};
enum validation_movement_t {neighbour_valid, jump, jump_valid, invalid};
enum direction_t { left, right, up_left, up_right, down_left, down_right };
enum api_function_t {ia_lib_init, ia_start_match, ia_start_game, ia_end_game , ia_end_match, ia_next_move};
@ -51,9 +52,9 @@ enum bool ia_call_function(const struct player_t player, const enum api_function
unsigned int a; int b; enum hole_t c;
void *d, *e;
if(!player.ia_lib_p) {
#ifdef debug
#ifdef debug
fputs("the player is not a strategy.\n",stderr);
#endif
#endif
return false;
}
va_start(ap, result);
@ -101,9 +102,9 @@ enum bool ia_call_function(const struct player_t player, const enum api_function
}
res = true;
} else {
#ifdef debug
#ifdef debug
fprintf(stderr,"function \"%s\" not found in strategy. (%s)\n", function_name, error);
#endif
#endif
res = false;
}
va_end(ap);
@ -130,8 +131,6 @@ ssize_t move_calculation(const size_t index, const enum direction_t move) {
block -= 2;
offset = index - index_lines[line];
/* printf("line %d, offset %d, block %d\n", line, offset,block); */
switch(move) {
case left:
return offset==0?-1:index-1;
@ -184,90 +183,89 @@ enum bool search(const size_t *tab, const size_t length, const size_t value) {
}
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) {
enum validation_movement_t 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;
#ifdef debug
/* si c'est le dernier mouvement, on ne stationne pas sur une branche */
if(last_move && previous_move.start_pos != -1 && previous_move.end_pos != -1) {
#ifdef debug
fputs("vérification de ne pas stationner sur une branche\n", stderr);
#endif
/* ne pas faire les branches de départ et d'arrivée */
for(j = (((player.branch-1)%3)+1)%6; j!=((player.branch-1)%3) ; j=(j+(j==((player.branch-1)%3)+2?2:1))%6 ) {
if(search(start_position[j],10,previous_move.end_pos))
return invalid;
}
return jump_valid;
}
#ifdef debug
fprintf(stderr, "=== validation de %d → %d===\n", move.start_pos, move.end_pos);
#endif
#endif
if(move.start_pos < 0 || move.end_pos < 0 || move.start_pos > 120 || move.end_pos > 120)
return false;
return invalid;
/* on vérifie que la case appartient au joueur */
if(game.board[move.start_pos] != player.branch )
{
#ifdef debug
if(game.board[move.start_pos] != player.branch ) {
#ifdef debug
fprintf(stderr, "la case %d n'appartient pas au joueur\n",move.start_pos);
#endif
return false;
#endif
return invalid;
}
/* si ce n'est pas le premier mouvement, on peut rester sur place */
if(previous_move.start_pos != -1 && previous_move.end_pos != -1 && move.start_pos == move.end_pos)
return true;
return jump;
/* on vérifie que la case de destination est libre */
if(game.board[move.end_pos] != none) {
#ifdef debug
/* if(game.board[move.end_pos] != none) {
#ifdef debug
fprintf(stderr, "la case %d de destination n'est pas libre\n", move.end_pos);
#endif
return false;
#endif
return invalid;
}
*/
/* on vérifie le collage si ce n'est pas le premier mouvement */
if(previous_move.start_pos != -1 && previous_move.end_pos != -1 && move.start_pos != previous_move.end_pos) {
#ifdef debug
#ifdef debug
fputs("le pion déplacé n'est pas le même qu'au mouvement précédent\n", stderr);
#endif
return false;
}
/* si c'est le dernier mouvement, on ne stationne pas sur une branche */
if(last_move) {
#ifdef debug
fputs("vérification de ne pas stationner sur une branche\n", stderr);
#endif
/* ne pas faire les branches de départ et d'arrivée */
for(j = (((player.branch-1)%3)+1)%6; j!=((player.branch-1)%3) ; j=(j+(j==((player.branch-1)%3)+2?2:1))%6 ) {
if(search(start_position[j],10,move.end_pos))
return false;
}
#endif
return invalid;
}
/* on regarde autour */
#ifdef debug
#ifdef debug
fputs("on regarde les voisins\n", stderr);
#endif
#endif
j = 0;
do {
if( (dest = move_calculation( (size_t) move.start_pos, j)) != -1 ) {
#ifdef debug
#ifdef debug
fprintf(stderr, "%d → %zu (j=%zu) ?\n", move.start_pos, dest, j);
#endif
#endif
switch(((dest == move.end_pos)?1:0)+((game.board[dest] == none)?2:0)) {
case 0: /*on veut pas y aller mais la place est occupée. peut etre qu'on veut faire le saut */
if((dest2 = move_calculation(dest,j)) != -1) {
#ifdef debug
#ifdef debug
fprintf(stderr, "%zu → %zu (j=%zu) ?\n", dest, dest2, j);
#endif
#endif
switch(((dest2 == move.end_pos)?1:0)+((game.board[dest2] == none)?2:0)) {
case 1: /* on veut y aller mais la place est occupée */ return false;
case 3: /* on veut y aller et la place est libre */ return true;
case 1: /* on veut y aller mais la place est occupée (déjà traité plus haut) */ return invalid;
case 3: /* on veut y aller et la place est libre */ return jump;
}
}
break;
case 1: /*on veut y aller mais la place est occupée*/
return false;
case 1: /*on veut y aller mais la place est occupée (déjà traité plus haut) */
return invalid;
case 3: /*on veut y aller et la place est libre*/
return (previous_move.start_pos == -1 && previous_move.end_pos == -1 && last_move );
return (previous_move.start_pos == -1 && previous_move.end_pos == -1)?neighbour_valid:invalid;
}
}
} while(++j < 6);
return false;
return invalid;
}
enum bool winner(const struct player_t player, const size_t start_position[6][10], const struct game_state_t game) {
@ -308,11 +306,10 @@ void save(const char *filename, const struct player_t *player_state, const int n
fputs("\n", file);
fclose(file);
}
#ifdef debug
#ifdef debug
else
fprintf(stderr, "cannot open file \"%s\"\n", filename);
#endif
printf("→ %d \n", nb_game_end);
#endif
}
int main(int argc, char** argv) {
@ -329,6 +326,7 @@ int main(int argc, char** argv) {
int nb_game, nb_player, nb_game_end, nb_player_end;
int i, j, k;
char *buffer;
enum validation_movement_t validation_movement;
/* heure de début du match et tableaux pour stocker les gagnants et la durée des parties */
time_t time_start_match, *duration_games;
@ -368,14 +366,14 @@ int main(int argc, char** argv) {
/* on choisit de placer un joueur réel ou une stratégie */
if( (rand()%(nb_player-i)) < (argc-j) ) {
/* on ajoute une stratégie */
#ifdef debug
#ifdef debug
fprintf(stderr,"strategy %s (%d)\n", argv[j], i);
#endif
#endif
player_state[i].ia_lib_p = dlopen(argv[j], RTLD_LAZY);
if( (buffer = (char*) dlerror()) != NULL ) {
#ifdef debug
#ifdef debug
fprintf(stderr,"error while loading %s : %s (%d)\n", argv[j], buffer, i);
#endif
#endif
/* échec du chargement, on décharge toutes les stratégies précédement chargées */
for( j=0 ; j<i ; j++ )
if( player_state[j].ia_lib_p )
@ -387,38 +385,37 @@ int main(int argc, char** argv) {
j++;
} else {
/* on ajoute un joueur réel */
#ifdef debug
#ifdef debug
fprintf(stderr,"real player (%d)\n", i);
#endif
#endif
player_state[i].ia_lib_p = NULL;
}
/* on vérifie le nom */
if(player_state[i].name[49] != '\0') {
#ifdef debug
/* petite vérification sur le nom */
#ifdef debug
if(player_state[i].name[49] != '\0')
fprintf(stderr,"warning : the length of the player's name %d must be to 49 characters maximum.\n", i);
#endif
} else
player_state[i].name[49] = '\0';
#endif
player_state[i].name[49] = '\0';
}
/* on initialise les tableaux pour stocker les gagnants et la durée de chaque partie */
if((winner_games = (int*) malloc(nb_game*sizeof(int))) == NULL) {
#ifdef debug
#ifdef debug
fputs("malloc error\n", stderr);
#endif
#endif
return 6;
}
if((duration_games = (time_t*) malloc(nb_game*sizeof(time_t))) == NULL) {
#ifdef debug
#ifdef debug
fputs("malloc error\n", stderr);
#endif
#endif
return 6;
}
/* ouverture de la fenêtre graphique */
puts("(GUI) Opening window");
struct gui_resource_t gui_res = display_start(gui_res);
/* dlsym inutile à cause du bug dlsym sdl (il faut trouver une meilleure solution) */
/* dlsym inutile, sert à contourner le bug dlsym sdl sur openbsd */
dlsym(NULL,"");
dlerror();
@ -435,9 +432,9 @@ int main(int argc, char** argv) {
int quit = 0;
for( nb_game_end = 0 ; nb_game_end < nb_game && !quit ; nb_game_end++ ) {
#ifdef debug
#ifdef debug
fprintf(stderr,"%d %s left\n", nb_game, nb_game>1?"games":"game");
#endif
#endif
duration_games[nb_game_end] = time(NULL);
winner_games[nb_game_end] = -1;
@ -468,20 +465,14 @@ int main(int argc, char** argv) {
free(buffer);
}
#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 */
i = 0;
nb_player_end = 0;
while(nb_player_end < nb_player-1 && !quit) {
#ifdef debug
#ifdef debug
fprintf(stderr, "joueur %d (%s)\n", i, player_state[i].name);
#endif
#endif
game_state_copy = game_state;
previous_movement.start_pos=-1; previous_movement.end_pos=-1;
first_move = 1;
@ -490,32 +481,24 @@ int main(int argc, char** argv) {
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 */
printf("(GUI) Moving pawn %d → hole %d\n", movement.start_pos, movement.end_pos);
if(movement.start_pos != movement.end_pos && movement.start_pos >= 0 && movement.end_pos >= 0 && movement.start_pos < 121 && movement.end_pos < 121)
/* on effectue le mouvement à l'écran */
validation_movement = valid_move(movement, previous_movement, player_state[i], game_state_copy, start_position, !next_move);
#ifdef debug
switch(validation_movement) {
case invalid: fputs("validation → invalide\n", stderr); break;
case jump: fputs("validation → jump\n", stderr); break;
case neighbour_valid: fputs("validation → voisin\n", stderr); break;
case jump_valid: fputs("validation → commit jump\n", stderr); break;
}
#endif
if(validation_movement != jump_valid && movement.start_pos != movement.end_pos && movement.start_pos >= 0 && movement.end_pos >= 0 && movement.start_pos < 121 && movement.end_pos < 121)
quit += display_animove_pawn(gui_res, game_state_copy, player_state[i].branch, movement.start_pos, movement.end_pos);
if(valid_move(movement, previous_movement, player_state[i], game_state_copy, start_position, !next_move)) {
#ifdef debug
fprintf(stderr, "mouvement (%d,%d) valide\n", movement.start_pos, movement.end_pos);
#endif
/* on effectue le mouvement */
game_state_copy.board[movement.start_pos]=none;
game_state_copy.board[movement.end_pos]=player_state[i].branch;
if(next_move)
previous_movement=movement;
else {
game_state=game_state_copy; /* commit */
if(winner(player_state[i], start_position, game_state)) {
nb_player_end=nb_player /* la partie se termine */;
puts("le joueur a gagné");
winner_games[nb_game_end] = i;
ia_call_function(player_state[i], ia_end_game, NULL);
}
}
} else {
#ifdef debug
/* on cherche à valider le coup */
if(validation_movement == invalid) {
#ifdef debug
fprintf(stderr, "mouvement (%d,%d) invalide\n",movement.start_pos, movement.end_pos);
#endif
#endif
if( (buffer = (char*) malloc( 28 *sizeof(char) ) ) == NULL)
display_animsg(gui_res, game_state, player_state[i].branch, "Coup non valide", 1000);
else {
@ -527,8 +510,7 @@ int main(int argc, char** argv) {
nb_player_end++;
puts("perdu");
/* on enlève les pions du joueur */
j=0;
k=0;
j=0; k=0;
do {
if(game_state.board[j] == player_state[i].branch) {
game_state.board[j] = none;
@ -537,10 +519,31 @@ int main(int argc, char** argv) {
} while(++j < 121 && k < 10);
ia_call_function(player_state[i], ia_end_game, NULL);
}
next_move=0;
}
if(validation_movement == jump || validation_movement == neighbour_valid) {
/* on effectue le mouvement */
#ifdef debug
fprintf(stderr, "mouvement (%d,%d) valide\n",movement.start_pos, movement.end_pos);
#endif
game_state_copy.board[movement.start_pos]=none;
game_state_copy.board[movement.end_pos]=player_state[i].branch;
previous_movement=movement;
}
if(validation_movement == jump_valid || validation_movement == neighbour_valid) {
/* commit */
#ifdef debug
fputs("commit\n",stderr);
#endif
game_state=game_state_copy; /* commit */
if(winner(player_state[i], start_position, game_state)) {
nb_player_end=nb_player /* la partie se termine */;
puts("le joueur a gagné");
winner_games[nb_game_end] = i;
ia_call_function(player_state[i], ia_end_game, NULL);
}
}
first_move=0;
} while(next_move && !quit);
} while(validation_movement == jump && nb_player_end < nb_player-1 && !quit);
/* on sélectionne le joueur suivant */
j=i;
do {
@ -584,3 +587,4 @@ int main(int argc, char** argv) {
return 0;
}

Loading…
Cancel
Save