Mesoscopic Programming

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

class Numer0n

ヌメロンのクラス定義は以下のようになっとります。

class Numer0n
{
public :

    TCHAR       title[ MAX_STRING ];
    Column      maxColumn;
    RuleID      rule;
    Player      players[ MAX_MOVE ];
    Record      records[ MAX_RECORD ];
    SHORT       maxRecord;
    Record      newRecord;

    HANDLE      hFile;
    LONG        line;
    TCHAR       text[ MAX_STRING ];
    LONG        integer;
    TCHAR       lineBuf[ MAX_STRING ];
    int         bufSize;

    Numer0n();

    VOID        Init();
    BOOL        Save( LPCTSTR path );
    BOOL        Load( LPCTSTR path );
    VOID        EncodeNumber( PTCHAR text, Number number, int column );
    Number      DecodeNumber( LPCTSTR text );
    LPCTSTR     GetDataName( DataID did );
    VOID        ConvDataText( LPCTSTR src, PTCHAR dst );
    int         Printf( LPCTSTR format, ... );
    DataID      ReadData();
    BOOL        DataError( ErrorCode code );

    BOOL        AddRecord( const Record & record );
    VOID        DeleteRecord();
    VOID        DeleteAllRecord();
    MoveID      GetWinner();

    VOID        NumberToArray( Number number, Array array );
    Number      ArrayToNumber( Array & array );
    Rank        ColumnToRank( Column column );
    Column      RankToColumn( Rank rank );
    VOID        Judge( Number number, Call & call );
    BOOL        CheckSetColumnNumber( Column column, BOOL message = TRUE );
    BOOL        CheckCardsNumber( int n, BOOL message = TRUE );
    BOOL        CheckItemsNumber( int n, BOOL message = TRUE );
    BOOL        CheckNumber( Number number, BOOL message = TRUE );
    BOOL        CheckShuffleNumber( Number number0, Number number, BOOL message = TRUE );
    BOOL        CheckDigitNumber( DigitID digit, BOOL message = TRUE );
    BOOL        CheckColumnNumber( Column column, BOOL message = TRUE );
    BOOL        CheckColumnNumber2( Column column, Column column2, BOOL message = TRUE );
    BOOL        CheckRankNumber( Rank rank, BOOL message = TRUE );
};

めんどくさいから全部publicです。だったらstructで良いじゃないかっつー話なんですが、一応クラスを使うのは将来的に派生しちゃったりなんかしそうな奴に限ります。仮想関数なんか使うとサイズがわけ分かんないしデータを消去したつもりが仮想関数テーブルまで消去しちゃったなんて無様な失敗をしょっちゅう繰り返しております。そこでサイズを固定にしたい場合はstructを使うという風に使い分けてます。
たとえばプレイヤーデータはstructで以下のように定義しました。

struct Player
{
    MoveID      move;
    TCHAR       name[ MAX_STRING ];
    TypeID      type;
    SHORT       cards[ MAX_DIGIT ];
    SHORT       gets[ MAX_DIGIT ];
    SHORT       items[ MAX_ITEM ];
    SHORT       useds[ MAX_ITEM ];
    Number      open;
    Number      secret;
    Number      number;
    Analyze     anals[ MAX_RECORD + 1 ];
    TCHAR       text[ MAX_STRING ];

    VOID        Init( MoveID move );
    LPCTSTR     DispName();
    LPCTSTR     LastName();
    LPCTSTR     ShortName();
    VOID        SetType( TypeID newType );
    VOID        ClearNumber();
    VOID        SetOpenNumber( Number newNumber );
    VOID        SetSecretNumber( Number newNumber );
    Number      LastCallNumber();
    BOOL        CheckTotalCards( DigitID digit, int n, BOOL message = TRUE );
    BOOL        CheckSetNumber( Number number, BOOL message = TRUE );
    BOOL        CheckSlashNumber( DigitID slash, BOOL message = TRUE );
    BOOL        CheckChangeNumber( Rank rank, DigitID digit, BOOL message = TRUE );
    BOOL        CanAttack();
    BOOL        CanDefense();
    BOOL        CanUseItem( ItemID item );
    Rank        GetCanChangeRank();
    BOOL        CanChangeRank( Rank rank );
    BOOL        CanChangeColumn( Column column );
    BOOL        CanChangeDigit( DigitID digit );
    BOOL        CanChangeHighLow( HighLowID highlow );

    BOOL        ThinkSetNumber();
    BOOL        ThinkCallNumber( Number & number );
    ItemID      ThinkAttackItem();
    ItemID      ThinkDefenseItem();
    BOOL        ThinkHighLowRank( Rank & rank );
    BOOL        ThinkDoubleOpenRank( Rank & rank );
    BOOL        ThinkTargetNumber( DigitID & digit );
    BOOL        ThinkShuffleNumber( Number & newNumber );
    BOOL        ThinkChangeRank( Rank & rank );
    BOOL        ThinkChangeNumber( Rank rank, DigitID & digit );
};

仮想関数が無いことを明確にしてるので安心して自分を消去できます。

VOID Player :: Init( MoveID move )
{
    ZeroMemory( this, sizeof * this );

    this->move  = move;
    type        = TYPE_MAN;

    for ( int digit = 0; digit < MAX_DIGIT; digit++ )
    {
        if ( digit < DIGIT_5 )
        {
            cards[ digit ]  = 1;
        }
        else
        {
            cards[ digit ]  = 2;
        }
    }

    items[ ITEM_HIGHLOW ]   = 1;
    items[ ITEM_DOUBLE ]    = 1;
    items[ ITEM_SHUFFLE ]   = 1;
}

同様に分析データもstructです。

struct Analyze
{
    BOOL        valids[ MAX_COLUMN ][ MAX_DIGIT ];
    BOOL        decides[ MAX_DIGIT ];
    Number      candids[ MAX_CANDID ];
    LONG        maxCandid;
    LONG        prob;

    VOID        Make( MoveID move );
    VOID        AddAnalRecord( BOOL * buffer, Number maxNumber, MoveID move, const Record & record );
    VOID        CollectCandidate( BOOL * buffer, Number maxNumber );
    VOID        CheckDecide( BOOL * buffer, Number maxNumber );
    VOID        InitValidate( MoveID move );
    VOID        ValidateByCandidate( BOOL * buffer, Number maxNumber );
    VOID        InitCandidate( BOOL * buffer, Number maxNumber );
    VOID        CandidateByValid( BOOL * buffer, Number maxNumber );
    VOID        CandidateByCall( BOOL * buffer, Number maxNumber, const Call & call );
    VOID        CandidateByShuffle( BOOL * buffer, Number maxNumber );
    int         * MakeOrderList( int & count );
};

終了。