第5回 基礎プログラミング II レポート課題 氏名:川島哲 学籍番号:c1090489 語学クラス:英語3 コース(系):政策マネ 1-1 川島哲 ↓ Kawashima Satoru ↓ K=0x4B=0d75 a=0x61=0d97 w=0x77=0d119 a=0x61=0d97 s=0x73=0d115 h=0x68=0d104 i=0x69=0d105 m=0x6D=0d109 a=0x61=0d97 S=0x53=0d83 a=0x61=0d97 t=0x74=0d116 o=0x6F=0d111 r=0x72=0d114 u=0x75=0d117 上記の16進数を計算していく。 K(4B)+a(61)ならばBは”11”なのでそこに1を足し12=cとなる、更に6+4は10でaとなる つまりK+a=0xACということになる。 このように残りのw,a,s,h・・・を0xACに足していく。 (w) 0xAC+0x77=0x123 (a-1)0x123+0x61=0x184 (s) 0x184+0x73=0x1F7 (h) 0x1F7+0x68=0x25F (i) 0x25F+0x69=0x2C8 (m) 0x2C8+0x6D=0x335 (a-2)0x335+0x61=0x396 (S) 0x396+0x53=0x3E9 (a-3)0x3E9+0x61=0x44A (t) 0x44A+0x74=0x4BE (o) 0x4BE+0x6F=0x52D (r) 0x52D+0x72=0x59F (u) 0x59F+0x75=0x614 全て足した結果0x614となった。 これを10進数に直すと 6*16^2=6*256 =1536 1*16=16 4*16^0=4 1536+16+4=1556 0d1556となる これを16で割った場合 16)1556・・・4 97・・・1 96・・・6 となり余りを下から繋げると614となり16進数時と同じ数値になる 次にASCIIコードを10進数にして計算する。 75+97+119+97+115+104+105+109+97 809 809+83+97+116+111+114+117 1556 10進数における合計は0d1556 同じく16で割った場合 16)1556・・・4 97・・・1 96・・・6 となり余りを下から繋げると614となり16進数時と同じ数値になる 0x614=0d1556 参考) ASCIIコード IT用語辞典 http://e-words.jp/p/r-ascii.html 2進数と16進数の計算: http://www.geocities.co.jp/SiliconValley-SanJose/7769/hard/keisan.html )1-2 学校に行くまでの過程 Def moring(okiru) For 0 ..wakeup.length Print(“眠い\n”) end end def bus(ride) #バスに乗る end print(“外に出よう”) while day <2 printf(“明日は休みだ") B。 プログラム問題A a, 欲しいソフトが沢山ある…でも予算内でしか買えない…そんなときにソフトの組 み合わせを考えるプログラム。 b.プログラム名:def_combination.rb #!/usr/koeki/bin/ruby def factorial(m) if m == 1 #mに1が入力された時の動作 return 1 #1なら1を返す else m * factorial(m-1) #1以外の場合の計算 end end def hard(f,g) #組み合わせの関数 if f == g return 1 elsif f < g #エラー文、予算内で買えるゲームが多かった場合 print("入力エラー、さっさとゲーム屋行け\n") exit else factorial(f)/factorial(g)/factorial(f-g) #組み合わせを弾きだす end end STDERR.print("遊びたいゲームは何本ありますか?:") soft = gets.chomp.to_i STDERR.print("現在の予算内で何本買えますか?:") buy = gets.chomp.to_i printf("現在遊びたい%d本のゲームを予算内で買える%d本分買おうとすると%d通りの組み合わせがあります。\n",soft,buy,hard(soft,buy)) c. 講義ページと2009年度受講者のレポート講評のページを参考に組み上げた。 d.実行結果 pan{c109048}% ./def_combination.rb [~/Ruby] 遊びたいゲームは何本ありますか?:10 現在の予算内で何本買えますか?:4 現在遊びたい10本のゲームを予算内で買える4本分買おうとすると210通りの組み合わせがあります。 (入力エラー文) pan{c109048}% ./def_combination.rb [~/Ruby] 遊びたいゲームは何本ありますか?:3 現在の予算内で何本買えますか?:5 入力エラー、さっさとゲーム屋行け e.考察 組み合わせがあっているかを計算する。 組み合わせ(nCr)はn!/r!(n-r)!で表せる。 10C4 10!/4!(10ー4)! bc-lで計算 pan{c109048}% bc -l [~/Ruby] 10*9*8*7*6*5*4*3*2*1/4*3*2*1*6*5*4*3*2*1 3919104000.00000000000000000000 異常な数値を示す、友人の助言でカッコに括ってみる 10*9*8*7*6*5*4*3*2*1/(4*3*2*1*6*5*4*3*2*1) 210.00000000000000000000 計算結果があっていることが確認された。 このプログラムの難点は人によっては組み合わせなんてどうでもいいということ である。 参考) 基礎プログラミングII第7回: /神田直弥 http://roy/~naoya/rubyII/7.html 基礎プログラミングII /2009年受講者 http://roy/~madoka/2009/r2/05/rpt/c108170.txt 階乗・順列・組み合わせ /K・N・I・F・E http://www.geocities.co.jp/Playtown-Toys/2593/JavaScript/fact.html B. a. スーパーファミコン用ソフト「ファイナルファンタジー5」においてショップで 品物を購入する際いくらかかるかを確かめるプログラム 注:ギルは通貨 b.プログラム名:two_methods.rb #!/usr/koeki/bin/ruby def shop(hi) #ハイポーションを計算する if 20 < hi #20個以上で20%OFF 300*hi*0.8 else 300*hi #20個以下なら普通通り end end def mise(pol) #ポーションを計算 pol*40 end def shop2(fe) #フェニックスの尾を計算 1000*fe end def shop3(sin) #金の針を計算 150*sin end def shop4(poi) #毒消しを計算 30*poi end print("ハイポーション:300ギル\n") #値段表一覧 print("ポーション :40ギル\n") print("フェニックスの尾:1000ギル\n") print("金の針:150ギル\n") print("毒消し:30ギル\n") print("ハイポーションは20個で二割り引きだ。\n") STDERR.print("ハイポーションをいくつ買う?\n") hp = gets.chomp.to_i STDERR.print("ポーションをいくつ買う?\n") hp2 = gets.chomp.to_i STDERR.print("フェニックスの尾をいくつ買う?\n") ph = gets.chomp.to_i STDERR.print("金の針をいくつ買う?\n") go = gets.chomp.to_i STDERR.print("毒消しをいくつ買う?\n") ps = gets.chomp.to_i #printf("%d",shop(hp),) #ポーションの値段デバッグ用 total = shop(hp) + mise(hp2) + shop2(ph) + shop3(go) + shop4(ps) printf("合計%dギルだ。毎度ありー\n",total) #結果表示 c. 講義ページのホタルの数と収穫量のプログラムを参考にして作成 d 実行画面 pan{c109048}% ./two_mthods.rb [~/Ruby] ハイポーション:300ギル ポーション :40ギル フェニックスの尾:1000ギル 金の針:150ギル 毒消し:30ギル ハイポーションは20個で二割り引きだ。 ハイポーションをいくつ買う? 30 ポーションをいくつ買う? 20 フェニックスの尾をいくつ買う? 10 金の針をいくつ買う? 18 毒消しをいくつ買う? 5 合計20850ギルだ。毎度ありー ハイポーション購入数20個未満の場合 pan{c109048}% ./two_mthods.rb [~/Ruby] ハイポーション:300ギル ポーション :40ギル フェニックスの尾:1000ギル 金の針:150ギル 毒消し:30ギル ハイポーションは20個で二割り引きだ。 ハイポーションをいくつ買う? 19 ポーションをいくつ買う? 20 フェニックスの尾をいくつ買う? 10 金の針をいくつ買う? 18 毒消しをいくつ買う? 5 合計19350ギルだ。毎度ありー e. 計算を確かめる ハイポーション20個以上の場合 (300*30*0.8)+(40*20)+(1000*10)+(150*18)+(30*5) 20850.0 20未満の場合 (300*19)+(40*20)+(1000*10)+(150*18)+(30*5) 19350 計算は正しいと言える ゲーム中だとそれぞれ99個しか買えないので完全には使えないのが難点だろう 参考) プログラム /西村まどか http://roy/~madoka/2010/r2/prog/def_firefly.rb プログラム問題C<未完成> a. RPGソフト「ファイナルファンタジー5」において、武器「チキンナイフ」を使用した際に与えられるダメージ量と特定の敵に対するダメージと撃破までに掛かるターン数を 算出するシュミレートプログラム。 解説)-1 「ファイナルファンタジー5」はATBというシステムを導入しており行動を開始す るにはATBゲージが貯まらなければ動けない、ATBゲージは時間と共に増加しこれ が貯まり行動の選択肢が出てくることで1ターンという扱いになる。行動を選択 することでゲージは0になりまた時間と共に増加し貯まったら行動…というのが 戦闘の流れである。本プログラムにおけるターン数はプレイヤーが行動し「こうげ き」コマンドを選んだ回数のことを指す 解説)-2 「チキンナイフ」は本作における最強武器で攻撃力は0だが戦闘から「にげる」 コマンドを選び戦闘を回避した場合に攻撃力が +1されていくという武器で最高 で127まで上る。本来の最強武器は攻撃力150だが「チキンナイフ」はダメージ算 出の際に独自の計算式を使用するため「チキンナイフ」が実質的な最強武器となっ ている。 解説)-3 「エクスデス」 エクスデスは本作における最後の敵であり、俗に言うラスボスである。このラス ボスを倒す際に与えられるダメージと掛かるであろうターンを出すのが2つ目と3 つ目のメソッドである。なお、これを撃破した直後に強化されて再び出現するの だが撃破対象が4つになる。 #!/usr/koeki/bin/ruby def atk(st,pow,tg,run,sl) #ダメージを与える際の計算式 #[{レベル×(力+素早さ)÷128}+2]*(武器の攻撃力-対象の防御力) if pow >255 pow = 255 end if st > 127 st = 127 end if tg > 99 tg = 99 end ((tg * (pow + run )/128) + 2) * ( st - sl ) end def exd(st,pow,tg,run) #エクスデスにダメージを与える際の計算式 #[{レベル×(力+素早さ)÷128}+2]*(武器の攻撃力-エクスデスの防御力) if pow >255 #力の値の上限 pow = 255 end if st > 127 #チキンナイフの攻撃力最大値 st = 127 end if #レベルの最大値 tg > 99 tg = 99 end ((tg * (pow + run )/128) + 2) * ( st - 30 ) end def turn(bd) #def exdで計算したダメージから撃破必要ターン数を計算 49001 / bd #49001という数値はエクスデスのHP(体力値) end STDERR.print("使用者のレベルを入力してください:") lv = gets.chomp.to_i STDERR.print("使用者のちからを入力してください:") cd = gets.chomp.to_i STDERR.print("逃げた回数を入力してください:") esc = gets.chomp.to_i STDERR.print("素早さを入力してください:") spd = gets.chomp.to_i STDERR.print("攻撃対象の防御力をいれてください:") grd = gets.chomp.to_i print("\n\n") if atk(esc,cd,lv,spd,grd) > 9999 #最大で与えられるダメージは9999までなのでそれ以上の場合の表示文 print("ダメージは最大の9999ダメージです。\n") elsif atk(esc,cd,lv,spd,grd) <= 0 #ダメージの最低値が0なので0未満の場合を0に直す print("ダメージは与えられません\n") else printf("ダメージは%dです\n",atk(esc,cd,lv,spd,grd)) end if exd(esc,cd,lv,spd) > 9999 #エクスデスに対するダメージが9999以上だっ た場合の文 print("またエクスデスを倒そうとした場合与えるダメージは9999で、\n撃破に は最低5ターンかかります\n")) elsif exd(esc,cd,lv,spd) < 0 #エクスデスに対してのダメージが0だった場合 print("エクスデスにはダメージを与えられません\n") else printf("またエクスデスを倒そうとした場合与えるダメージは%dで、\n撃破には最低%dターンかかります\n",exd(esc,cd,lv,spd),turn(exd(esc,cd,lv,spd))) end c. 講義中にダウンロードした農薬とホタルのプログラムを元にゲーム攻略サイト 等から数値や計算式をいれて改変した。 d.実行結果 )普通の数値の場合 pan{c109048}% ./def_sim.rb [~/Ruby] 使用者のレベルを入力してください:32 使用者のちからを入力してください:34 逃げた回数を入力してください:54 素早さを入力してください:12 攻撃対象の防御力をいれてください:10 ダメージは572です またエクスデスを倒そうとした場合与えるダメージは312で、 撃破には最低157ターンかかります )値が9999以上(適当に入力)だった場合 pan{c109048}% ./def_sim.rb [~/Ruby] 使用者のレベルを入力してください:100 使用者のちからを入力してください:400 逃げた回数を入力してください:1000 素早さを入力してください:4543 攻撃対象の防御力をいれてください:42 ダメージは最大の9999ダメージです。 またエクスデスを倒そうとした場合与えるダメージは9999で、 撃破には最低5ターンかかります )値が0以下だった場合 pan{c109048}% ./def_sim.rb [~/Ruby] 使用者のレベルを入力してください:-1 使用者のちからを入力してください:-45 逃げた回数を入力してください:-54 素早さを入力してください:-77 攻撃対象の防御力をいれてください:1000 ダメージは与えられません エクスデスにはダメージを与えられません e.考察 計算が正しいか検証 )値が9999以上(適当に入力)だった場合 pan{c109048}% bc -l [~/Ruby] ((32*(34+12)/128)+2)*(54-10) 594.00000000000000000000 計算結果が全く違うものになっている。 数値のメソッドが間違っているのか検証するために数値を入れ替えてみたが実行結 果の数値に当てはまるものは出てこなかった。 結局原因が分からず途中で挫折してしまった。 しかしゲームのダメージ算出プログラムが作れると分かったのは収穫である。 参考) プログラム /西村まどか http://roy/~madoka/2010/r2/prog/def_firefly.rb チキンナイフとは ニコニコ大百科 http://dic.nicovideo.jp/a/%E3%83%81%E3%82%AD%E3%83%B3%E3%83%8A%E3%82%A4%E3%83%95 AWS FF5 ボスモンスターその2 http://aws-ff.com/ff5/ff5_bossdate2.html 感想) スイッチを押すと手が出てきて自分でスイッチを切ってしまうというおもちゃが あった作動するとそのスイッチまで手が伸びるように設定されている 共同学習者 田村周 遠藤太朗