Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cctype>
- #include <algorithm>
- #include <functional>
- #include <array>
- class TicTacToe
- {
- public:
- bool isFull() const;
- void draw() const;
- void turn(char player);
- bool check(char player) const;
- private:
- bool fill(char player, int position);
- private:
- static const std::size_t mDim = 3;
- std::array<char, mDim * mDim> grid
- {
- {
- '-', '-', '-',
- '-', '-', '-',
- '-', '-', '-'
- }
- };
- };
- template<std::size_t dim>
- struct column : public std::unary_function<int, bool>
- {
- column(int i) : colNum(i){}
- bool operator() (int number) { return (number % dim == colNum); }
- int colNum;
- };
- bool TicTacToe::fill(char player, int position)
- {
- if (grid[position] != '-')
- return false;
- grid[position] = player;
- return true;
- }
- bool TicTacToe::isFull() const
- {
- return 0 == std::count_if(grid.begin(), grid.end(),
- [](const char& i)
- {
- return '-';
- });
- }
- bool TicTacToe::check(char player) const
- {
- column<mDim>::argument_type input;
- // check for row or column wins
- bool row1 = true, row2 = true, row3 = true,
- col1 = true, col2 = true, col3 = true,
- diag1 = true, diag2 = true;
- int j = 0;
- // columns
- std::for_each(grid.begin(), grid.end(),
- [&](char i)
- {
- int x = j++;
- if (column<mDim>(0)(input = x))
- col1 &= i == player;
- if (column<mDim>(1)(input = x))
- col2 &= i == player;
- if (column<mDim>(2)( input = x))
- col3 &= i == player;
- });
- // diagonals
- j = 0;
- for (const auto& m : grid)
- {
- int x = j++;
- if (x == 0 || x == 4 || x == 8)
- diag1 &= m == player;
- if (x == 2 || x == 4 || x == 6)
- diag2 &= m == player;
- }
- if (col1 || col2 || col3 || diag1 || diag1)
- return true;
- // rows
- return std::search_n(grid.begin(), grid.end(), 3, player) != grid.end();
- }
- void TicTacToe::draw() const
- {
- //Creating a onscreen grid
- std::cout << ' ';
- for (std::size_t i = 1; i <= mDim; ++i)
- std::cout << " " << i;
- int j = 0;
- char A = 'A';
- column<mDim>::argument_type input;
- for (auto& i : grid)
- {
- int x = j++;
- if (column<mDim>(0)(input = x ))
- std::cout << "n " << A++;
- std::cout << ' ' << i << ' ';
- }
- std::cout << "nn";
- }
- void TicTacToe::turn(char player)
- {
- char row = 0;
- char column = 0;
- std::size_t position = 0;
- bool applied = false;
- std::cout << "n" << player << ": Please play. n";
- while (!applied)
- {
- std::cout << "Row(1,2,3,...): ";
- std::cin >> row;
- std::cout << player << ": Column(A,B,C,...): ";
- std::cin >> column;
- position = mDim * (std::toupper(column) - 'A') + (row - '1');
- if (position < grid.size())
- {
- applied = fill(player, position);
- if (!applied)
- std::cout << "Already Used. Try Again. n";
- }
- else
- {
- std::cout << "Invalid position. Try again.n";
- }
- }
- std::cout << "nn";
- }
- class Game
- {
- public:
- Game();
- void run();
- private:
- TicTacToe ttt;
- std::array<char, 2> players{ { 'X', 'O' } };
- int player = 0;
- std::function<void()> display = std::bind(&TicTacToe::draw, &ttt);
- std::function<void(char)> turn = std::bind(&TicTacToe::turn, &ttt, std::placeholders::_1);
- std::function<bool(char)> win = std::bind(&TicTacToe::check, &ttt, std::placeholders::_1);
- std::function<bool()> full = std::bind(&TicTacToe::isFull, &ttt);
- };
- Game::Game()
- :ttt()
- {
- }
- void Game::run()
- {
- while (!win(players[player]) && !full())
- {
- player ^= 1;
- display();
- turn(players[player]);
- }
- display();
- if (win)
- {
- std::cout << "n" << players[player] << " is the Winner!n";
- }
- else
- {
- std::cout << "nTie game!n";
- }
- }
- int main()
- {
- Game game;
- game.run();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement