 |
Ibi Hors ligne Statut: Membre
Niveau: Elite
Points: 586
Défis: 114
Email | Message | |
Posté le 04/05/2008 10:17
Différentes IA (applications) - Deuxieme partie:Cette fois je vais vous parler de l'IA programmée pour réagir aux actions d'un humain dans un programme.
Par exemple dans un jeu d'échecs l'IA va devoir analyser la disposition des pièces de chaque joueur les risques pondérés qu'il a et ensuite lister les actions qu'il peut effectuer avant d'en choisir une et de jouer. Cette IA ne concerne que les jeux ou programme avec un déroulement au tour par tour (pour l'IA en temps réel voir la partie 3)
Ce type d'IA est assez interessant mais tout comme l'IA vocale il demande un grand nombre de tests a effectuer.
Il faut en effet que l'IA observe tous les mouvements possibles pour l'adversaire (humain ou autre IA - personnellement j'adore faire des jeux IA vs IA ...) puis affecte a chaque mouvement possible une valeur correspondant a l'importance de l'action pouvant etre effectuée. Plus l'adversaire de l'IA a de chance de faire cette action (parce qu'elle a une importance dans la partie) plus l'IA va affecter une grande valeur a cette action potentielle.
Ensuite la seconde étape consiste a voir quelles actions peut effectuer l'IA et de même affecter une valeur a chacune de ces actions (selon ce qui peut l'avantager directement et ce qui peut empêcher a l'adversaire de faire une action affectée d'une forte valeur numérique de l'adversaire).
L'IA choisit ensuite une action a effectuer d'après les critères précédent.
L'action est effectuée.
Le problème de ce raisonnement qui est le plus réaliste (puisque c'est de cette manière que nous raisonnons) c'est que la somme des tests a effectuer est très importante (surtout dans un jeu type échecs ou chaque pièce fonctionne différemment).
Pour remédier a ce problème il faut donc trouver des algorithmes permettant de supprimer une partie de ces tests.
Voici par exemple un extrait d'un code source d'un jeu en C de Zeljko Juric. Ce code contient l'intelligence artificielle d'un jeu de Reversi.
Pour le code complet (open-source) contactez moi. Le langage est en C pout ti89 (A68k)
// Tries to perform a move, and returns an advance in the material plus
// extra bonus for corners (returns zero if the move is not possible)
int try_a_move(int i,int j,char figure)
{
int captured,loc_i,loc_j,i_step,j_step,p,q,score=0;
char next;
if(board[i ][j]==BLANK_NEAR)
{
for(i_step=-1;i_step 1;i_step++)
for(j_step=-1;j_step 1;j_step++)
if(i_step||j_step)
{
loc_i=i; loc_j=j; captured=0;
do
{
next=board[loc_i+=i_step][loc_j+=j_step];
if(next BLANK_NEAR)
captured=0;
else if(next figure)
captured++;
} while(next==!figure);
if(captured)
{
loc_i=i; loc_j=j;
while(board[loc_i+=i_step][loc_j+=j_step] figure)
board[loc_i][loc_j]=figure;
score+=captured;
}
}
if(score)
{
board[i ][j]=figure;
for(p=i-1;p i+1;p++)
for(q=j-1;q j+1;q++)
if(board[p][q]==BLANK_FAR)
board[p][q]=BLANK_NEAR;
if((i==1||i==8)&&(j==1||j==8))
score+=3;
score+=!score;
}
}
return score;
}
// Performs a human move, and returns FALSE if there is no moves avaliable
BOOL human_move(char figure)
{
int i,j,score,char1,char2;
BOARD board_save;
memcpy(board_save,board,sizeof(BOARD));
if(two_players)
draw_str(Q89_92(93,130),Q89_92(34,46),
black_on_turn?>> BLACK <<:>> WHITE <<);
for(i=1;i 8;i++)
for(j=1;j 8;j++)
if(try_a_move(i,j,figure))
{
memcpy(board,board_save,sizeof(BOARD));
do
{
input_move(&char1,&char2);
if(!(score=try_a_move(char2-'0',char1-'A'+1,figure)))
draw_str(Q89_92(93,130),Q89_92(55,68),WRONG MOVE!);
} while(!score);
return TRUE;
}
draw_str(Q89_92(93,130),Q89_92(42,56),You must pass!);
getch();
return FALSE;
}
// Recursive minmax search for a best move with alpha pruning: returns best
// minmax value, and as a side effect, returns coordinates of such best move
int minmax_search(char figure,int depth,int alpha,int *best_i,int *best_j)
{
int i,j,max=-1000,score,dummy;
BOARD board_save;
*best_i=0; *best_j=0;
memcpy(board_save,board,sizeof(BOARD));
if(kbhit())
if(ngetchx()==ESC_KEY)
longjmp(jmp_buffer,1);
for(i=1;i 8;i++)
for(j=1;j 8;j++)
if((score=try_a_move(i,j,figure))) // Yes, =, not == !
{
if(depth level)
score-=minmax_search(!figure,depth+1,score-max,&dummy,&dummy);
if(level==1)
score+=5*((i==1||i==8)+(j==1||j==8)-(i==2||i==7)-(j==2||j==7));
if(score>max)
{
max=score; *best_i=i; *best_j=j;
}
else if((score==max)&&random)
{
*best_i=i; *best_j=j;
}
memcpy(board,board_save,sizeof(BOARD));
if(score alpha)
return max;
}
if(!*best_i)
return 0;
return max;
}
// Performs computer move, and returns FALSE if there is no avaliable moves
BOOL computer_move(void)
{
int best_i,best_j;
char str[50];
draw_str(Q89_92(93,130),Q89_92(42,56),Thinking...);
minmax_search(WHITE,1,1000,&best_i,&best_j);
if(!best_i)
draw_str(Q89_92(93,130),Q89_92(50,66),I must pass!);
else
{
try_a_move(best_i,best_j,WHITE);
sprintf(str,My move: %c%d,best_j-1+'A',best_i);
draw_str(Q89_92(93,130),Q89_92(50,68),str);
}
getch();
return best_i 0;
}
// Asks the user for a move, and put its coordinates in char1 and char2
void input_move(int *char1,int *char2)
{
char tmp[]= _;
int key=0;
while(key ENTER_KEY)
{
draw_str(Q89_92(93,130),Q89_92(42,56),Your move: _ );
*char1=key&0xffdf;
while(*char1<'A'||*char1>'H')
*char1=Q89_92(convert_key(getch()),getch())&0xffdf;
*tmp=*char1;
draw_str(Q89_92(133,196),Q89_92(42,56),tmp);
*char2=0;
while(*char2<'1'||*char2>'8')
*char2=getch();
*tmp=*char2;
draw_str(Q89_92(133+FontCharWidth(*char1),202),Q89_92(42,56),tmp);
key=getch();
}
}
// Routine for getting a key, with handling ESC keypress
int getch(void)
{
int i;
if ((i=ngetchx()) ESC_KEY)
return i;
else
longjmp(jmp_buffer,1);
return 0;
}
#ifdef USE_TI89
// Converts non-alpha keys into alpha ones on TI-89 (for easier typing)
// '=' 'A' '(' 'B' ')' 'C' ',' 'D' '/' 'E' '|' 'F' '7' 'G' '8' 'H'
int convert_key(int key)
{
int i;
for(i=0;i<8;i++)
if(key===(),/|78[i ])
return 'A'+i;
return key;
}
#endif
On remarque ici également l'utilisation d'une fonction nommée best qui évalue le nombre maximum de point qui peuvent être gagnés en une aciton.
Cela équivaut aux points dont je vous ai parlé précédemment même ci cet exemple est plus simple puisque les points à gagner sont les mêmes que ceux attribués au coup à effectuer (ce qui ne fonctionne pas à tous les jeux).
Je posterais la suite prochainement
|