Mesoscopic Programming

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

ヌメロン製作講座第26回:Shuffle アイテム処理

今回は Shuffle アイテム処理を実装します。

プレイ画面

Shuffle アイテムを使用した例です。

修正ソースファイル
  1. Numer0n.h
  2. Numer0n.cpp
  3. main.h
  4. main.cpp


enum ErrorID(ファイル読込みエラーコード)

棋譜データファイル読込み時の以下のエラーコードを追加しました。

  1. ERR_SHUFFLE_NUMBER
    • Shuffle アイテムのシャッフルナンバー読込みエラー


Number ThinkShuffleNumber()

シャッフルナンバー思考ルーチンを追加しました。

Number ThinkShuffleNumber( MoveID move )
{
    Column  max = maxColumn;
    Array   array;
    Array   array2;
    int     column;

    NumberToArray( players[ move ].number, array );
    NumberToArray( 0, array2 );

    for ( int column2 = 0; column2 < maxColumn; column2++ )
    {
        column = rand() % max;

        array2[ column2 ] = array[ column ];

        for ( ; column < max - 1; column++ )
        {
            array[ column ] = array[ column + 1 ];
        }

        max--;
    }

    return ArrayToNumber( array2 );
}
処理内容
  • 各位の番号をランダムで入れ替える


struct Analyze(分析データ構造体)

Shuffle アイテム対応処理を追加しました。

  1. VOID AddData( BOOL * buffer, Number maxNumber, MoveID move, const Record & record )
    • Shuffle アイテム対応処理追加
  2. VOID CandidateByShuffle( BOOL * buffer, Number maxNumber, MoveID move )
    • Shuffle アイテム使用時の正解候補更新処理
  3. int * MakeOrderList( int & count )
    • シャッフルによる組み合わせパタン列挙配列生成

VOID Analyze :: AddData()

棋譜データ追加による分析データ更新処理

VOID Analyze :: AddData( BOOL * buffer, Number maxNumber, MoveID move, const Record & record )
{
    ~中略~

    else if ( record.did == DATA_ITEM_SHUFFLE )
    {
        CandidateByShuffle( buffer, maxNumber, move );
        ValidateByCandidate( buffer, maxNumber );
    }

    ~中略~
}
処理内容
  • Shuffle アイテム使用による正解候補更新

VOID Analyze :: CandidateByShuffle()

Shuffle アイテム使用による正解候補更新処理

VOID Analyze :: CandidateByShuffle( BOOL * buffer, Number maxNumber, MoveID move )
{
    int     * order;
    int     count;
    Array   array;
    BOOL    result;

    InitCandidate( buffer, maxNumber, move );

    order = MakeOrderList( count );

    for ( int number = 0; number < maxNumber; number++ )
    {
        if ( buffer[ number ] )
        {
            NumberToArray( number, array );

            for ( int n = 0; n < count; n++ )
            {
                result = TRUE;

                for ( int column = 0; column < maxColumn; column++ )
                {
                    if ( ! valids[ order[ maxColumn * n + column ] ][ array[ column ] ] )
                    {
                        result = FALSE;

                        break;
                    }
                }

                if ( result )
                {
                    break;
                }
            }

            buffer[ number ] = result;
        }
    }

    free( order );
}
処理内容
  1. 正解候補を初期化(3桁でロストが無ければ 720 パタン)
  2. すべての正解候補に対しすべてのシャッフルパタンを検査し、無効な番号が含まれているならば除外する

int * Analyze :: MakeOrderList()

設定桁数分のすべてのシャッフルパタンを列挙する

int * Analyze :: MakeOrderList( int & count )
{
    struct Local
    {
        static int * func( int * list, int max, int n )
        {
            int     set = 0;
            BOOL    result;
            int     * list0;

            for ( int i = 0; i < max - n; i++ )
            {
                for ( int j = 0; j < max; j ++ )
                {
                    result = TRUE;

                    for ( int k = 0; k < n; k++ )
                    {
                        if ( list[ k ] == set )
                        {
                            result = FALSE;

                            break;
                        }
                    }

                    if ( result )
                    {
                        break;
                    }

                    set = ( set + 1 ) % max;
                }

                list[ n ]   = set;
                set         = ( set + 1 ) % max;

                if ( n == max - 1 )
                {
                    return list + max;
                }

                list0   = list;
                list    = func( list, max, n + 1 );

                if ( i + 1 < max - n )
                {
                    for ( int j = 0; j < n; j++ )
                    {
                        list[ j ] = list0[ j ];
                    }
                }
            }

            return list;
        }
    };

    SIZE_T  size;
    int     * order;

    count = 1;

    for ( int i = maxColumn; i > 1; i-- )
    {
        count *= i;
    }

    size    = sizeof ( int ) * count * maxColumn;
    order   = ( int * ) malloc( size );

    ZeroMemory( order, size );

    Local :: func( order, maxColumn, 0 );

    return order;
}
処理内容
  1. すべてのシャッフルパタン(3桁ならば 3 x 2 x 1 = 6 パタン)を生成する


struct Player(プレイヤー構造体)

非公開設定ナンバーを追加しました。

  1. Number number;
    • 非公開設定ナンバー


class Numer0n(ヌメロンクラス)

Save() 関数と Load() 関数に Shuffle アイテム対応処理を追加しました。

  1. BOOL Save( LPCTSTR path )
  2. BOOL Load( LPCTSTR path )
    • Shuffle アイテム対応処理追加


enum EditModeID(編集モード識別子)

Shuffle アイテム使用時のシャッフルナンバー入力モードを追加しました。

  1. EDIT_NUMBER
    • シャッフルナンバー入力モード


struct Cell(セル構造体)

関連する既存関数に Shuffle アイテム処理を追加しました。

  1. BOOL GetRecordText( PTCHAR text )
    • セル表示文字列取得関数
  2. BOOL GetRecordEditParam( EditParam & edit )
    • セル編集開始関数
  3. BOOL SetRecordEditData( EditParam & edit )
    • セル編集終了関数

以上です。