SSブログ

資産管理電卓でゲーム6(疑似クラス継承について) [資産管理電卓(LineCalc)]

久々にゲームをプログラムしました。

今回はカードゲームの 21 を作りました。

このゲームは 資産管理電卓v2.0.43.0 以降でないと動作しません。

一般のルールと違い親はおらず、CPU と ユーザー2人対戦です。

*インストール方法

以下から newCDisp.dat をダウンロードして



メニューの

設定 -> 設定読み込み

から読み込んでください。
(※)絶対に 設定読み込み(初期化) を選ばないようにしてください。
元々の設定がクリアされてしまいます。

newCDisp グローバル関数がインストールされます。

後は、ここからソースをコピーして資産管理電卓に貼り付けて計算をすれば実行できます。



*ゲーム画面

   ------------- TWENTY ONE -------------                                       
 SCORE : 0 LEVEL : 1                                                            
+------CPU------              +------USER------                                 
|CARD :[*  ]                  |CARD :[2  ]                                      
|MONEY:79                     |MONEY:100 BEST:2 SUM LIST: {2 }                  
|BET  :21                     |BET  :0                                          


*ルール
最高3枚の待ち札のうち 21 に近い方が勝ちになります。
J,Q,K は数値 10 になります。
掛け金をかけて負けると掛け金は相手のもので、相手の掛けた掛け金も支払う必要があります。
相手の持ち金より多くを掛ける事ができ、1~自分の持ち金までかける事ができます。
特殊札があり、A は 1 , 11 のどちらでも、(ジョーカー)は 0 , 10 , 1 , 11 のどの数値にもなります。
相手が破産していくとレベルが上がり CPU がミスをしずらくなっていき、初期の相手の持ち金が増えていきます。

*遊び方

・最初に一枚手札を引いた状態から始まります。カードは自分しか見れません。
・ CPU が掛け金を掛けるので掛け値と自分の持ち札を見て掛け金を決めます。
・もう一枚 CPU ユーザー共に引きます。このカードは双方見る事ができます。
・CPU がもう一枚引くか、このままにするか決めます。
・CPUの行動を見て一枚引くなら y 引かないなら n を押してください。
・勝負の判定をして自分の掛け金が無くなるまでループします。

普通にかけて行くと長く遊べますが持ち金はあまり増えていきません。
掛け金を一気に増やせば相手を大破産させて自分の持ち金を増やすことができますが、一気に自分が破産するかもしれません。
大金持ちになるには大リスクを取って掛けを続けなくてはなりません。
一気に大金持ちを目指すか、安定してスコア、レベルの上昇を目指すか。
やり方によりさまざまなゲーム展開が楽しめると思います。

・LCSでのクラス継承について

このゲームではコンテキストリソースを使った疑似クラスを使用していますが、クラスの継承を行っています。

(
 fnc(newCTes ,
  (
   ctx = context , // コンテキストリソース作成(クラスの中身を入れる)
   ctx.foo = @1 ,  // メンバ変数 foo 定義
   fnc(ctx.calc ,  // メンバ関数 calc 定義
    this.foo * this.foo
   ),
   ctx
  )
 ),
 bindres(ctes , newCTes(123)) , // CTes 作成
 ctes.calc // CTes の関数 calc 呼び出し
)

疑似クラスは上記のようなソースになります。
コンテキストリソースを作成してその中にメンバ変数、メンバ関数を定義してコンテキストリソースを返す関数を定義して、それを呼び出すことで疑似クラスのインスタンスを作成して返します。
bindres はリソースIDを変数に代入しますが変数消去時に中身のリソースIDを delres して削除するための let の代わりの関数です。

{
 def(newCTes ,
  =>
  {
   ctx = context , // コンテキストリソース作成(クラスの中身を入れる)
   ctx.foo = @1 ,  // メンバ変数 foo 定義
   fnc(ctx.calc ,  // メンバ関数 calc 定義
    this.foo
   ),
   ctx
  }
 ),

 def(newCTes2 , // CTes をオーバーライド
  =>
  {
   ctx = newCTes(@1) , // CTes を継承(コンテキストリソースの中身を加工する)
   fnc(ctx.calc ,  // メンバ関数 calc オーバーライド
    this.foo * this.foo * this.foo
   ),
   ctx
  }
 ),

 bindres(ctes , newCTes2(123)) , // CTes2 作成
 ctes.calc // CTes の関数 calc 呼び出し
}

上記では newCTes を定義してそれを newCTes2 で継承してメンバ関数 calc をオーバーライドしています。
newCTes で帰ってきたコンテキストリソースの中身を加工しています。
newCTes2 では呼び出し元のコンテキスト内で定義された newCTes にアクセスするために callcnt を使用しています。
関数呼び出し内では変数定義領域(コンテキスト)が切り替わることに注意する必要があります。
ゲームではゲームクラスを定義してそのコンテキストリソース中で疑似クラスを作成して、継承しています。

クラスについては使わないと何もできないかというとそうでもありません。
実際グローバル関数の定義だけで管理プログラムは書けていますので使わなくても問題ありません。
今回のような大きめの単体プログラムや使いまわせる関数をまとめたい場合に使用するとグローバル関数が増えて行かずに機能ごとにまとめられて便利です。

コメント(0) 
共通テーマ:パソコン・インターネット

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。