ヌメロン製作講座第14回:棋譜データグリッドの作成
プレイ画面のうち前回はプレイ情報画面のみを作成しました。
今回は棋譜データ画面を作成します。
- 棋譜グリッド表示画面
class RecGrid
棋譜データグリッドクラスです。
class RecGrid : public Grid { public : static const Cell base[ MAX_RECORD_CELL + 1 ]; Cell cells[ MAX_RECORD_CELL * MAX_RECORD + 1 ]; Cell * turnCell; Cell * moveCell; int maxCell2; Cell * GetCells() { return cells; } VOID Init( HWND hWnd ); VOID MakeGrid(); VOID MakeGrid( BOOL attack, BOOL defense ); VOID MakeTable( BOOL attack, BOOL defense ); VOID AddTable(); };
内容は以下の通りです。
- base[ MAX_RECORD_CELL + 1 ]
- 棋譜データグリッドのベースとなる1行分のセル定義データです。これをコピーして使います。
- cells[ MAX_RECORD_CELL * MAX_RECORD + 1 ]
- 実際に使用するセル定義データです。
- turnCell
- セル定義データを作成する際に、ターン番号を表示するセルを指すポインタです。
- moveCell
- セル定義データを作成する際に、各手番の情報を表示するセルを指すポインタです。
- maxCell2
- セル定義データ作成時に使用するワーク変数です。
- GetCells()
- セル定義データアドレスを返します。
- Init( HWND hWnd )
- 表示オフセットを変更するためにオーバーライドしています。
- MakeGrid()
- セル定義データを動的に作成するためにオーバーライドしています。
- MakeGrid( BOOL attack, BOOL defense )
- 攻撃アイテム選択の表示の有無、防御アイテム選択の表示の有無を指定してセル定義データを作成します。
- MakeTable( BOOL attack, BOOL defense )
- 現在の棋譜データに基づいて動的にセル定義データを作成します。
- AddTable()
- セル定義データに新しい行を追加します。
enum RecordCellID
棋譜データグリッドの1行分のセル内容を表す識別子です。
enum RecordCellID { RECORD_CELL_NULL = -1, RECORD_CELL_TURN, RECORD_CELL_FIRST, RECORD_CELL_SECOND, RECORD_CELL_NEWLINE, MAX_RECORD_CELL };
内容は以下の通りです。
VOID RecGrid :: Init()
グリッドクラスの初期化メソッドのオーバーライドです。
VOID RecGrid :: Init( HWND hWnd ) { CopyMemory( cells, base, sizeof base ); Grid :: Init( hWnd ); SetOffset( app.infoGrid.offset.x, app.infoGrid.rect.bottom + app.infoGrid.offset.y + 4 ); }
セル定義データの1行目にベース定義データをコピーしてグリッドを初期化します。
表示オフセットをプレイ情報グリッドの直下になるように調整します。
VOID RecGrid :: MakeGrid()
グリッド作成メソッドのオーバーライドです。
VOID RecGrid :: MakeGrid() { MakeGrid( TRUE, TRUE ); }
攻撃アイテム選択表示の有無、防御アイテム選択表示の有無を指定して固有のグリッド作成メソッドを実行します。
VOID RecGrid :: MakeGrid()
攻撃アイテム選択表示の有無、防御アイテム選択表示の有無を指定して棋譜データグリッドを作成します。
VOID RecGrid :: MakeGrid( BOOL attack, BOOL defense ) { MakeTable( attack, defense ); Grid :: MakeGrid(); }
動的セル定義データを作成して基底クラスのグリッド作成メソッドを呼びます。
VOID RecGrid :: MakeTable()
セル定義データを動的に作成します。
VOID RecGrid :: MakeTable( BOOL attack, BOOL defense ) { BOOL attacks[ MAX_MOVE ]; BOOL defenses[ MAX_MOVE ]; MoveID move = MOVE_NULL; MoveID move0 = move; DataID did = DATA_NULL; DataID did0 = did; CellID cid = CELL_ATTACK; int turn = 0; int doubling = 0; BOOL finish = FALSE; for ( int move2 = 0; move2 < MAX_MOVE; move2++ ) { attacks[ move2 ] = attack; defenses[ move2 ] = defense; for ( int item = 0;; item++ ) { if ( item >= ITEM_SHUFFLE ) { attacks[ move2 ] = FALSE; break; } else if ( numer0n.players[ move2 ].items[ item ] > 0 ) { break; } } for ( int item = ITEM_SHUFFLE;; item++ ) { if ( item >= MAX_ITEM ) { defenses[ move2 ] = FALSE; break; } else if ( numer0n.players[ move2 ].items[ item ] > 0 ) { break; } } } maxCell2 = 0; AddTable(); turnCell->data = ++turn; for ( int n = 0; n < numer0n.maxRecord; n++ ) { Record & record = numer0n.records[ n ]; move0 = move; move = record.move; did0 = did; did = record.did; if ( did < DATA_ITEM_SHUFFLE ) { if ( move0 != MOVE_NULL ) { if ( move == MOVE_FIRST && move0 == MOVE_SECOND ) { AddTable(); turnCell->data = ++turn; } else if ( move == move0 ) { AddTable(); if ( ( did0 >= DATA_ITEM_SHUFFLE && did0 <= DATA_ITEM_CHANGE ) && move == MOVE_FIRST ) { turnCell->data = ++turn; } } } moveCell[ move ].cid = CELL_RECORD; moveCell[ move ].data = n; if ( did == DATA_CALL ) { if ( record.call.eat == numer0n.maxColumn ) { finish = TRUE; break; } else if ( doubling == 1 ) { doubling++; cid = CELL_CALL; move0 = move; } else { doubling = 0; cid = CELL_DEFENSE; move0 = move; } } else { if ( did == DATA_ITEM_DOUBLE ) { doubling = 1; } cid = CELL_CALL; move0 = move; } } else { if ( move == MOVE_SECOND ) { AddTable(); } move = Enemy( move ); moveCell[ move ].cid = CELL_RECORD; moveCell[ move ].data = n; move0 = move; cid = CELL_ATTACK; } } if ( ! finish ) { if ( move == MOVE_NULL ) { move0 = move; move = MOVE_FIRST; } if ( cid == CELL_DEFENSE ) { if ( ! defenses[ move ] ) { move0 = move; move = Enemy( move ); cid = CELL_ATTACK; } } if ( cid == CELL_ATTACK && ! attacks[ move ] ) { cid = CELL_CALL; } if ( move0 != MOVE_NULL ) { if ( move0 == MOVE_NULL ) { move0 = move; } if ( move == MOVE_FIRST && move0 == MOVE_SECOND ) { AddTable(); turnCell->data = ++turn; } else if ( move == move0 ) { AddTable(); } } moveCell[ move ].cid = cid; } }
現在の棋譜データをセル定義データとして展開します。
まだ勝敗がついていない場合は次の手番の入力プロンプトを表示します。
VOID RecGrid :: AddTable()
セル定義データに1行分の棋譜データ行を追加します。
VOID RecGrid :: AddTable() { CopyMemory( & cells[ maxCell2 ], base, sizeof base ); turnCell = & cells[ maxCell2 + RECORD_CELL_TURN ]; moveCell = & cells[ maxCell2 + RECORD_CELL_FIRST ]; moveCell[ MOVE_FIRST ].data = EDIT_NULL; moveCell[ MOVE_SECOND ].data = EDIT_NULL; maxCell2 += MAX_RECORD_CELL; }
1行分のベースセル定義データをコピーしてセル定義データ数をカウントアップします。
- ヌメロンクラス関係の修正点
enum CellID
以下の識別子を追加しました。
- CELL_RECORD
- 棋譜データセルです。
- CELL_CALL
- コール入力セルです。
- CELL_ATTACK
- 攻撃アイテム選択入力セルです。
- CELL_DEFENSE
- 防御アイテム選択入力セルです。
enum EditModeID
棋譜データの入力では1つのセルに対して複数の項目を入力する必要があるので、現在の入力モードを示すための編集モード識別子を追加しました。
- EDIT_BEGIN
- 初期状態です。
- EDIT_EAT
- イート数入力中です。
- EDIT_BYTE
- バイト数入力中です。
- EDIT_RANK
- 位を選択中です。
- EDIT_HIGHLOW
- ハイまたはローを選択中です。
- EDIT_HIGH
- ハイの数を入力中です。
- EDIT_LOW
- ローの数を入力中です。
- EDIT_DIGIT
- カードの番号を入力中です。
- EDIT_SLASH
- スラッシュナンバーを入力中です。
- EDIT_NUMBER
- 設定ナンバー入力中です。
- EDIT_DIGIT2
- チェンジ後のカード番号を入力中です。
struct Cell
以下のメンバ変数とメソッドを追加しました。
- アプリケーションクラス関係の修正点
class Application
以下のメンバ変数を追加しました。
- RecGrid recGrid
- 棋譜データグリッドオブジェクトです。
- Grid * playFocus
- プレイ画面のフォーカス所有グリッドのアドレスです。
以上です。
次回は未定です。