Advertisement
Guest User

Checkers

a guest
Nov 5th, 2015
432
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.03 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include <iostream>
  3. #include <vector>
  4. #include <algorithm>
  5. using namespace std;
  6.  
  7. class Move
  8. {
  9. public:
  10.     pair<int, int> start;
  11.     pair<int, int> end;
  12.     bool lethal;
  13.     Move(int x, int y, int x1, int y1, bool kill)
  14.     {
  15.         start.first = x; start.second = y;
  16.         end.first = x1; end.second = y1;
  17.         lethal = kill;
  18.     }
  19. };
  20.  
  21.  
  22. char **initBoard(int size)
  23. {
  24.     char **board = new char*[size];
  25.     for (int count = 0; count < size; count++)
  26.         board[count] = new char[size];
  27.     return board;
  28. }
  29.  
  30. void newGame(char **board, int size)
  31. {
  32.     for (int i = 0; i < size; i++)
  33.         for (int j = 0; j < size; j++)
  34.         {
  35.             board[i][j] = '-';
  36.             if ((i == 0 || i == 2) && j % 2 == 1) board[i][j] = 'O';
  37.             if (i == 1 && j % 2 == 0) board[i][j] = 'O';
  38.             if ((i == size - 3 || i == size - 1) && j % 2 == 0) board[i][j] = 'X';
  39.             if (i == size - 2 && j % 2 == 1) board[i][j] = 'X';
  40.         }
  41. }
  42.  
  43. void printBoard(char **board, int size)
  44. {
  45.     for (int i = 0; i < size; i++)
  46.     {
  47.         for (int j = 0; j < size; j++)
  48.         {
  49.             cout << board[i][j] << " ";
  50.         }
  51.         cout << endl;
  52.     }
  53.     cout << endl;
  54. }
  55.  
  56. void do_move(char **board, Move play)
  57. {
  58.     char temp = board[play.start.first][play.start.second];
  59.     board[play.start.first][play.start.second] = board[play.end.first][play.end.second];
  60.     board[play.end.first][play.end.second] = temp;
  61.     if (play.lethal)
  62.         board[(play.end.first + play.start.first) / 2][(play.end.second + play.start.second) / 2] = '-';
  63. }
  64.  
  65. void undo_move(char **board, Move play)
  66. {
  67.     board[play.start.first][play.start.second] = board[play.end.first][play.end.second];
  68.     board[play.end.first][play.end.second] = '-';
  69.     if (play.lethal)
  70.     {
  71.         if (board[play.start.first][play.start.second] == 'X')
  72.             board[(play.end.first + play.start.first) / 2][(play.end.second + play.start.second) / 2] = 'O';
  73.         if (board[play.start.first][play.start.second] == 'O')
  74.             board[(play.end.first + play.start.first) / 2][(play.end.second + play.start.second) / 2] = 'X';
  75.     }
  76. }
  77.  
  78. vector<Move> findMoves(char **board, int size, bool whiteTurn)
  79. {
  80.     vector<Move> moves;
  81.     //first jump (if possible)
  82.     for (int x = 0; x < size; x++)
  83.     {
  84.         for (int y = 0; y < size; y++)
  85.         {
  86.             if (whiteTurn && board[x][y] == 'X')
  87.             {  
  88.                 if (x > 1 && y > 1 && board[x - 1][y - 1] == 'O' && board[x - 2][y - 2] == '-')
  89.                     moves.push_back(Move(x, y, x - 2, y - 2, true));
  90.                 if (x > 1 && y < size - 2 && board[x - 1][y + 1] == 'O' && board[x - 2][y + 2] == '-')
  91.                     moves.push_back(Move(x, y, x - 2, y + 2, true));
  92.                 if (x < size - 2 && y > 1 && board[x + 1][y - 1] == 'O' && board[x + 2][y - 2] == '-')
  93.                     moves.push_back(Move(x, y, x + 2, y - 2, true));
  94.                 if (x < size - 2 && y < size - 2 && board[x + 1][y + 1] == 'O' && board[x + 2][y + 2] == '-')
  95.                     moves.push_back(Move(x, y, x + 2, y + 2, true));
  96.             }
  97.             if (!whiteTurn && board[x][y] == 'O')
  98.             {
  99.                 if (x > 1 && y > 1 && board[x - 1][y - 1] == 'X' && board[x - 2][y - 2] == '-')
  100.                     moves.push_back(Move(x, y, x - 2, y - 2, true));
  101.                 if (x > 1 && y < size - 2 && board[x - 1][y + 1] == 'X' && board[x - 2][y + 2] == '-')
  102.                     moves.push_back(Move(x, y, x - 2, y + 2, true));
  103.                 if (x < size - 2 && y > 1 && board[x + 1][y - 1] == 'X' && board[x + 2][y - 2] == '-')
  104.                     moves.push_back(Move(x, y, x + 2, y - 2, true));
  105.                 if (x < size - 2 && y < size - 2 && board[x + 1][y + 1] == 'X' && board[x + 2][y + 2] == '-')
  106.                     moves.push_back(Move(x, y, x + 2, y + 2, true));
  107.             }
  108.         }
  109.     }
  110.     //then move
  111.     for (int x = 0; x < size; x++)
  112.     {
  113.         for (int y = 0; y < size; y++)
  114.         {
  115.             if (whiteTurn && board[x][y] == 'X')
  116.             {
  117.                 if (x > 0 && y > 0 && board[x - 1][y - 1] == '-')
  118.                     moves.push_back(Move(x, y, x - 1, y - 1, false));
  119.                 if (x > 0 && y < size - 1 && board[x - 1][y + 1] == '-')
  120.                     moves.push_back(Move(x, y, x - 1, y + 1, false));
  121.  
  122.             }
  123.             if (!whiteTurn && board[x][y] == 'O')
  124.             {
  125.                 if (x < size - 1 && y > 0 && board[x + 1][y - 1] == '-')
  126.                     moves.push_back(Move(x, y, x + 1, y - 1, false));
  127.                 if (x < size - 1 && y < size - 1 && board[x + 1][y + 1] == '-')
  128.                     moves.push_back(Move(x, y, x + 1, y + 1, false));
  129.             }
  130.         }
  131.     }
  132.     return moves;
  133. }
  134.  
  135. //plain score calculation function
  136. int getScore(char **board, int size, bool whiteTurn)
  137. {
  138.     int whiteNum = 0, blackNum = 0;
  139.  
  140.     for (int i = 0; i < size; i++)
  141.     {
  142.         for (int j = 0; j < size; j++)
  143.         {
  144.             if (board[i][j] == 'X') whiteNum++;
  145.             if (board[i][j] == 'O') blackNum++;
  146.         }
  147.     }
  148.  
  149.     if (whiteTurn)
  150.         return whiteNum - blackNum;
  151.     else
  152.         return blackNum - whiteNum;
  153. }
  154.  
  155. //old function, doesnt work as intended too
  156. /*Move getBestMove(char **board, int size, bool whiteTurn)
  157. {
  158.     int score, tmp;
  159.     Move bestMove(0, 0, 0, 0, false);
  160.     vector<Move> movelist = findMoves(board, size, whiteTurn);
  161.     score = getScore(board, size, whiteTurn);
  162.  
  163.     for (unsigned int i = 0; i < movelist.size(); i++)
  164.     {
  165.         do_move(board, movelist.at(i));
  166.         tmp = getScore(board, size, whiteTurn);
  167.         undo_move(board, movelist.at(i));
  168.  
  169.         if (tmp >= score)
  170.         {
  171.             score = tmp;
  172.             bestMove = movelist.at(i);
  173.         }
  174.     }
  175.     return bestMove;
  176. }*/
  177.  
  178. //made this global - no idea how to avoid it being global with recursion in alphabeta
  179. Move bestMove(0, 0, 0, 0, false);
  180.  
  181. //alphabeta function with more detailed calculations
  182. /*int AlphaBeta(char **board, int size, bool whiteTurn, int depth, int alpha, int beta)
  183. {
  184.     if (depth == 0) return getScore(board, size, whiteTurn);
  185.     int score = -100;
  186.     vector<Move> movelist = findMoves(board, size, whiteTurn);
  187.  
  188.     for (unsigned int i = 0; i < movelist.size(); i++)
  189.     {
  190.         do_move(board, movelist.at(i));
  191.         int tmp = -AlphaBeta(board, size, !whiteTurn, depth - 1, alpha, beta);
  192.         undo_move(board, movelist.at(i));
  193.         if (tmp > score)
  194.         {
  195.             if (whiteTurn)
  196.             {
  197.                 if (score > alpha)
  198.                 {
  199.                     alpha = score;
  200.                 }
  201.                 if (-alpha <= beta)
  202.                 {
  203.                     return alpha;
  204.                 }
  205.             }
  206.             else
  207.             {
  208.                 if (score > beta)
  209.                 {
  210.                     beta = score;
  211.                 }
  212.                 if (-beta <= alpha)
  213.                 {
  214.                     return beta;
  215.                 }
  216.             }
  217.         }
  218.     }
  219.     return score;
  220. }*/
  221.  
  222. //generic alphabeta function
  223. int alphabeta(char **board, int size, bool whiteTurn, int depth, int alpha, int beta)
  224. {
  225.     if (depth == 0) return getScore(board, size, whiteTurn);
  226.     vector<Move> movelist = findMoves(board, size, whiteTurn);
  227.  
  228.     for (const Move &move : movelist)
  229.     {
  230.         do_move(board, move);
  231.         int tmp = -alphabeta(board, size, !whiteTurn, depth - 1, -beta, -alpha);
  232.         undo_move(board, move);
  233.         if (tmp > alpha)
  234.         {
  235.             if (depth == 5)
  236.                 bestMove = move;
  237.             alpha = tmp;
  238.         }
  239.     }
  240.     return alpha;
  241. }
  242.  
  243. //main game loop
  244. void game(char **board, int size, bool &whiteTurn)
  245. {
  246.     newGame(board, size);
  247.     printBoard(board, size);
  248.     system("PAUSE");
  249.  
  250.     int a = -std::numeric_limits<int>::max();
  251.     int b = std::numeric_limits<int>::max();
  252.  
  253.     do
  254.     {
  255.         alphabeta(board, size, whiteTurn, 5, a, b);
  256.         do_move(board, bestMove);
  257.         whiteTurn = !whiteTurn;
  258.         system("cls");
  259.         printBoard(board, size);
  260.         system("PAUSE");
  261.     } while (!findMoves(board, size, whiteTurn).empty());
  262. }
  263.  
  264. int main()
  265. {  
  266.     int n = 8;
  267.     bool whTurn = true;
  268.     char **board=initBoard(n);
  269.     game(board, n, whTurn);
  270.     return 0;
  271. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement