#include <iostream>
#include <string>
using namespace std;

#define countof( arr )  ( sizeof arr / sizeof *arr )
#define CSTR
#define _____
#define rigid       constexpr

using   i32 = int;
using   u32 = unsigned int;

//---------------------------------------------------------------------------------------

union                           EVENT
{
        u32         data;
    struct
    {
        u32         se  : 3,    s   : 3,    sw  : 3;
        u32         e   : 3,                w   : 3;
        u32         ne  : 3,    n   : 3,    nw  : 3;

        u32         y   : 3,    x   : 3,    t   : 2;
    };

    CSTR                        EVENT() : data( 0 ) {}
    CSTR                        EVENT( const i32 value ) : data( value ) {}
    CSTR                        EVENT( const u32 stone, const u32 x, const u32 y )
                                : t( stone ), x( x ), y( y ) { data &= 0xF0000000; }

    std::string                 to_string()
    {
        char    temp[12];
        sprintf( temp, "%11o", data );
        return  temp;
    }

    auto                        score()
    {
        return  (u32)se + s + sw + e + w + ne + n + nw;
    }

    auto                        is_valid()
    {
        return  ( data & 0xFFFFFF ) > 0;
    }
};

rigid   u32     othello_length = 8;
_____   EVENT   history[ othello_length * othello_length - 4 ];

//---------------------------------------------------------------------------------------

enum    class                   CELL    : u32
{
    empty,
    black,
    white,
    wall,
};

enum    class                   MODE    : u32
{
    valid,
    eval,
    action,
};

class                           BOARD
{
private:
    CELL                        board[ othello_length + 2 ][ othello_length + 2 ];

    void                        put_( const u32 x, const u32 y, const CELL stone )
    {
        board[ y + 1 ][ x + 1 ] = stone;
    }

public:
    auto                        get( const u32 x, const u32 y ) const
    {
        return  board[ y + 1 ][ x + 1 ];
    }

    template< MODE M >
    EVENT                       put( const u32 x, const u32 y, const CELL stone )
    {
        EVENT   event( (u32)stone, x, y );

        if( board[ y + 1 ][ x + 1 ] != CELL::empty )
            return  event;

        const   CELL    opposite =
            static_cast< CELL >( (int)stone ^ (int)CELL::wall );

        typedef struct  DIRECTION
        {
            i32 x, y;
        }
        DIRECTION;
        rigid   DIRECTION   directions[]
        {
            { -1, -1 }, { +0, -1 }, { +1, -1 },
            { -1, +0 },             { +1, +0 },
            { -1, +1 }, { +0, +1 }, { +1, +1 },            
        };

        for( u32 i = 0; i < countof( directions ); ++i )
        {
            const   DIRECTION   d = directions[ i ];
            u32 count = 0;
            while( ++count, get( x + count * d.x, y + count * d.y ) == opposite );
            if( get( x + count * d.x, y + count * d.y ) == stone && count > 1 )
            {
                event.data |= ( count - 1 ) << ( 7 * 3 - i * 3 );
                if( M == MODE::valid )
                    break;
                if( M == MODE::action )
                    for( u32 c = 1; c < count; ++c )
                       put_( x + c * d.x, y + c * d.y, stone );
            }
        }

        if( M == MODE::action && event.is_valid() )
        {
            put_( x, y, stone );
            // add to history
        }

        return  event;
    }

    CSTR                        BOARD()
    {
        for( u32 x = 0; x < othello_length + 2; ++x )
            board[ 0 ][ x ] = CELL::wall;
        for( u32 y = 1; y < othello_length + 1; ++y )
        {
            board[ y ][ 0 ] = CELL::wall;
            for( u32 x = 1; x < othello_length + 1; ++x )
                board[ y ][ x ] = CELL::empty;
            board[ y ][ othello_length + 1 ] = CELL::wall;
        }
        for( u32 x = 0; x < othello_length + 2; ++x )
            board[ othello_length + 1 ][ x ] = CELL::wall;

        put_( 3, 3, CELL::black );
        put_( 4, 4, CELL::black );
        put_( 3, 4, CELL::white );
        put_( 4, 3, CELL::white );
    }

    friend  std::ostream&       operator<<( std::ostream& os, const BOARD& b )
    {
        const   std::string tile[] = { "·", "○", "●", "▨" };
        for( u32 y = 0; y < othello_length + 2; ++y )
        {
            for( u32 x = 0; x < othello_length + 2; ++x )
                os << tile[ (int)b.board[ y ][ x ] ];
            os << std::endl;
        }
        return  os;
    }
};
//---------------------------------------------------------------------------------------

#include <sstream>

int main()
{
    std::istringstream cin_( "53 52 42 32 22 54 55 23 62 " );

    BOARD   board;
    CELL    turn = CELL::black;

    while( 1 )
    {
        cout << board << endl;
        int x, y, i;        
        cin_ >> i;
        x = i / 10;
        y = i % 10;
        if( cin_.eof() )
            break;
        EVENT   event = board.put< MODE::action >( x, y, turn );
        cout << event.to_string() << " " << event.score() << endl;
        turn = static_cast< CELL >( (u32)turn ^ (u32)CELL::wall );
    }

    getchar();
    return 0;
}
//---------------------------------------------------------------------------------------
