#include <bits/stdc++.h>
using namespace std;
map< int ,pair< int ,int > > Mp;
map< int ,int > nex;
// -1 for O, 1 for x, 0 for empty
bool winning( int a[ 3 ] [ 3 ] , int type) {
//check hor rows
for ( int i= 0 ; i< 3 ; i++ ) {
bool res = true ;
for ( int j= 0 ; j< 3 ; j++ ) {
if ( a[ i] [ j] ! = type) {
res = false ; break ;
}
}
if ( res) { return true ; }
}
//check ver cols
for ( int i= 0 ; i< 3 ; i++ ) {
bool res = true ;
for ( int j= 0 ; j< 3 ; j++ ) {
if ( a[ j] [ i] ! = type) {
res = false ; break ;
}
}
if ( res) { return true ; }
}
//check two dias
bool left = true ;
bool right = true ;
for ( int i= 0 ; i< 3 ; i++ ) {
if ( a[ i] [ i] ! = type) { left = false ; }
if ( a[ i] [ 2 - i] ! = type) { right = false ; }
}
return ( left| right) ;
}
bool draw( int a[ 3 ] [ 3 ] , int type) {
for ( int i= 0 ; i< 3 ; i++ ) {
for ( int j= 0 ; j< 3 ; j++ ) {
if ( a[ i] [ j] == 0 ) { return false ; }
}
}
return ( ! winning( a,type) ) ;
}
bool losing( int a[ 3 ] [ 3 ] , int type) {
return winning( a,nex[ type] ) ;
}
int getnew( int a[ 3 ] [ 3 ] , int na[ 3 ] [ 3 ] , int tomove, int id) {
for ( int i= 0 ; i< 3 ; i++ ) {
for ( int j= 0 ; j< 3 ; j++ ) {
na[ i] [ j] = a[ i] [ j] ;
}
}
pair< int ,int > xy = Mp[ id] ;
int xi = xy.first , yj = xy.second ;
if ( na[ xi] [ yj] ! = 0 ) { return false ; }
na[ xi] [ yj] = tomove;
return true ;
}
bool print( int a[ 3 ] [ 3 ] ) {
for ( int i= 0 ; i< 3 ; i++ ) {
for ( int j= 0 ; j< 3 ; j++ ) {
cout << a[ i] [ j] << " " ;
}
cout << "\n " ;
}
return true ;
}
///1 for win, 0 for draw, -1 for loss
int nodes;
pair< int ,int > findmove( int a[ 3 ] [ 3 ] , int tomove) {
nodes++ ;
if ( winning( a,- 1 ) ) {
return make_pair( 1 ,- 1 ) ;
}
if ( losing( a,- 1 ) ) {
return make_pair( - 1 ,- 1 ) ;
}
if ( draw( a,- 1 ) ) {
return make_pair( 0 ,- 1 ) ;
}
int best = - 1 ;
int nbest = - 1 ;
int gstat = - 1 ;
if ( tomove== 1 ) {
gstat = 1 ;
}
for ( int i= 0 ; i< 9 ; i++ ) {
int na[ 3 ] [ 3 ] ;
int flag = getnew( a,na,tomove,i) ;
if ( flag== 0 ) { continue ; }
pair< int ,int > getstatus = findmove( na, nex[ tomove] ) ;
int status = getstatus.first ;
if ( status== 1 ) {
if ( tomove== - 1 ) {
best = i;
gstat = 1 ;
}
continue ;
}
if ( status== 0 ) {
if ( tomove== - 1 ) {
if ( nbest== - 1 ) {
nbest = i;
}
if ( gstat< 0 ) {
gstat = 0 ;
}
}
if ( tomove== 1 ) {
if ( gstat> 0 ) {
gstat = 0 ;
}
}
continue ;
}
if ( status== - 1 ) {
if ( tomove== 1 ) {
gstat = - 1 ;
}
continue ;
}
}
if ( gstat== 1 ) {
return make_pair( 1 ,best) ;
}
if ( gstat== 0 ) {
if ( best! = - 1 ) {
nbest = best;
}
return make_pair( 0 ,nbest) ;
}
return make_pair( - 1 ,- 1 ) ;
}
int main( ) {
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
nex[ - 1 ] = 1 ;
nex[ 1 ] = - 1 ;
pair< int ,int > p;
for ( int i= 0 ; i< 9 ; i++ ) {
p.first = i/ 3 ;
p.second = i% 3 ;
Mp[ i] = p;
}
int a[ 3 ] [ 3 ] ;
for ( int i= 0 ; i< 3 ; i++ ) {
for ( int j= 0 ; j< 3 ; j++ ) {
cin >> a[ i] [ j] ;
}
}
cout << "Current board\n " ;
print( a) ;
p = findmove( a,- 1 ) ;
cout << "Minimax returns " << p.first << " " << p.second << endl;
if ( p.first == - 1 ) { cout << "AI resigns, all moves are losing\n " ; return 0 ; }
if ( p.first == 1 ) { cout << "AI thinks that it will win\n " ; }
if ( p.first == 0 ) { cout << "AI thinks that it will be draw if played optimally\n " ; }
p = Mp[ p.second ] ;
a[ p.first ] [ p.second ] = - 1 ;
cout << "Nodes scanned = " << nodes<< "\n " ;
nodes = 0 ;
cout << "Board after AI move\n " ;
print( a) ;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgptYXA8aW50LHBhaXI8aW50LGludD4gPiBNcDsKbWFwPGludCxpbnQ+IG5leDsKLy8gLTEgZm9yIE8sIDEgZm9yIHgsIDAgZm9yIGVtcHR5Cgpib29sIHdpbm5pbmcoaW50IGFbM11bM10sIGludCB0eXBlKXsKICAgIC8vY2hlY2sgaG9yIHJvd3MKICAgIGZvciAoaW50IGk9MDsgaTwzOyBpKyspewogICAgICAgIGJvb2wgcmVzID0gdHJ1ZTsKICAgICAgICBmb3IgKGludCBqPTA7IGo8MzsgaisrKXsKICAgICAgICAgICAgaWYgKGFbaV1bal0hPXR5cGUpewogICAgICAgICAgICAgICAgcmVzID0gZmFsc2U7IGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChyZXMpIHtyZXR1cm4gdHJ1ZTt9CiAgICB9CiAgICAvL2NoZWNrIHZlciBjb2xzCiAgICBmb3IgKGludCBpPTA7IGk8MzsgaSsrKXsKICAgICAgICBib29sIHJlcyA9IHRydWU7CiAgICAgICAgZm9yIChpbnQgaj0wOyBqPDM7IGorKyl7CiAgICAgICAgICAgIGlmIChhW2pdW2ldIT10eXBlKXsKICAgICAgICAgICAgICAgIHJlcyA9IGZhbHNlOyBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocmVzKSB7cmV0dXJuIHRydWU7fQogICAgfQogICAgLy9jaGVjayB0d28gZGlhcwogICAgYm9vbCBsZWZ0ID0gdHJ1ZTsKICAgIGJvb2wgcmlnaHQgPSB0cnVlOwogICAgZm9yIChpbnQgaT0wOyBpPDM7IGkrKyl7CiAgICAgICAgaWYgKGFbaV1baV0hPXR5cGUpe2xlZnQgPSBmYWxzZTt9CiAgICAgICAgaWYgKGFbaV1bMi1pXSE9dHlwZSl7cmlnaHQgPSBmYWxzZTt9CiAgICB9CiAgICByZXR1cm4gKGxlZnR8cmlnaHQpOwp9Cgpib29sIGRyYXcoaW50IGFbM11bM10sIGludCB0eXBlKXsKICAgIGZvciAoaW50IGk9MDsgaTwzOyBpKyspewogICAgICAgIGZvciAoaW50IGo9MDsgajwzOyBqKyspewogICAgICAgICAgICBpZiAoYVtpXVtqXT09MCl7cmV0dXJuIGZhbHNlO30KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gKCF3aW5uaW5nKGEsdHlwZSkpOwp9Cgpib29sIGxvc2luZyhpbnQgYVszXVszXSwgaW50IHR5cGUpewogICAgcmV0dXJuIHdpbm5pbmcoYSxuZXhbdHlwZV0pOwp9CgppbnQgZ2V0bmV3KGludCBhWzNdWzNdLCBpbnQgbmFbM11bM10sIGludCB0b21vdmUsIGludCBpZCl7CiAgICBmb3IgKGludCBpPTA7IGk8MzsgaSsrKXsKICAgICAgICBmb3IgKGludCBqPTA7IGo8MzsgaisrKXsKICAgICAgICAgICAgbmFbaV1bal0gPSBhW2ldW2pdOwogICAgICAgIH0KICAgIH0KICAgIHBhaXI8aW50LGludD4geHkgPSBNcFtpZF07CiAgICBpbnQgeGkgPSB4eS5maXJzdCwgeWogPSB4eS5zZWNvbmQ7CiAgICBpZiAobmFbeGldW3lqXSE9MCl7cmV0dXJuIGZhbHNlO30KICAgIG5hW3hpXVt5al0gPSB0b21vdmU7CiAgICByZXR1cm4gdHJ1ZTsKfQoKYm9vbCBwcmludChpbnQgYVszXVszXSl7CiAgICBmb3IgKGludCBpPTA7IGk8MzsgaSsrKXsKICAgICAgICBmb3IgKGludCBqPTA7IGo8MzsgaisrKXsKICAgICAgICAgICAgY291dDw8YVtpXVtqXTw8IiAiOwogICAgICAgIH0KICAgICAgICBjb3V0PDwiXG4iOwogICAgfQogICAgcmV0dXJuIHRydWU7Cn0KCi8vLzEgZm9yIHdpbiwgMCBmb3IgZHJhdywgLTEgZm9yIGxvc3MKaW50IG5vZGVzOwoKcGFpcjxpbnQsaW50PiBmaW5kbW92ZShpbnQgYVszXVszXSwgaW50IHRvbW92ZSl7CiAgICBub2RlcysrOwogICAgaWYgKHdpbm5pbmcoYSwtMSkpewogICAgICAgIHJldHVybiBtYWtlX3BhaXIoMSwtMSk7CiAgICB9CiAgICBpZiAobG9zaW5nKGEsLTEpKXsKICAgICAgICByZXR1cm4gbWFrZV9wYWlyKC0xLC0xKTsKICAgIH0KICAgIGlmIChkcmF3KGEsLTEpKXsKICAgICAgICByZXR1cm4gbWFrZV9wYWlyKDAsLTEpOwogICAgfQoKICAgIGludCBiZXN0ID0gLTE7CiAgICBpbnQgbmJlc3QgPSAtMTsKICAgIGludCBnc3RhdCA9IC0xOwogICAgaWYgKHRvbW92ZT09MSl7CiAgICAgICAgZ3N0YXQgPSAxOwogICAgfQogICAgZm9yIChpbnQgaT0wOyBpPDk7IGkrKyl7CiAgICAgICAgaW50IG5hWzNdWzNdOwogICAgICAgIGludCBmbGFnID0gZ2V0bmV3KGEsbmEsdG9tb3ZlLGkpOwogICAgICAgIGlmIChmbGFnPT0wKXtjb250aW51ZTt9CiAgICAgICAgcGFpcjxpbnQsaW50PiBnZXRzdGF0dXMgPSBmaW5kbW92ZShuYSwgbmV4W3RvbW92ZV0pOwogICAgICAgIGludCBzdGF0dXMgPSBnZXRzdGF0dXMuZmlyc3Q7CgogICAgICAgIGlmIChzdGF0dXM9PTEpewogICAgICAgICAgICBpZiAodG9tb3ZlPT0tMSl7CiAgICAgICAgICAgICAgICBiZXN0ID0gaTsKICAgICAgICAgICAgICAgIGdzdGF0ID0gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKHN0YXR1cz09MCl7CiAgICAgICAgICAgIGlmICh0b21vdmU9PS0xKXsKICAgICAgICAgICAgICAgIGlmIChuYmVzdD09LTEpewogICAgICAgICAgICAgICAgICAgIG5iZXN0ID0gaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChnc3RhdDwwKXsKICAgICAgICAgICAgICAgICAgICBnc3RhdCA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRvbW92ZT09MSl7CiAgICAgICAgICAgICAgICBpZiAoZ3N0YXQ+MCl7CiAgICAgICAgICAgICAgICAgICAgZ3N0YXQgPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBpZiAoc3RhdHVzPT0tMSl7CiAgICAgICAgICAgIGlmICh0b21vdmU9PTEpewogICAgICAgICAgICAgICAgZ3N0YXQgPSAtMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICB9CiAgICBpZiAoZ3N0YXQ9PTEpewogICAgICAgIHJldHVybiBtYWtlX3BhaXIoMSxiZXN0KTsKICAgIH0KICAgIGlmIChnc3RhdD09MCl7CiAgICAgICAgaWYgKGJlc3QhPS0xKXsKICAgICAgICAgICAgbmJlc3QgPSBiZXN0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFrZV9wYWlyKDAsbmJlc3QpOwogICAgfQogICAgcmV0dXJuIG1ha2VfcGFpcigtMSwtMSk7Cn0KCmludCBtYWluKCl7CiAgICAvL2ZyZW9wZW4oImluLnR4dCIsInIiLHN0ZGluKTsKICAgIC8vZnJlb3Blbigib3V0LnR4dCIsInciLHN0ZG91dCk7CiAgICBuZXhbLTFdID0gMTsKICAgIG5leFsxXSA9IC0xOwogICAgcGFpcjxpbnQsaW50PiBwOwogICAgZm9yIChpbnQgaT0wOyBpPDk7IGkrKyl7CiAgICAgICAgcC5maXJzdCA9IGkvMzsKICAgICAgICBwLnNlY29uZCA9IGklMzsKICAgICAgICBNcFtpXSA9IHA7CiAgICB9CiAgICBpbnQgYVszXVszXTsKICAgIGZvciAoaW50IGk9MDsgaTwzOyBpKyspewogICAgICAgIGZvciAoaW50IGo9MDsgajwzOyBqKyspewogICAgICAgICAgICBjaW4+PmFbaV1bal07CiAgICAgICAgfQogICAgfQogICAgY291dDw8IkN1cnJlbnQgYm9hcmRcbiI7CiAgICBwcmludChhKTsKICAgIHAgPSBmaW5kbW92ZShhLC0xKTsKICAgIGNvdXQ8PCJNaW5pbWF4IHJldHVybnMgIjw8cC5maXJzdDw8IiAiPDxwLnNlY29uZDw8ZW5kbDsKICAgIGlmIChwLmZpcnN0PT0tMSl7Y291dDw8IkFJIHJlc2lnbnMsIGFsbCBtb3ZlcyBhcmUgbG9zaW5nXG4iOyByZXR1cm4gMDt9CiAgICBpZiAocC5maXJzdD09MSl7Y291dDw8IkFJIHRoaW5rcyB0aGF0IGl0IHdpbGwgd2luXG4iO30KICAgIGlmIChwLmZpcnN0PT0wKXtjb3V0PDwiQUkgdGhpbmtzIHRoYXQgaXQgd2lsbCBiZSBkcmF3IGlmIHBsYXllZCBvcHRpbWFsbHlcbiI7fQogICAgcCA9IE1wW3Auc2Vjb25kXTsKICAgIGFbcC5maXJzdF1bcC5zZWNvbmRdID0gLTE7CiAgICBjb3V0PDwiTm9kZXMgc2Nhbm5lZCA9ICI8PG5vZGVzPDwiXG4iOwogICAgbm9kZXMgPSAwOwogICAgY291dDw8IkJvYXJkIGFmdGVyIEFJIG1vdmVcbiI7CiAgICBwcmludChhKTsKfQo=