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

(Microsoft Word - java\221n\221\242\203\214\203|\201[\203g.doc)

N/A
N/A
Protected

Academic year: 2021

シェア "(Microsoft Word - java\221n\221\242\203\214\203|\201[\203g.doc)"

Copied!
12
0
0

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

全文

(1)

創造プログラミング演習報告書

( Java™言語 )

(2)

1 プログラムの内容

カジノなどで有名な「ブラックジャック」のトランプゲームを作った。チップを賭けたりする機

能はなく、本当にゲームの基本的な部分しかないが、そこそこ遊べるものになったと思う。

「ブラ

ックジャック」のゲームの性質上、自分は自分の意志で自由にカードを処理できるが、相手は決め

られたルールに従ってカードを処理するので、相手の思考プログラムというのが必要ない分、プロ

グラムは簡単なものになった。今回作ったプログラムに採用した「ブラックジャック」の基本ルー

ルを以下に示す。なおこのルールは、現在通用している一般的なルールと若干異なる。

2 インターフェース設計

ここでは図を用いて説明する。このアプレットは図 1 のような画面の上で操作が行われる。上下

のカードのうち、上側(裏面が赤)の方は親を示し、下側(裏面が青)の方はプレイヤーを示す。ユー

ザが操作する部分は、hit と stand のボタン 2 つのみであり、それぞれ状況に応じて押せなくなっ

たり、名前が変わったりする(図 2、図 3)。このボタンの下には、現在のカードの値の合計が表示さ

れている。

また、勝敗が決定されると、ダイアログボックスが表示される(図 4)。ダイアログボックスに表

示するテキストは、勝敗とその状況に応じて、7 種類用意されている。

「ブラックジャック」は、親(ディーラー)との間で 1 対 1 の勝負を行う。プレイヤーの目標は、手持ちのカードの 値の合計を 21 に近づけ、その数字が親より 21 に近づくことである。カードの値は、2~10 ではその数字通りの値で あり、K,Q,J は 10 と数える。A は 1 か 11 のどちらかを自由に選ぶことができる。 親はカードを全員に 2 枚ずつ配る。親の 2 枚のカードのうちの 1 枚は見ることができ、もう 1 枚のカードは伏せら れている。この時点でプレイヤーの手札が J と A の組み合わせならば、自動的にプレイヤーの勝ちとなる(BLACK JACK という)。 次にプレイヤーは hit(カードをもう 1 枚引く)または stand(カードを引かずにその時点の値で勝負する)の選択を行 う。プレイヤーは 21 を超えなければ 5 枚表になるまで hit することができる。21 を超えてしまうことを bust と呼び、 直ちにプレイヤーの負けとなる。プレイヤーが stand すると親は伏せてあったカードを開く(この時点で親が BLACK JACK なら親の勝ち)。親は値が 17 以上になるまで hit しなければならず、17 以上になったらその後は hit すること はできない。ただし 5 枚表になった時点で hit はできなくなる。親が hit できなくなった時点で、親とプレイヤーの値 を比べ勝敗を決める。また、親が 21 を超えた場合にはプレイヤーの勝ちとなり、プレイヤーと親が同じ値の場合には 引き分けとなる。

(3)

図 1 アプレットの主な画面 図 2 hit と stand のボタンの変化(1)

(4)

3 プログラムの処理概要(フローチャート)

No

Yes

Yes

No

No Yes(hit)

Yes(stand)

Yes

No

No

Yes

Yes

No

No

start

各変数の初期化 相手側に 1 枚,自分側に 2 枚のカード を表で表示し、他を裏で表示する。 ボタンが押された 自分側のカードをさら に 1 枚表にする 5 枚表になった 相手のカードを 1 枚 表にする 21 を超えた BLACK JACK になった 21 を超えた 16 を超えた 勝敗を判定する NewGame が押された 初期化が必要な 変数の初期化

(5)

4 プログラムリスト

//--- // プログラミング III 創造プログラミング演習

// ~ Black Jack (Java version) ~ // 3I 4 番 大上 雅史 // // ++++++更新履歴++++++++++++++++++++ // 2005.02.02 ほぼ完成 // 02.04 エースの処理を改良 // 02.05 カードの gif 画像を変更 //--- import java.awt.*; import java.awt.event.*; import javax.swing.*;

public class bj extends JApplet implements ActionListener{ int[] ply=new int[5]; // 自分のカード int[] com=new int[5]; // 相手のカード

int ply_n=0; // 自分が開いたカード枚数 int com_n=0; // 相手が開いたカード枚数 int p_sum=0; // 自分の合計 int c_sum=0; // 相手の合計 int p_ace=0; // 自分の手札の「A」のうち、11 として数えている枚数 int c_ace=0; // 相手の手札の「A」のうち、11 として数えている枚数 int x; // 乱数取得の際の変数

int flg=0; // BLACK JACK になったときの使う変数 String fn; // ファイル名

JButton bt[]=new JButton[2]; // hit か stand のボタン JPanel pn[]=new JPanel[2]; // パネル

Icon icb1; // カード裏(相手) Icon icb2; // カード裏(自分)

Icon icc[]=new Icon[13]; // カード表(A,1,2,・・・,K) JLabel lb[]=new JLabel[10]; // 画像用ラベル

JLabel ptxt,ctxt,msglb; // テキスト用ラベル Container c; // コンテナ public void init(){

// コンポーネントの設定

c=getContentPane(); // コンテナの取得 bt[0]=new JButton("hit"); // hit ボタン bt[1]=new JButton("stand"); // stand ボタン pn[0]=new JPanel(); pn[1]=new JPanel(); ptxt=new JLabel(); ctxt=new JLabel(); msglb=new JLabel(); icb1=new ImageIcon(getImage(getDocumentBase(),"back1.gif")); // カード裏(相手) icb2=new ImageIcon(getImage(getDocumentBase(),"back2.gif")); // カード裏(自分) c.setLayout(new BorderLayout()); // ボーダーレイアウト pn[0].setLayout(new GridLayout(2,5)); // グリッドレイアウト 2 行 5 列 pn[1].setLayout(new GridLayout(2,2)); // グリッドレイアウト 2 行 2 列 for(int i=0;i<5;i++){ // 相手の表示範囲を初期化 lb[i]=new JLabel(); lb[i].setIcon(icb1); // 相手のカード裏の画像をセット lb[i].setHorizontalTextPosition(JLabel.CENTER); lb[i].setVerticalTextPosition(JLabel.CENTER); ply[i]=0; //ついでに初期化 com[i]=0; //ついでに初期化 } for(int i=5;i<10;i++){ // 自分の表示範囲を初期化

(6)

lb[i]=new JLabel(); lb[i].setIcon(icb2); // 自分のカード裏の画像をセット lb[i].setHorizontalTextPosition(JLabel.CENTER); lb[i].setVerticalTextPosition(JLabel.CENTER); } for(int i=0;i<13;i++){ // カード表の画像の準備 fn="card"+(i)+".gif"; icc[i]=new ImageIcon(getImage(getDocumentBase(),fn)); //0~12 が A~K に対応 } // カードを引く処理【☆】 x=((int)(Math.random()*52981))%13; // 0~12 までの乱数発生(52981 は適当に選んだ大きめの数) lb[0].setIcon(icc[x]); // 選ばれた数字の画像をセット com[0]=x; // 1 枚目に数字をセット if(x==0){ //「A」を引いたとき c_sum+=11; // 11 とする。 c_ace++; // 11 としている「A」が 1 枚増えた。 }else if(x>=10){ //「J,Q,K」を引いたとき c_sum+=10; // 10 とする。 }else{ // それ以外を引いたとき c_sum+=(x+1); // そのまま }

if(c_ace>=1 && c_sum>21){ // 11 としている「A」が 1 枚以上あって 21 を超えていたら c_sum-=10; // その「A」を 1 と数える c_ace--; // 11 としている「A」が 1 枚減った。 } com_n++; // 引いたカードが増えた // カードを引く処理(【☆】と同様なのでコメント省略) x=((int)(Math.random()*52981))%13; lb[5].setIcon(icc[x]); ply[0]=x; if(x==0){ p_sum+=11; p_ace++; }else if(x>=10){ p_sum+=10; }else{ p_sum+=(x+1); }

if(p_ace>=1 && p_sum>21){ p_sum-=10; p_ace--; } ply_n++; // カードを引く処理(【☆】と同様なのでコメント省略) x=((int)(Math.random()*52981))%13; lb[6].setIcon(icc[x]); ply[1]=x; if(x==0){ p_sum+=11; p_ace++; }else if(x>=10){ p_sum+=10; }else{ p_sum+=(x+1); }

if(p_ace>=1 && p_sum>21){ p_sum-=10; p_ace--; }

(7)

for(int i=0;i<lb.length;i++){ pn[0].add(lb[i]); // パネルにラベル追加 } pn[1].add(bt[0]); // パネルにボタン追加 pn[1].add(bt[1]); // パネルにボタン追加 ptxt.setText("Player : "+(p_sum)); // 自分の合計表示 ctxt.setText("Computer : "+(c_sum)); // 相手の合計表示 msglb.setText("~Black Jack~\n"); // タイトル表示 msglb.setFont(new Font("Dialog",Font.BOLD,20)); // フォント設定 pn[1].add(ptxt); // パネルにラベル追加 pn[1].add(ctxt); // パネルにラベル追加 // コンテナに追加 c.add(msglb,"North"); c.add(pn[0],"Center"); c.add(pn[1],"South"); bt[0].addActionListener(this); // リスナの登録 bt[1].addActionListener(this); // リスナの登録 // 自分が BLACK JACK になったときの処理

if((ply[0]==0 && ply[1]==10) || (ply[1]==0 && ply[0]==10)){ Dlg(6);

}else if(p_sum==21){ // ちょうど 21 なら bt[0].setEnabled(false); // hit を押せなくする bt[1].setText("Computer's cards open"); // stand ボタンのラベル変更 }

}

public void actionPerformed(ActionEvent e){

String bname=e.getActionCommand(); // 押されたボタンのテキスト取得 if(bname=="hit"){ // hit で if(ply_n<5){ // 5 枚未満なら // カードを引く処理(【☆】と同様なのでコメント省略) x=(int)(Math.random()*52981)%13; lb[ply_n+5].setIcon(icc[x]); ply[ply_n]=x; if(x==0){ p_sum+=11; p_ace++; }else if(x>=10){ p_sum+=10; }else{ p_sum+=(x+1); }

if(p_ace>=1 && p_sum>21){ p_sum-=10; p_ace--; } ply_n++; ptxt.setText("Player : "+(p_sum)); // 合計表示 if(ply_n==5){ // 5 枚に達したら bt[0].setEnabled(false); // hit を押せなくする

bt[1].setText("Computer's cards open"); // stand ボタンのラベル変更 }

if(p_sum>21){ // 合計 22 以上なら Dlg(1); // ダイアログ表示 }else if(p_sum==21){ // ちょうど 21 なら

bt[0].setEnabled(false); // hit を押せなくする

bt[1].setText("Computer's cards open"); //stand ボタンのラベル変更 VictoryOrDefeat(); // 勝敗判定

(8)

} }

}

if(bname=="stand"){ // stand なら bt[0].setEnabled(false); // hit を押せなくする bt[1].setText("Computer's cards open"); // stand ボタンのラベル変更 VictoryOrDefeat(); // 勝敗判定

}

if(bname=="Computer's cards open"){

if(com_n<5){ // 相手が 5 枚未満 // カードを引く処理(【☆】と同様なのでコメント省略) x=(int)(Math.random()*52981)%13; lb[com_n].setIcon(icc[x]); com[com_n]=x; com_n++; if(com_n==2){ // 相手の BLACK JACK の処理

if((com[0]==0 && com[1]==10) || (com[1]==0 && com[0]==10)){ Dlg(7); // ダイアログ表示 flg=1; // 相手が BLACK JACK になったことをあらわす } } if(x==0){ c_sum+=11; c_ace++; }else if(x>=10){ c_sum+=10; }else{ c_sum+=(x+1); }

if(c_ace>=1 && c_sum>21){ c_sum-=10; c_ace--; } ctxt.setText("Computer : "+(c_sum)); // 合計表示 if(c_sum>21){ // 相手が 22 以上なら Dlg(2); // ダイアログ表示

}else if(flg==0){ // BLACK JACK 以外でちょうど 21 なら VictoryOrDefeat(); // 勝敗判定 } } } if(bname=="NewGame"){ // NewGame なら NewGame(); // 初期化処理 } } //----勝敗判定メソッド--- void VictoryOrDefeat(){ if(c_sum>16 || com_n==5){ // 相手が 17 以上か 5 枚なら勝敗を決める if(c_sum>p_sum){ Dlg(3); }else if(c_sum<p_sum){ Dlg(4); }else if(c_sum==p_sum){ Dlg(5); } } } //----ダイアログ表示メソッド--- void Dlg(int cp){

(9)

int type=JOptionPane.WARNING_MESSAGE; c=getContentPane();

if(cp==1){

JOptionPane.showMessageDialog(c,"BUST!! Player lost.","Game Information",type); }else if(cp==2){

JOptionPane.showMessageDialog(c,"Computer BUST. Player won!!","Game Information",type); }else if(cp==3){

JOptionPane.showMessageDialog(c,"Player lost.","Game Information",type); }else if(cp==4){

JOptionPane.showMessageDialog(c,"Player won!!","Game Information",type); }else if(cp==5){

JOptionPane.showMessageDialog(c,"Draw Game.","Game Information",type); }else if(cp==6){

JOptionPane.showMessageDialog(c,"BLACK JACK!! Player won!!","Game Information",type); }else if(cp==7){

JOptionPane.showMessageDialog(c,"Computer is BLACK JACK.","Game Information",type); }

bt[0].setEnabled(false); // hit を押せなくする bt[1].setEnabled(true); // stand を押せるようにする bt[1].setText("NewGame"); // stand を NewGame に変更 } //----再初期化メソッド--- void NewGame(){ // 画像をカード裏にする for(int i=0;i<5;i++){ lb[i].setIcon(icb1); lb[i].setHorizontalTextPosition(JLabel.CENTER); lb[i].setVerticalTextPosition(JLabel.CENTER); ply[i]=0; // ついでに初期化 com[i]=0; // ついでに初期化 } for(int i=5;i<10;i++){ lb[i].setIcon(icb2); lb[i].setHorizontalTextPosition(JLabel.CENTER); lb[i].setVerticalTextPosition(JLabel.CENTER); } // 各変数の初期化 ply_n=0; com_n=0; p_sum=0; c_sum=0; p_ace=0; c_ace=0; flg=0; // カードを引く処理(【☆】と同様なのでコメント省略) x=((int)(Math.random()*52981))%13; lb[0].setIcon(icc[x]); com[0]=x; if(x==0){ c_sum+=11; c_ace++; }else if(x>=10){ c_sum+=10; }else{ c_sum+=(x+1); }

if(c_ace>=1 && c_sum>21){ c_sum-=10; c_ace--; }

(10)

// カードを引く処理(【☆】と同様なのでコメント省略) x=((int)(Math.random()*52981))%13; lb[5].setIcon(icc[x]); ply[0]=x; if(x==0){ p_sum+=11; p_ace++; }else if(x>=10){ p_sum+=10; }else{ p_sum+=(x+1); }

if(p_ace>=1 && p_sum>21){ p_sum-=10; p_ace--; } ply_n++; // カードを引く処理(【☆】と同様なのでコメント省略) x=((int)(Math.random()*52981))%13; lb[6].setIcon(icc[x]); ply[1]=x; if(x==0){ p_sum+=11; p_ace++; }else if(x>=10){ p_sum+=10; }else{ p_sum+=(x+1); }

if(p_ace>=1 && p_sum>21){ p_sum-=10; p_ace--; } ply_n++; // ボタンの初期化 bt[0].setEnabled(true); // ボタンを押せるようにする bt[0].setText("hit"); // ボタン名を hit にする bt[1].setEnabled(true); // ボタンを押せるようにする bt[1].setText("stand"); // ボタン名を stand にする // ラベルにテキストを表示 ptxt.setText("Player : "+(p_sum)); ctxt.setText("Computer : "+(c_sum)); // 自分の BLACK JACK の処理

if((ply[0]==0 && ply[1]==10) || (ply[1]==0 && ply[0]==10)){ Dlg(6);

}else if(p_sum==21){ // ちょうど 21 なら bt[0].setEnabled(false); // hit を押せなくする

bt[1].setText("Computer's cards open"); // stand ボタンのラベル変更 }

} }

(11)

5 実行手順(使い方)

※ゲームのルールは、1 で示したとおりである。

①アプレットを実行すると、図 5 の画面が表示され

る。この画面を初期状態とする。この状態で、hit

もしくは stand のボタンを押すと、処理が進む。た

だし、初期状態で自分が 21 ならば、hit は押せない

ようになっており、

stand は Computer’s cards open

というボタンになっている。また、初期状態で

BLACK JACK を成立させていたら、自分が勝った

ときのメッセージを表示して、NewGame(stand が

変化したボタン)のみ押せる状態になる。(図 6)

②hit を押すと、自分のカードが 1 枚表になる。こ

の時点で自分が 21 を超えてしまったら、自分が負

けたときのメッセージを表示して図 6 のような状態

になる。21 を超えなかったら、自分が 5 枚になる

まで、さらに hit を押すこともできる。

③stand を押すと、stand が Computer’s cards open

に変わり、hit は押せなくなる。Computer’s cards

open を押すと相手のカードが 1 枚表になる(図 7)。

この時点で、相手が BLACK JACK を成立させてい

たら、自分が負けたときのメッセージを表示して図

6 のような状態になる。相手が 16 を超えるか、5 枚

になるまで、Computer’s cards open を押す度に相

手のカードが 1 枚表になる。

④相手が 16 を超えるか、5 枚になったら、その時

点での両者の合計を比べて、21 に近い方を勝ちとし、

メッセージ(例:図 8)を表示して図 6 のような状態

になる。

⑤NewGame が押されると、図 5 の初期状態に戻る。

図 5 初期状態 図 6 NewGame ボタンのみが押せる状態

図 7 Computer’s cards open を押したとき

(12)

6 感想

今回は Java の Swing を用いての創造プログラミングだったが、GUI プログラムが簡単に書け

ることを改めて実感した。夏に C++で書いたプログラムのソースの量を考えると(プログラムの規

模は全然違うが)、Java は簡単だなぁと思う。しかし、Java の GUI インターフェースは、C++よ

りいまいち自由度が低いように感じた。これは、自分で Java のプログラミングの手法をもっと勉

強すれば、解決できる問題だと思うが、自分の今の能力では、複雑なプログラムを書くなら C++

を選ぶなと思った。

BLACK JACK の Java アプレットを作っていて、Appletviewer では表示されるが Internet

Explorer ではアプレットが起動しないという状態に陥った。しかし、この原因はインターネット上

の素材屋から借りた、カードの gif 画像にあったようで、自分でデザインして作った gif 画像にす

べて取り替えたら、Internet Explorer でも表示されるようになった。

図 7    Computer’s cards open  を押したとき

参照

関連したドキュメント

今回、新たな制度ができることをきっかけに、ステークホルダー別に寄せられている声を分析

そのため、ここに原子力安全改革プランを取りまとめたが、現在、各発電所で実施中

学校の PC などにソフトのインストールを禁じていることがある そのため絵本を内蔵した iPad

本判決が不合理だとした事実関係の︱つに原因となった暴行を裏づける診断書ないし患部写真の欠落がある︒この

C :はい。榎本先生、てるちゃんって実践神学を教えていたんだけど、授

・毎回、色々なことを考えて改善していくこめっこスタッフのみなさん本当にありがとうございます。続けていくことに意味

当社は,⾃らが引き起こした今回の⼀連のトラブルについて責任を痛感し深く

 今年は、目標を昨年の参加率を上回る 45%以上と設定し実施 いたしました。2 年続けての勝利ということにはなりませんでし