Partage
  • Partager sur Facebook
  • Partager sur Twitter

petit programme utilisant negamax

    23 août 2020 à 7:03:03

    bonjour,

    j'ai décidé de programmer un puissance4 intelligent pour faire plaisir à ma petite' soeur.

    Le problème que je rencontre ne se situe pas au niveau de l'IA je pense, car l'algorithme m'est familier.

    Le problème se situe plutôt du côté de la fonction undo du négamax.

    Cette dernière ne fait pas son travail et l'algorithme remplit le tableau sans dépiler les coups simulés.

    Il s'agit de la fonction  power4_placeholder.

    Je vous présente mon code:

    #include<stdlib.h>
    #include<stdio.h>
    #include<string.h>
    #include<limits.h>
    
    #define MAKINA 1
    
    int power4_panel(int game[6][7]);
    int alphabeta_negamax(int game[6][7], int depth, int alpha, int beta, int gamer);
    int max(int x, int y);
    int min(int x, int y);
    long games_str_to_int(int length);
    int games_free_buffer();
    int games_read(char *string, int length);
    int power4_read(int *i);
    int power4_evaluate(int game[6][7], int gamer);
    int power4_placeholder(int game[6][7], int position, int gamer);
    int power4_isover(int game[6][7], int gamer);
    int power4_isfull(int game[6][7]);
    
    int main(int argc, char **argv)
    {
    	int game[6][7] = {0};
    	int moves = 0;
    	while(1)
    	{
    		int gamer = -1;
    		int position, tmp, value;
    		do{
    			position = games_str_to_int(1);
    		}while(position < 0 || position > 6 || power4_placeholder(game, position, gamer) == EXIT_FAILURE);
    		if(power4_isover(game, gamer))
    		{
    			power4_panel(game);
    			printf("FOU ÇAFÉ KANIÉ !!\n");
    			break;
    		}
    		value = INT_MIN;
    		for(int i = 0; i < 7; i++)
    		{
    			power4_placeholder(game, i, -gamer);
    			tmp = max(value, alphabeta_negamax(game, 9, INT_MIN, INT_MAX, gamer));
    			power4_placeholder(game, i, 0);
    			if(value < tmp)
    			{
    				value = tmp;
    				position = i;
    			}
    		}
    		printf("%d\n", position);
    		power4_placeholder(game, position, -gamer);
    		power4_panel(game);
    		moves += 2;
    		if(power4_isover(game, -gamer))
    		{
    			printf("LA MAKINA ES IMMMPATAPLE !!\n");
    			break;
    		}else if(moves == 42)
    		{
    			printf("ex aequo...\n");
    			break;
    		}
    	}
    	return EXIT_SUCCESS;
    }
    
    int power4_placeholder(int game[6][7], int position, int gamer)
    {
    	int i = 5;
    	if(gamer){
    		if(game[0][position])
    			return EXIT_FAILURE;
    		while(game[i][position])
    		{
    			i--;
    			if(i < 1)
    				break;
    		}
    	}else{
    		do{
    			i--;
    			if(i < 0)
    				break;
    		}while(game[i][position]);
    		i++;
    	}
    	game[i][position] = gamer;
    
    	return EXIT_SUCCESS;
    }
    
    int power4_panel(int game[6][7])
    {
    	for(int i = 0; i < 7; i++)
    	{
    		if(i > 5)
    			printf("---------------\n");
    		printf("|");
    		for(int j = 0; j < 7; j++)
    		{
    			if(i < 6){
    				if(game[i][j])
    					printf("%c|", (game[i][j] > 0)?'x':'o');
    				else
    					printf(" |");
    			}else{
    				printf("%d|", j);
    			}
    		}
    		printf("\n");
    	}
    
    	return EXIT_SUCCESS;
    }
    
    int max(int x, int y)
    {
    	if(x > y)
    		return x;
    	else
    		return y;
    	return EXIT_SUCCESS;
    }
    
    int min(int x, int y)
    {
    	if(x < y)
    		return x;
    	else
    		return y;
    	return EXIT_SUCCESS;
    }
    
    
    int alphabeta_negamax(int game[6][7], int depth, int alpha, int beta, int gamer)
    {
    	if(depth == 0 || power4_isfull(game))
            	return gamer * power4_evaluate(game, gamer);
    	int score = INT_MIN;
    	for(int j = 0; j < 7; j++)
    	{
    		if(power4_placeholder(game, j, gamer) == EXIT_SUCCESS)
    		{
    			score = max(score, -alphabeta_negamax(game, depth - 1, -beta, -alpha, -gamer));
    			power4_placeholder(game, j, 0);
    			alpha = max(alpha, score);
    			if(alpha >= beta) break;
    		}
    	}
    	return score;
    }
    
    int power4_isover(int game[6][7], int gamer)
    {
    	for(int i = 0; i < 2; i++)
    	{
    		for(int j = 0; j < 7; j++)
    		{
    			if(game[i][j] == gamer && game[i + 1][j] == gamer && game[i + 2][j] == gamer && game[i + 3][j] == gamer)
    			{
    				return gamer;
    			}
    		}
    	}
    	// lines
    	for(int i = 0; i < 6; i++)
    	{
    		for(int j = 0; j < 3; j++)
    		{
    			if(game[i][j] == gamer && game[i][j + 1] == gamer && game[i][j + 2] == gamer && game[i][j + 3] == gamer)
    			{
    				return gamer;
    			}
    		}
    	}
    	// diagonal right
    	for(int i = 0; i < 2; i++)
    	{
    		for(int j = 3; j < 7; j++)
    		{
    			if(game[i][j] == gamer && game[i + 1][j - 1] == gamer && game[i + 2][j - 2] == gamer && game[i + 3][j - 3] == gamer)
    			{
    				return gamer;
    			}
    		}
    	}
    	// diagonal left
    	for(int i = 0; i < 2; i++)
    	{
    		for(int j = 0; j < 3; j++)
    		{
    			if(game[i][j] == gamer && game[i + 1][j + 1] == gamer && game[i + 2][j + 2] == gamer && game[i + 3][j + 3] == gamer)
    			{
    				return gamer;
    			}
    		}
    	}
    	return 0;
    }
    
    int power4_isfull(int game[6][7])
    {
    	for(int i = 0; i < 7; i++)
    		if(!game[0][i]) return 0;
    
    	return 1;			
    }
    
    int power4_evaluate(int game[6][7], int gamer)
    {
    	int value= 0;
    	// columns
    	for(int i = 0; i < 2; i++)
    	{
    		for(int j = 0; j < 7; j++)
    		{
    			if(game[i][j] == gamer)
    			{
    				if(game[i + 1][j] == gamer)
    				{
    					value += 10;
    					if(game[i + 2][j] == gamer)
    					{
    						value += 100;
    						if(game[i + 3][j] == gamer)
    						{	
    							value += 1000;
    						}
    					}
    				} 
    			}else if(game[i][j] == -gamer)
    			{
    				if(game[i + 1][j] == -gamer){
    					value -= 10;
    					if(game[i + 2][j] == -gamer)
    					{
    						value -= 100;
    						if(game[i + 3][j] == -gamer)
    						{	
    							value -= 1000;
    						}
    					}
    				}
    			}
    		}
    	}
    	// lines
    	for(int i = 0; i < 6; i++)
    	{
    		for(int j = 0; j < 3; j++)
    		{
    			if(game[i][j] == gamer)
    			{
    				if(game[i][j + 1] == gamer)
    				{
    					value += 10;
    					if(game[i][j + 2] == gamer)
    					{
    						value += 100;
    						if(game[i][j + 3] == gamer)
    						{	
    							value += 1000;
    						}
    					}
    				} 
    			}else if(game[i][j] = -gamer)
    			{
    				if(game[i][j + 1] = -gamer){
    					value -= 10;
    					if(game[i][j + 2] == -gamer)
    					{
    						value -= 100;
    						if(game[i][j + 3] == -gamer)
    						{	
    							value -= 1000;
    						}
    					}
    				}
    			}
    		}
    	}
    	// diagonal right
    	for(int i = 0; i < 2; i++)
    	{
    		for(int j = 3; j < 7; j++)
    		{
    			if(game[i][j] == gamer)
    			{
    				if(game[i + 1][j - 1] == gamer)
    				{
    					value += 10;
    					if(game[i + 2][j - 2] == gamer)
    					{
    						value += 100;
    						if(game[i + 3][j - 3] == gamer)
    						{	
    							value += 1000;
    						}
    					}
    				} 
    			}else if(game[i][j] == -gamer)
    			{
    				if(game[i + 1][j - 1] == -gamer){
    					value -= 10;
    					if(game[i + 2][j - 2] == -gamer)
    					{
    						value -= 100;
    						if(game[i + 3][j - 3] == -gamer)
    						{	
    							value -= 1000;
    						}
    					}
    				}
    			}
    		}
    	}
    	// diagonal left
    	for(int i = 0; i < 2; i++)
    	{
    		for(int j = 0; j < 3; j++)
    		{
    			if(game[i][j] == gamer)
    			{
    				if(game[i + 1][j + 1] == gamer)
    				{
    					value += 10;
    					if(game[i + 2][j + 2] == gamer)
    					{
    						value += 100;
    						if(game[i + 3][j + 3] == gamer)
    						{	
    							value += 1000;
    						}
    					}
    				}
    			}else if(game[i][j] == -gamer)
    			{
    				if(game[i + 1][j + 1] == -gamer){
    					value -= 10;
    					if(game[i + 2][j + 2] == -gamer)
    					{
    						value -= 100;
    						if(game[i + 3][j + 3] == -gamer)
    						{	
    							value -= 1000;
    						}
    					}
    				}
    			}
    		}
    	}
    	return value;
    }
    
    long games_str_to_int(int length)
    {
    	char num_text[2] = {0};
    	if (!games_read(num_text, length + 1))
    		return atoi(num_text);
    	else
            	return -1;
    }
    
    int games_free_buffer()
    {
    	int c = 0;
    	while (c != '\n' && c != EOF)
    		c = getchar();
    	return EXIT_SUCCESS;
    }
     
    int games_read(char *string, int length)
    {
    	char *enter_position = NULL;
    	if (fgets(string, length, stdin) != NULL)
    	{
    		enter_position = strchr(string, '\n');
    		if (enter_position != NULL)
    		{
    			*enter_position = '\0';
    		}else
    			games_free_buffer();
    
    		return EXIT_SUCCESS;
    	}else{
    		games_free_buffer();
    		return EXIT_FAILURE;
    	}
    }


    merci pour votre aide.

    -
    Edité par amaurybenard 23 août 2020 à 7:05:04

    • Partager sur Facebook
    • Partager sur Twitter
      3 septembre 2020 à 18:44:46

      Je te passe le miens

      /** made by me **/
      #include <unistd.h>
      #include <stdlib.h>
      #include <stdio.h>
      
      #define GRID_X		7
      #define GRID_Y		6
      #define NUMB		4
      
      typedef unsigned int	uint;
      
      /** Simple strlen                         **/
      uint			_strlen(char *s)
      {
      	uint			i;
      
      	i = 0;
      	while (*s)
      	{
      		s++;
      		i++;
      	}
      	return (i);
      }
      
      /** Return end of string position         **/
      char					*strEnd(char *c)
      {
      	if (!c)
      		return (NULL);
      	while (*c)
      		c++; // Goto Terminator
      	return (c); // Return address
      }
      
      /** Stdin newLine                         **/
      static void				zbleh(uint i)
      {
      	char		bb = '\r';
      	char		z = '\0';
      
      	while (i--)
      		write(1, &bb, 1);
      }
      
      /** Display string                        **/
      void					strDsp(char *s, char flg)
      {
      	uint		l;
      
      	l = _strlen(s);
      	if (flg)
      		zbleh(l);
      	write(1, s, (size_t)l);
      }
      
      
      /********** Triggers  ***********/
      
      int			up(char *grd, int *dim, int *cnt, char *p)
      {
      	int			i;
      	int			n[2];
      
      	i = 1;
      	n[0] = NUMB - 1;
      	n[1] = NUMB;
      	if (cnt[1] >= n[0])
      	{
      		while (i < n[1] && *(p - ((dim[0] * i) + i)) == *p)
      			i++;
      		if (i == n[1])
      			return (1);
      	}
      	return (0);
      }
      
      int			down(char *grd, int *dim, int *cnt, char *p)
      {
      	int			i;
      	int			n[2];
      
      	i = 1;
      	n[0] = NUMB - 1;
      	n[1] = NUMB;
      	if (cnt[1] <= dim[1] - n[0])
      	{
      		while (i < n[1] && *(p + ((dim[0] * i) + i)) == *p)
      			i++;
      		if (i == n[1])
      			return (1);
      	}
      	return (0);
      }
      
      int			right(char *grd, int *dim, int *cnt, char *p)
      {
      	int			i;
      	int			n[2];
      
      	i = 1;
      	n[0] = NUMB - 1;
      	n[1] = NUMB;
      	if (cnt[0] <= dim[0] - n[0])
      	{
      		while (i < n[1] && *(p + i) == *p)
      			i++;
      		if (i == n[1])
      			return (1);
      	}
      	return (0);
      }
      
      int			left(char *grd, int *dim, int *cnt, char *p)
      {
      	int			i;
      	int			n[2];
      
      	i = 1;
      	n[0] = NUMB - 1;
      	n[1] = NUMB;
      	if (cnt[0] >= n[0])
      	{
      		while (i < n[1] && *(p - i) == *p)
      			i++;
      		if (i == n[1])
      			return (1);
      	}
      	return (0);
      }
      
      int			diagup(char *grd, int *dim, int *cnt, char *p)
      {
      	int			i;
      	int			n[2];
      
      	i = 1;
      	n[0] = NUMB - 1;
      	n[1] = NUMB;
      	if (cnt[0] <= dim[0] - n[0] && cnt[1] >= n[0])
      	{
      		while (i < n[1] && *(p - (dim[0] * i)) == *p)
      			i++;
      		if (i == n[1])
      			return (1);
      	}
      	return (0);
      }
      
      int			diagdown(char *grd, int *dim, int *cnt, char *p)
      {
      	int			i;
      	int			n[2];
      
      	i = 1;
      	n[0] = NUMB - 1;
      	n[1] = NUMB;
      	if (cnt[0] <= dim[0] - n[0] && cnt[1] <= dim[1] - n[0])
      	{
      		while (i < n[1] && *(p + (dim[0] * i)) == *p)
      			i++;
      		if (i == n[1])
      			return (1);
      	}
      	return (0);
      }
      
      int			diagleft(char *grd, int *dim, int *cnt, char *p)
      {
      	int			i;
      	int			n[2];
      
      	i = 1;
      	n[0] = NUMB - 1;
      	n[1] = NUMB;
      	if (cnt[0] >= n[0] && cnt[1] <= dim[1] - n[0])
      	{
      		while (i < n[1] && *(p + ((dim[0] * i) + (i * 2))) == *p)
      			i++;
      		if (i == n[1])
      			return (1);
      	}
      	return (0);
      }
      
      int			diagright(char *grd, int *dim, int *cnt, char *p)
      {
      	int			i;
      	int			n[2];
      
      	i = 1;
      	n[0] = NUMB - 1;
      	n[1] = NUMB;
      	if (cnt[0] >= n[0] && cnt[1] >= n[0])
      	{
      		while (i < n[1] && *(p - ((dim[0] * i) + (i * 2))) == *p)
      			i++;
      		if (i == n[1])
      			return (1);
      	}
      	return (0);
      }
      
      /********************************/
      
      /** Retrieve grid width/height                                               **/
      void		dimgrid(char *grd, int *c, int *l)
      {
      	int			nc[2];
      	char		*p;
      
      	p = grd;
      	nc[0] = 0;
      	nc[1] = 0;
      	while (*p)
      	{
      		if (nc[0] == 1 && *p != '\n')
      			nc[1]++;
      		if (*p == '\n')
      			nc[0]++;
      		p++;
      	}
      	*l = nc[0]--;
      	*c = nc[1];
      }
      
      /** Get Next Line Up^ **/
      char			*nextLine(char *p, int col, int wdt)
      {
      	int			pci;    /** Pointer Column Index **/
      
      	if ((pci = (wdt - col)) < 0)
      		return (NULL);
      	while (pci--)
      		p--;
      	return (p);
      }
      
      /** Put piece T at column C in grid GRD                                      **/
      char		*put(char *grd, char c, char t, char *ilg)
      {
      	int			col;    /** Input column         **/
      	char		*p;     /** Grid PTR             **/
      	int			dim[2]; /** Grid Dimensions      **/
      
      	col = c - '0';
      	dimgrid(grd, &dim[0], &dim[1]);
      	if (!(p = strEnd(grd)) || *(--p) != '\n')
      		return (NULL);
      	while (dim[1]-- != 0) /** For each line **/
      	{
      		if (!(p = nextLine(p, col, dim[0])))
      			return (NULL);
      		if (*p == 'O' && (*p = t))
      			return (grd);
      		while (dim[1] && *p != '\n')
      			p--;
      	}
      	if (ilg)
      		*ilg = 1;
      	return (grd);
      }
      
      /** Winner Scanner                                                           **/
      char			win(char *grd)
      {
      	char		*p;
      	char		t;
      	int			dim[2];
      	int			cnt[2];
      
      	p = grd;
      	dimgrid(grd, &dim[0], &dim[1]);
      	cnt[0] = 0;
      	cnt[1] = 0;
      	while (*p)
      	{
      		if ((t = *p) != 'O' && t != '\n' && t != '\0')
      			if (up(grd, dim, cnt, p) || down(grd, dim, cnt, p) ||
      				left(grd, dim, cnt, p) || right(grd, dim, cnt, p) ||
      				diagup(grd, dim, cnt, p) || diagdown(grd, dim, cnt, p) ||
      				diagleft(grd, dim, cnt, p) || diagright(grd, dim, cnt, p))
      				return (t);
      		cnt[0]++;
      		if (*p == '\n' && (cnt[0] = 0) == 0)
      			cnt[1]++;
      		p++;
      	}
      	return ('\0');
      }
      
      /** Player input: l=game width                                               **/
      char		pinput(int l)
      {
      	char		inp[l + 1];
      	char		ret;
      	int			rd;
      	int			i;
      
      	i = -1;
      	while (++i < l)
      		inp[i] = '\0';
      	if ((rd = read(1, inp, l)) > l) // Read player's input      **/
      		return (pinput(l));          // if Overflow then Modulus **/
      	ret = '\n';
      	inp[l] = '\0';
      	write(1, &ret, 1);
      	ret = (_strlen(inp) - 1) + '0';
      	return (ret);
      }
      
      /** Choose player's symbol                                                   **/
      void		player_sym(char *pt, char **av, int flg)
      {
      	if (flg)
      	{
      		pt[0] = av[1][0];
      		pt[1] = av[2][0];
      	}
      	else
      	{
      		pt[0] = 'X';
      		pt[1] = 'D';
      	}
      	pt[2] = '\0';
      }
      
      /** Return next input char                                                   **/
      char		nextInput(char **list, int width)
      {
      	static int		index = 0;
      
      	if (list)
      		return (list[3][index++]);
      	return (pinput(width));
      }
      
      const char			tn[] = "'s turn\n";
      const char			wt[] = "+=========+\n[  loose ]\n+=========+\n";
      #define GAMEMODE	1
      #define INIT		'O'
      
      /** Allocae a new screen in string format                                    **/
      char					*newScreen(uint x, uint y)
      {
      	char		*scr;
      	uint		i;
      	uint		total;
      
      	total = (x + 1) * y;
      	if (!(scr = (char *)malloc(sizeof(char) * total)))
      		return (NULL);
      	i = -1;
      	while (++i < total)
      	{
      		scr[i] = INIT;
      		if (i % (x + 1) == 0)
      			scr[i] = '\n';
      	}
      	scr[i] = '\n';
      	return (scr);
      }
      
      /** Game Loop Screen                                                         **/
      void		dspGame(char *scr, char *player)
      {
      	write(1, player, 1);
      	write(1, tn, 8);
      	strDsp(scr, 0);
      }
      
      /** End Game Screen                                                          **/
      int			printWin(char t)
      {
      	if (!t)
      		return (0);
      	write(1, wt, 14);
      	write(1, &t, 1);
      	write(1, wt + 14, 21);
      	return ((int)t);
      }
      
      /** Swap Player's Turn                                                       **/
      char		*nextPlayer(char *player, char *ful)
      {
      	if (!ful)
      		return (player);
      	if (*ful == 0 && *(++player) == '\0' &&
      		(*ful = 0) == 0) // Next Player **/
      		player -= 2;
      	if (*ful == 1)
      		*ful = 0;
      	return (player);
      }
      
      int			main(int ac, char **av)
      {
      	char		ful;     /** Errors **/
      	char		*sc;     /** Screen **/
      	char		t[3];    /** Pieces **/
      	char		*player; /** Player **/
      
      	player_sym(t, av, ac != 3 ? 0 : 1); // Choose sym       **/
      	if (!(sc = newScreen(GRID_X, GRID_Y))) // Init game 7 by 6 **/
      		return (0);
      	player = t;
      	dspGame(sc, t);
      	ful = 0;
      	while (1) // Game loop        **/
      	{
      		if (!(sc = put(sc, pinput(GRID_X + 1), *player, &ful)))
      			return (0);
      		if (!(player = nextPlayer(player, &ful)))
      			return (0);
      		dspGame(sc, player);
      		if (GAMEMODE == 1 && (t[2] = win(sc)) != 'O' && t[2] != '\0')
      			return (printWin(t[2] == t[0] ? t[1] : t[0]));
      	}
      	return (0);
      }


      Cordialement,

      T.

      • Partager sur Facebook
      • Partager sur Twitter
        9 septembre 2020 à 16:12:46

        ENFIN!!

        voilà un algo d'IA qui fonctionne, mais il faut prendre un "depth" qui soit paire:

        #include<stdlib.h>
        #include<stdio.h>
        #include<string.h>
        #include<limits.h>
        
        #define MAKINA 1
        
        int power4_panel(int game[6][7]);
        int alphabeta_negamax(int game[6][7], int depth, int alpha, int beta, int gamer);
        int alphabeta_minmax(int game[6][7], int depth, int alpha, int beta, int gamer);
        int power4_AI_play(int game[6][7], int depth, int alpha, int beta, int gamer, int *position);
        int max(int x, int y);
        int min(int x, int y);
        long games_str_to_int(int length);
        int games_free_buffer();
        int games_read(char *string, int length);
        int power4_read(int *i);
        int power4_evaluate(int game[6][7], int gamer);
        int power4_placeholder(int game[6][7], int position, int gamer);
        int power4_isover(int game[6][7]);
        int power4_isfull(int game[6][7]);
        
        int main(int argc, char **argv)
        {
        	int game[6][7] = {0};
        	int moves = 0;
        	power4_panel(game);
        	while(1)
        	{
        		int gamer = -1;
        		int position;
        		do{
        			position = games_str_to_int(1);
        		}while(position < 0 || position > 6 || power4_placeholder(game, position, gamer) == EXIT_FAILURE);
        		if(power4_isover(game) == EXIT_SUCCESS)
        		{
        			power4_panel(game);
        			printf("FOU ÇAFÉ KANIÉ !!\n");
        			break;
        		}
        		power4_AI_play(game, 12, INT_MIN, INT_MAX, -gamer, &position);
        		power4_placeholder(game, position, -gamer);
        		power4_panel(game);
        		moves += 2;
        		if(power4_isover(game) == EXIT_SUCCESS)
        		{
        			power4_panel(game);
        			printf("LA MAKINA ES IMMMPATAPLE !!\n");
        			break;
        		}else if(moves == 42)
        		{
        			printf("ex aequo...\n");
        			break;
        		}
        	}
        	return EXIT_SUCCESS;
        }
        
        int power4_placeholder(int game[6][7], int position, int gamer)
        {
        	int i = 5;
        	if(gamer){
        		if(game[0][position])
        			return EXIT_FAILURE;
        		while(game[i][position])
        		{
        			i--;
        			if(i < 1)
        				break;
        		}
        	}else{
        		while(game[i][position]){
        			i--;
        			if(i < 0)
        				break;
        		}
        		i++;
        	}
        	game[i][position] = gamer;
        
        	return EXIT_SUCCESS;
        }
        
        int power4_panel(int game[6][7])
        {
        	for(int i = 0; i < 7; i++)
        	{
        		if(i > 5)
        			printf("---------------\n");
        		printf("|");
        		for(int j = 0; j < 7; j++)
        		{
        			if(i < 6){
        				if(game[i][j])
        					printf("%c|", (game[i][j] > 0)?'x':'o');
        				else
        					printf(" |");
        			}else{
        				printf("%d|", j);
        			}
        		}
        		printf("\n");
        	}
        
        	return EXIT_SUCCESS;
        }
        
        int max(int x, int y)
        {
        	if(x > y)
        		return x;
        	else
        		return y;
        	return EXIT_SUCCESS;
        }
        
        int min(int x, int y)
        {
        	if(x < y)
        		return x;
        	else
        		return y;
        	return EXIT_SUCCESS;
        }
        
        int power4_AI_play(int game[6][7], int depth, int alpha, int beta, int gamer, int *position)
        {
            	int score = INT_MIN, tmp;
        	char progression[20] = {0};
        	for(int i = 0; i < 7; i++)
        	{
        		if(power4_placeholder(game, i, gamer) == EXIT_SUCCESS)
        		{
        			progression[0]='\0';
        			for(int j = 1; j < i +1; j++)
        				strcat(progression, "==");
        			strcat(progression, ">");
        			for(int j = 14 - ( i + 1) * 2; j > 0; j--)
        				strcat(progression, " ");
        			printf("%s", progression);
        			fflush(stdout);
        			tmp = alphabeta_negamax(game, depth, alpha, beta, -gamer);
        			if(tmp > score)
        			{
        				*position = i;
        				score = tmp;
        			}
        			power4_placeholder(game, i, 0);
        			for(int j = 0; j < 20; j++)
        				printf("\b");
        			fflush(stdout);
        		}
        	}
        
        	return EXIT_SUCCESS;
        }
        
        int alphabeta_minmax(int game[6][7], int depth, int alpha, int beta, int gamer)
        {
        	if(depth == 0 || power4_isfull(game))
                	return gamer * power4_evaluate(game, gamer);
        	int score;
        	if(gamer != MAKINA)
        	{
        		score = INT_MAX;
        		for(int j = 0; j < 7; j++)
        		{
        			if(power4_placeholder(game, j, gamer) == EXIT_SUCCESS)
        			{
        				score = min(score, alphabeta_minmax(game, depth - 1, alpha, beta, -gamer));
        				power4_placeholder(game, j, 0);
        				if(alpha >= score){
        					return score;
        				}
        				beta=min(beta, score);
        			}
        		}
        	}else{
        		score = INT_MIN;
        		for(int j = 0; j < 7; j++)
        		{
        			if(power4_placeholder(game, j, gamer) == EXIT_SUCCESS)
        			{
        				score = max(score, alphabeta_minmax(game, depth - 1, alpha, beta, -gamer));
        				power4_placeholder(game, j, 0);
        				if(beta <= score){
        					return score;
        				}
        				alpha = max(alpha, score);
        			}
        		}
        	}
        	return score;
        }
        
        
        int alphabeta_negamax(int game[6][7], int depth, int alpha, int beta, int gamer)
        {
        	if(depth == 0 || power4_isfull(game))
                	return gamer * power4_evaluate(game, gamer);
        	int score = INT_MAX;
        	for(int j = 0; j < 7; j++)
        	{
        		if(power4_placeholder(game, j, gamer) == EXIT_SUCCESS)
        		{
        			score = min(score, -alphabeta_negamax(game, depth - 1, -beta, -alpha, -gamer));
        			power4_placeholder(game, j, 0);
        			alpha = max(alpha, score);
        			if(alpha >= beta) break;
        		}
        	}
        	return score;
        }
        
        int power4_isover(int game[6][7])
        {
        	// columns
        	for(int i = 0; i < 6; i++)
        	{
        		for(int j = 0; j < 7; j++)
        		{
        			if(game[i][j] ==1 || game[i][j] == -1)
        			{
        				if(game[i][j] == game[i + 1][j] &&  game[i + 2][j] == game[i][j] && game[i + 3][j] == game[i][j])
        				{
        					return EXIT_SUCCESS;
        				}
        			}
        		}
        	}
        	// lines
        	for(int i = 0; i < 6; i++)
        	{
        		for(int j = 0; j < 7; j++)
        		{
        			if(game[i][j] ==1 || game[i][j] == -1)
        			{
        				if(game[i][j + 1] == game[i][j] && game[i][j + 2] == game[i][j] && game[i][j + 3] == game[i][j])
        				{
        					return EXIT_SUCCESS;
        				}
        			}
        		}
        	}
        	// diagonal right
        	for(int i = 0; i < 6; i++)
        	{
        		for(int j = 3; j < 7; j++)
        		{
        			if(game[i][j] ==1 || game[i][j] == -1)
        			{
        				if(game[i + 1][j - 1] == game[i][j] && game[i + 2][j - 2] == game[i][j] && game[i + 3][j - 3] == game[i][j])
        				{
        					return EXIT_SUCCESS;
        				}
        			}
        		}
        	}
        	// diagonal left
        	for(int i = 0; i < 6; i++)
        	{
        		for(int j = 0; j < 7; j++)
        		{
        			if(game[i][j] ==1 || game[i][j] == -1)
        			{
        				if(game[i + 1][j + 1] == game[i][j] && game[i + 2][j + 2] == game[i][j] && game[i + 3][j + 3] == game[i][j])
        				{
        					return EXIT_SUCCESS;
        				}
        			}
        		}
        	}
        	return EXIT_FAILURE;
        }
        
        int power4_isfull(int game[6][7])
        {
        	for(int i = 0; i < 7; i++)
        		if(!game[0][i]) return 0;
        
        	return 1;			
        }
        
        int power4_evaluate(int game[6][7], int gamer)
        {
        	int value= 0;
        	// columns
        	for(int i = 0; i < 6; i++)
        	{
        		for(int j = 0; j < 7; j++)
        		{
        			if(game[i + 1][j] == game[i][j])
        			{
        				if(game[i][j] == gamer)
        					value += 10;
        				if(game[i + 2][j] == game[i][j])
        				{
        					if(game[i][j] == gamer)
        						value += 100;
        					if(game[i + 3][j] == game[i][j])
        					{
        						if(game[i][j] == gamer)
        							value += 1000;
        					}
        				}
        			}
        		}
        	}
        	// lines
        	for(int i = 0; i < 6; i++)
        	{
        		for(int j = 0; j < 7; j++)
        		{
        			if(game[i][j + 1] == game[i][j])
        			{
        				if(game[i][j] == gamer)
        					value += 10;
        				if(game[i][j + 2] == game[i][j])
        				{
        					if(game[i][j] == gamer)
        						value += 100;
        					if(game[i][j + 3] == game[i][j])
        					{	
        						if(game[i][j] == gamer)
        							value += 1000;
        					}
        				}
        			}  
        		}
        	}
        	// diagonal right
        	for(int i = 0; i < 6; i++)
        	{
        		for(int j = 3; j < 7; j++)
        		{
        			if(game[i + 1][j - 1] == game[i][j])
        			{
        				if(game[i][j] == gamer)
        					value += 10;
        				if(game[i + 2][j - 2] == game[i][j])
        				{
        					if(game[i][j] == gamer)
        						value += 100;
        					if(game[i + 3][j - 3] == game[i][j])
        					{	
        						if(game[i][j] == gamer)
        							value += 1000;
        					}
        				}
        			} 
        		}
        	}
        	// diagonal left
        	for(int i = 0; i < 6; i++)
        	{
        		for(int j = 0; j < 7; j++)
        		{
        			if(game[i + 1][j + 1] == game[i][j])
        			{
        				if(game[i][j] == gamer)
        					value += 10;
        				if(game[i + 2][j + 2] == game[i][j])
        				{
        					if(game[i][j] == gamer)
        						value += 100;
        					if(game[i + 3][j + 3] == game[i][j])
        					{	
        						if(game[i][j] == gamer)
        							value += 1000;
        					}
        				}
        			}
        		}
        	}
        	return value;
        }
        
        long games_str_to_int(int length)
        {
        	char num_text[2] = {0};
        	if (!games_read(num_text, length + 1))
        		return atoi(num_text);
        	else
                	return -1;
        }
        
        int games_free_buffer()
        {
        	int c = 0;
        	while (c != '\n' && c != EOF)
        		c = getchar();
        	return EXIT_SUCCESS;
        }
         
        int games_read(char *string, int length)
        {
        	char *enter_position = NULL;
        	if (fgets(string, length, stdin) != NULL)
        	{
        		enter_position = strchr(string, '\n');
        		if (enter_position != NULL)
        		{
        			*enter_position = '\0';
        		}else
        			games_free_buffer();
        
        		return EXIT_SUCCESS;
        	}else{
        		games_free_buffer();
        		return EXIT_FAILURE;
        	}
        }


        -
        Edité par amaurybenard 10 septembre 2020 à 19:15:48

        • Partager sur Facebook
        • Partager sur Twitter
          11 septembre 2020 à 7:16:21

          2 petites rectifications:

          #include<stdlib.h>
          #include<stdio.h>
          #include<string.h>
          #include<limits.h>
          
          #define MAKINA 1
          
          int power4_panel(int game[6][7]);
          int alphabeta_negamax(int game[6][7], int depth, int alpha, int beta, int gamer);
          int alphabeta_minmax(int game[6][7], int depth, int alpha, int beta, int gamer);
          int power4_AI_play(int game[6][7], int depth, int alpha, int beta, int gamer, int *position);
          int minmax_max(int game[6][7], int depth, int alpha, int beta, int gamer);
          int minmax_min(int game[6][7], int depth, int alpha, int beta, int gamer);
          int max(int x, int y);
          int min(int x, int y);
          long games_str_to_int(int length);
          int games_free_buffer();
          int games_read(char *string, int length);
          int power4_read(int *i);
          int power4_evaluate(int game[6][7], int gamer);
          int power4_placeholder(int game[6][7], int position, int gamer);
          int power4_isover(int game[6][7]);
          int power4_isfull(int game[6][7]);
          
          int main(int argc, char **argv)
          {
          	int game[6][7] = {0};
          	int moves = 0;
          	power4_panel(game);
          	while(1)
          	{
          		int gamer = -1;
          		int position;
          		do{
          			position = games_str_to_int(1);
          		}while(position < 0 || position > 6 || power4_placeholder(game, position, gamer) == EXIT_FAILURE);
          		if(power4_isover(game) == EXIT_SUCCESS)
          		{
          			power4_panel(game);
          			printf("FOU ÇAFÉ KANIÉ !!\n");
          			break;
          		}
          		if(power4_AI_play(game, 13, INT_MIN, INT_MAX, -gamer, &position) == EXIT_FAILURE)
          			break;
          		power4_placeholder(game, position, -gamer);
          		power4_panel(game);
          		moves += 2;
          		if(moves == 42)
          		{
          			printf("ex aequo...\n");
          			break;
          		}
          	}
          	return EXIT_SUCCESS;
          }
          
          int power4_placeholder(int game[6][7], int position, int gamer)
          {
          	int i = 5;
          	if(gamer){
          		if(game[0][position])
          			return EXIT_FAILURE;
          		while(game[i][position])
          		{
          			i--;
          			if(i < 1)
          				break;
          		}
          	}else{
          		while(game[i][position]){
          			i--;
          			if(i < 0)
          				break;
          		}
          		i++;
          	}
          	game[i][position] = gamer;
          
          	return EXIT_SUCCESS;
          }
          
          int power4_panel(int game[6][7])
          {
          	for(int i = 0; i < 7; i++)
          	{
          		if(i > 5)
          			printf("---------------\n");
          		printf("|");
          		for(int j = 0; j < 7; j++)
          		{
          			if(i < 6){
          				if(game[i][j])
          					printf("%c|", (game[i][j] > 0)?'x':'o');
          				else
          					printf(" |");
          			}else{
          				printf("%d|", j);
          			}
          		}
          		printf("\n");
          	}
          
          	return EXIT_SUCCESS;
          }
          
          int max(int x, int y)
          {
          	if(x > y)
          		return x;
          	else
          		return y;
          	return EXIT_SUCCESS;
          }
          
          int min(int x, int y)
          {
          	if(x < y)
          		return x;
          	else
          		return y;
          	return EXIT_SUCCESS;
          }
          
          int power4_AI_play(int game[6][7], int depth, int alpha, int beta, int gamer, int *position)
          {
              	int score = INT_MIN, tmp;
          	char progression[20] = {0};
          	int is_over = 0;
          	for(int i = 0; i < 7; i++)
          	{
          		if(power4_placeholder(game, i, gamer) == EXIT_SUCCESS)
          		{
          			if(power4_isover(game) == EXIT_SUCCESS)
          			{
          				power4_panel(game);
          				printf("LA MAKINA ES IMMMPATAPLE !!\n");
          				is_over = 1;
          				break;
          			} 
          			progression[0]='\0';
          			for(int j = 1; j < i +1; j++)
          				strcat(progression, "==");
          			strcat(progression, ">");
          			for(int j = 14 - ( i + 1) * 2; j > 0; j--)
          				strcat(progression, " ");
          			printf("%s", progression);
          			fflush(stdout);
          			tmp = alphabeta_negamax(game, depth, alpha, beta, -gamer);
          			if(tmp > score)
          			{
          				*position = i;
          				score = tmp;
          			}
          			power4_placeholder(game, i, 0);
          			for(int j = 0; j < 20; j++)
          				printf("\b");
          			fflush(stdout);
          		}
          	}
          	
          	if(is_over)
          		return EXIT_FAILURE;
          
          	return EXIT_SUCCESS;
          }
          
          int alphabeta_minmax(int game[6][7], int depth, int alpha, int beta, int gamer)
          {
          	if(depth == 0 || power4_isfull(game))
                  	return gamer * power4_evaluate(game, gamer);
          	int score;
          	if(gamer != MAKINA)
          	{
          		score = INT_MAX;
          		for(int j = 0; j < 7; j++)
          		{
          			if(power4_placeholder(game, j, gamer) == EXIT_SUCCESS)
          			{
          				score = min(score, alphabeta_minmax(game, depth - 1, alpha, beta, -gamer));
          				power4_placeholder(game, j, 0);
          				if(alpha >= score){
          					return score;
          				}
          				beta=min(beta, score);
          			}
          		}
          	}else{
          		score = INT_MIN;
          		for(int j = 0; j < 7; j++)
          		{
          			if(power4_placeholder(game, j, gamer) == EXIT_SUCCESS)
          			{
          				score = max(score, alphabeta_minmax(game, depth - 1, alpha, beta, -gamer));
          				power4_placeholder(game, j, 0);
          				if(beta <= score){
          					return score;
          				}
          				alpha = max(alpha, score);
          			}
          		}
          	}
          	return score;
          }
          
          
          int alphabeta_negamax(int game[6][7], int depth, int alpha, int beta, int gamer)
          {
          	if(depth == 0 || power4_isfull(game))
                  	return gamer * power4_evaluate(game, gamer);
          	int score = INT_MAX;
          	for(int j = 0; j < 7; j++)
          	{
          		if(power4_placeholder(game, j, gamer) == EXIT_SUCCESS)
          		{
          			score = min(score, -alphabeta_negamax(game, depth - 1, -beta, -alpha, -gamer));
          			power4_placeholder(game, j, 0);
          			alpha = max(alpha, score);
          			if(alpha >= beta) break;
          		}
          	}
          	return score;
          }
          
          int power4_isover(int game[6][7])
          {
          	// columns
          	for(int i = 0; i < 3; i++)
          	{
          		for(int j = 0; j < 7; j++)
          		{
          			if(game[i][j])
          			{
          				if(game[i][j] == game[i + 1][j] &&  game[i + 2][j] == game[i][j] && game[i + 3][j] == game[i][j])
          				{
          					return EXIT_SUCCESS;
          				}
          			}
          		}
          	}
          	// lines
          	for(int i = 0; i < 6; i++)
          	{
          		for(int j = 0; j < 4; j++)
          		{
          			if(game[i][j])
          			{
          				if(game[i][j + 1] == game[i][j] && game[i][j + 2] == game[i][j] && game[i][j + 3] == game[i][j])
          				{
          					return EXIT_SUCCESS;
          				}
          			}
          		}
          	}
          	// diagonal right
          	for(int i = 0; i < 3; i++)
          	{
          		for(int j = 3; j < 7; j++)
          		{
          			if(game[i][j])
          			{
          				if(game[i + 1][j - 1] == game[i][j] && game[i + 2][j - 2] == game[i][j] && game[i + 3][j - 3] == game[i][j])
          				{
          					return EXIT_SUCCESS;
          				}
          			}
          		}
          	}
          	// diagonal left
          	for(int i = 0; i < 3; i++)
          	{
          		for(int j = 0; j < 4; j++)
          		{
          			if(game[i][j])
          			{
          				if(game[i + 1][j + 1] == game[i][j] && game[i + 2][j + 2] == game[i][j] && game[i + 3][j + 3] == game[i][j])
          				{
          					return EXIT_SUCCESS;
          				}
          			}
          		}
          	}
          	return EXIT_FAILURE;
          }
          
          int power4_isfull(int game[6][7])
          {
          	for(int i = 0; i < 7; i++)
          		if(!game[0][i]) return 0;
          
          	return 1;			
          }
          
          int power4_evaluate(int game[6][7], int gamer)
          {
          	int value= 0;
          	// columns
          	for(int i = 0; i < 6; i++)
          	{
          		for(int j = 0; j < 7; j++)
          		{
          			if(game[i + 1][j] == game[i][j])
          			{
          				if(game[i][j] == gamer)
          					value += 10;
          				if(game[i + 2][j] == game[i][j])
          				{
          					if(game[i][j] == gamer)
          						value += 100;
          					if(game[i + 3][j] == game[i][j])
          					{
          						if(game[i][j] == gamer)
          							value += 1000;
          					}
          				}
          			}
          		}
          	}
          	// lines
          	for(int i = 0; i < 6; i++)
          	{
          		for(int j = 0; j < 7; j++)
          		{
          			if(game[i][j + 1] == game[i][j])
          			{
          				if(game[i][j] == gamer)
          					value += 10;
          				if(game[i][j + 2] == game[i][j])
          				{
          					if(game[i][j] == gamer)
          						value += 100;
          					if(game[i][j + 3] == game[i][j])
          					{	
          						if(game[i][j] == gamer)
          							value += 1000;
          					}
          				}
          			}  
          		}
          	}
          	// diagonal right
          	for(int i = 0; i < 6; i++)
          	{
          		for(int j = 3; j < 7; j++)
          		{
          			if(game[i + 1][j - 1] == game[i][j])
          			{
          				if(game[i][j] == gamer)
          					value += 10;
          				if(game[i + 2][j - 2] == game[i][j])
          				{
          					if(game[i][j] == gamer)
          						value += 100;
          					if(game[i + 3][j - 3] == game[i][j])
          					{	
          						if(game[i][j] == gamer)
          							value += 1000;
          					}
          				}
          			} 
          		}
          	}
          	// diagonal left
          	for(int i = 0; i < 6; i++)
          	{
          		for(int j = 0; j < 7; j++)
          		{
          			if(game[i + 1][j + 1] == game[i][j])
          			{
          				if(game[i][j] == gamer)
          					value += 10;
          				if(game[i + 2][j + 2] == game[i][j])
          				{
          					if(game[i][j] == gamer)
          						value += 100;
          					if(game[i + 3][j + 3] == game[i][j])
          					{	
          						if(game[i][j] == gamer)
          							value += 1000;
          					}
          				}
          			}
          		}
          	}
          	return value;
          }
          
          long games_str_to_int(int length)
          {
          	char num_text[2] = {0};
          	if (!games_read(num_text, length + 1))
          		return atoi(num_text);
          	else
                  	return -1;
          }
          
          int games_free_buffer()
          {
          	int c = 0;
          	while (c != '\n' && c != EOF)
          		c = getchar();
          	return EXIT_SUCCESS;
          }
           
          int games_read(char *string, int length)
          {
          	char *enter_position = NULL;
          	if (fgets(string, length, stdin) != NULL)
          	{
          		enter_position = strchr(string, '\n');
          		if (enter_position != NULL)
          		{
          			*enter_position = '\0';
          		}else
          			games_free_buffer();
          
          		return EXIT_SUCCESS;
          	}else{
          		games_free_buffer();
          		return EXIT_FAILURE;
          	}
          }



          • Partager sur Facebook
          • Partager sur Twitter
            12 septembre 2020 à 11:09:30

            Le programme ci-dessus est également faux.

            Dans le code précédent, ce n'était pas negamax que voulais appeler, mais bien le minmax.

            Mais je ne lâche pas l'affaire pour le negamax...

            J'y arrive très bien avec le minmax.

            Le problème avec le negamax c'est qu'il commence avec un Maximizer.

            -
            Edité par amaurybenard 12 septembre 2020 à 13:26:11

            • Partager sur Facebook
            • Partager sur Twitter

            petit programme utilisant negamax

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown