学籍番号: c111084 クラス: 英語6 ・作成したプログラム #!/usr/koeki/bin/ruby # coding: euc-jp def createCardsArray2() card=Array.new for suit in ["ハート", "スペード", "ダイヤ", "クラブ"] card << [suit, "A"] 2.upto(10) do |n| card << [suit, n.to_s] end for n in ["J", "Q", "K"] card << [suit, n] end end card << ["その他", "JOKER"] card end def shuffle(a) srand 0.upto(a.length-1) do |i| j = rand(a.length) w = a[i] a[i] = a[j] a[j] = w end a end cards = createCardsArray2 cards = shuffle(cards) for c in 0..4 printf("%sの%s\n", cards[c][0], cards[c][1]) end ・プログラムの解説 トランプのカードの表現方法として 1.単純通し番号管理 2.配列によるスートと数字の管理 3.ハッシュによるスートと数字の管理 の3種類があるが、今回は2番を用いる。 カードにはスートと数字があり、この2つの情報を表すことで それぞれのカードが特定できる。 配列を使って、 [スート,数字] と表す。 したがって、この方式を使って配列にカードを格納する場合は、 以下のようなイメージになる。このとき、配列の要素にさらに 配列があることに注意する必要がある。 ------------------------------ | [0] | ["ハート", "A"] ------------------------------ | [1] | ["ハート", "2"] ------------------------------ | [2] | ["ハート", "3"] ------------------------------ ・ ・ ・ ・ ・ ・ ------------------------------ | [51] | ["クラブ", "K"] ------------------------------ | [52] | ["その他", "JOKER"] ------------------------------ def で createCardsArray2 というメソッドを定義し、 card=Array.new で空の配列を作る。 トランプのスートにはハート、スペード、ダイヤ、クラブがあるので 変数 suit を使って for suit in ["ハート", "スペード", "ダイヤ", "クラブ"] とする。 for 配列の各要素を1つ1つ取り出しながらの繰り返す まず、A を表すために card のスートの中に A を追加するので card << [suit, "A"] となる。 << other 元の文字列に別の文字列 other を追加する。 このとき、元の文字列自体が破壊的に変更される。 次に、2〜10までのカードを表すために開始値2、終了値10として 変数 n を使うと、 2.upto(10) do |n| となる。 upto 1ずつ値を増やしていく。 card のスートの中に n(2〜10)を追加し、値を文字列に変換するので card << [suit, n.to_s] となる。 また、変数 n の中に J、Q、K もあるので追加して考えると、 for n in ["J", "Q", "K"] card << [suit, n] となる。 最後に JOKER を別に追加して考えるので card << ["その他", "JOKER"] となる。 そして card 配列を呼び主に返す。 カードを表現したあとでシャッフルする必要がある。 配列の要素をでたらめな順番に並べ替える(シャッフルする)には乱数を 生成する rand メソッドを利用してランダムな位置にある要素と値を 交換していけばよい。 「ランダムな位置」は、配列の要素を超えてはならないので rand メソッドに 上限となる整数を指定する。 def で shuffle というメソッドを定義する。 srand で乱数の種を初期化する。 カードは53枚あるが、0番目から数えると52番目までしかないので 開始値0、終了値52として、変数 i を使うと、 0.upto(a.length-1) do |i| となる。 次に、交換相手をランダムに選ぶために rand を使う。 この場合は、rand が0から自然数-1の範囲の意味を持つので length とする。 rand(自然数) 0〜自然数-1の範囲の整数の擬似乱数を生成する。 srand 乱数の種を初期化する。乱数を利用する前にこれを呼ぶことで 起動するたびに違う乱数が得られる。 length 配列の長さを返す。 カードの位置の交換を説明するために、 ここからは2つのコップにあるジュースを入れ替える例で考える。 a[i] : 1つ目のコップ a[j] : 2つ目のコップ w : 2つのコップとは別の空のコップ として考える。 w = a[i] → 1つ目のコップにあるジュースを空のコップに入れる a[i] = a[j] → 2つ目のコップにあるジュースを1つ目のコップに入れる a[j] = w → 1つ目のコップにあったジュースを2つ目のコップに入れる これで位置の交換ができることになる。 よって、cards は カードの配列を作るメソッド となり、 次の cards は 1つ目の cards をシャッフルしたものである。 最初の5枚だけ表示するために、変数 c として 開始位置..終了位置 を使い、0から始めて5つなので 0..4 となる。 [c] シャッフルしたあとの番数 [0] スート [1] 数字 よって、最初の5枚のカードのスートと数字が表示される。 ・実行結果 pan{c111084}% ./poker1.rb [~/Ruby] ハートの10 ダイヤのJ クラブのJ ダイヤの2 スペードのK pan{c111084}% ./poker1.rb [~/Ruby] スペードの9 ダイヤの4 ダイヤの9 ダイヤの5 クラブの6 pan{c111084}% ./poker1.rb [~/Ruby] ダイヤの10 スペードの3 ダイヤのJ スペードの8 クラブの5 ・参考文献 広瀬雄二. "第10回 実用的なプログラム". 2012年度 基礎プログラミングI. http://roy/~yuuji/2012/pf1/10/index.html,(参照 2012-12-1). 広瀬雄二. "第3回 繰り返し処理". 2012年度 基礎プログラミングII. http://roy/~yuuji/2012/pf2/03/index.html,(参照 2012-12-1). 広瀬雄二. "第7回 文字列処理". 2012年度 基礎プログラミングII. http://roy/~yuuji/2012/pf2/08/index.html,(参照 2012-12-1). 広瀬雄二. "第9回 データ構造と外部表現". 2012年度 基礎プログラミングII. http://roy/~yuuji/2012/pf2/09/index.html,(参照 2012-12-1). ・感想 久しぶりのプログラミングの課題だったので少し手こずった。 試行錯誤を繰りかえして、カードの配列を作るメソッドがハッシュを使う プログラムだとできないことが判明した。 最初の5枚だけを表示することに苦戦したが、何とかできたのでよかった。