Mesoscopic Programming

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

ヌメロン製作講座第22回:High & Low アイテム処理

今回は High & Low アイテム処理を実装します。
アイテム対応のための基本処理も含まれているのでかなり大規模な改修になりました。

  • プレイ画面

  • 修正ソースファイル

Numer0n.h
Numer0n.cpp
main.h
main.cpp


Numer0n.h & Numer0n.cpp

ヌメロンソースファイル

  • 追加マクロ
  1. #define HighLow( digit ) ( ( digit >= DIGIT_5 ) ? HIGH : LOW )
    • digit が High or Low を判定するマクロ
  • 追加修正列挙子

enum HighLowID

High or Low 列挙子を追加しました。

enum HighLowID
{
    HIGHLOW_NULL = -1,
    LOW,
    HIGH,
    MAX_HIGHLOW
};

enum DataID

High と Low データ識別子を追加しました。

  1. DATA_HIGHLOW_LOW
    • Low
  2. DATA_HIGHLOW_HIGH
    • High

enum ErrorID

High & Low アイテム使用棋譜データ読込みエラーコードを追加しました。

  1. ERR_HIGHLOW_RANK
    • ヌメロン第1回大会ルールの High & Low の位数読み込み時のデータエラー
  2. ERR_HIGHLOW_HIGHLOW
    • High or Low 読み込み時のデータエラー
  3. ERR_HIGHLOW_HIGH
    • ヌメロン第3回大会ルールの High & Low の High の数読み込み時のデータエラー
  4. ERR_HIGHLOW_LOW
    • ヌメロン第3回大会ルールの High & Low の Low の数読み込み時のデータエラー
  • 追加変数
  1. LPCTSTR highLowNames[ MAX_HIGHLOW ];
    • High or Low 文字列配列
  2. LPCTSTR targetRankNames[ MAX_COLUMN + 1 ];
    • 位数文字列配列
  • 追加関数
  1. Rank ThinkHighLowRank( MoveID move );
    • High & Low ヌメロン第1回大会ルールの位指定時のコンピュータ思考ルーチン

Rank ThinkHighLowRank()

Rank ThinkHighLowRank( MoveID move )
{
    Column  columns[ MAX_COLUMN ];
    int     count = 0;

    for ( int column = 0; column < maxColumn; column++ )
    {
        for ( int digit = 0; digit < DIGIT_5; digit++ )
        {
            if ( anals[ move ][ maxRecord ].valids[ column ][ digit ] )
            {
                for ( int digit = DIGIT_5; digit < MAX_DIGIT; digit++ )
                {
                    if ( anals[ move ][ maxRecord ].valids[ column ][ digit ] )
                    {
                        columns[ count++ ] = column;

                        break;
                    }
                }

                break;
            }
        }
    }

    if ( count > 0 )
    {
        return ColumnToRank( columns[ rand() % count ] );
    }
    else
    {
        return ColumnToRank( rand() % maxColumn );
    }
}
  • 処理内容
  • すべての位の有効番号のうち High と Low の両方を含むもの即ち High or Low 未確定な位をリストアップし、ランダムで選択する。
  • もしすべての位で High or Low が確定済みの場合は High & Low アイテムの使用自体が無意味なので完全ランダムで適当な位を選択する。


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

  • 修正メソッド
  1. VOID AddData( BOOL * buffer, Number maxNumber, MoveID move, const Record & record );
    • 追加棋譜データによる分析データ更新

VOID Analyze :: AddData()

High & Low アイテム使用棋譜データの追加に対応しました。

