Mesoscopic Programming

タコさんプログラミング専門

ヌメロン製作講座第19回:棋譜データファイル保存処理

今回は棋譜データ保存処理を実装します。

保存コマンドを実行すると以下のようなテキストファイルが出力されます。

Title	"Numer0n 2012/9/25 11:51";
Column	3;
Rule	Numer0n6;
First	Type	Man;
First	Card	0 1 2 3 4 5 5 6 6 7 7 8 8 9 9;
First	Open	659;
Second	Type	Com;
Second	Card	0 1 2 3 4 5 5 6 6 7 7 8 8 9 9;
Second	Number	376;
First	Call	012 0 - 0;
Second	Call	069 1 - 1;
First	Call	345 1 - 0;
Second	Call	560 0 - 2;
First	Call	678 1 - 1;
Second	Call	046 0 - 1;
First	Call	875 1 - 0;
Second	Call	659 3 Eat;
  • 修正ソースファイル

Numer0n.h
Numer0n.cpp
main.cpp


enum DataID

棋譜データ識別子

  • 追加識別子
  1. DATA_SET_TITLE
  2. DATA_SET_COLUMN
  3. DATA_SET_RULE
  4. DATA_RULE_NUMER0N1
  5. DATA_RULE_NUMER0N3
  6. DATA_RULE_NUMER0N4
  7. DATA_RULE_NUMER0N6
  8. DATA_PLAYER_FIRST
  9. DATA_PLAYER_SECOND
  10. DATA_PLAYER_NAME
  11. DATA_PLAYER_TYPE
  12. DATA_TYPE_MAN
  13. DATA_TYPE_COM
  14. DATA_PLAYER_CARD
  15. DATA_PLAYER_ITEM
  16. DATA_PLAYER_OPEN
  17. DATA_PLAYER_NUMBER
  18. DATA_JUDGE_EAT
    • 棋譜データファイル用の識別子

DataName dataNames[]

棋譜データ識別子名称文字列


class Numer0n

ヌメロンクラス

  • 追加メソッド
  1. BOOL Save( LPCTSTR path );
  2. LPCTSTR GetDataName( DataID did );
    • 棋譜データ識別子名称文字列取得
  3. int Printf( LPCTSTR format, ... );
    • 書式付ファイル出力

BOOL Numer0n :: Save( LPCTSTR path )

