» Rubyのブログ記事

前回のプログラムでは「human_hand = rand(3)+1」でランダムに値を設定していました。
今回はこれをキーボードから設定できるように変更します。前回プログラムに下記のように、
変更してください。

STDOUT.sync = true #追加

goo = 1
par = 2
choki = 3

print("[1:グー、2:パー、3:チョキ]","\n") #追加
print("[1,2,3]の数字を入力","\n") #追加

human_hand = gets  #この部分を変更
computer_hand = rand(3)+1

最初の行にある「STDOUT.sync = true」はRDEで必要なだけで、通常はいりません。
さて、画面左下のコンソールに実行結果が表示されているとおもいますが、何か変です。

引き分け判定を実行
グー判定を実行
パー判定を実行
チョキ判定を実行

は表示されるのですが、何度実行しなおしても、
じゃんけんの結果である、「引き分け、You Win、You Lose」が表示されません。
これは「if文」の条件がどれも成立していないと思われます。
「gets命令」でキーボードから取得した値を「p命令」を使ってコンソールに表示してみます。

STDOUT.sync = true

goo = 1
par = 2
choki = 3

print("[1:グー、2:パー、3:チョキ]","\n")
print("[1,2,3]の数字を入力","\n")

human_hand = gets  
computer_hand = rand(3)+1
p(human_hand) #追加
p(computer_hand) #追加

試しにキーボードから3を入力します。
実行結果

[1:グー、2:パー、3:チョキ]
[1,2,3]の数字を入力
3 #この数字はRDEが表示しています。
"3\n" #この部分がキーボートから入力した値です
1 #ここはコンピューターがランダムに決めた値です。
引き分け判定を実行
グー判定を実行
パー判定を実行
チョキ判定を実行
Complete(0)

この結果を見てみると、「human_hand」には「”3\n”」が代入され、「computer_hand」には「1」が代入されています。
「”3\n”」は「ダブルクォートで囲まれた文字」、「1」は整数。文字と整数を比較していたことになります。
「human_hand」に「”3\n”」(文字)が代入されている状態で条件が成立する「if文」がなかったので、ブログラムが予想した
通りに動かなかったようです。
「gets」と「p」はこちら
rubyには文字を整数に変換する命令があるので、それを使用します。

STDOUT.sync = true

goo = 1
par = 2
choki = 3

print("[1:グー、2:パー、3:チョキ]","\n")
print("[1,2,3]の数字を入力","\n")

human_hand = gets.to_i  #この部分を変更
computer_hand = rand(3)+1
p(human_hand)
p(computer_hand)

これで実行結果が正しく表示されます。
「to_i」についてはこちら

前回のプログラムでは勝敗判定が決定したあとも、それ以降のプログラムが実行されています。
確認するために、前回のプログラムを変更します。
「#」以降の行はコメントとしてRubyは実行しません。

goo = 1
par = 2
choki = 3

human_hand = rand(3)+1 #この部分を変更
computer_hand = rand(3)+1

print("引き分け判定を実行","\n") #追加
if computer_hand == human_hand then
  print("引き分け","\n")
  #exit #追加
end

print("グー判定を実行","\n") #追加
if human_hand == goo then
  if (computer_hand - goo) == 2 then
    print("You Win","\n")
    #exit #追加
  end

  if (computer_hand - goo) == 1 then
    print("You Lose","\n")
    #exit #追加
  end
end

print("パー判定を実行","\n") #追加
if human_hand == par then
  if (computer_hand - par) == -1 then
    print("You Win","\n")
    #exit #追加
  end

  if (computer_hand - par) == 1 then
    print("You Lose","\n")
    #exit #追加
  end
end

print("チョキ判定を実行","\n") #追加
if human_hand == choki then
  if (computer_hand - choki) == -1 then
    print("You Win","\n")
    #exit #追加
  end

  if (computer_hand - choki) == -2 then
    print("You Lose","\n")
    #exit #追加
  end
end

プログラムを実行するとcomputer_handとhuman_handの手が同じで引き分けの判定が表示された後も、
「グー、パー、チョキ判定を実行」という文がすべて表示されると思います。
たとえば「引き分け」の勝敗が決まった後にも、それ以降のプログラムが実行され、
「グー、パー、チョキ判定」をする「if文」が実行されています。「引き分け」で勝敗が決まっているので、
それ以降のプログラム実行は無駄です。
追加した「#exit」の「#」をすべて削除します。これで
「引き分け」の勝敗が決まった後、「グー、パー、チョキ判定を実行」というメッセージは表示されなくなります。
「exit」を実行した段階でプログラムが終了し、それ以降のコードは実行されなくなりました。

「exit」についてはこちらを参照

前回のじゃんけんプログラムは自分の手とコンピューターの手を予め設定していました。
これではゲームになりません。コンピューター側の手はコンピューター自身に考えて決めてもらいたいです。
じゃんけんの手には1、2、3、の数字を設定しています。ではコンピューターに1~3の数字をランダムに
決めてもらいます。Rubyにはランダムな数字を作るための命令が用意されています。
Rubyリファレンスマニュアルの組み込み関数に「rand」なるものがあります。
これによると、

rand([max=0])
 0 以上 max 未満の範囲の整数の乱数を発生します。

とありますので、とりあえず使ってみます。
computer_hand = rand(2)
print(computer_hand)

何回か実行してみたところ0と1の数字が表示されました。
rand()に2を設定したので「0 以上 2 未満の範囲の整数の乱数」
が出来たようです。欲しい数字は1、2、3、なのでrand()に3を
設定します。これで0、1、2、が表示される様になりました。
あとは+1を加算すれば最初に欲しかった数字が
表示できます。
computer_hand = rand(3)+1
print(computer_hand)

前回のプラグラムの「computer_hand =par」の部分を
「computer_hand = rand(3)+1」に書き換えます。
これで今回の目的であるコンピューター自身にじゃんけんの手を考えてもらう事が出来ました。
-Happily Ever After- 終わり。

今回rand()を使用して0、1、2の数字をランダムに作りましたので、ちょっと
グーグルさんに「乱数 アルゴリズム」というキーワードでお尋ねしてみます。
ウィキペディアの擬似乱数というのが検索結果にでました。少しのぞいて見ると

擬似乱数は計算によって作るので、作り方が分かれば理論的には予測可能

とあります。「予測可能」とあるので、コンピューター相手に勝率100%なんてこともあるかもしれませんね。

乱数を作るプログラムは前回紹介した本
C言語によるはじめてのアルゴリズム入門改訂第3版
C言語による最新アルゴリズム事典
にも掲載されています。

最後にもう一つグーグルさんから「メルセンヌ・ツイスタ」という物を教えてもらいました。
なにやら日本人が作成した「最強の乱数発生プログラム」だそうです。
僕には全く分かりません。

「if then else end」 文を使用してじゃんけんプログラムを作ってみます。
if 条件 then
条件成立時の処理
else
条件不成立時の処理
end

「if 条件 then」の条件の部分には比較演算子を使用して左辺と右辺を比較します。

a = 100
b = 100
if a == b then
 print("aとbは等しい")
else
 print("aとbは等しくない")
end

「a == b」の条件が成立しているので、then-else間の「print(“aとbは等しい”)」を実行して終了しています。
条件不成立の場合はthen-elseを飛ばしてelse-end間の処理を実行します。
条件の部分の比較演算子には他に「!=」、「<」、「>」、「<=」、「>=」、などがあります。
条件不成立時の処理が必要ない場合は「else」を省略できます。
では、じゃんけんプログラムを作ってみます。

goo = 1    
par = 2
choki = 3

human_hand = goo
computer_hand =goo

if computer_hand == human_hand then
  print("引き分け","\n")
end

最初に変数「goo」、「par」、「choki」に数字を代入しています。この数字はじゃんけんの勝敗判定に使用します。
次に変数「human_hand」、「computer_hand」です。この変数にはプレイヤーとコンピューターの手を設定します。
「最初はぐー」ということで、「goo(数字の1)」を設定していますが、プログラム完成後には「goo」、「par」、「choki」の好きなものを
入れる事が出来ます。
「if computer_hand == human_hand then」は「if 1 == 1 then」で条件成立しているので、
このプログラムの実行結果は「引き分け」が表示されます。
最後に「goo」、「par」、「choki」の手における勝敗判定を考えます。自分の出した手を中心に考えます。
まずは自分が「goo」を出した時。分かりやすいように代入してある数字を()に入れて各変数の後ろに記述します。
「goo(1)」は「choki(3)」に勝ちます。「goo(1)」は「par(2)」に負けます。ここで最初に代入した数字の出番です。
「par(2)」ー「goo(1)」=1。「choki(3)」ー「goo(1)」=2。自分の手が「goo(1)」の時、「1」なら負け。
「2」なら勝ちになります。これを「if then else end」を使用してコードにしてみます。

if human_hand == goo then
  if (computer_hand - goo) ==  2 then 
     print("You Win","\n") 
  end 

  if (computer_hand - goo) ==  1 then 
    print("You Lose","\n") 
  end
end

