Skip to content

Sid3548/hello-world

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 

Repository files navigation

#include <stdio.h>
#include <stdlib.h>

#define N 9

enum { O,X,EMPTY };

int HUMAN = 0;
int COMP = 1;

// initialize the borad with empty cells
void initBoard(int board[]) {

	for(int i=0; i<N; i++)
		board[i] = EMPTY;
}

// print the board on console
void printBoard(const int board[]) {

	char symbol[] = { 'O','X','-' };

	printf("\n  BOARD\n\n");
	for(int i=0; i<N; i++) {
		if(i != 0 && i%3 == 0)
			printf("\n\n");
		printf(" %c ",symbol[board[i]]);
	}
	printf("\n\n");
}

// checks if the board is full or not
// returns 1(true) if full
// returns 0(false) if even one cell is empty
int isBoardFull(const int board[]) {

	for(int i=0; i<N; i++)
		if(board[i] == EMPTY)
			return 0;
	return 1;
}

// makes a move on the given cell by given side
void makeMove(int board[], const int cell, const int side) {
	board[cell] = side;
}


// checks if a 3 is formed by a side
// returns 1 if yes
// returns 0 if no
int is3inARow(const int board[], const int side) {

	// horizontal
	if(board[0] == side && board[1] == side && board[2] == side)
		return 1;
	if(board[3] == side && board[4] == side && board[5] == side)
		return 1;
	if(board[6] == side && board[7] == side && board[8] == side)
		return 1;

	// vertical
	if(board[0] == side && board[3] == side && board[6] == side)
		return 1;
	if(board[1] == side && board[4] == side && board[7] == side)
		return 1;
	if(board[2] == side && board[5] == side && board[8] == side)
		return 1;

	// diagonal
	if(board[0] == side && board[4] == side && board[8] == side)
		return 1;
	if(board[2] == side && board[4] == side && board[6] == side)
		return 1;

	return 0;
}

// returns score for side
// +10 if particular side wins
// -10 if particular side loses
//  0 if draw or not yet complete
int isAWin(const int board[], const int side) {

	if(is3inARow(board,side))
		return 10;
	if(is3inARow(board,!side))
		return -10;
	return 0;
}

// returns which moves gives the maximum score
int max(int *scoreList,int moveCount,int *moveList,int *bestMove) {
    
    if(!moveCount)
    	return 0;

    int max = -20;
    
    for(int i=0;i<moveCount;i++) {
        if(scoreList[i] > max) {
            max = scoreList[i];
            *bestMove = moveList[i];
        }
    }
    return max;
}

// returns which moves gives the minimum score
int min(int *scoreList,int moveCount,int *moveList,int *bestMove) {
    
    if(!moveCount)
    	return 0;

    int min = +20;
    
    for(int i=0;i<moveCount;i++) {
        if(scoreList[i] < min) {
            min = scoreList[i];
            *bestMove = moveList[i];
        }
    }
    return min;
}

int minMax(int board[], int side, int *depth) {

	int moveList[N];
	int moveCount = 0;
	int bestMove;
	int scoreList[N];
	int bestScore;

	bestScore = isAWin(board,COMP);
	if(bestScore)
		return bestScore - *depth;

	// fill the moveList[]
	for(int i=0;i<N;i++) {
		if(board[i] == EMPTY)
			moveList[moveCount++] = i;
	}

	// loop through all moves
	int move;
	for(int i=0;i<moveCount;i++) {

		move = moveList[i];
		makeMove(board,move,side);

		(*depth)++;
		scoreList[i] = minMax(board,!side,depth);
		(*depth)--;

		makeMove(board,move,EMPTY);
	}

	if(side == COMP) {
		// MAX
		bestScore = max(scoreList,moveCount,moveList,&bestMove);
	}
	if(side == HUMAN) {
		// MIN
		bestScore = min(scoreList,moveCount,moveList,&bestMove);
	}

	if(*depth != 0)
        return bestScore;
    else
        return bestMove;
}

int getComputerMove(int *board,int side) {

    int depth = 0;
    int bestMove = minMax(board,side,&depth);
    printf("Searched.... bestMove: %d\n",bestMove+1);
    return bestMove;
}

int getHumanMove(const int *board) {

	printf("\nEnter your move !!\n\n");
	int move;
	while(1) {

		scanf("%d",&move);
		if(board[move-1] == EMPTY && move >=0 && move <=9)
			break;
		else
			printf("try again : ");
	}
	return move-1;
}

void runGame() {

	printf("\nChoose X or O. O moves first !!\n\n");
	while(1) {
		
		char choice = getchar();
		getchar();
		if(choice == 'O') {
			HUMAN = O;
			COMP = X;
			break;
		}
		if(choice == 'X') {
			HUMAN = X;
			COMP = O;
			break;
		}
		else {
			printf("Choose correct symbols\n");
		}
	}

	int gameOver = 0;
	int side = O;
	int move;
	int board[N];

	initBoard(board);
	printBoard(board);

	while(!gameOver) {

		if(side == HUMAN) {
			//Human Move
			move = getHumanMove(board);
			makeMove(board,move,side);
			printBoard(board);
		}
		else {
			//Computer Move
			move = getComputerMove(board,side);
			makeMove(board,move,side);
			printBoard(board);
		}


		//WIN
		if(is3inARow(board,side)) {
			printf("Game Over\n");
			gameOver = 1;
			if(side == COMP)
				printf("Computer Wins\n");
			else
				printf("Human Wins\n");
		}

		//DRAW
		if(isBoardFull(board)) {
			printf("Game Over\n");
			gameOver = 1;
			printf("It's a Draw\n");
		}

		side = !side;

	}
}

int main(int argc, char *argv[]) {

	runGame();

	return 0;
}




About

A Repository

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages