
前回の記事
動機
過去にRubyのインストールしてから触っていなかったので、久々にプログラミングしてみました。
プログラミングの練習しないと忘れてしまいますので、簡単なゲームでも作ってみようかと思います。
何を作るか
どんなものを作りたいのかイメージします。
簡単にできるゲームを作りたいと思います。
RubyなのでCUIでできるゲームがいいですね
タイピングゲームなんか作れるんじゃないかな。
プログラミングの設計
まずは簡単にルールを考えてみます。
1.CUI上で指定された文字を入力する。
2.入力された文字が正解か不正解を判定する。
3.一定回数正解したらクリア、一定回数間違えたらゲームオーバーにする。
4.スコアなんかあったらゲームっぽい
5.時間計測もあったらいいな
6.入力する文字は一回正解するごとに1文字づつ足していったほうがいいな
ソースコード
できたものがコチラ
#require宣言
require 'securerandom'
require 'benchmark'
#クラス
#カウンター用クラス
class Counter
def initialize(init=0)
@current = init
end
def inc
@current += 1
end
def dec
@current -= 1
end
def now
@current
end
end
#変数宣言
char_num = 1
OKcount = Counter.new
NGcount = Counter.new
GAMECLEAR_COUNT = 5
GAMEOVER_COUNT = 3
puts "◆◆◆GAME START◆◆◆"
#計測スタート
result = Benchmark.realtime do
loop do
#入力する文字を生成する
puts "次の文字を入力してください"
target_word = SecureRandom.alphanumeric(char_num)
puts target_word
input_word = gets
#正誤判定処理
if target_word == input_word.chomp! then
puts "正解"
OKcount.inc
char_num += 1
else
puts "不正解"
NGcount.inc
#一定回数間違えたらゲームオーバー
if NGcount.now == GAMEOVER_COUNT then
score = (OKcount.now * 10) + (NGcount.now * -30)
puts "xxxGAME OVERxxx score:#{score}"
break
else
#do nothing
end
end
#ゲームクリア処理
if(OKcount.now == GAMECLEAR_COUNT)
score = (OKcount.now * 10) + (NGcount.now * -30)
puts "●●●GAME CLEAR●●● score:#{score}"
break
end
puts "あと#{GAMECLEAR_COUNT - OKcount.now}回でGAME CLEARです"
end
end
#計測終了
puts "プレイ時間: #{result}秒"
感想
いろいろコーディングが雑なところがありますが、期待する動きは達成できたと思います。
入力する文字は標準ライブラリのsecurerandomを使用して、SecureRandom.alphanumericで生成しています。
時間計測は標準ライブラリのbenchmarkを使用しています。
ハマったところ
2点ほどハマったところがありましたので、備忘録として残しておきます。
①指定された文字列とCUIから入力した文字列を比較しようとしたところでうまく比較できなかった。
✔︎NG例
下のコードのように比較した場合、なぜか上手くいかなかった。
理由は、CUIで文字入力後のENTERの文字(改行コード)までinput_wordに入っていた。
if target_word == input_word then
✔︎OK例
.chomp!をつけることでENTERの文字(改行コード)を除いた文字をinput_wordに入れることができた。
if target_word == input_word.chomp! then
2.変数を使ってカウンターを作ろうとしたらwarningが表示された。
Rubyはローカル変数をカウンターのようにインクリメント、デクリメントするとwarningが出力されるようです。
warningを表示できないようにできるようですが、根本的な解決になっていないので、本記事ではクラス変数を用意することで、warningが表示されないようにしました。
✔︎NG例
以下のようにコーディングするとwarningが表示されました。
Rubyは変数というより定数というイメージなのでしょうかね。
一応値は変化するので、warningは無視すれば期待の動作はするようです。
#変数宣言
OKcount = 0
#インクリメント
OKcount += 1
#デクリメント
OKcount -= 1
✔︎OK例
#クラス作成
class Counter
def initialize(init=1)
@current = init
end
def inc
@current += 1
end
def dec
@current -= 1
end
def now
@current
end
end
#インスタンス生成
OKcount = Counter.new
#インクリメント
OKcount.inc
#デクリメント
OKcount.dec
#現在値を取得する
OKcount.now
✔︎出力されたwarning
warning: already initialized constant OKcount
warning: previous definition of OKcount was here
まとめ
意外と初歩的なところでハマったような気がします。
やらないと忘れたり、腕が落ちたりしますので日々鍛錬していかないといけませんね。
でもプログラミングは楽しいですね。
アイデアがあればもっと作っていきたいです。
◆プレイ画面を残しておきます