VOID Analyze :: AddData( BOOL * buffer, Number maxNumber, MoveID move, const Record & record )
{
    Call    call2;
    Column  column;
    Array   array;
    Column  high;
    Column  low;

    if ( record.move == move )
    {
        ~中略~

        else if ( record.did == DATA_ITEM_HIGHLOW )
        {
            if ( rule == RULE_NUMER0N1 )
            {
                column = RankToColumn( record.itemHighLow.rank );

                if ( record.itemHighLow.highlows[ 0 ] == HIGH )
                {
                    for ( int digit = 0; digit < DIGIT_5; digit++ )
                    {
                        valids[ column ][ digit ] = FALSE;
                    }
                }
                else
                {
                    for ( int digit = DIGIT_5; digit < MAX_DIGIT; digit++ )
                    {
                        valids[ column ][ digit ] = FALSE;
                    }
                }

                CandidateByValid( buffer, maxNumber );
                ValidateByCandidate( buffer, maxNumber );
            }
            else if ( rule == RULE_NUMER0N3 )
            {
                for ( int number = 0; number < maxNumber; number++ )
                {
                    if ( buffer[ number ] )
                    {
                        NumberToArray( number, array );

                        high    = 0;
                        low     = 0;

                        for ( int column = 0; column < maxColumn; column++ )
                        {
                            if ( HighLow( array[ column ] ) == HIGH )
                            {
                                high++;
                            }
                            else
                            {
                                low++;
                            }
                        }

                        if ( high != record.itemHighLow.high || low != record.itemHighLow.low )
                        {
                            buffer[ number ] = FALSE;
                        }
                    }
                }

                ValidateByCandidate( buffer, maxNumber );
            }
            else if ( rule >= RULE_NUMER0N4 )
            {
                for ( int column = 0; column < maxColumn; column++ )
                {
                    if ( record.itemHighLow.highlows[ column ] == HIGH )
                    {
                        for ( int digit = 0; digit < DIGIT_5; digit++ )
                        {
                            valids[ column ][ digit ] = FALSE;
                        }
                    }
                    else
                    {
                        for ( int digit = DIGIT_5; digit < MAX_DIGIT; digit++ )
                        {
                            valids[ column ][ digit ] = FALSE;
                        }
                    }
                }

                CandidateByValid( buffer, maxNumber );
                ValidateByCandidate( buffer, maxNumber );
            }
        }

    ~中略~
}

High & Low には3種類のルールがあります。

  1. ヌメロン第1~2回大会ルール
    • 指定した位の番号の High or Low を開示
  2. ヌメロン第3回大会ルール
    • 設定ナンバーに使用している High の枚数と Low の枚数を開示
  3. ヌメロン第4~6回大会ルール
    • すべての位の High or Low を開示
  • 処理内容
  1. ヌメロン第1~2回大会ルール
    • 指定した位の有効番号を開示された結果に応じて無効化し、更新された有効番号により正解候補を更新
  2. ヌメロン第3回大会ルール
    • すべての正解候補ナンバーに対して開示された結果が成立するかチェックし、非成立ならば正解候補から除外したのち正解候補群から有効番号を更新
  3. ヌメロン第4~6回大会ルール
    • すべての位に対して開示された結果に応じて有効番号を無効化し、更新された有効番号により正解候補を更新


class Numer0n(ヌメロンクラス)

  • 修正メソッド
  1. BOOL Save( LPCTSTR path )
  2. BOOL Load( LPCTSTR path )
    • 各々 High & Low アイテムに対応


main.h & main.cpp

メインソースファイル

enum EditModeID

High & Low 入力項目識別子を追加。

  1. EDIT_RANK
    • ヌメロン第1~2回大会ルールの位選択
  2. EDIT_HIGHLOW
    • High or Low 選択
  3. EDIT_HIGH
    • ヌメロン第3回大会ルールの High の数入力
  4. EDIT_LOW
    • ヌメロン第3回大会ルールの Low の数入力


struct Cell(セル構造体)

  • 修正メソッド
  1. BOOL GetRecordText( PTCHAR text )
  2. BOOL GetRecordEditParam( EditParam & edit )
  3. BOOL SetRecordEditData( EditParam & edit )
    • 各々 High & Low 入力処理対応


class RecGrid(棋譜データグリッドクラス)

棋譜データ数が増えたとき画面からはみ出る現象回避のためのスクロール処理を追加しました。

  • 追加修正メソッド
  1. VOID MakeGrid( BOOL attack, BOOL defense )
    • 表示領域調整処理対応
  2. VOID ResetOffset()
    • 表示オフセット調整メソッド追加
  3. VOID AdjustOffset()
    • 表示領域調整メソッド追加
  4. VOID Draw( HDC hdc )
    • 表示領域調整処理対応

以上です。