まず「if human_hand == goo then」で自分の手が「goo(1)」かどうかを判定しています。
次にコンピューターの手(仮に「par(2)」とします)から「goo(1)」を引きます。結果は「1」になるので、
「if (computer_hand – goo) == 2 then」この条件は成立せず、 「print(“You Win”,”\n”)」は
実行されません。
処理は次の「if (computer_hand – goo) == 1 then」に移ります 「par(2)ー「goo(1)」=1なので、
この条件は成立します。よって、「print(“You Lose”,”\n”)」が表示されます。
このプログラムでは「if」条件文の中に2つの「if文」を入れています。
残りの手、自分が「par」、「choki」を出した時のコードも記載します。

if human_hand == par then
  if (computer_hand - par) == -1 then 
   print("You Win","\n") 
  end 

  if (computer_hand - par) ==  1 then 
   print("You Lose","\n") 
  end
end

if human_hand == choki then
  if (computer_hand - choki) == -1 then 
    print("You Win","\n") 
  end 

  if (computer_hand - choki) ==  -2 then 
    print("You Lose","\n") 
  end
end

かなり不完全なじゃんけんプログラムです。自分の手もコンピュータの手も最初に設定しておかなければなりません。(次回改良します)
しかし5個の変数と「if文」でプログラムらしくはなっていると思います。
じゃんけんの勝敗判定などは「Ruby じゃんけん アルゴリズム」などのキーワードでグーグルに尋ねれば良いと思います。
アルゴリズムについてRubyで書かれた本はあまりみませんので、C言語の本を載せておきます。
C言語によるはじめてのアルゴリズム入門改訂第3版
C言語による最新アルゴリズム事典

プログラミング言語で変数といえば、入れ物です。数字や文字などを入れる入れ物です。
ただしRubyでは少し違います。なにが違うのかは、難しいので今は考えないようにします。
「print」を使用して四則演算をしてみます。
print("10×5=",10*5,"\n","10÷5=",10/5,"\n","10+5=",10+5,"\n","10-5=",10-5,"\n")
実行結果
10×5=50
10÷5=2
10+5=15
10-5=5

この四則演算プログラムは非常に読みにくいです。
読みやすく変更します。
print("10×5=",10*5,"\n")
print("10÷5=",10/5,"\n")
print("10+5=",10+5,"\n")
print("10-5=",10-5,"\n")

実行結果は先ほどと同じになります。

print(値,値,値)命令は値を「,」で区切り与えられた文字や数字、計算式を画面に出力します。
命令に与える値のことを引数(ひきすう)と呼びます。
「”10×5=”」 は「”」で囲んであるので文字として画面にそのまま出力します。
「,」で区切ります。
「10*5」は計算結果を出力します。
「,」で区切ります。
「”\n”」は改行マークです。「’\n’」シングルクォートで囲むと改行されずにそのまま表示されます。

変数を使用して最初のprintを書き換えてみます。
multiplication = "10×5="
m = 10*5
division = "10÷5="
d = 10/5
addition = "10+5="
a = 10+5
subtraction = "10-5="
s = 10-5
print(multiplication,m,"\n",division,d,"\n",addition,a,"\n",subtraction,s,"\n")

変数「multiplication」に”10×5=”を代入、変数「m」に10*5の結果を代入。
少し読みやすくなったと思います。
次のコードを上のprint命令のあとに追加してみます。
total = m+d+a+s
print("合計=",total)

実行結果
10×5=50
10÷5=2
10+5=15
10-5=5
合計=72

「m+d+a+s」の各変数には計算結果が入っているので、
簡単に四則演算の結果を合計できました。

最後にもう少しRubyの変数が単なる入れ物ではない事を見てみます。
a = "hello world"
a.upcase!
print(a)

実行結果
HELLO WORLD
変数「a」に入れた「hello world」が大文字に変換されました。

「upcase」についてはこちらRubyリファレンスマニュアル
リンク先のリファレンスには「upcase」と「upcase!」とがあります。試しに「!」を削除して
「upcase」を使用してください。実行結果が小文字のまま表示されると思います。
リファレンスには、
「upcase は置換後の文字列を生成して返します。 upcase! は self を変更して返します」
とあるので、
a = "hello world"
b = a.upcase
print(a,"\n",b)

「a.upcase」で大文字に変換された”hello world”を変数「b」に代入して、
print命令で表示します。
変数が「upcase」という大文字に変換する命令を持っていました。
Rubyの変数はデータを入れておくだけでなく、データを処理する命令も持っていました。

2024年5月
« 4月    
 1234
567891011
12131415161718
19202122232425
262728293031  

カテゴリー

広告

現在の住まい、将来はVPSへ引越します。 ロリポップの上位版です。

広告

広告

最近のコメント

    広告

    Railsを動かす予定のVPS。無料キャンペーン中。

    広告