1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
#include <iostream>
#include <bitset>
namespace tictactoe
{
constexpr std::size_t N = 3 ;
using board = std::bitset<N*N> ;
const board wins[] = {
board("111000000"), board("000111000"), board("000000111"), // rows
board("100100100"), board("010010010"), board("001001001"), // cols
board("100010001"), board("001010100") // diagonals
} ;
board noughts ; // bit board for first player
board crosses ; // bit board for second player
constexpr char NOUGHT = 'O' ;
constexpr char CROSS = 'X' ;
bool curr_move_noughts = true ;
board combined() { return noughts | crosses ; } // combined bit board for both players
bool valid( std::size_t row, std::size_t col ) { return row<N && col<N ; }
std::size_t pos( std::size_t row, std::size_t col ) { return row*N + col ; } // map row, col to bit position
bool occupied( std::size_t row, std::size_t col ) { return valid(row,col) && combined()[ pos(row,col) ] ; }
bool free( std::size_t row, std::size_t col ) { return valid(row,col) && !occupied(row,col) ; }
void make_move( std::size_t row, std::size_t col, board& b ) { if( free(row,col) ) b[ pos(row,col) ] = true ; }
void make_move( std::size_t row, std::size_t col )
{ if(curr_move_noughts) make_move(row,col,noughts) ; else make_move(row,col,crosses) ; }
bool is_win( board b )
{
for( board w : wins ) if( (w&b) == w ) return true ;
return false ;
}
bool is_win() { return is_win( curr_move_noughts ? noughts : crosses ) ; }
std::ostream& print_board( std::ostream& stm = std::cout, board b = combined() )
{
stm << "------\n" ;
for( std::size_t i = 0 ; i < N ; ++i )
{
for( std::size_t j = 0 ; j < N ; ++j )
{
const std::size_t k = pos(i,j) ;
if( b[k] ) stm << ( noughts[k] ? NOUGHT : CROSS ) << ' ' ;
else stm << ". " ;
}
stm << '\n' ;
}
return stm << "------\n" ;
}
}
int main()
{
using namespace tictactoe ;
make_move(1,2) ;
print_board() ;
curr_move_noughts = !curr_move_noughts ;
// for testing: let the same player make three consecutive moves
make_move(2,0) ; make_move(1,1) ; make_move(0,2) ;
print_board() ;
std::cout << "win? " << std::boolalpha << is_win() << '\n' ;
}
|