160 lines
3.0 KiB
C++
160 lines
3.0 KiB
C++
/* Check cf5-opt.vim defs.
|
|
VIM: let g:lcppflags="-std=c++11 -O2 -pthread"
|
|
VIM: let g:wcppflags="/O2 /EHsc /DWIN32"
|
|
VIM: let g:cppflags=g:Iboost.g:Itbb
|
|
VIM: let g:ldflags=g:Lboost.g:Ltbb.g:tbbmalloc.g:tbbmproxy
|
|
VIM: let g:ldlibpath=g:Bboost.g:Btbb
|
|
VIM: let g:argv=" < tic_tac_toy_tomek.sample_input"
|
|
*/
|
|
#include <iostream>
|
|
#include <exception>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <stdexcept>
|
|
|
|
//typedef std::vector<std::vector<int>> puzzle_type;
|
|
typedef unsigned puzzle_type;
|
|
|
|
void read_puzzle( puzzle_type& puzzle )
|
|
{
|
|
static const int _ = '.';
|
|
static const int t = 'T';
|
|
static const int x = 'X';
|
|
static const int o = 'O';
|
|
|
|
puzzle = 0;
|
|
std::string line;
|
|
for ( int i = 0; i < 4; ++i )
|
|
{
|
|
std::getline(std::cin,line);
|
|
if ( line.size() != 4 )
|
|
throw std::runtime_error( "input error" );
|
|
for ( int j = 0; j < 4; ++j )
|
|
{
|
|
int c = line[j];
|
|
if ( c == '.' )
|
|
c = 0;
|
|
else if ( c == 'T' )
|
|
c = 1;
|
|
else if ( c == 'X' )
|
|
c = 2;
|
|
else if ( c == 'O' )
|
|
c = 3;
|
|
else
|
|
throw std::runtime_error( "input error" );
|
|
puzzle = (puzzle << 2) | c;
|
|
}
|
|
}
|
|
//
|
|
// Read empty line.
|
|
//
|
|
std::getline(std::cin,line);
|
|
if ( line.size() != 0 )
|
|
throw std::runtime_error( "input error" );
|
|
}
|
|
|
|
// possoble states
|
|
int states[5][4] = {
|
|
//. T X O
|
|
{ 4,0,1,2 }, // 0 - init
|
|
{ 4,1,1,3 }, // 1 - x
|
|
{ 4,2,3,2 }, // 2 - o
|
|
{ 4,3,3,3 }, // 3 - nowin no empty
|
|
{ 4,4,4,4 }, // 3 - nowin and empty
|
|
};
|
|
|
|
int solve_puzzle( puzzle_type& puzzle )
|
|
{
|
|
bool has_empty = false;
|
|
for ( int i = 0; i < 4; ++i )
|
|
{
|
|
int s = 0;
|
|
unsigned p = puzzle >> i*8;
|
|
for ( int j = 0; j < 4; ++j, p >>= 2 )
|
|
s = states[s][ p & 0x03 ];
|
|
|
|
if ( s == 1 )
|
|
return 0;
|
|
else if ( s == 2 )
|
|
return 1;
|
|
else if ( s == 4 )
|
|
has_empty = true;
|
|
}
|
|
|
|
for ( int i = 0; i < 4; ++i )
|
|
{
|
|
int s = 0;
|
|
unsigned p = puzzle >> i*2;
|
|
for ( int j = 0; j < 4; ++j, p >>= 8 )
|
|
s = states[s][ p & 0x03 ];
|
|
|
|
if ( s == 1 )
|
|
return 0;
|
|
else if ( s == 2 )
|
|
return 1;
|
|
}
|
|
|
|
{
|
|
int s = 0;
|
|
unsigned p = puzzle;
|
|
for ( int j = 0; j < 4; ++j, p >>= 10 )
|
|
s = states[s][ p & 0x03 ];
|
|
|
|
if ( s == 1 )
|
|
return 0;
|
|
else if ( s == 2 )
|
|
return 1;
|
|
}
|
|
{
|
|
int s = 0;
|
|
unsigned p = puzzle >> 6;
|
|
for ( int j = 0; j < 4; ++j, p >>= 6 )
|
|
s = states[s][ p & 0x03 ];
|
|
|
|
if ( s == 1 )
|
|
return 0;
|
|
else if ( s == 2 )
|
|
return 1;
|
|
}
|
|
|
|
return ( has_empty ) ? 2 : 3;
|
|
}
|
|
|
|
const char * msg [] = {
|
|
"X won",
|
|
"O won",
|
|
"Game has not completed",
|
|
"Draw"
|
|
};
|
|
|
|
int main ( void )
|
|
{try{
|
|
|
|
int puzzle_count;
|
|
puzzle_type puzzle;
|
|
|
|
std::cin >> puzzle_count;
|
|
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
|
|
for ( int i = 0; i < puzzle_count; i++ )
|
|
{
|
|
read_puzzle(puzzle);
|
|
int s = solve_puzzle(puzzle);
|
|
std::cout << "Case #" << (i+1) << ": " << msg[s] << std::endl;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
catch ( const std::exception& e )
|
|
{
|
|
std::cerr << std::endl
|
|
<< "std::exception(\"" << e.what() << "\")." << std::endl;
|
|
return 2;
|
|
}
|
|
catch ( ... )
|
|
{
|
|
std::cerr << std::endl
|
|
<< "unknown exception." << std::endl;
|
|
return 1;
|
|
}}
|
|
|