Subject:#04 supermatch.rb 5月11日 supermatch.rb To: ruby-05-11@e.koeki-u.ac.jp Date: Sun, 13 May 2012 03:16:45 +0900 (JST) 氏名: maple 学籍番号: c111084 クラス: 英語6 選択した番号: 3番 1. 3番 最初の本数をプレイヤーが好きな数に設定できるプログラムを作った。 なおかつ、コンピュータが必勝するものである。 2. #!/usr/koeki/bin/ruby # coding: euc-jp print "1〜3本の範囲でマッチ棒を取ります。最後の1本を取った方の負け!\n" print "マッチ棒の本数を決めます。(ただし、5本以上30本以下とします。)\n" print "何本にしますか? : " match = gets.chomp.to_i while match < 5 || match > 30 print "エラー! 5本以上30以下にしてもう一度やり直して下さい。\n" print "何本にしますか? : " match =gets.chomp.to_i end if match %4 == 1 then elsif match %4 == 2 match -= 1 print "最初にわたしが1本取ります。\n" elsif match %4 == 3 match -= 2 print "最初にわたしが2本取ります。\n" elsif match %4 == 0 match -= 3 print "最初にわたしが3本取ります。\n" end while match > 0 printf("あなたの番: マッチ棒が%d本あります\n", match) print "何本取りますか?(1〜3): " toru = gets.chomp.to_i if toru < 1 || toru > 3 then print "1〜3の範囲で取って下さい。\n" redo end match -= toru if match < 1 then print "最後の1本を取りました。あなたの負けです! また挑戦してね!\n" break end printf("わたしの番: マッチ棒が%d本あります\n", match) com_toru = 3-toru+1 printf("私は%d本取りました。\n", com_toru) match -= com_toru if match < 1 then print "最後の1本を取りました。わたしの負けです! さすがだね!!\n" break end end 3. 1〜3本の範囲でマッチ棒を取ります。最後の1本を取った方の負け! マッチ棒の本数を決めます。(ただし、5本以上30本以下とします。) 何本にしますか? : 3 エラー! 5本以上30以下にしてもう一度やり直して下さい。 何本にしますか? : 33 エラー! 5本以上30以下にしてもう一度やり直して下さい。 何本にしますか? : 26 最初にわたしが1本取ります。 あなたの番: マッチ棒が25本あります 何本取りますか?(1〜3): 3 わたしの番: マッチ棒が22本あります 私は1本取りました。 あなたの番: マッチ棒が21本あります 何本取りますか?(1〜3): 3 わたしの番: マッチ棒が18本あります 私は1本取りました。 あなたの番: マッチ棒が17本あります 何本取りますか?(1〜3): 2 わたしの番: マッチ棒が15本あります 私は2本取りました。 あなたの番: マッチ棒が13本あります 何本取りますか?(1〜3): 2 わたしの番: マッチ棒が11本あります 私は2本取りました。 あなたの番: マッチ棒が9本あります 何本取りますか?(1〜3): 3 わたしの番: マッチ棒が6本あります 私は1本取りました。 あなたの番: マッチ棒が5本あります 何本取りますか?(1〜3): 1 わたしの番: マッチ棒が4本あります 私は3本取りました。 あなたの番: マッチ棒が1本あります 何本取りますか?(1〜3): 1 最後の1本を取りました。あなたの負けです! また挑戦してね! 4. ゲームの説明文を文字列として表すのでprintを使った。 print : 表示する \n" : 改行文字 マッチの本数はプレイヤーが決めるので本数を入力できるように match = gets.chomp.to_i を使う。 gets : 指定された場所から文字列を読みこんでその値を返す chomp : 文字列の末尾が改行文字('\n')である場合にそれを切り取る to_i : 文字列を整数に変換した値に返す while ~ end の制御構造を使って、マッチの本数をプレイヤーが4本以下31 本以上入力した場合のことを考える。 論理演算子を使って、 match < 5 || match > 30 となる。 比較演算子 < : 左辺が右辺より小さいか > : 左辺が右辺より大きいか || : または この場合、エラーとなり、プレイヤーに再入力してもらうために 最後にもう一度、 match = gets.chomp.to_i を使う。 if ~ then ~ elsif ~ end の制御構造を使って、コンピュータが先手となり、 必勝となるように数を調整する。 コンピュータが必勝するには4の倍数に1を足した数の場合のみだけなので その他の場合も勝つようにプログラムする。 マッチの本数が ・4の倍数に1足した数(= 4の倍数で割ると1余る数)のとき match %4 == 1 通常のプログラム通りになる。 ・4の倍数に2足した数(= 4の倍数で割ると2余る数)のとき match %4 == 2 コンピュータが最初に1本取れば、4の倍数に1足した数の場合が成り立つ。 match %4 == 2 match -= 1 ・4の倍数に3足した数(= 4の倍数で割ると4余る数)のとき match %4 == 3 コンピュータが最初に2本取れば、4の倍数に2足した数の場合が成り立つ。 match %4 == 3 match -= 2 ・4の倍数(= 4の倍数で割ると余り0)のとき match %4 == 0 コンピュータが最初に4本取れば、4の倍数の場合が成り立つ。 match %4 == 0 match -= 3 match : マッチの本数 (gets.chomp.to_i) %4 : マッチの本数を4で割った余り == : 左辺と右辺が等しいか (余りは左辺にする) -= : コンピュータが取る本数 while ~ end と if ~ end の制御構造を使う。 まず、プレイヤーが取る本数を決めるので toru = gets.chomp.to_i プレイヤーがマッチの本数を1から3の範囲でとるために toru < 1 || toru > 3 プレイヤーの番でマッチの本数が1本から3本の範囲で残ると ゲームの終了となり、プレイヤーが負けとなる。 match -= toru match < 1 次にコンピュータがマッチを取る本数を決めるが、それはプレイヤーの 前回の本数によって決まる。 コンピュータの本数 = 4 - プレイヤーの前回の本数 com_toru = 3-toru+1 コンピュータの番でマッチの本数が1本から3本の範囲で残ると ゲームの終了となり、コンピュータが負けとなる。 (このプログラムの場合は成立しない。) match -= com_toru match < 1 redo : その回のループを先頭からやり直す break : そこでループの実行を中止しループを終了する 5. コンピュータが必勝するには、両者が取れるマッチの本数の最大本数3に1を 足した数である4の倍数に1を足した数にすればよい。 マッチの本数がどのような場合でも4の倍数に1を足した数になるようにする。 5以上30以下に範囲を設定したのは、マッチの本数が4本以下やマイナスの 値をとらせないようにするためである。本数の上限は適度にした。 6. 広瀬先生のページ 基礎プログラミングI 講義内容 同じクラスの寛野水希、冨樫貴政、長橋愛海と協力した。 7. 今回の課題はかなり難しかった。2日間かけてやっとできたが、 自力では絶対にできない課題であったと思う。 しかし、時間をかけて考え抜く中で1つ1つの意味をある程度、理解できた。