Dumb but not dumber IA
This commit is contained in:
parent
033a436be2
commit
87e7ff5829
7 changed files with 145 additions and 34 deletions
|
@ -24,4 +24,9 @@ typedef enum {
|
|||
ALMOST,
|
||||
} e_status;
|
||||
|
||||
typedef enum {
|
||||
HUMAN,
|
||||
RANDOM,
|
||||
CLEVER,
|
||||
} e_tactic;
|
||||
#endif /*COMMON*/
|
||||
|
|
17
include/ia.h
Normal file
17
include/ia.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef IA_H
|
||||
#define IA_H
|
||||
#include "common.h"
|
||||
#include "model.h"
|
||||
/*!
|
||||
* This function modify the move in parameter in order to get a valid move (1) randomly if tactic is 0 or
|
||||
* (2) in a clever way if tactic is 1 in the corresponding utictactoe u.
|
||||
*
|
||||
* \param p_uttt a pointer on a s_utictactoe.
|
||||
* \param p_move a pointer on a s_move to be modified.
|
||||
* \param tactic an e_tactic set to 0 for random strategy and 1 for clever one.
|
||||
*/
|
||||
void best_move(s_utictactoe* p_uttt, s_move* p_move, e_tactic tactic);
|
||||
|
||||
s_tictactoe * clone_ttt( s_tictactoe * p_ttt );
|
||||
e_location get_best_random_position( s_tictactoe * p_uttt, e_player player);
|
||||
#endif
|
|
@ -25,8 +25,9 @@ int elocation_to_coord(e_location l);
|
|||
* \param p_move a pointer on a s_move to be modified.
|
||||
* \param v a pointer on the view to use.
|
||||
*/
|
||||
void set_next_player_move(s_move * p_move, p_view v);
|
||||
void set_next_player_move(s_move * p_move, p_view v, e_tactic tactic);
|
||||
|
||||
void display_winner(p_view v);
|
||||
/*!
|
||||
* This function free all the memory used by a given view which
|
||||
* reference is given.
|
||||
|
|
|
@ -3,4 +3,4 @@ set(CMAKE_C_FLAGS "-std=c99 -lncurses -g -Wall")
|
|||
set(CMAKE_INSTALL_PREFIX ".")
|
||||
include_directories(../include)
|
||||
project(utictactoe)
|
||||
add_executable(${PROJECT_NAME} utictactoe.c model.c view.c)
|
||||
add_executable(${PROJECT_NAME} utictactoe.c model.c view.c ia.c)
|
||||
|
|
76
src/ia.c
Normal file
76
src/ia.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
#include "common.h"
|
||||
#include "model.h"
|
||||
#include "view.h"
|
||||
#include "ia.h"
|
||||
|
||||
void best_move (s_utictactoe * p_uttt, s_move * m ,e_tactic tactic)
|
||||
{
|
||||
//do{
|
||||
if ( p_uttt->inception_level == 1 ) {
|
||||
m->outer_position = get_best_random_position(
|
||||
p_uttt->outer_tictactoe,
|
||||
m->player
|
||||
);
|
||||
}
|
||||
else {
|
||||
m->outer_position = get_next_outer_position(p_uttt);
|
||||
if ( m->outer_position == FREE ) {
|
||||
do {
|
||||
m->outer_position = (e_location)(TOPLEFT + rand() % TICTACTOE_SIZE);
|
||||
} while(p_uttt->inner_tictactoes[m->outer_position]->winner != NOBODY);
|
||||
}
|
||||
|
||||
m->inner_position = get_best_random_position(
|
||||
p_uttt->inner_tictactoes[m->outer_position],
|
||||
m->player
|
||||
);
|
||||
}
|
||||
//} while (is_move_valid(p_uttt,m) != YES);
|
||||
return;
|
||||
}
|
||||
|
||||
s_tictactoe * clone_ttt( s_tictactoe * p_ttt ) {
|
||||
s_tictactoe * t = create_empty_tictactoe();
|
||||
for (int i=0; i<TICTACTOE_SIZE; i++){
|
||||
t->content[i] = p_ttt->content[i];
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
e_location get_best_random_position (s_tictactoe * p_ttt, e_player player) {
|
||||
mvwprintw(stdscr, 13, 0, " ");
|
||||
s_tictactoe * c_ttt = clone_ttt(p_ttt);
|
||||
e_player opponent = ( player == PLAYER_O )?PLAYER_X:PLAYER_O;
|
||||
|
||||
// Check if IA player can win
|
||||
for(int i=0; i<TICTACTOE_SIZE; i++) {
|
||||
if(c_ttt->content[i] == NOBODY) {
|
||||
c_ttt->content[i] = player;
|
||||
set_tictactoe_winner(c_ttt);
|
||||
if ( c_ttt->winner != NOBODY ) {
|
||||
free_tictactoe(c_ttt);
|
||||
mvwprintw(stdscr, 13, 0, "Je vais gagner ");
|
||||
return i;
|
||||
}
|
||||
c_ttt->content[i] = NOBODY;
|
||||
}
|
||||
}
|
||||
|
||||
// avoid loosing
|
||||
for(int i=0; i<TICTACTOE_SIZE; i++) {
|
||||
if(c_ttt->content[i] == NOBODY) {
|
||||
c_ttt->content[i] = opponent;
|
||||
set_tictactoe_winner(c_ttt);
|
||||
if ( c_ttt->winner != NOBODY ) {
|
||||
free_tictactoe(c_ttt);
|
||||
mvwprintw(stdscr, 13, 0, "Je ne peux pas te laisser gagner!");
|
||||
return i;
|
||||
}
|
||||
c_ttt->content[i] = NOBODY;
|
||||
}
|
||||
}
|
||||
|
||||
// We have not a winnner move...
|
||||
free_tictactoe(c_ttt);
|
||||
return (e_location)(rand() % TICTACTOE_SIZE);
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
#include "common.h"
|
||||
#include "model.h"
|
||||
#include "view.h"
|
||||
#include "ia.h"
|
||||
|
||||
#define OPTIONAL_ARGUMENT_IS_PRESENT \
|
||||
((optarg == NULL && optind < argc && argv[optind][0] != '-') \
|
||||
|
@ -46,15 +47,15 @@ int check_int_value ( char *value, int min, int max){
|
|||
|
||||
int main(int argc, char* argv[]) {
|
||||
int optc;
|
||||
int cross_ai, round_ai = 0;
|
||||
int inception_level = 0;
|
||||
e_tactic tactic_cross = HUMAN, tactic_round = HUMAN;
|
||||
int inception_level = 2;
|
||||
bool verbose, contest_mode = false;
|
||||
char * contest_file;
|
||||
static struct option long_opts[] =
|
||||
{
|
||||
{"inception-level", optional_argument, 0, 'i'},
|
||||
{"cross-ai", required_argument, 0, 'x'},
|
||||
{"round-ai", required_argument, 0, 'o'},
|
||||
{"tactic_cross", required_argument, 0, 'x'},
|
||||
{"tactic_round", required_argument, 0, 'o'},
|
||||
{"contest", required_argument, 0, 'c'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
|
@ -80,8 +81,8 @@ int main(int argc, char* argv[]) {
|
|||
case 'x':
|
||||
printf ("cross ai\n");
|
||||
if ( optarg ) {
|
||||
cross_ai = check_int_value(optarg, 0, 1);
|
||||
if ( cross_ai == -1 ) {
|
||||
tactic_cross = check_int_value(optarg, 0, 2);
|
||||
if ( tactic_cross == -1 ) {
|
||||
fprintf(stderr, "Error: incorrect cross ai value\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
@ -96,8 +97,8 @@ int main(int argc, char* argv[]) {
|
|||
case 'o':
|
||||
printf ("round ai\n");
|
||||
if ( optarg ) {
|
||||
round_ai = check_int_value(optarg, 0, 1);
|
||||
if ( round_ai == -1 ) {
|
||||
tactic_round = check_int_value(optarg, 0, 2);
|
||||
if ( tactic_round == -1 ) {
|
||||
fprintf(stderr, "Error: incorrect round ai value\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
@ -141,35 +142,23 @@ int main(int argc, char* argv[]) {
|
|||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
s_utictactoe *s = create_empty_utictactoe(1);
|
||||
srand(time(NULL));
|
||||
s_utictactoe *s = create_empty_utictactoe(inception_level);
|
||||
s_move *m = create_empty_move();
|
||||
p_view v = create_view(s);
|
||||
while (s->outer_tictactoe->winner == NOBODY) {
|
||||
m->player = get_next_player_to_play(s);
|
||||
m->outer_position=get_next_outer_position(s);
|
||||
set_next_player_move(m,v);
|
||||
m->outer_position = get_next_outer_position(s);
|
||||
if (m->player == PLAYER_X) {
|
||||
set_next_player_move(m, v, tactic_cross);
|
||||
} else {
|
||||
set_next_player_move(m, v, tactic_round);
|
||||
}
|
||||
play_move(s, m);
|
||||
}
|
||||
display_winner(v);
|
||||
getchar();//just to pause before quitting the program
|
||||
free_view(v);
|
||||
draw_utictactoe(s);
|
||||
draw_utictactoe_history(s);
|
||||
printf("The winner is : %c\n", s->outer_tictactoe->winner);
|
||||
free_move(m);
|
||||
free_utictactoe(s);
|
||||
|
||||
s = create_empty_utictactoe(2);
|
||||
m = create_empty_move();
|
||||
v = create_view(s);
|
||||
while (s->outer_tictactoe->winner == NOBODY) {
|
||||
m->player = get_next_player_to_play(s);
|
||||
m->outer_position=get_next_outer_position(s);
|
||||
set_next_player_move(m,v);
|
||||
play_move(s, m);
|
||||
m->outer_position = m->inner_position;
|
||||
}
|
||||
free_view(v);
|
||||
draw_utictactoe_history(s);
|
||||
printf("The winner is : %c\n", s->outer_tictactoe->winner);
|
||||
free_move(m);
|
||||
free_utictactoe(s);
|
||||
}
|
||||
|
|
25
src/view.c
25
src/view.c
|
@ -1,6 +1,7 @@
|
|||
#include "common.h"
|
||||
#include "model.h"
|
||||
#include "view.h"
|
||||
#include "ia.h"
|
||||
|
||||
struct view{
|
||||
s_utictactoe * p_uttt;
|
||||
|
@ -66,8 +67,15 @@ void draw_ttt(WINDOW * w, s_tictactoe * u){
|
|||
}
|
||||
}
|
||||
|
||||
void set_next_player_move(s_move * m, p_view v)
|
||||
void set_next_player_move(s_move * m, p_view v, e_tactic tactic )
|
||||
{
|
||||
|
||||
// computer player
|
||||
if(tactic != HUMAN) {
|
||||
best_move(v->p_uttt, m, tactic);
|
||||
return ;
|
||||
}
|
||||
|
||||
char * s="Player to play:%c";
|
||||
int in_x = 3, out_x = 3;
|
||||
int out_y = 2, in_y = 2;
|
||||
|
@ -242,6 +250,21 @@ int elocation_to_coord(e_location l){
|
|||
}
|
||||
}
|
||||
|
||||
void display_winner(p_view v){
|
||||
int ch = ' ';
|
||||
draw_ttt(v->w_uttt, v->p_uttt->outer_tictactoe);
|
||||
wrefresh(v->w_uttt);
|
||||
if (v->p_uttt->inception_level == 2){
|
||||
draw_ttt(v->w_ttt, v->p_uttt->inner_tictactoes[TOPLEFT]);
|
||||
}
|
||||
wrefresh(stdscr);
|
||||
do {
|
||||
mvwprintw(stdscr, 1, 0, "le gagnant est : %c, apputez sur 'entree' pour quitter",
|
||||
v->p_uttt->outer_tictactoe->winner);
|
||||
ch = wgetch(stdscr);
|
||||
} while (ch != '\n');
|
||||
|
||||
}
|
||||
void free_view(p_view v){
|
||||
delwin(v->w_uttt);
|
||||
v->w_uttt = NULL;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue