Thread: help with tic tac toe look ahead algorithm

  1. #1
    Registered User
    Join Date
    Mar 2004
    Posts
    1

    help with tic tac toe look ahead algorithm

    i have been stuck here around a week...can you pls give me some idea how to start it? thanks..here is my codes for the TTT.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <time.h>
    
    void makeboard();
    void printboard();
    int checkwin();
    void makemove(int move, int counter);
    int lookahead();
    int computermove(int turn,int counter);
    int chkcompmove(int move);
    int getmove(int counter);
    int enemymove(int);
    
    char board[3][3]={0};
    char tempboard[3][3]={0};
    
    int turn, win, counter, X,O, lahlvl, compmove,chkcomp, move;
    
    int main(void){
    	win=0;
    	srand(time(NULL));
    	printf("X is [1] human, [2] computer :");
    	scanf("%d",&X);
    	printf("O is [1] human, [2] computer :");
    	scanf("%d",&O);
    	printf("Set lookahead level[0-3]:");
    	scanf("%d",&lahlvl);
    
    	makeboard();
    	turn=1;
    	while(win==0&&turn!=10)
    	{
    		turn++;
    		counter=turn%2;
    		switch(counter)
    		{
    		case 0: 
    			if(X==1)
    			{
    				printboard();
    				move=getmove(counter);
    				makemove(move, counter);
    				win=checkwin();
    				break;
    			}
    			else
    			{
    				move=computermove(turn, counter);
    				makemove(move, counter);
    				win=checkwin();
    				break;
    			}
    
    		case 1: 
    			if(O==1)
    			{
    				printboard();
    				move=getmove(counter);
    				makemove(move, counter);
    				win=checkwin();			
    			break;
    			}
    			else
    			{
    				move=computermove(turn, counter);
    				makemove(move, counter);
    				win=checkwin();
    				break;
    			}
    			
    		}			
    	}
    	if(turn==10)
    	{
    		printboard();
    		printf("Draw!\n");
    	}
    	else if(counter==0)
    	{
    		printboard();
    		printf("X wins!\n");
    	}
    	else if(counter==1)
    	{
    		printboard();
    		printf("O wins!\n");
    	}
    	
    	return(0);
    }
    
    void makeboard() {
    	int a,b;
    	char c='1';
    	
    		for (a=0;a<3;a++)
    	{
    		for (b=0;b<3;b++)
    		{
    			board[a][b]=c;
    			c+=1;
    		}
    	}
    }
    
    void printboard() {
    	
    	int a,b;
    	
    	for (a=0;a<3;a++)
    		{
    			for (b=0;b<3;b++)
    			{
    				printf("%c",board[a][b]);
    			}
    			printf("\n");
    		}
    }
    
    void makemove(int move,int counter) {
    	switch(move)
    	{
    	case 1:
    		if(board[0][0]!='1')
    		{
    			printf("invalid move\n");
    			move=getmove(counter);
    			makemove(move, counter);
    			break;
    		}
    		else
    		{	
    			if(counter==0)
    				board[0][0]='X';
    			else
    				board[0][0]='O';
    			break;
    
    		}
    
    		
    	
    	case 2:
    		if(board[0][1]!='2')
    		{
    			printf("invalid move\n");
    			move=getmove(counter);
    			makemove(move, counter);
    			break;
    		}
    		else
    		{	
    			if(counter==0)
    				board[0][1]='X';
    			else
    				board[0][1]='O';
    			break;
    		}
    		
    	
    	case 3:
    		if(board[0][2]!='3')
    		{
    			printf("invalid move\n");
    			move=getmove(counter);
    			makemove(move, counter);
    			break;
    		}
    		else
    		{	
    			if(counter==0)
    				board[0][2]='X';
    			else
    				board[0][2]='O';
    			break;
    		}
    	
    
    	case 4:
    		if(board[1][0]!='4')
    		{
    			printf("invalid move\n");
    			move=getmove(counter);
    			makemove(move, counter);
    			break;
    		}
    		else
    		{	
    			if(counter==0)
    				board[1][0]='X';
    			else
    				board[1][0]='O';
    			break;
    		}
    
    	case 5:
    		if(board[1][1]!='5')
    		{
    			printf("invalid move\n");
    			move=getmove(counter);
    			makemove(move, counter);
    			break;
    		}
    		else
    		{	
    			if(counter==0)
    				board[1][1]='X';
    			else
    				board[1][1]='O';
    			break;
    		}
    		
    
    	case 6:
    		if(board[1][2]!='6')
    		{
    			printf("invalid move\n");
    			move=getmove(counter);
    			makemove(move, counter);
    			break;
    		}
    		else
    		{	
    			if(counter==0)
    				board[1][2]='X';
    			else
    				board[1][2]='O';
    			break;
    		}
    
    	case 7:
    		if(board[2][0]!='7')
    		{
    			printf("invalid move\n");
    			move=getmove(counter);
    			makemove(move, counter);
    			break;
    		}
    		else
    		{	
    			if(counter==0)
    				board[2][0]='X';
    			else
    				board[2][0]='O';
    			break;
    		}
    		
    
    	case 8:
    		if(board[2][1]!='8')
    		{
    			printf("invalid move\n");
    			move=getmove(counter);
    			makemove(move, counter);
    			break;
    		}
    		else
    		{	
    			if(counter==0)
    				board[2][1]='X';
    			else
    				board[2][1]='O';
    			break;
    		}
    	
    	case 9:
    		if(board[2][2]!='9')
    		{
    			printf("invalid move\n");
    			move=getmove(counter);
    			makemove(move, counter);
    			break;
    		}
    		else
    		{	
    			if(counter==0)
    				board[2][2]='X';
    			else
    				board[2][2]='O';
    			break;
    		}
    	}
    }
    
    int getmove(int counter) {
    	if(counter==0)
    	{
    		printf("X move:");
    		scanf("%d",&move);
    	}
    	else
    	{
    		printf("O move:");
    		scanf("%d",&move);
    	}
    	return move;
    }
    
    int checkwin() 
    	{
    	int a=0,b=0;
    	for (a=0;a<3;a++)
    	{
    		if (board[a][b]=='O' && board[a][b+1]=='O' && board[a][b+2]=='O')
    		{
    				return 1;
    			
    		}
    		else if (board[a][b]=='X' && board[a][b+1]=='X' && board[a][b+2]=='X')
    		{
    				return 1;
    		}
    	}
    	a=0;
    	for (b=0;b<3;b++)
    	{
    		if (board[a][b]=='O' && board[a+1][b]=='O' && board[a+2][b]=='O')
    		{
    				return 1;
    		}
    		else if (board[a][b]=='X' && board[a+1][b]=='X' && board[a+2][b]=='X')
    		{	
    				return 1;
    		}
    	}
    	a=0;
    	b=0;
    	if (board[a][b]=='O' && board[a+1][b+1]=='O' && board[a+2][b+2]=='O')
    	{
    				return 1;
    	}
    	else if (board[a][b]=='X' && board[a+1][b+1]=='X' && board[a+2][b+2]=='X')
    	{
    				return 1;
    	}
    	else if (board[a][b+2]=='O' && board[a+1][b+1]=='O' && board[a+2][b]=='O')
    	{
    				return 1;
    	}
    	else if (board[a][b+2]=='X' && board[a+1][b+1]=='X' && board[a+2][b]=='X')
    	{
    				return 1;
    	}
    	return 0;
    }
    
    int chkcompmove(int compmove){
    
    switch(compmove)
    	{
    	case 1:
    		if(board[0][0]!='1')
    		{
    			return 0;
    			break;
    		}
    		else
    		{	
    			return 1;
    			break;
    		}
    	case 2:
    		if(board[0][1]!='2')
    		{
    			return 0;
    			break;
    		}
    		else
    		{	
    			return 1;
    			break;
    		}
    	case 3:
    		if(board[0][2]!='3')
    			{
    			return 0;
    			break;
    		}
    		else
    		{	
    			return 1;
    			break;
    		}
    	case 4:
    		if(board[1][0]!='4')
    			{
    			return 0;
    			break;
    		}
    		else
    		{	
    			return 1;
    			break;
    		}
    	case 5:
    		if(board[1][1]!='5')
    			{
    			return 0;
    			break;
    		}
    		else
    		{	
    			return 1;
    			break;
    		}
    	case 6:
    		if(board[1][2]!='6')
    			{
    			return 0;
    			break;
    		}
    		else
    		{	
    			return 1;
    			break;
    		}
    	case 7:
    		if(board[2][0]!='7')
    			{
    			return 0;
    			break;
    		}
    		else
    		{	
    			return 1;
    			break;
    		}
    	case 8:
    		if(board[2][1]!='8')
    			{
    			return 0;
    			break;
    		}
    		else
    		{	
    			return 1;
    			break;
    		}
    	case 9:
    		if(board[2][2]!='9')
    			{
    			return 0;
    			break;
    		}
    		else
    		{	
    			return 1;
    			break;
    		}
    	}
    return 0;
    }
    
    int computermove(int turn,int counter)
    {	
    	int comp,a,b;
    	tempboard[3][3]=board[3][3];
    	for (a=0;a<3;a++)
    		{
    			for (b=0;b<3;b++)
    			{
    				tempboard[a][b]=board[a][b];
    			}
    	}
    	if(turn==2)
    	{
    	switch(compmove)
    		{
    		case 0:
    			return 1;
    			break;
    		case 1:
    			return 2;
    			break;
    		case 3:
    			return 5;
    			break;
    
    		}
    	}
    	else
    	{
    		if(lahlvl==0)
    		{
    			chkcomp=0;
    
    			while(chkcomp==0)
    			{
    				compmove=rand()%9+1;
    				chkcomp=chkcompmove(compmove);
    			}
    			return compmove;
    		}
    		if (lahlvl==2 || lahlvl==3)	
    		{
    			chkcomp=lookahead();
    			return compmove;
    		}
    		
    	}
    	
    return 0;
    }
    
    int lookahead()
    {
    	int n=lahlvl,a,b,ahead,marks[3][3]={a},check=0,cpu,player;
    	
    	/*marks not initialized to 0 for checking purpose*/
    	
    	for (a=0;a<3;a++)
    	{
    		for (b=0;b<3;b++)
    		{	
    			for (ahead==0;ahead<n;ahead++)	/*for the number of look ahead*/
    			{
    				if (isdigit(tempboard[a][b]!=0)
    				{
    					cpu = tempboard[a][b];
    					player= enemymove();
    					check=checkwin();
    					if (check ==1)
    						mark[a][b]=1;
    					
    
    
    
    int enemymove();
    {
    	compmove=rand()%9+1;
    	chkcomp=chkcompmove(compmove);
    the ending is the place where i got stuck... >_<

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Nice (not)
    First post and you dump 500+ lines of code on the board, and it isn't even complete.
    The all-important lookahead() has simply been chopped in half.

    You'd do better to pass some more (and relevant parameters) to various functions, then they wouldn't be so long.

    Here's an example
    int checkwin()

    If you wrote
    Code:
    int checkwin( char player ) {
    ...
        if (board[a][b]==player && board[a][b+1]==player && board[a][b+2]==player)
    }
    You could chop half the lines out of this function

    All the other functions with 9 cases in them should be reduced as well.
    Code:
    void makemove(int move,int counter) {
        switch(move)
        {
        case 1:
            if(board[0][0]!='1')
            {
                printf("invalid move\n");
                move=getmove(counter);
                makemove(move, counter);
                break;
            }
            else
            {
                if(counter==0)
                    board[0][0]='X';
                else
                    board[0][0]='O';
                break;
    
            }
    Would be better as
    Code:
    void makemove(int move,char player) {
        int row = (move-1) % 3;
        int col = (move-1) / 3;
        if(board[row][col]!=0)
        {
            printf("invalid move\n");
            move=getmove(player);
            makemove(move, player);
        }
        else
        {
            board[row][col]=player;
        }
    }
    See - it copes with all positions using the same code.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help me with my simple Tic tac toe prog
    By maybnxtseasn in forum C Programming
    Replies: 2
    Last Post: 04-04-2009, 06:25 PM
  2. tic tac toe crashes :(
    By stien in forum Game Programming
    Replies: 4
    Last Post: 05-13-2007, 06:25 PM
  3. tic tac toe
    By holden in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 05-09-2004, 09:59 AM
  4. Help with Tic Tac Toe game
    By snef73 in forum C++ Programming
    Replies: 1
    Last Post: 04-25-2003, 08:33 AM
  5. my tic tac toe game, please try it
    By Leeman_s in forum C++ Programming
    Replies: 2
    Last Post: 04-14-2002, 05:16 PM