Advertisement Jump to content
Sign in to follow this  
LAURENT*

AI is harder than I thought

This topic is 1736 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I wanted to make an AI for my tic-tac-toe game that was really random. I tried a LOT of ideas that failed and still have more but, now I think I need some assitances. Sorry but I don't have code now. I'm making this thread to force myself to commit to ask for help later. See ya in 7 hours!

 

 

Share this post


Link to post
Share on other sites
Advertisement

If you want you can have a look at this code: click

Specifically line 146 - computerMove() function.

I have written this version in my early years when I was learning C++ and some parts of the code look horrible :D, 

but the algorithm for the AI should work just fine.
 

Share this post


Link to post
Share on other sites
Yeah, you should look for a tic-tac-toe algorithm and use that, because if it is a soloved game, there is not really any way that you can make the computer 100% intelligent yet fair (If the computer was programmed to know the solution to the game it would win every time. Then it comes down to who goes first, or second (it depends on the solution of tic tac toe, which I don't know myself.)

Share this post


Link to post
Share on other sites

You can used the 'solved' solution, and yes that will make it a better (perfect) tic tac toe machine, but I don't know if that really helps you with AI.

If anything, it would give you practice with matrix rotations and comparisons.

 

The problem you are going to run into is most 'trivial' games have been solved. A few you might try that would give you more room to play with the AI:

 

1) Don't know the name of it - 'game board' is lines of dots. You take away dots on your turn. You win if you opponent picks up the last dot.

2) Fox and the Hounds and its many variants - the simplest of which simply start with a 'character marker' on a hex grid. That players goal is to reach the edge of the board and 'escape'. Player 2 places blocking markers - 1 per turn. His goal is to 'trap' the fox.

3) You could go into games without perfect information: blackjack is a nice simple game to get started with there.

Share this post


Link to post
Share on other sites

Sorry for the delay, my network was acting up and it look like my a driver got corrupted while I was updating my tablet. Anyways I've fix the problem and now i'm ready to code.

 

Here are 2 of my files. What I thought would be easy isn't so easy. In the first file in the while statement there is a switch case statement. Within one of the options it check for X and O turn and blit the surface after a button event. I just need the computer to blit the surface without a button event or make it own turn.

 

Thanks guys for the resources. I've try them out right now.

 

 

 

I screwed up the formatting in these 2. Ignore and look at the reply below

#include <iostream>
#include <SDL.h>
#include <SDL_image.h>
#include <time.h>
#include "Game.h"
Game::Game()
{ 
cmark= IMG_Load("cmark.jpg");    
xmark= IMG_Load("xmark.jpg");    
board= IMG_Load("board.jpg");    
horizontale=IMG_Load("horizontale.jpg");    
verticale=IMG_Load("verticale.jpg");    
diagonale1=IMG_Load("diagonale1.png");    
diagonale2=IMG_Load("diagonale2.png");
}

void Game::play(SDL_Surface *screen)
{    int continuer=1, turn=0, end=0; 
position.x=0;    
position.y=0;
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));    
SDL_BlitSurface(board, NULL, screen, &position);    
SDL_Flip(screen);
    for(i=0; i<3; i++)
    {        
	for(j=0; j<3; j++)        
	{            
	grid[i][j]=EMPTY;        
	}    }    
while(continuer)    
{        
SDL_WaitEvent(&event);        
switch(event.type)        
{        
    case SDL_QUIT:                
continuer=0;                
break;            
//Click management            
case SDL_MOUSEBUTTONDOWN:                
if(!end && grid[event.button.y/70][event.button.x/70]==EMPTY)                
{                    
positionforme.x=((event.button.x/70)*70)+15;                    
positionforme.y=((event.button.y/70)*70)+15;
   
if(turn)                    
{   //Check for circles                        

grid[event.button.y/70][event.button.x/70]=CIRCLE;                        
SDL_BlitSurface(cmark, NULL, screen, 
&positionforme);                        
SDL_Flip(screen);                        
turn=0;                    
}
//The type of AI I want is a random AI. I was going to use rand operator but I didn't have any idea for it at the time.

                    
else 
if(!turn)                    
{   //Check for X 
            
grid[event.button.y/70][event.button.x/70]=CROSS;                      
SDL_BlitSurface(xmark, NULL, screen, &positionforme);                        
SDL_Flip(screen);                        
turn=1;                    
}                
}                
break;        
}        
continuer=check_victory(screen);    }}


