Files
test/google_code_jam/2013/tic_tac_toy_tomek.cpp

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;
}}