BOOL Numer0n :: Save( LPCTSTR path )
{
    LPCTSTR moveName;
    int     count;

    hFile = CreateFile( path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );

    if ( hFile != INVALID_HANDLE_VALUE )
    {
        Printf( "%s\t\"%s\";\r\n", GetDataName( DATA_SET_TITLE ), title );
        Printf( "%s\t%d;\r\n", GetDataName( DATA_SET_COLUMN ), maxColumn );
        Printf( "%s\t%s;\r\n", GetDataName( DATA_SET_RULE ), GetDataName( ( DataID ) ( DATA_RULE_NUMER0N1 + rule ) ) );

        for ( int move = 0; move < MAX_MOVE; move++ )
        {
            moveName = GetDataName( ( DataID ) ( DATA_PLAYER_FIRST + move ) );

            if ( strlen( players[ move ].name ) > 0 )
            {
                Printf( "%s\t%s\t\"%s\";\r\n", moveName, GetDataName( DATA_PLAYER_NAME ), players[ move ].name );
            }

            Printf( "%s\t%s\t%s;\r\n", moveName, GetDataName( DATA_PLAYER_TYPE ), GetDataName( ( DataID ) ( DATA_TYPE_MAN + players[ move ].type ) ) );

            count = 0;

            for ( int digit = 0; digit < MAX_DIGIT; digit++ )
            {
                for ( int i = players[ move ].cards[ digit ]; i > 0; i-- )
                {
                    if ( count == 0 )
                    {
                        Printf( "%s\t%s\t", moveName, GetDataName( DATA_PLAYER_CARD ) );
                    }
                    else
                    {
                        Printf( " " );
                    }

                    Printf( "%d", digit );

                    count++;
                }
            }

            if ( count > 0 )
            {
                Printf( ";\r\n" );
            }

            count = 0;

            for ( int item = 0; item < MAX_ITEM; item++ )
            {
                for ( int i = players[ move ].items[ item ]; i > 0; i-- )
                {
                    if ( count == 0 )
                    {
                        Printf( "%s\t%s\t", moveName, GetDataName( DATA_PLAYER_ITEM ) );
                    }
                    else
                    {
                        Printf( " " );
                    }

                    Printf( "%s", GetDataName( ( DataID ) ( DATA_ITEM_HIGHLOW + item ) ) );

                    count++;
                }
            }

            if ( count > 0 )
            {
                Printf( ";\r\n" );
            }

            if ( players[ move ].open != 0 )
            {
                Printf( "%s\t%s\t%0*d;\r\n", moveName, GetDataName( DATA_PLAYER_OPEN ), maxColumn, players[ move ].open );
            }
            else if ( players[ move ].number != 0 )
            {
                Printf( "%s\t%s\t%0*d;\r\n", moveName, GetDataName( DATA_PLAYER_NUMBER ), maxColumn, players[ move ].number );
            }
        }

        for ( int n = 0; n < maxRecord; n++ )
        {
            if ( records[ n ].did == DATA_CALL )
            {
                Printf( "%s\t%s\t%0*d %d",  GetDataName( ( DataID ) ( DATA_PLAYER_FIRST + records[ n ].move ) ),
                                            GetDataName( records[ n ].did ), maxColumn,
                                            records[ n ].call.number, records[ n ].call.eat );

                if ( records[ n ].call.eat < maxColumn )
                {
                    Printf( " - %d;\r\n", records[ n ].call.byte );
                }
                else
                {
                    Printf( " %s;\r\n", GetDataName( DATA_JUDGE_EAT ) );
                }
            }
        }

        CloseHandle( hFile );

        return TRUE;
    }

    return FALSE;
}

LPCTSTR Numer0n :: GetDataName( DataID did )

LPCTSTR Numer0n :: GetDataName( DataID did )
{
    for ( int i = 0;; i++ )
    {
        if ( dataNames[ i ].did == DATA_NULL )
        {
            break;
        }
        else if ( dataNames[ i ].did == did )
        {
            return dataNames[ i ].name;
        }
    }

    return NULL;
}

int Numer0n :: Printf( LPCTSTR format, ... )

int Numer0n :: Printf( LPCTSTR format, ... )
{
    va_list args;
    int     len;
    char    * buf;
    DWORD   dwWrite;

    va_start( args, format );

    len = _vscprintf( format, args ) + 1;
    buf = ( char * ) malloc( len * sizeof ( char ) );
    len = vsprintf( buf, format, args );

    WriteFile( hFile, buf, len, & dwWrite, NULL );

    free( buf );

    return len;
}


class Application

アプリケーションクラス

  • 修正メソッド
  1. VOID OnFileSave();
    • 棋譜データファイル保存処理実装

VOID Application :: OnFileSave()

VOID Application :: OnFileSave()
{
    OPENFILENAME    ofn;
    TCHAR           path[ _MAX_PATH ];

    ZeroMemory( & ofn, sizeof ofn );

    strcpy( path, filename );

    ofn.lStructSize     = sizeof ofn;
    ofn.hwndOwner       = hwnd;
    ofn.hInstance       = GetModuleHandle( NULL );
    ofn.lpstrFilter     = "Numer0n Data Files { *.dat }\0*.dat\0All files {*.*}\0*.*\0\0";
    ofn.lpstrFile       = path;
    ofn.nMaxFile        = sizeof path;

#ifdef _DEBUG
    ofn.Flags           = OFN_CREATEPROMPT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
#else
    ofn.Flags           = OFN_CREATEPROMPT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
#endif

    ofn.lpstrDefExt     = "dat";

    if ( GetSaveFileName( & ofn ) )
    {
        if ( numer0n.Save( path ) )
        {
            strcpy( filename, path );
        }
    }
}

以上です。