Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<stdio.h>
- #include<stdlib.h>
- #include<time.h>
- #define size 3
- #define Immortal 1
- #define Demigod 2
- #define Mortal 3
- #define Fodder 4
- typedef struct move{
- int score;
- int x;
- int y;
- }moveEval;
- void clearBoard(char board[size][size]){
- int i,j;
- for(i = 0 ; i < size ; i++)
- for(j = 0 ; j < size ; j++)
- board[i][j] = ' ';
- }
- void printBoard(char board[size][size]){
- int i,j;
- printf("\n");
- printf(" 0 1 2\n");
- for(i=0;i<size;i++)
- for(j=0;j<size;j++){
- if(j == 0)
- printf("%d ",i);
- printf("|%c|",board[i][j]);
- if(j == 2)
- printf("\n");
- }
- }
- char checkWin(char board[size][size]){
- int x,y;
- if( (board[0][0] == 'X' && board[1][1] == 'X' && board[2][2] == 'X') || (board[0][0] == 'O' && board[1][1] == 'O' && board[2][2] == 'O') )
- return board[0][0];
- else if( (board[0][2] == 'X' && board[1][1] == 'X' && board[2][0] == 'X') || (board[0][2] == 'O' && board[1][1] == 'O' && board[2][0] == 'O') )
- return board[0][2];
- for(x = 0, y = 0 ; x < size ; x++)
- if( (board[x][y] == 'X' && board[x][y+1] == 'X' && board[x][y+2] == 'X') || (board[x][y] == 'O' && board[x][y+1] == 'O' && board[x][y+2] == 'O') )
- return board[x][y];
- for(y = 0, x = 0 ; y < size ; y++)
- if( (board[x][y] == 'X' && board[x+1][y] == 'X' && board[x+2][y] == 'X') || (board[x][y] == 'O' && board[x+1][y] == 'O' && board[x+2][y] == 'O') )
- return board[x][y];
- return ' ';
- }
- int checkBoard(char board[size][size]){
- int i,j;
- for(i = 0 ; i < size ; i++)
- for(j = 0 ; j < size ; j++)
- if(board[i][j] == ' ')
- return 1;
- return 0;
- }
- int checkScore(char board[size][size], int x , int y){
- int i,j;
- int northsouth = 0, eastwest = 0, northwestsoutheast = 0, northeastsouthwest = 0;
- int scoreadd;
- if(board[x][y] == 'X')
- scoreadd = 1;
- else if(board[x][y] == 'O')
- scoreadd = -1;
- for(i = x - 1, j = y ; i >= 0 ; i--){ // NORTH
- if(board[i][j] == board[x][y]){
- northsouth += scoreadd * 3;
- }else if(board[i][j] == ' '){
- northsouth += scoreadd;
- }else{
- northsouth = 0;
- }
- }
- for(i = x + 1, j = y; i < size; i++){ // SOUTH
- if(board[i][j] == board[x][y]){
- northsouth += scoreadd * 3;
- }else if(board[i][j] == ' '){
- northsouth += scoreadd;
- }else{
- northsouth = 0;
- }
- }
- for(j = y + 1, i = x; j < size; j++){ // EAST
- if(board[i][j] == board[x][y]){
- eastwest += scoreadd * 3;
- }else if(board[i][j] == ' '){
- eastwest += scoreadd;
- }else{
- eastwest = 0;
- }
- }
- for(j = y - 1, i = x ; j >= 0 ; j--){ // WEST
- if(board[i][j] == board[x][y]){
- eastwest += scoreadd * 3;
- }else if(board[i][j] == ' '){
- eastwest += scoreadd;
- }else{
- eastwest = 0;
- }
- }
- for(i = x - 1, j = y - 1; i >= 0 && j >= 0; i--, j--){ // NORTHWEST
- if(board[i][j] == board[x][y]){
- northwestsoutheast += scoreadd * 5;
- }else if(board[i][j] == ' '){
- northwestsoutheast += scoreadd * 2;
- }else{
- northwestsoutheast = 0;
- }
- }
- for(i = x + 1, j = y + 1; i < size && j < size; i++, j++){ // SOUTHEAST
- if(board[i][j] == board[x][y]){
- northwestsoutheast += scoreadd * 5;
- }else if(board[i][j] == ' '){
- northwestsoutheast += scoreadd * 2;
- }else{
- northwestsoutheast = 0;
- }
- }
- for(i = x - 1, j = y + 1; i >= 0 && j < size; i--, j++){ // NORTHEAST
- if(board[i][j] == board[x][y]){
- northeastsouthwest += scoreadd * 5;
- }else if(board[i][j] == ' '){
- northeastsouthwest += scoreadd * 2;
- }else{
- northeastsouthwest = 0;
- }
- }
- for(i = x + 1, j = y - 1; i < size && j >= 0; i++, j--){ // SOUTHWEST
- if(board[i][j] == board[x][y]){
- northeastsouthwest += scoreadd * 5;
- }else if(board[i][j] == ' '){
- northeastsouthwest += scoreadd * 2;
- }else{
- northeastsouthwest = 0;
- }
- }
- if(northsouth == 1 || northsouth == -1 || northsouth == 3 || northsouth == -3){
- northsouth = 0;
- }
- if(eastwest == 1 || eastwest == -1 || eastwest == 3 || eastwest == -3){
- eastwest = 0;
- }
- if(northwestsoutheast == 2 || northwestsoutheast == -2 || northwestsoutheast == 5 || northwestsoutheast == -5){
- northwestsoutheast = 0;
- }
- if(northeastsouthwest == 2 || northeastsouthwest == -2 || northeastsouthwest == 5 || northeastsouthwest == -5){
- northeastsouthwest = 0;
- }
- //printf("%c | NS: %d EW: %d NWSE: %d NESW: %d\n",board[x][y],northsouth,eastwest,northwestsoutheast,northeastsouthwest);
- return northsouth+eastwest+northwestsoutheast+northeastsouthwest;
- }
- moveEval evaluateMove(char board[size][size], int x, int y, char movetype, int multiplier){
- moveEval move;
- int i,j;
- move.score = 0;
- move.x = x;
- move.y = y;
- board[move.x][move.y] = movetype;
- for(i=0;i<size;i++)
- for(j=0;j<size;j++){
- if(board[i][j] == 'X')
- move.score += checkScore(board,i,j);
- else if(board[i][j] == 'O')
- move.score += checkScore(board,i,j);
- }
- if(checkWin(board) == 'X')
- move.score += 100*multiplier;
- else if(checkWin(board) == 'O')
- move.score -= 100*multiplier;
- //printf("\n(%d , %d) = %d\n",move.x,move.y,move.score);
- board[move.x][move.y] = ' ';
- return move;
- }
- moveEval firstPlyCheckAllMoves(char board[size][size], int x, int y, char movetype){
- int first = 1;
- int i,j;
- moveEval checkmove;
- moveEval move;
- int scorecheck;
- board[x][y] = movetype;
- if(movetype == 'X')
- movetype = 'O';
- else if(movetype == 'O')
- movetype = 'X';
- for(i=0;i<size;i++){
- for(j=0;j<size;j++){
- if(board[i][j] == ' '){
- checkmove = evaluateMove(board,i,j,movetype,1);
- scorecheck = checkmove.score;
- if(first){
- move = checkmove;
- first--;
- }else{
- if(movetype == 'X'){
- if(move.score <= scorecheck)
- move = checkmove;
- }else if(movetype == 'O'){
- if(move.score >= scorecheck)
- move = checkmove;
- }
- }
- }
- }
- }
- board[x][y] = ' ';
- return move;
- }
- moveEval checkAllMoves(char board[size][size], char movetype, int AILevel){
- int first = 1;
- int i,j;
- moveEval checkmove;
- moveEval checkmove2;
- moveEval move;
- moveEval trailingmove;
- moveEval worstmove;
- int scorecheck;
- time_t t;
- srand((unsigned) time(&t));
- for(i=0;i<size;i++){
- for(j=0;j<size;j++){
- if(board[i][j] == ' '){
- checkmove = evaluateMove(board,i,j,movetype,2);
- checkmove2 = firstPlyCheckAllMoves(board,i,j,movetype);
- checkmove.score = checkmove.score + checkmove2.score;
- scorecheck = checkmove.score;
- //printf("(%d,%d) : %d = %d + %d\n",i,j,scorecheck,checkmove.score,checkmove2.score);
- if(first){
- move = checkmove;
- trailingmove = checkmove;
- first--;
- }
- if(movetype == 'X'){
- if(move.score <= scorecheck){
- trailingmove = move;
- move = checkmove;
- }
- if(move.score >= scorecheck){
- worstmove = checkmove;
- }
- }else if(movetype == 'O'){
- if(move.score >= scorecheck){
- trailingmove = move;
- move = checkmove;
- }
- if(move.score <= scorecheck){
- worstmove = checkmove;
- }
- }
- }
- }
- }
- if(AILevel == Immortal){
- return move;
- }else if(AILevel == Demigod){
- int random = rand() % 10;
- if(random <= 6 && random >= 0)
- return move;
- else
- return trailingmove;
- }else if(AILevel == Mortal){
- int random = rand() % 3;
- if(random == 0)
- return move;
- else if(random == 1)
- return trailingmove;
- else if(random == 2)
- return worstmove;
- }else if(AILevel == Fodder){
- return worstmove;
- }
- return move;
- }
- moveEval executeMove(char board[size][size], char movetype, int AILevel){
- moveEval move;
- move = checkAllMoves(board,movetype,AILevel);
- board[move.x][move.y] = movetype;
- return move;
- }
- int addMove(char board[size][size], int x, int y, char movetype){
- if(board[x][y] == ' '){
- board[x][y] = movetype;
- return 0;
- }
- return 1;
- }
- void narrate(moveEval move, int AILevel, char movetype){
- if(AILevel == Immortal)
- printf("\nImmortal (%c) has determined that (%d , %d) is the best move!\n",movetype,move.x,move.y);
- else if(AILevel == Demigod)
- printf("\nDemigod (%c) strongly feels that (%d , %d) is a good move!\n",movetype,move.x,move.y);
- else if(AILevel == Mortal)
- printf("\nMortal (%c) guesses that (%d , %d) may be a good move!\n",movetype,move.x,move.y);
- else if(AILevel == Fodder)
- printf("\nFodder (%c) doesn't know whether (%d , %d) is a good move!\n",movetype,move.x,move.y);
- }
- void changeAILevel(int* AILevelX, int* AILevelO){
- char AI;
- int AILevel;
- while(AI!='X' && AI!='x' && AI!='O' && AI!='o'){
- printf("Pick AI to change [X / O]: ");
- fflush(stdin);
- scanf("%c",&AI);
- }
- while(AILevel > 4 || AILevel < 1){
- printf("\nPick AI Level: \n\n");
- printf("Immortal [1]\n");
- printf("Demigod [2]\n");
- printf("Mortal [3]\n");
- printf("Fodder [4]\n\n");
- printf("Input: ");
- fflush(stdin);
- scanf("%d",&AILevel);
- }
- if(AI == 'X'||AI == 'x')
- *AILevelX = AILevel;
- else if(AI == 'O'||AI == 'o')
- *AILevelO = AILevel;
- }
- int main(){
- char board[size][size];
- int x,y,input = 0,turn = 0;
- moveEval move;
- int AILevelX = Immortal;
- int AILevelO = Immortal;
- clearBoard(board);
- while(input <= 0 || input > 4){
- printf("## XO ##\n\n");
- if(AILevelX == Immortal)
- printf("AI Level (X): Immortal\n");
- else if(AILevelX == Demigod)
- printf("AI Level (X): Demigod\n");
- else if(AILevelX == Mortal)
- printf("AI Level (X): Mortal\n");
- else if(AILevelX == Fodder)
- printf("AI Level (X): Fodder\n");
- if(AILevelO == Immortal)
- printf("AI Level (O): Immortal\n\n");
- else if(AILevelO == Demigod)
- printf("AI Level (O): Demigod\n\n");
- else if(AILevelO == Mortal)
- printf("AI Level (O): Mortal\n\n");
- else if(AILevelO == Fodder)
- printf("AI Level (O): Fodder\n\n");
- printf("[1] BOT vs BOT\n");
- printf("[2] HUMAN (X) vs BOT\n");
- printf("[3] HUMAN (O) vs BOT\n");
- printf("[4] HUMAN vs HUMAN\n");
- printf("[5] CHANGE AI LEVEL\n\n");
- printf("Input: ");
- fflush(stdin);
- scanf("%d",&input);
- if(input == 5){
- changeAILevel(&AILevelX,&AILevelO);
- }
- if(input < 1 || input > 5)
- printf("\nInvalid input.\n");
- }
- if(input == 1){
- clearBoard(board);
- while(checkBoard(board) && checkWin(board) == ' '){
- turn++;
- printf("\n## Turn %d ##\n",turn);
- move = executeMove(board,'X',AILevelX);
- narrate(move,AILevelX,'X');
- printBoard(board);
- if(checkBoard(board) && checkWin(board) == ' '){
- move = executeMove(board,'O',AILevelO);
- narrate(move,AILevelO,'O');
- }
- printBoard(board);
- }
- }else if(input == 2){
- while(checkBoard(board) && checkWin(board) == ' '){
- turn++;
- printf("\n## Turn %d ##\n",turn);
- printBoard(board);
- if(checkBoard(board) && checkWin(board) == ' ')
- do{
- printf("Enter move (x): ");
- fflush(stdin);
- scanf("%d",&y);
- printf("Enter move (y): ");
- fflush(stdin);
- scanf("%d",&x);
- }while(addMove(board,x,y,'X'));
- if(checkBoard(board) && checkWin(board) == ' '){
- move = executeMove(board,'O',AILevelO);
- narrate(move,AILevelO,'O');
- }
- printBoard(board);
- }
- }else if(input == 3){
- while(checkBoard(board) && checkWin(board) == ' '){
- turn++;
- printf("\n## Turn %d ##\n",turn);
- printBoard(board);
- if(checkBoard(board) && checkWin(board) == ' '){
- move = executeMove(board,'X',AILevelX);
- narrate(move,AILevelO,'X');
- }
- printBoard(board);
- if(checkBoard(board) && checkWin(board) == ' ')
- do{
- printf("Enter move (x): ");
- fflush(stdin);
- scanf("%d",&y);
- printf("Enter move (y): ");
- fflush(stdin);
- scanf("%d",&x);
- }while(addMove(board,x,y,'O'));
- }
- }else if(input == 4){
- while(checkBoard(board) && checkWin(board) == ' '){
- turn++;
- printf("\n## Turn %d ##\n",turn);
- printBoard(board);
- if(checkBoard(board) && checkWin(board) == ' ')
- do{
- printf("Enter move (x): ");
- fflush(stdin);
- scanf("%d",&y);
- printf("Enter move (y): ");
- fflush(stdin);
- scanf("%d",&x);
- }while(addMove(board,x,y,'X'));
- printBoard(board);
- if(checkBoard(board) && checkWin(board) == ' ')
- do{
- printf("Enter move (x): ");
- fflush(stdin);
- scanf("%d",&y);
- printf("Enter move (y): ");
- fflush(stdin);
- scanf("%d",&x);
- }while(addMove(board,x,y,'O'));
- }
- }
- printf("\n-------\n");
- printBoard(board);
- if(checkWin(board) == ' ')
- printf("\n## Tie. ##\n");
- else
- printf("\n## %c wins! ##\n",checkWin(board));
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement