• 検索結果がありません。

繝医Λ繝ウ繝暦シ/A> 隨ャ20蝗 繝医Λ繝ウ繝励た繝ェ繝い縲繧キ繝ウ繝励Ν繧オ繧、繝「繝ウ 螳溯。後繝ュ繧ー繝ゥ繝 繝ヲ繝九ャ繝/A> 隨ャ21蝗 繝医Λ繝ウ繝励た繝ェ繝い縲荳荳ヲ縺ケ 螳溯。後繝ュ繧ー繝ゥ繝 隨ャ22蝗 隱イ鬘梧署遉コ 隱イ鬘鯉シ托シ壼ョ溯。後繝ュ繧ー繝ゥ繝 隱イ鬘鯉シ抵シ壼ョ溯。後繝ュ繧ー繝ゥ繝

N/A
N/A
Protected

Academic year: 2021

シェア "繝医Λ繝ウ繝暦シ/A> 隨ャ20蝗 繝医Λ繝ウ繝励た繝ェ繝い縲繧キ繝ウ繝励Ν繧オ繧、繝「繝ウ 螳溯。後繝ュ繧ー繝ゥ繝 繝ヲ繝九ャ繝/A> 隨ャ21蝗 繝医Λ繝ウ繝励た繝ェ繝い縲荳荳ヲ縺ケ 螳溯。後繝ュ繧ー繝ゥ繝 隨ャ22蝗 隱イ鬘梧署遉コ 隱イ鬘鯉シ托シ壼ョ溯。後繝ュ繧ー繝ゥ繝 隱イ鬘鯉シ抵シ壼ョ溯。後繝ュ繧ー繝ゥ繝"

Copied!
8
0
0

読み込み中.... (全文を見る)

全文

(1)

19

トランプ

(2)

19.1

マウスを使う

前回の例では,あらかじめ決められた札(ハート全部)しか裏返すことができません。マウスで 札を選べるようにしたいのですが,それにはマウスのイベントハンドラーが必要です。コンポーネ ントを設計時にフォームに置く場合は,オブジェクトインスペクターのイベントの欄をダブルク リックすると,必要なことが自動的に書かれるので苦労無しでしたが,実行時に置く場合は自分で 書かないといけません。 また,イベントハンドラーを書くユニット ExampleU と,コンポーネント(TCard)を生成する ユニット TrumpU が別なので,両者の間で情報を交換するための工夫が必要です。 19.1.1 TrumpU の変更点 TrumpU が表示されてないときは,[表示|ユニットの表示]をして TrumpU を選択して表示させ て,変更してください。 (1) イベントハンドラーの型を宣言する。 イベントハンドラーは,イベントによって引数の個数や型が異なります。その引数の情報を イベントハンドラーの型として宣言しておきます。 type

TMouseUpDown = procedure (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,Y: Integer) of object;

TMouseMove = procedure (Sender: TObject;

Shift: TShiftState; X,Y: Integer) of object;

TSuit = (stClub,stDiamond,stHeart,stSpade,stOther); TRank = 1..13;

(2) TTrump のメソッドを追加。

end; { Sakusei }

procedure TTrump.MouseHandler(OnDown : TMouseUpDown; OnUp : TMouseUpDown; OnMove : TMouseMove); (* Mouse のイベントハンドラーを定義する *) var CardNo: TCardNo; begin for CardNo := 0 to 51 do with Cards[CardNo] do begin

(2)

OnMouseUp := OnUp; // MouseUp したときのハンドラー

OnMouseMove := OnMove; // MouseMove したときのハンドラー

end; end; {MouseHandler} 19.1.2 ExampleU の変更点 (1) イベントハンドラーを宣言する。 設計時に置いたコンポーネントならば,オブジェクトインスペクターのイベント欄をダブル クリックすると自動生成される部分ですが,実行時に生成するコンポーネントの場合は自分 で書かないといけません。

procedure ButtonCloseClick(Sender: TObject); procedure ButtonJikkouClick(Sender: TObject); procedure ButtonSakuseiClick(Sender: TObject);

procedure CardMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,Y: Integer); procedure CardMouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X,Y: Integer); procedure CardMouseMove(Sender: TObject;

Shift: TShiftState; X,Y: Integer);

(2) 実現部に骨格を書く。

これも今までは自動作成された部分です。 (********** イベントハンドラー **********)

procedure TFormMain.CardMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin

end; \{CardMouseDown\}

procedure TFormMain.CardMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin

end; \{CardMouseUp\}

procedure TFormMain.CardMouseMove(Sender: TObject;

Shift: TShiftState; X, Y: Integer); begin

end; \{CardMouseMove\}

(3) トランプを作成したらマウスハンドラーを設定する。

procedure TFormMain.ButtonSakuseiClick(Sender: TObject); begin

(3)

Trump.MouseHandler(CardMouseDown,CardMouseUp,CardMouseMove); ButtonSakusei.Visible := False; // 作成は1度だけ ButtonJikkou.Enabled := True; end; {ButtonSakuseiClick} これで準備はOKです。 翻訳してエラーがないことを確認してください。 19.1.3 OnMouseDown ハンドラーのテスト カードをクリックしたら,裏返したり反転したりするようにしてみましょう。 (1) CardMouseDown の中身を書く。

procedure TFormMain.CardMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin

with TCard(Sender) do // クリックしたカード

begin

if ssShift in Shift // Shift キーを押しながらクリック

then begin case Button of mbLeft : OmoteNiSuru; mbRight : UraNiSuru; end; end;

if ssAlt in Shift // Alt キーを押しながらクリック

then begin case Button of mbLeft : PosiNiSuru; mbRight : NegaNiSuru; end; end; if ssCtrl in Shift // Ctrl キーを押しながらクリック then begin case Button of mbLeft : BringToFront; mbRight : SendToBack; end; end; end; end; {CardMouseDown} (2) 実行 同じマウスボタンの操作(たとえば,“裏にする” と “ネガにする”)は,2 つ以上のキーを押 しながらクリックして一度にできます。

(4)

19.1.4 OnMouseMove と OnMouseUp のテスト 選んだカードを好きな位置に引きずっていくようにします。 カード上のマウスダウンしたときの点 A を憶えておいて,カード上を点 P までマウスムーブし たら,−→AP だけカードの位置をずらします。 (1) FormMain の private 部に変数を追加する。 private Trump : TTrump; Idouchuu : Boolean; XDown,YDown : Integer; (2) CardMouseDown に “キーを押さないで左クリック” の処理を追加する。 if Shift * [ssShift,ssAlt,ssCtrl] = [] // キーを押さないでクリック then begin case Button of mbLeft : begin XDown := X; YDown := Y; Idouchuu := True; end; end; end; (3) CardMouseMove と CardMouseUp の中身を書く。

procedure TFormMain.CardMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin

Idouchuu := False;

end; {CardMouseUp}

procedure TFormMain.CardMouseMove(Sender: TObject;

Shift: TShiftState; X, Y: Integer); begin with TCard(Sender) do begin if Idouchuu then begin Left := Left+X-XDown; Top := Top +Y-YDown; end;

end;

end; {CardMouseMove}

(5)

19.2

シャッフル

トランプのゲームをするには,カードをきる(Shuffle)必要があります。 19.2.1 アルゴリズム 5 個のデータをシャッフルするには次のようにします。わかりやすいように,阿弥陀くじで表し てみました。ただし,この阿弥陀くじは隣の線路(縦線)を結ぶ橋(横線)だけでなく,離れた線 路を結ぶ跨線橋もあります。   0 1 2 3 4 番目   a b c d e   │ │ │ │ │1回目,0∼4の乱数を引く,2だったとする   │ │ ├───┤    4番目と2番目を交換   │ │ │ │ │    (4番目が確定)   a b e d c   │ │ │ │ │2回目,0∼3の乱数を引く,0だったとする   ├─────┤ │    3番目と0番目を交換   │ │ │ │ │    (3番目が確定)   d b e a c   │ │ │ │ │3回目,0∼2の乱数を引く,2だったとする   │ │ │ │ │    2番目と2番目を交換   │ │ │ │ │    (2番目が確定)   d b e a c   │ │ │ │ │4回目,0∼1の乱数を引く,0だったとする   ├─┤ │ │ │    1番目と0番目を交換   │ │ │ │ │    (1番目が確定)   b d e a c    (0番目も確定) 乱数の出方によって,5! = 5 · 4 · 3 · 2 通りの順列が,すなわちすべての順列が生成されることが わかりますね。 19.2.2 TrumpU のメソッドを追加 (********** TTrump のメソッド **********) procedure TTrump.Shuffle; (* でたらめに並べかえる *) var CardNo,RandomNo : TCardNo; begin

for CardNo := 51 downto 1 do begin

RandomNo := Random(CardNo+1); // 0 ∼ CardNo の乱数

Swap(CardNo,RandomNo); // データを交換する end; end; {Shuffle} 交換するデータは,Suit, Rank および表の絵です。 コメントとを参考にして完成させてください。 (********** TTrump のメソッド **********) procedure TTrump.Swap(No1,No2 : TCardNo);

(* Cards の No1 番目と No2 番目のデータを交換する *) var

(6)

RankSave : TRank; // Rank 保存用 begin // ┐ //  Cards[No1] と //  Cards[No2] の //  Suit と Rank を // 交換する // ┘ // それぞれを表にする // end; {Swap} 19.2.3 ExampleU の ButtonJikkouClick ハンドラーを変更 実行部の先頭に追加する。 Trump.Shuffle; 実行して,実行ボタンを押すたびにシャッフルされることを確認してください。同じ札が 2 枚 あったりしてはいけませんよ。

19.3

逆引き機能

シャッフルした後で,たとえば 23 番目のカードが何かは スート Trump.Cards[23].Suit ランク Trump.Cards[23].Rank で わかりますが,逆に,たとえば “ハートのA” が何番目にあるかは,Suit と Rank から計算して得 ることができなくなりました。探さなくてもわかるように,逆引き用のデータを持たせることにし ます。 19.3.1 TTrump の public 部に変数 No を追加 public

Cards : array [TCardNo] of TCard;

No : array [TSuit,TRank] of TCardNo;

19.3.2 TTrump.Sakusei に No の初期設定を追加 with Cards[CardNo] do begin Left := CardNo*12; // 左端の位置 Top := CardNo*8; // 上端の位置 Tag := CardNo; // 札から番号がわかるようにするため

Suit := TSuit(CardNo div 13); // スート Ord(Suit)03 Rank := (CardNo mod 13)+1; // ランク 113

OmoteNiSuru; // 表の絵にする

No[Suit,Rank] := CardNo; // 逆引き

(7)

19.3.3 TTrump.Swap で No も変更 begin 途中省略(先の問題の部分) No[Cards[No1].Suit,Cards[No1].Rank] := No1; // 逆引き No[Cards[No2].Suit,Cards[No2].Rank] := No2; // end; {Swap} 19.3.4 動作確認のための変更 カードを右クリックしたら,その相方のカードと交換するようにします。

procedure TFormMain.CardMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

var TargetNo : TCardNo; // 交換するカードの番号 TargetSuit : TSuit; //         スート TargetRank : TRank; //         ランク begin 途中省略 if Shift * [ssShift,ssAlt,ssCtrl] = [] // キーを押さないでクリック then begin case Button of mbLeft : begin XDown := X; YDown := Y; Idouchuu := True; end; mbRight : begin

TargetSuit := TSuit(Ord(Suit) xor 1); TargetRank := (Rank mod 13)+1;

TargetNo := Trump.No[TargetSuit,TargetRank]; Trump.Swap(Tag,TargetNo); end; end; end; end; end; {CardMouseDown} 相方は次のように決めています。 列挙型 TSuit が (stClub,stDiamond,stHeart,stSpade) と定義されているので,型キャスト TSuit(整数) と 関数 Ord(スート) の値は次のようになります。 オーダー TSuit(オーダー) 0 stClub 1 stDiamond 2 stHeart 3 stSpade Ord(スート) スート ここでは xor は論理演算子ではなく,算術演算子として用いられています。and,or,not も論 理演算子としても算術演算子としても用いることができます。算術演算子のときは,数を 2 進法で

(8)

考えて各桁ごとに,(0 = False,1 = True として)論理演算した結果を値とします。なお,xor は 排他的論理和(eXclusive OR)です。ペンモードでも出てきましたね。 例 2 進法 16 進法 10 進法 M 1010 $A 10 N 1100 $C 12 not M 0101 $5 5 M and N 1000 $8 8 M or N 1110 $E 14 M xor N 0110 $6 6

上のプログラムでは,Ord(Suit) xor 1 としているので,Ord(Suit) を 2 進法で書いた数の最 も右の桁の 0 と 1 を反転します。したがって,相方のカードは次のようになります。 Suit クラブ ↔ ダイヤ, ハート ↔ スペード Rank A → 2 → 3 → · · · → Q → K → A 問題 相方が下記のようになるように書き換えなさい。 (1) Suit クラブ → スペード → ハート → ダイヤ → クラブ Rank A ↔ K,  2 ↔ Q,  3 ↔ J,  · · · ,  6 ↔ 8,  7 ↔ 7 (2) Suit クラブ ↔ ハート, ダイヤ ↔ スペード Rank K → Q → J → · · · → 2 → A → K

参照

関連したドキュメント

シンポジウム レ ク チ ャ ー / 特別発言/COIセッション 日本専門医機構泌尿器科専門医卒後教育セミナー特別講演/教育講演/会長発言JCS専門医セミナー Tak e Hom

Conversely, Lemma 3.1.10(4) implies that every subpath of λ is contained in a tile in λ... 542 MLADEN BESTVINA, MARK FEIGHN, AND MICHAEL HANDEL.. Definitions 3.1.12. if

励磁方式 1相励磁 2相励磁 1-2相励磁 W1-2相励磁 2W1-2相励磁 4W1-2相励磁. Full Step Half Step Quarter Step Eighth Step Sixteenth

The different colors shown in the three pictures of Figure 5, obtained with λ 20, λ 60, λ 500 respectively, represent the kind of asymptotic behavior numerically observed:

性状 性状 規格に設定すべき試験項目 確認試験 IR、UV 規格に設定すべき試験項目 含量 定量法 規格に設定すべき試験項目 純度

This gives a bijection between the characters [ν ] ∈ [λ/µ] with maximal first part and arbitrary characters [ξ] ∈ [ˆ λ/µ] with ˆ λ/µ the skew diagram obtained by removing

A cocomplete monoidal closed category is said to be locally λ-bounded as a closed category if its underlying ordinary category is locally λ-bounded and, in addition, the functors A ⊗

る省令(平成 9