int Game::check_victory(SDL_Surface* screen)
{  
int 
nowinner=0;     //It verifies if there is a winner 
for(i=0; i<3; i++)
        {    
//horizontal Win Line            
if((grid[i][0]==CROSS && grid[i][1]==CROSS && grid[i][2]==CROSS) || (grid[i][0]==CIRCLE && grid[i][1]==CIRCLE && grid[i][2]==CIRCLE))            
{                
positionwon.x=20;                
positionwon.y=i*70+34;                
SDL_BlitSurface(horizontale, NULL, screen, 
&positionwon);                
SDL_Flip(screen);                
end=1;                
return 0;            
}            
//Vertical Win 
Line            
if((grid[0][i]==CROSS && grid[1][i]==CROSS && grid[2][i]==CROSS) || (grid[0][i]==CIRCLE && grid[1][i]==CIRCLE && grid[2][i]==CIRCLE))            
{                
positionwon.x=i*70+34;                
positionwon.y=20;                
SDL_BlitSurface(verticale, NULL, screen, 
&positionwon);                
SDL_Flip(screen);                
end=1;                
return 0;            
}        
}        //Diagonal Win 
Line        if((grid[0][0]==CROSS 
&& grid[1][1]==CROSS && grid[2][2]==CROSS) || 
(grid[0][0]==CIRCLE && grid[1][1]==CIRCLE && 
grid[2][2]==CIRCLE))        
{            
positionwon.x=20;            
positionwon.y=20;            
SDL_BlitSurface(diagonale1, NULL, screen, 
&positionwon);            
SDL_Flip(screen);            
end=1;            
return 0;        
}        if((grid[0][2]==CROSS && 
grid[1][1]==CROSS && grid[2][0]==CROSS) || (grid[0][2]==CIRCLE 
&& grid[1][1]==CIRCLE && 
grid[2][0]==CIRCLE))        
{            
positionwon.x=22;            
positionwon.y=20;            
SDL_BlitSurface(diagonale2, NULL, screen, 
&positionwon);            
SDL_Flip(screen);            
end=1;            
return 0;        
}        for(i=0; i<3; 
i++)        
{            for(j=0; 
j<3; 
j++)            
{                
if(grid[i][j]!=EMPTY)                
{                    
nowinner++;                
}            
}        
}        
if(nowinner==9)        
{            
end=1;            
return 0;        
}        return 1;}
Game::~Game(){    
SDL_FreeSurface(horizontale);    
SDL_FreeSurface(verticale);    
SDL_FreeSurface(diagonale1);    
SDL_FreeSurface(diagonale2);    
SDL_FreeSurface(xmark);    SDL_FreeSurface(cmark);}
#ifndef GAME_H_INCLUDED#define GAME_H_INCLUDED
enum {EMPTY, CIRCLE, CROSS};class Game{    
public:        
Game();        void play(SDL_Surface* 
screen);        int 
check_victory(SDL_Surface* 
screen);        ~Game();
    private:        
SDL_Surface *board, *cmark, *xmark, *horizontale, *verticale, *diagonale1, 
*diagonale2;        SDL_Event 
event;        int grid[3][3], continuer, 
i, j, turn, end, nowinner;        
SDL_Rect position, positionforme, positionwon;};
#endif // GAME_H_INCLUDED
Edited by LAURENT*

Share this post


Link to post
Share on other sites

Well, this is my first opportunity to experiment with this new subject I am looking into called Fuzzy Logic. And actually, I have been making an AI system that does stuff based on senses like sight and hearing, and touch. But this type of intellectual intelligence I haven't considered. 

 

Yet, it seems that this is the perfect scenario to use Fuzzy Logic in. I am actually just now getting ready to write a program that implements fuzzy logic, perhaps I can use tic-tac-toe as a test case. 

Share this post


Link to post
Share on other sites
#include <iostream>
#include <SDL.h>
#include <SDL_image.h>
#include <time.h>
#include "Game.h"

Game::Game()
{
    cmark= IMG_Load("cmark.jpg");
    xmark= IMG_Load("xmark.jpg");
    board= IMG_Load("board.jpg");
    horizontale=IMG_Load("horizontale.jpg");
    verticale=IMG_Load("verticale.jpg");
    diagonale1=IMG_Load("diagonale1.png");
    diagonale2=IMG_Load("diagonale2.png");
}
void Game::play(SDL_Surface *screen)
{
    int continuer=1, turn=0, end=0;
    position.x=0;
    position.y=0;
    SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
    SDL_BlitSurface(board, NULL, screen, &position);
    SDL_Flip(screen);
    for(i=0; i<3; i++)
    {
        for(j=0; j<3; j++)
        {
            grid[i][j]=EMPTY;
        }
    }
    while(continuer)
    {
        SDL_WaitEvent(&event);
        switch(event.type)
        {
            case SDL_QUIT:
                continuer=0;
                break;
            //Click management
            case SDL_MOUSEBUTTONDOWN:
                if(!end && grid[event.button.y/70][event.button.x/70]==EMPTY)
                {
                    positionforme.x=((event.button.x/70)*70)+15;
                    positionforme.y=((event.button.y/70)*70)+15;//
                    
					
					
					if(turn)
                    {   //Check for circles turn
                        grid[event.button.y/70][event.button.x/70]=CIRCLE;
                        SDL_BlitSurface(cmark, NULL, screen, &positionforme);
                        SDL_Flip(screen);
                        turn=0;
                    }

//The type of AI I want is a random AI. I was going to use rand operator but I didn't have any idea for it at the time.
//Goodluck and thank you very much for this support

                    else if(!turn)
                    {   //Check for X turn
                        grid[event.button.y/70][event.button.x/70]=CROSS;                      						
						SDL_BlitSurface(xmark, NULL, screen, &positionforme);
                        SDL_Flip(screen);
                        turn=1;
                    }
                }
                break;
        }
        continuer=check_victory(screen);
    }
}

int Game::check_victory(SDL_Surface* screen)
{
    int nowinner=0;
     //It verifies if there is a winner
        for(i=0; i<3; i++)
        {    //horizontal Win Line
            if((grid[i][0]==CROSS && grid[i][1]==CROSS && grid[i][2]==CROSS) || (grid[i][0]==CIRCLE && grid[i][1]==CIRCLE && grid[i][2]==CIRCLE))
            {
                positionwon.x=20;
                positionwon.y=i*70+34;
                SDL_BlitSurface(horizontale, NULL, screen, &positionwon);
                SDL_Flip(screen);
                end=1;
                return 0;
            }
            //Vertical Win Line
            if((grid[0][i]==CROSS && grid[1][i]==CROSS && grid[2][i]==CROSS) || (grid[0][i]==CIRCLE && grid[1][i]==CIRCLE && grid[2][i]==CIRCLE))
            {
                positionwon.x=i*70+34;
                positionwon.y=20;
                SDL_BlitSurface(verticale, NULL, screen, &positionwon);
                SDL_Flip(screen);
                end=1;
                return 0;
            }
        }
        //Diagonal Win Line
        if((grid[0][0]==CROSS && grid[1][1]==CROSS && grid[2][2]==CROSS) || (grid[0][0]==CIRCLE && grid[1][1]==CIRCLE && grid[2][2]==CIRCLE))
        {
            positionwon.x=20;
            positionwon.y=20;
            SDL_BlitSurface(diagonale1, NULL, screen, &positionwon);
            SDL_Flip(screen);
            end=1;
            return 0;
        }
        if((grid[0][2]==CROSS && grid[1][1]==CROSS && grid[2][0]==CROSS) || (grid[0][2]==CIRCLE && grid[1][1]==CIRCLE && grid[2][0]==CIRCLE))
        {
            positionwon.x=22;
            positionwon.y=20;
            SDL_BlitSurface(diagonale2, NULL, screen, &positionwon);
            SDL_Flip(screen);
            end=1;
            return 0;
        }
        for(i=0; i<3; i++)
        {
            for(j=0; j<3; j++)
            {
                if(grid[i][j]!=EMPTY)
                {
                    nowinner++;
                }
            }
        }
        if(nowinner==9)
        {
            end=1;
            return 0;
        }
        return 1;
}

Game::~Game()
{
    SDL_FreeSurface(horizontale);
    SDL_FreeSurface(verticale);
    SDL_FreeSurface(diagonale1);
    SDL_FreeSurface(diagonale2);
    SDL_FreeSurface(xmark);
    SDL_FreeSurface(cmark);
}

Share this post


Link to post
Share on other sites
#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED

enum {EMPTY, CIRCLE, CROSS};
class Game
{
    public:
        Game();
        void play(SDL_Surface* screen);
        int check_victory(SDL_Surface* screen);
        ~Game();

    private:
        SDL_Surface *board, *cmark, *xmark, *horizontale, *verticale, *diagonale1, *diagonale2;
        SDL_Event event;
        int grid[3][3], continuer, i, j, turn, end, nowinner;
        SDL_Rect position, positionforme, positionwon;
};


#endif // GAME_H_INCLUDED

MUCH MUCH Better! Sorry I had formatting problems. Man it just one problem after another today

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!