占領双六ゲーム C# 2005 9 プログラムの概要 赤と青の 2 者が順番にサイコロを振り 出た目の数だけ駒を進めて行き 停止したマス目を自分の色に塗り潰して 自分の陣地に出来ると謂う 所有る陣取りゲームを作成する マス目は最初に其のマスに停止した方の陣地となり 既に孰れかの色に塗り潰されて居るマスに 後から別の駒が停止しても 陣地の占領者が変わる事は無い 総てのマス目が孰れかの色に塗り潰されゝばゲームは終了し 最終的に多くのマスを塗り潰した方が勝ちと成る 今回の課題項目 単純 配列変数の宣言 ( 適用範囲データ型変数名 ;) 標準コントロールの利用 (Panel PictureBox Label Button Timer) コントロール配列の利用 (Control 型のオブジェクト配列変数にコントロールを格納 ) プロパティの値の取得と設定 (BackColor Name Text Width Height Location 等 ) イベントの利用 (Load Click Tick) メソッドの利用 (Contains Equals Add ToByte ToString Next Substring) 自作メソッドの利用 ( 適用範囲戻り値型メソッド名 ( 引数 ) return) リソースの利用 (Properties.Resources ResourceManager GetObject) メッセージボックスの利用 (MessageBox Show) 演算子 ( 代入演算子 比較演算子 結合演算子 三項条件演算子?: ) 制御構造構文 ( 条件分岐 :if ~ else if ~ else switch ループ処理 :for foreach) 今回の重点項目 コントロール配列の利用 (Control 型のオブジェクト配列変数にコントロールを格納 ) 自作メソッドの利用 ( 適用範囲戻り値型メソッド名 ( 引数 ) return) 埋め込み画像の利用 ( リソースの利用 ) 三項条件演算子の利用 ( 戻り値を格納する変数 = 条件式? 真の時の値 : 偽の時の値 ; ) 今回の応用項目 マス毎に点数を付け 高得点を競うゲームにする 先に 9 地点占領するとゲームが終了する様にする 色々なルールを考えて観る -1-
~ C# 2005 9 C# 2005 基礎 Ⅰ noa オブジェクト プロパティ一覧 左上を起点に時計廻りに配置パネル 1 ピクチャーボックス 1 パネル 16 ピクチャーボックス 3 ピクチャーボックス 2 ラベル コマンドボタン タイマー 1 タイマー 2 コントロールの種類 プロパティ プロパティの設定値 フォーム Name sugoroku BackColor White FormBorderStyle FixedSingle Icon saikoro.ico MaximizeBox False StartPosition CenterScreen Text 占領双六ゲーム パネル1 Name pnlmasu00 BackColor Aqua( 任意の色に設定しても良い ) パネル16 Name pnlmasu15 BackColor Aqua( 任意の色に設定しても良い ) ピクチャーボックス1 Name picdice Image 1.gif( ローカルリソースでインポート ) Size 32, 39 ピクチャーボックス2 Name picred Image picred.gif( ローカルリソースでインポート ) Size 37, 37 ピクチャーボックス3 Name picblue Image picblue.gif( ローカルリソースでインポート ) Size 37, 37-2-
コントロールの種類 プロパティ プロパティの設定値 ラベル Name lbldisp AutoSize False BackColor Black ForeColor White Text Font 1(MS 明朝, 太字, 12) TextAlign MiddleCenter ボタン Name btndice BackColor Blue ForeColor White Text Font ぽちっと ( 任意 ) タイマー 1 Name tmrdice Interval 200 タイマー 2 Name tmrgo Interval 500 ラベルテキストを表示するコントロール 此のテキストは ユーザーが直接入力したり変更したりする事は出来ない ボタンユーザーが選択したコマンド ( 命令 ) や操作を実行するコントロール OK ボタンや実行ボタン等 処理の開始や中断 終了の合図に用いられ 最も良く利用されるコントロールです パネル他のコントロールをグループ化する為のコンテナと成るコントロールで有る 通常は 機能別にフォームを細分化する為に使用する 亦 BackgroundImage プロパティを設定すると コントロールの背景にイメージが表示される タイマー一定の時間間隔でイベントが発生する様にするコントロール 一定時間毎にプログラムを実行したい時に使用する 此のコントロールは 実行時には表示されない ビットマップ アイコン メタファイル JPEG ファイル GIF ファイル等の画像を表示するコントロール 従来のバージョン (VB 6.0) の様に 描画メソッドを用いて描画する事や 内部に他のコントロールを配置してコンテナと仕て使用する事はは出来ない デザイン時の注意 パネルは 左上隅を起点にに最初のパネル (pnlmasu00) を配置して 以下時計廻りに 15 個のパネル (pnlmasu01~pnlmasu15) を配置する -3-
画像ファイルを実行ファイルに埋め込む ソリューションエクスプローラで Properties を展開して ( 左図 ) Resouces.resx をダブルクリックする ( 右図 ) 下図の様に RESX タブが表示されるので 文字列が表示されて居れば イメージに変更してから リソースの追加 新しいイメージ と進み GIF イメージ をクリックする 下図のダイアログボックスでは リソース識別名 ( 此処では Dice1 から Dice6 とする ) を入力し 追加 ボタンをクリックする WEB ブラウザ等の関連付けられたアプリケーションが起動し 該当ファイル ( 上記では Dice1.gif) を表示しようとするが 何も表示されないので アプリケーションを閉じる 追加したリソース ( 例えば Dice1) のプロパティで Persistence プロパティを.resx に埋め込まれました に変更する -4-
追加したリソースを右クリックして ポップアップメニューを表示し ファイルからインポート をクリックする ( 上図では 表示方法を 一覧での表示 と仕て居る ) ファイルを指定するダイアログボックスが表示されるので 対応する画像を選択し 開く ボタンをクリックする 上記の手順で 必要な画像ファイル ( 此処では 1.gif から 6.gif) を リソースに取り込む 猶 RESX タブに 画像ファイル等を直接ドラッグ & ドロップするか 又は プロジェクト内の Resouces フォルダに 画像ファイル等を直接コピーして ポップアップメニューから プロジェクトに含める をクリックして リソースを取り込む事も出来る -5-
プログラムリスト using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; ネームスペース ( 名前空間 ) の使用を宣言して居る 此の部分は エディタが 自動的に記述して下れる namespace sugoroku public partial class sugoroku : Form 此処で Private 宣言した変数は同 じフォームモジュール内の総ての // フォームレベルでグローバルな変数の宣言 private byte dice; サブプロシージャで値の参照と設 private byte gocnt; 定を行う事が出来る private byte redcnt; private byte masucnt; private byte turn; 色を格納する変数には Color オブ private Color basecolor; ジェクト型を使用する private byte[ ] pmasu = new byte[ 2 ]; private Panel[ ] pnlmasu = new Panel[ 16 ]; private Control[ ] pickoma = new Control[ 2 ]; private Random rnd = new Random( ( int )DateTime.Now.Ticks ); public sugoroku( ) InitializeComponent( ); // フォームが読み込まれた時の処理 private void sugoroku_load( object sender, EventArgs e ) byte n; // 桝目の元の背景色の取得 basecolor = pnlmasu00.backcolor; // コントロールの Object 配列化 foreach ( Control c in this.controls ) if ( c.name.contains( "pnlmasu" ) ) n = System.Convert.ToByte( c.name.substring( 7 ) ); pnlmasu[ n ] = ( Panel ) c; else if ( c.name.equals( "picred" ) ) pickoma[ 0 ] = c; else if ( c.name.equals( "picblue" ) ) pickoma[ 1 ] = c; // ゲームの初期化 GameInit( ); クラスを生成する為のコンストラクタで有る 此の部分は エディタが 自動的に記述して下れる 此処で宣言した変数は宣言したサブプロシージャ内でしか値の参照と設定を行う事が出来ない 従来のコントロール配列は使用出来ない為 コントロールを配列変数に格納して居る Equals メソッドは 2 個の String オブジェクトの値が同じで有るかを判断するメソッドで有る 自作メソッドも組込メソッドと同じ様に呼び出す事が出来る -6-
// 駒を表示するメソッド ( ジェネラルプロシージャ ) private void KomaDisp( byte t ) int x, y; x = ( pnlmasu[ pmasu[ t ] ].Width - pickoma[ t ].Width ) / 2; y = ( pnlmasu[ pmasu[ t ] ].Height - pickoma[ t ].Height ) / 2; x = t == 0? x -= x / 2 : x += x / 2; pickoma[ t ].Location = new Point( x, y ); pnlmasu[ pmasu[ t ] ].Controls.Add( pickoma[ t ] ); // ゲームを初期化するメソッド ( ジェネラルプロシージャ ) private void GameInit( ) byte i; 駒を枡の中央に配置する様に横方向と縦方向の座標を求めた後 駒が同じ枡に停止した時の為に 横方向の位置を外らして居る コントロールの Left プロパティと Top プロパティは Location プロパティで纏めて設定出来る コンテナの Controls コレクションに Add メソッドでコントロールをコンテナ化する事が出来る // 各枡の背景色を元の色に設定 for ( i = 0; i < 16; i++ ) pnlmasu[ i ].BackColor = basecolor; // 変数や駒位置の初期化 turn = 0; masucnt = 0; pmasu[ 0 ] = 0; KomaDisp( 0 ); pmasu[ 1 ] = 8; KomaDisp( 1 ); lbldisp.text = " 赤の番 "; btndice.enabled = true; 此のループ処理ではカウンター i の値を 0 から 15 に 1 宛変化させて ステートメントブロック処理を繰り返し行う 引数を指定してメソッドを呼び出す 此れは ローカルな変数値等を他のメソッドに引き渡す時に利用する // ボタン ( ぽちっと ) がクリックされた時の処理 private void btndice_click( object sender, EventArgs e ) // トグル形式で tmrdice の Enabled プロパティを変更 if ( tmrdice.enabled == false ) tmrdice.enabled = true; else tmrdice.enabled = false; tmrgo.enabled = true; Enabled プロパティが true の場合は false に false の場合は true にと謂う様に循環する動作をトグルと謂い プログラムでは良く利用される // タイマー ( 賽子を振る ) が一定間隔で行う時の処理 Random オブジェクトの Next メ private void tmrdice_tick( object sender, EventArgs e ) ソッドを用いて1から6 迄の乱数 string s; を発生させて整数化し 其れをラベルに表示して居る // 乱数で賽子の目を設定 dice = ( byte ) rnd.next( 1, 7 ); lbldisp.text = dice.tostring( ); 埋め込まれたリソースを実行時に // リソース識別名の設定読み込む為の処理で有る s = "Dice" + dice.tostring( ); // 賽子の画像の表示 picdice.image = ( Image ) Properties.Resources.ResourceManager.GetObject( s ); -7-
// タイマー ( 駒を進める ) が一定間隔で行う時の処理 private void tmrgo_tick( object sender, EventArgs e ) Color c; 変数の値を 1 増やす事をインクリ メントと謂い プログラムでは良 く利用される btndice.enabled = false; A++ は A=A+1 と等価で A+=1 gocnt++; pmasu[ turn ]++; と記述する事も出来る if ( pmasu[ turn ] == 16 ) pmasu[ turn ] = 0; KomaDisp( turn ); 最高値を超えた場合に最初に戻る if ( dice == gocnt ) 様な動作もトグルと謂い プログ tmrgo.enabled = false; gocnt = 0; ラムでは良く利用される // 駒が占領されて居ない枡に停止した場合 if ( pnlmasu[ pmasu[ turn ] ].BackColor.Equals( basecolor ) ) if ( turn == 0 ) c = Color.Red; redcnt++; インクリメントは A=A+1 と謂う 事で有るが 使用頻度が高い為に else A+=1 や A++ と謂う簡略形式で記 述する事も出来る c = Color.Blue; pnlmasu[ pmasu[ turn ] ].BackColor = c; masucnt++; // ゲーム終了 if ( masucnt == 16 ) 条件判定に 比較演算子を使用し て居る if ( redcnt > 8 ) A > B : AはBより大きい MessageBox.Show( " 赤の勝ち!!", " ゲーム終了 " ); else if 節は 最初の条件を満たさ else if ( redcnt == 8 ) 無い場合で 更に条件分岐する必 要の有る時に用いる 評価する変 MessageBox.Show( " 引き分け!!", " ゲーム終了 " ); 数が同一の場合には switch 文を 使用する事も出来る else MessageBox.Show( " 青の勝ち!!", " ゲーム終了 " ); return ステートメントは 以降の コードを実行せずに 直ちにメソ redcnt = 0; GameInit( ); return; ッドを抜ける命令で有る // 順番の交代 switch ( turn ) 変数の取り得る値が0か1で 0 なら1に 1なら0にトグル形式 case 0: turn = 1; lbldisp.text = " 青の番 "; break; で変更するには 論理演算子 ^を case 1: turn = 0; lbldisp.text = " 赤の番 "; break; 用いて A=A ^ 1 と謂う様に記述す る事も出来る btndice.enabled = true; -8-
System.Convert オブジェクトの ToByte メソッドに依るデータ型変換 機能 書式 解説 指定した値を 8 ビット符号無し整数に変換するメソッド バイト型変数 = System.Convert.ToByte( 値 ) 指定した数値を 8 ビット符号無し整数に変換する ToByte メソッドには 様々なオーバーロードが有り 様々なデータ型の引数から 8 ビット符号無し整数に変換する事が出来る 亦 System.Convert クラスには 様々なパブリックメソッドが有り 様々なデータ型の引数から 其れと等価な様々なデータ型に変換する事が出来る C# では 暗黙的にデータ型を変換して下れる事は 殆ど無く 明示的にデータ型を変換する必要が有る為 System.Convert クラスは 重要なクラスで有る 猶 データ型を変換する事をキャスティングと謂う System.Covert クラスのデータ型変換に関するメソッドを 下記に示す 名前 ToBoolean ToByte ToChar ToDateTime ToDecimal ToDouble ToInt16 ToInt32 ToInt64 ToSByte ToSingle ToString ToUInt16 ToUInt32 ToUInt64 説明指定した値を等価のブール値に変換する 指定した値を 8 ビット符号無し整数に変換する 指定した値を Unicode 文字に変換する 指定した値を DateTime に変換する 指定した値を Decimal の数値に変換する 指定した値を倍精度浮動小数点数に変換する 指定した値を 16 ビット符号付き整数に変換する 指定した値を 32 ビット符号付き整数に変換する 指定した値を 64 ビット符号付き整数に変換する 指定した値を 8 ビット符号付き整数に変換する 指定した値を単精度浮動小数点数に変換する 指定した値を 其れと等価な String 形式に変換する 指定した値を 16 ビット符号無し整数に変換する 指定した値を 32 ビット符号無し整数に変換する 指定した値を 64 ビット符号無し整数に変換する キャスト演算子に依るデータ型変換 パーレン ( ) は 式の演算順序を指定する丈で無く キャスト 又は 型変換を指定する為にも使用する 下記に 例を示す double x = 1234.7; int a; a = (int)x; // double を int にキャスト キャストでは 型変換演算子が明示的に呼び出される 型変換演算子が定義されて居ない場合 キャストは失敗する 詳しくは explicit キーワード ( キャストを使って呼び出す必要が有るユーザー定義型の変換演算子を宣言 ) や implicit キーワード ( 暗黙のユーザー定義型変換演算子を宣言 ) を参照され度い -9-
Equals メソッドに依るオブジェクトの比較 機能 書式 解説 2 個のオブジェクトが同一か比較するメソッド Object.Equals( オブジェクト ) 2 個のオブジェクトが同一で有れば True を 同一でなければ False を返す 引数のオブジェクトには 比較するオブジェクトを指定し 省略する事は出来ない オブジェクトの比較は プリミティブな型の値を比較する == 演算子で比較する事は出来ない 其処でオブジェクトの比較には is キーワードか Equals メソッドを用いる 猶 String 型は 実際には オブジェクト型で有るが 使用頻度が高い為 C# では プリミティブな型の様に == 演算子でも比較する事が出来る Add メソッドに依るコントロールのコンテナ化 機能 書式 解説 コントロールコレクションにコントロールを追加するメソッド Object.Controls.Add( コントロール ) コントロールコレクションにコントロールを追加し コンテナ化 ( 内包 ) する 引数のコントロールには コレクションに追加するコントロールを指定し 省略する事は出来ない Object は フォーム パネル グループボックス等のコンテナに成る事の出来るコントロールで有る必要が有る コンテナに成る事の出来るコントロールとは 他のコントロールを内包する事の出来るコントロールの事を謂う 猶 追加されるコントロールが 既に他のコントロールの子コントロールで有る場合 別のコントロールに追加される前に 現在の親コントロールのコレクションから削除される?: 演算子に依る条件に応じた値の取得 機能 書式 解説 条件に応じた値を取得する演算子 戻り値を代入する変数 = 条件式? 真の場合の式 : 偽の場合の式 ; 条件式が真 (true) の場合は 真の場合の式が評価された値が 偽 (false) の場合は 偽の場合の式が評価された値が返される 条件が true の場合 1 番目の式が評価され 此れが結果と成る 条件が false の場合 2 番目の式が評価され 此れが結果と成る 常に 2 つの式の孰れか 1 つ丈が評価される if-else の構造が必要に成る計算は 条件演算子を使用すると 簡潔で明快に表現する事が出来る -10-