Quantcast
Viewing latest article 2
Browse Latest Browse All 10

First Program Tic-Tac-Toe. Trouble with abstraction?

This is the first little project I’ve made that didn’t feel it was complete gibberish. But I couldn’t tell.

The biggest problem I had with this was using the BoardValue enum working like I wanted to. I understand that classes should have a level of abstraction to them and I suspect that the way I implemented the at(int) returning a char over a BoardValue took away from that. However, I though having to convert the return from at(int) to a char if it returned a BoardValue would be redundant. For example, using a statement like this

char print_char = Board.at(some_index) == BoardValue::o ? 'O' : 'X'; 

I hope I’ve done a decent job describing my dilemma.

Overall, I’m hoping for some overall general code style tips and pointers on how to write better code from here.

tictactoe.h

#ifndef TICTACTOE #define TICTACTOE #include <array> #include <iostream>  enum BoardValue : char{ none = ' ', o = 'O', x = 'X' };  class Board { public:     Board()     {         for(auto begin = board.begin(),end = board.end();begin != end; ++begin)             *begin = BoardValue::none;     }      char at(int index) const{ return board.at(index); }     inline bool check_win(BoardValue) const;     bool place(int, BoardValue); private:     bool check_diagonals(BoardValue) const;     bool check_horizontals(BoardValue) const;     bool check_verticals(BoardValue) const;      std::array<char, 9> board{}; };  inline bool Board::check_win(BoardValue check) const {     if(check == BoardValue::none)         throw "Trying to check_win for check == BoardValue::none!";     return check_diagonals(check) || check_horizontals(check) || check_verticals(check); }  #endif 

tictactoe.cpp

#include "tictactoe.h" #include <iostream>  //returns false if index is occupied bool Board::place(int index, BoardValue value) {     if(board.at(index) != BoardValue::none)         return false;     board.at(index) = value;     return true; }  bool Board::check_diagonals(BoardValue check) const {     //if middle is not check no diagnols will pass     if(board.at(4) != check)         return false;     //backward diagonal '\'     if(board.at(0) == check && board.at(4) == check)         return true;     //forward diaganol '/'     if(board.at(2) == check && board.at(6) == check)         return true;     return false; }  bool Board::check_horizontals(BoardValue check) const {     for(int row = 0; row < 3; ++row){         if(board.at(row) == check &&             board.at(row + 3) == check &&             board.at(row + 6) == check)             return true;     }     return false; }  bool Board::check_verticals(BoardValue check) const {     for(int col = 0; col < 3; ++col){         if(board.at(col * 3) == check &&             board.at(col * 3 + 1) == check &&             board.at(col * 3 + 2 ) == check)             return true;     }     return false; } 

main.cpp

#include "tictactoe.h" #include <iostream>  int ask_input(char player, bool retry = false) {     if(!retry)         std::cout << "It's " << player             << "'s turn. Where do you want to go(e.g. A1 B3 C2)? ";     else         std::cout << "No, no, no " << player             << "! Input a letter followed bt a number: ";     std::string input;     std::cin >> input;      if(input.size() < 2)         return ask_input(player, true);      int col_input{};     switch(*input.begin())     {         case 'A':         case 'a':             col_input = 0;             break;         case 'B':         case 'b':             col_input = 1;             break;         case 'C':         case 'c':             col_input = 2;             break;         default:             return ask_input(player, true);     }      int row_input = *(input.begin() + 1) - '0'; //convers char '1' to int 1     --row_input;      return col_input * 3 + row_input; }  BoardValue ask_turn() //ask whos first if return true O goes first {     BoardValue turn;     std::string input;     std::cout << "Who goes first(X or O)? ";     for(bool valid_input{false}; !valid_input;)     {         std::cin >> input;         switch(input.front()) //input cannot be null at this point         {             case 'x':             case 'X':                 valid_input = true;                 turn = BoardValue::x;                 break;             case '0':             case 'o':             case 'O':                 valid_input = true;                 turn = BoardValue::x;                 break;             default:                 std::cout << "Invalid input! Try X or O :";         }     }     return turn; }  std::ostream &print_board(std::ostream &os,const Board &board) {     os << " |A|B|C\n";     for(int row = 0; row < 3; ++row)     {         os << std::string( 8, '-') << '\n';         os << row + 1 << '|';         for(int col = 0; col < 3; ++col)         {             char follow_char{ col == 2 ? '\n' : '|' };             os << board.at(col * 3 + row) << follow_char;         }     }     os << std::endl;     return os; }  int main(){     Board board{};     BoardValue turn{ ask_turn() };      //turn will be set back to appropriate value at start of game loop     turn = turn == BoardValue::o  ? BoardValue::x : BoardValue::o;     int turn_count{0};     while(board.check_win(turn) == false)     {         turn = turn == BoardValue::o  ? BoardValue::x : BoardValue::o;         print_board(std::cout, board);         bool input_valid{false};         while(input_valid == false)         {             int input;             input = ask_input(turn);             input_valid = board.place(input, turn);             if( input_valid == false )                 std::cout << "That place is take! Try again..\n";         }         if(++turn_count == 9) //max amount of turns game is tie             break;     }     print_board(std::cout, board);     if(turn_count == 9)//game is tie         std::cout << "Looks like its a tie...\n";     else         std::cout << (char)turn << " wins!\n"; } 

The post First Program Tic-Tac-Toe. Trouble with abstraction? appeared first on 100% Private Proxies - Fast, Anonymous, Quality, Unlimited USA Private Proxy!.


Viewing latest article 2
Browse Latest Browse All 10

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>