Advertisement
Guest User

Untitled

a guest
Oct 22nd, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.85 KB | None | 0 0
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<time.h>
  4. #define size 3
  5. #define Immortal 1
  6. #define Demigod 2
  7. #define Mortal 3
  8. #define Fodder 4
  9.  
  10. typedef struct move{
  11.  
  12.     int score;
  13.     int x;
  14.     int y;
  15.    
  16. }moveEval;
  17.  
  18. void clearBoard(char board[size][size]){
  19.    
  20.     int i,j;
  21.     for(i = 0 ; i < size ; i++)
  22.         for(j = 0 ; j < size ; j++)
  23.             board[i][j] = ' '; 
  24.            
  25. }
  26.  
  27. void printBoard(char board[size][size]){
  28.    
  29.     int i,j;
  30.     printf("\n");
  31.     printf("   0  1  2\n");
  32.     for(i=0;i<size;i++)
  33.         for(j=0;j<size;j++){
  34.             if(j == 0)
  35.                 printf("%d ",i);
  36.             printf("|%c|",board[i][j]);
  37.             if(j == 2)
  38.                 printf("\n");
  39.         }
  40.    
  41. }
  42.  
  43. char checkWin(char board[size][size]){
  44.    
  45.     int x,y;
  46.    
  47.     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') )
  48.         return board[0][0];
  49.     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') )
  50.         return board[0][2];
  51.    
  52.     for(x = 0, y = 0 ; x < size ; x++)
  53.         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') )
  54.             return board[x][y];
  55.  
  56.     for(y = 0, x = 0 ; y < size ; y++)
  57.         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') )
  58.             return board[x][y];
  59.            
  60.     return ' ';
  61.                    
  62. }
  63.  
  64. int checkBoard(char board[size][size]){
  65.    
  66.     int i,j;
  67.    
  68.     for(i = 0 ; i < size ; i++)
  69.         for(j = 0 ; j < size ; j++)
  70.             if(board[i][j] == ' ')
  71.                 return 1;
  72.     return 0;
  73. }
  74.  
  75. int checkScore(char board[size][size], int x , int y){
  76.    
  77.     int i,j;
  78.     int northsouth = 0, eastwest = 0, northwestsoutheast = 0, northeastsouthwest = 0;
  79.     int scoreadd;
  80.    
  81.     if(board[x][y] == 'X')
  82.         scoreadd = 1;
  83.     else if(board[x][y] == 'O')
  84.         scoreadd = -1;
  85.    
  86.     for(i = x - 1, j = y ; i >= 0 ; i--){ // NORTH
  87.       if(board[i][j] == board[x][y]){
  88.         northsouth += scoreadd * 3;
  89.       }else if(board[i][j] == ' '){
  90.         northsouth += scoreadd;  
  91.       }else{
  92.         northsouth = 0;  
  93.       }
  94.     }  
  95.    
  96.     for(i = x + 1, j = y; i < size; i++){ // SOUTH
  97.       if(board[i][j] == board[x][y]){
  98.         northsouth += scoreadd * 3;
  99.       }else if(board[i][j] == ' '){
  100.         northsouth += scoreadd;  
  101.       }else{
  102.         northsouth = 0;  
  103.       }
  104.     }
  105.  
  106.        
  107.     for(j = y + 1, i = x; j < size; j++){ // EAST
  108.       if(board[i][j] == board[x][y]){
  109.         eastwest += scoreadd * 3;
  110.       }else if(board[i][j] == ' '){
  111.         eastwest += scoreadd;    
  112.       }else{
  113.         eastwest = 0;    
  114.       }
  115.     }
  116.        
  117.     for(j = y - 1, i = x ; j >= 0 ; j--){ // WEST
  118.       if(board[i][j] == board[x][y]){
  119.         eastwest += scoreadd * 3;
  120.       }else if(board[i][j] == ' '){
  121.         eastwest += scoreadd;    
  122.       }else{
  123.         eastwest = 0;    
  124.       }
  125.     }        
  126.  
  127.     for(i = x - 1, j = y - 1; i >= 0 && j >= 0; i--, j--){ // NORTHWEST
  128.       if(board[i][j] == board[x][y]){
  129.         northwestsoutheast += scoreadd * 5;
  130.       }else if(board[i][j] == ' '){
  131.         northwestsoutheast += scoreadd * 2;  
  132.       }else{
  133.         northwestsoutheast = 0;  
  134.       }
  135.     }
  136.    
  137.     for(i = x + 1, j = y + 1; i < size && j < size; i++, j++){ // SOUTHEAST
  138.       if(board[i][j] == board[x][y]){
  139.         northwestsoutheast += scoreadd * 5;
  140.       }else if(board[i][j] == ' '){
  141.         northwestsoutheast += scoreadd * 2;  
  142.       }else{
  143.         northwestsoutheast = 0;  
  144.       }
  145.     }
  146.    
  147.     for(i = x - 1, j = y + 1; i >= 0 && j < size; i--, j++){ // NORTHEAST
  148.       if(board[i][j] == board[x][y]){
  149.         northeastsouthwest += scoreadd * 5;
  150.       }else if(board[i][j] == ' '){
  151.         northeastsouthwest += scoreadd * 2;  
  152.       }else{
  153.         northeastsouthwest = 0;  
  154.       }
  155.     }
  156.    
  157.     for(i = x + 1, j = y - 1; i < size && j >= 0; i++, j--){ // SOUTHWEST
  158.       if(board[i][j] == board[x][y]){
  159.         northeastsouthwest += scoreadd * 5;
  160.       }else if(board[i][j] == ' '){
  161.         northeastsouthwest += scoreadd * 2;  
  162.       }else{
  163.         northeastsouthwest = 0;  
  164.       }
  165.     }
  166.    
  167.     if(northsouth == 1 || northsouth == -1 || northsouth == 3 || northsouth == -3){
  168.         northsouth = 0;
  169.     }
  170.     if(eastwest == 1 || eastwest == -1 || eastwest == 3 || eastwest == -3){
  171.         eastwest = 0;
  172.     }
  173.     if(northwestsoutheast == 2 || northwestsoutheast == -2 || northwestsoutheast == 5 || northwestsoutheast == -5){
  174.         northwestsoutheast = 0;
  175.     }
  176.     if(northeastsouthwest == 2 || northeastsouthwest == -2 || northeastsouthwest == 5 || northeastsouthwest == -5){
  177.         northeastsouthwest = 0;
  178.     }
  179.            
  180.    
  181.     //printf("%c | NS: %d EW: %d NWSE: %d NESW: %d\n",board[x][y],northsouth,eastwest,northwestsoutheast,northeastsouthwest);
  182.     return northsouth+eastwest+northwestsoutheast+northeastsouthwest;
  183. }
  184.  
  185. moveEval evaluateMove(char board[size][size], int x, int y, char movetype, int multiplier){
  186.    
  187.     moveEval move;
  188.     int i,j;
  189.    
  190.     move.score = 0;
  191.     move.x = x;
  192.     move.y = y;
  193.        
  194.     board[move.x][move.y] = movetype;
  195.                
  196.     for(i=0;i<size;i++)
  197.         for(j=0;j<size;j++){
  198.             if(board[i][j] == 'X')
  199.                 move.score += checkScore(board,i,j);
  200.             else if(board[i][j] == 'O')
  201.                 move.score += checkScore(board,i,j);
  202.             }
  203.            
  204.     if(checkWin(board) == 'X')
  205.         move.score += 100*multiplier;
  206.     else if(checkWin(board) == 'O')
  207.         move.score -= 100*multiplier;
  208.    
  209.     //printf("\n(%d , %d) = %d\n",move.x,move.y,move.score);
  210.    
  211.     board[move.x][move.y] = ' ';
  212.    
  213.     return move;
  214.    
  215. }
  216.  
  217.  
  218. moveEval firstPlyCheckAllMoves(char board[size][size], int x, int y, char movetype){
  219.    
  220.     int first = 1;
  221.     int i,j;
  222.     moveEval checkmove;
  223.     moveEval move;
  224.     int scorecheck;
  225.    
  226.     board[x][y] = movetype;
  227.    
  228.     if(movetype == 'X')
  229.         movetype = 'O';
  230.     else if(movetype == 'O')
  231.         movetype = 'X';
  232.    
  233.     for(i=0;i<size;i++){
  234.         for(j=0;j<size;j++){
  235.             if(board[i][j] == ' '){
  236.                 checkmove = evaluateMove(board,i,j,movetype,1);
  237.                 scorecheck = checkmove.score;
  238.                 if(first){
  239.                     move = checkmove;
  240.                     first--;
  241.                 }else{
  242.                     if(movetype == 'X'){
  243.                         if(move.score <= scorecheck)
  244.                             move = checkmove;
  245.                     }else if(movetype == 'O'){
  246.                         if(move.score >= scorecheck)
  247.                             move = checkmove;
  248.                     }
  249.                 }
  250.             }
  251.         }
  252.     }  
  253.    
  254.     board[x][y] = ' ';
  255.    
  256.     return move;
  257. }
  258.  
  259. moveEval checkAllMoves(char board[size][size], char movetype, int AILevel){
  260.    
  261.     int first = 1;
  262.     int i,j;
  263.     moveEval checkmove;
  264.     moveEval checkmove2;
  265.     moveEval move;
  266.     moveEval trailingmove;
  267.     moveEval worstmove;
  268.     int scorecheck;
  269.     time_t t;
  270.     srand((unsigned) time(&t));
  271.    
  272.     for(i=0;i<size;i++){
  273.         for(j=0;j<size;j++){
  274.             if(board[i][j] == ' '){
  275.                 checkmove = evaluateMove(board,i,j,movetype,2);
  276.                 checkmove2 = firstPlyCheckAllMoves(board,i,j,movetype);
  277.                 checkmove.score = checkmove.score + checkmove2.score;
  278.                 scorecheck = checkmove.score;
  279.                 //printf("(%d,%d) : %d = %d + %d\n",i,j,scorecheck,checkmove.score,checkmove2.score);
  280.                 if(first){
  281.                     move = checkmove;
  282.                     trailingmove = checkmove;
  283.                     first--;
  284.                 }
  285.                 if(movetype == 'X'){
  286.                         if(move.score <= scorecheck){
  287.                             trailingmove = move;
  288.                             move = checkmove;                          
  289.                         }
  290.                         if(move.score >= scorecheck){
  291.                             worstmove = checkmove;                         
  292.                         }      
  293.                 }else if(movetype == 'O'){
  294.                         if(move.score >= scorecheck){
  295.                             trailingmove = move;
  296.                             move = checkmove;                          
  297.                         }
  298.                         if(move.score <= scorecheck){
  299.                             worstmove = checkmove;                             
  300.                         }      
  301.                 }
  302.             }
  303.         }
  304.     }  
  305.    
  306.     if(AILevel == Immortal){
  307.         return move;
  308.     }else if(AILevel == Demigod){
  309.         int random = rand() % 10;
  310.         if(random <= 6 && random >= 0)
  311.             return move;
  312.         else
  313.             return trailingmove;
  314.     }else if(AILevel == Mortal){
  315.         int random = rand() % 3;
  316.         if(random == 0)
  317.             return move;
  318.         else if(random == 1)
  319.             return trailingmove;
  320.         else if(random == 2)
  321.             return worstmove;
  322.     }else if(AILevel == Fodder){
  323.         return worstmove;
  324.     }
  325.    
  326.     return move;
  327. }
  328.  
  329. moveEval executeMove(char board[size][size], char movetype, int AILevel){
  330.    
  331.     moveEval move;
  332.  
  333.     move = checkAllMoves(board,movetype,AILevel);
  334.    
  335.     board[move.x][move.y] = movetype;
  336.    
  337.     return move;
  338.    
  339. }
  340.  
  341. int addMove(char board[size][size], int x, int y, char movetype){
  342.    
  343.     if(board[x][y] == ' '){
  344.         board[x][y] = movetype;
  345.         return 0;
  346.     }
  347.     return 1;
  348.    
  349. }
  350.  
  351. void narrate(moveEval move, int AILevel, char movetype){
  352.     if(AILevel == Immortal)
  353.         printf("\nImmortal (%c) has determined that (%d , %d) is the best move!\n",movetype,move.x,move.y);    
  354.     else if(AILevel == Demigod)
  355.         printf("\nDemigod (%c) strongly feels that (%d , %d) is a good move!\n",movetype,move.x,move.y);   
  356.     else if(AILevel == Mortal)
  357.         printf("\nMortal (%c) guesses that (%d , %d) may be a good move!\n",movetype,move.x,move.y);       
  358.     else if(AILevel == Fodder)
  359.         printf("\nFodder (%c) doesn't know whether (%d , %d) is a good move!\n",movetype,move.x,move.y);   
  360. }
  361.  
  362. void changeAILevel(int* AILevelX, int* AILevelO){
  363.    
  364.     char AI;
  365.     int AILevel;
  366.    
  367.     while(AI!='X' && AI!='x' && AI!='O' && AI!='o'){
  368.         printf("Pick AI to change [X / O]: ");
  369.         fflush(stdin);
  370.         scanf("%c",&AI);       
  371.     }
  372.     while(AILevel > 4 || AILevel < 1){
  373.         printf("\nPick AI Level: \n\n");
  374.         printf("Immortal [1]\n");
  375.         printf("Demigod [2]\n");
  376.         printf("Mortal [3]\n");
  377.         printf("Fodder [4]\n\n");
  378.         printf("Input: ");
  379.         fflush(stdin);
  380.         scanf("%d",&AILevel);      
  381.     }
  382.     if(AI == 'X'||AI == 'x')
  383.         *AILevelX = AILevel;
  384.     else if(AI == 'O'||AI == 'o')
  385.         *AILevelO = AILevel;
  386.    
  387. }
  388.  
  389. int main(){
  390.  
  391.     char board[size][size];
  392.    
  393.     int x,y,input = 0,turn = 0;
  394.    
  395.     moveEval move;
  396.    
  397.     int AILevelX = Immortal;
  398.     int AILevelO = Immortal;
  399.    
  400.     clearBoard(board);
  401.            
  402.     while(input <= 0 || input > 4){
  403.        
  404.         printf("## XO ##\n\n");
  405.        
  406.         if(AILevelX == Immortal)
  407.             printf("AI Level (X): Immortal\n");    
  408.         else if(AILevelX == Demigod)
  409.             printf("AI Level (X): Demigod\n");     
  410.         else if(AILevelX == Mortal)
  411.             printf("AI Level (X): Mortal\n");      
  412.         else if(AILevelX == Fodder)
  413.             printf("AI Level (X): Fodder\n");      
  414.    
  415.         if(AILevelO == Immortal)
  416.             printf("AI Level (O): Immortal\n\n");      
  417.         else if(AILevelO == Demigod)
  418.             printf("AI Level (O): Demigod\n\n");       
  419.         else if(AILevelO == Mortal)
  420.             printf("AI Level (O): Mortal\n\n");    
  421.         else if(AILevelO == Fodder)
  422.             printf("AI Level (O): Fodder\n\n");
  423.            
  424.         printf("[1] BOT vs BOT\n");
  425.         printf("[2] HUMAN (X) vs BOT\n");
  426.         printf("[3] HUMAN (O) vs BOT\n");
  427.         printf("[4] HUMAN vs HUMAN\n");
  428.         printf("[5] CHANGE AI LEVEL\n\n");
  429.         printf("Input: ");
  430.        
  431.         fflush(stdin);
  432.         scanf("%d",&input);
  433.         if(input == 5){
  434.             changeAILevel(&AILevelX,&AILevelO);
  435.         }
  436.         if(input < 1 || input > 5)
  437.             printf("\nInvalid input.\n");
  438.     }
  439.    
  440.     if(input == 1){
  441.         clearBoard(board);
  442.         while(checkBoard(board) && checkWin(board) == ' '){
  443.             turn++;
  444.             printf("\n## Turn %d ##\n",turn);
  445.             move = executeMove(board,'X',AILevelX);
  446.             narrate(move,AILevelX,'X');
  447.             printBoard(board);
  448.             if(checkBoard(board) && checkWin(board) == ' '){
  449.                 move = executeMove(board,'O',AILevelO);
  450.                 narrate(move,AILevelO,'O');
  451.             }                      
  452.             printBoard(board);
  453.         }          
  454.     }else if(input == 2){
  455.         while(checkBoard(board) && checkWin(board) == ' '){
  456.            
  457.             turn++;
  458.             printf("\n## Turn %d ##\n",turn);          
  459.             printBoard(board);
  460.            
  461.             if(checkBoard(board) && checkWin(board) == ' ')
  462.                 do{
  463.                     printf("Enter move (x): ");
  464.                     fflush(stdin);
  465.                     scanf("%d",&y);
  466.                     printf("Enter move (y): ");
  467.                     fflush(stdin);
  468.                     scanf("%d",&x);        
  469.                 }while(addMove(board,x,y,'X'));
  470.            
  471.             if(checkBoard(board) && checkWin(board) == ' '){
  472.                 move = executeMove(board,'O',AILevelO);    
  473.                 narrate(move,AILevelO,'O');
  474.             }          
  475.  
  476.             printBoard(board);     
  477.                        
  478.         }  
  479.     }else if(input == 3){
  480.         while(checkBoard(board) && checkWin(board) == ' '){
  481.  
  482.             turn++;
  483.             printf("\n## Turn %d ##\n",turn);          
  484.             printBoard(board);
  485.            
  486.             if(checkBoard(board) && checkWin(board) == ' '){
  487.                 move = executeMove(board,'X',AILevelX);    
  488.                 narrate(move,AILevelO,'X');
  489.             }              
  490.        
  491.             printBoard(board);         
  492.            
  493.             if(checkBoard(board) && checkWin(board) == ' ')        
  494.                 do{
  495.                     printf("Enter move (x): ");
  496.                     fflush(stdin);
  497.                     scanf("%d",&y);
  498.                     printf("Enter move (y): ");
  499.                     fflush(stdin);
  500.                     scanf("%d",&x);        
  501.                 }while(addMove(board,x,y,'O'));
  502.        
  503.         }  
  504.     }else if(input == 4){
  505.         while(checkBoard(board) && checkWin(board) == ' '){
  506.  
  507.             turn++;
  508.             printf("\n## Turn %d ##\n",turn);          
  509.             printBoard(board);
  510.            
  511.             if(checkBoard(board) && checkWin(board) == ' ')
  512.             do{
  513.                 printf("Enter move (x): ");
  514.                 fflush(stdin);
  515.                 scanf("%d",&y);
  516.                 printf("Enter move (y): ");
  517.                 fflush(stdin);
  518.                 scanf("%d",&x);        
  519.             }while(addMove(board,x,y,'X'));
  520.                
  521.             printBoard(board);
  522.            
  523.             if(checkBoard(board) && checkWin(board) == ' ')
  524.             do{
  525.                 printf("Enter move (x): ");
  526.                 fflush(stdin);
  527.                 scanf("%d",&y);
  528.                 printf("Enter move (y): ");
  529.                 fflush(stdin);
  530.                 scanf("%d",&x);        
  531.             }while(addMove(board,x,y,'O'));
  532.            
  533.         }  
  534.     }      
  535.    
  536.     printf("\n-------\n");
  537.     printBoard(board);
  538.    
  539.     if(checkWin(board) == ' ')
  540.         printf("\n## Tie. ##\n");
  541.     else
  542.         printf("\n## %c wins! ##\n",checkWin(board));
  543.    
  544.     return 0;
  545.    
  546. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement