5章:奇跡のスピードで完成 “数当てゲーム”
この章だけで
“数当てゲーム”を完成させます。
こんばんは。
あいさつをいったん変えてみたものの
今まで「こんにちは」でやってきたのだから
それを貫き通した方が良かったのではないか。
そう思い始めたゲンキです。
↑あいさつに葛藤するゲンキ
今回はかなりぶっとんだ章になってしまいます。
というのも
昨日はプログラミングの勉強を
サボらずやったくせに
ブログを書いていないことに
23時くらに気づいてしまい
「もう今日は書かなくていいや」
となってしまったため、
2日分の勉強内容の
アウトプットを書かなければなりません。
前回の文字数の倍以上は
いくんじゃねえかな…。
一応目次
今回の目標
今回の目標は
<数当てゲーム>をつくること。
数当てゲームの内容は以下の通り。
①親は「0」~「9」の数字を使って、4桁の数字を考えます。その際、同じ数字を2個以上使っても構いません。
②子は、その数字を予想して親に提示します。
③親は②で提示された数字を判定し、ヒットとブローの数を子に提示します。
・数字と位置が正しい場合=ヒット
・位置は正しくないが、その数字が含まれている=ブロー
④②~③を繰り返し、子はヒットとブローの結果を参考にして、親が考えた4桁の数字を当てます。
ヌメロンっていうゲームを知っていたら
ほぼそれみたいな感じ。
テレビでもやってたね。
個人的にはオリラジ対決が好き。
今回の章はこれを作り始めてから
作り終えるまでのアウトプット。
この章で
このゲーム作り終えまーす。
なんだか楽しくなってきたぞ~!
ランダムな値の生成 random
このゲームの親はコンピューターになる。
まずはコンピューターに
ランダムな数字を生成してもらわないと
ゲームが始まらない。
import random
そこで登場するのが
randomモジュール。
テキトーな値を
出してくれるらしい。
ただ今回
数字は0~9の間に納めてほしい。
randomモジュール:randint
そんなときは
randintという関数を使うことで
範囲を指定できる。
a = random.randint(0,9)
このままだと
一桁だけになっちゃうから
a1 = random.randint(0,9)
a2 = random.randint(0,9)
a3 = random.randint(0,9)
a4 = random.randint(0,9)
これでおkだけど
これを書くのはダルいな。
リストを使う
上のやつをリストを使って書くと
下の通りになる。
a = [random.randint(0,9), #a[0]の値
random.randint(0,9), #a[1]の値
random.randint(0,9), #a[2]の値
random.randint(0,9)] #a[3]の値
0から始まるのは直感的でない。
注意しよう。
これでランダムな4桁の数字を
生成できるようになった(はず)。
文字を入力する
数字を入力できなかったら
ゲームもクソもない。
だから文字を入力できるようにする。
input関数
b = input('数を入れてね>')
こうすることで
表示される文字の右側に
文字を入力できるようになる。
数字を正しく入力してもらう
4桁でない数字が入力されたり
数字以外のものが入力されたときは
エラーを出すようにしたい。
そのためにいろいろやっていく。
4桁であることのチェック:len関数
Pythonではlen関数をつかうことで
文字列の長さを求めることができる。
if len(b) != 4:
print('4桁の数字を入力してください')
この処理を
4桁の数が入力されるまで
繰り返すようにしたい。
条件が満たされる(4桁の数字の入力)まで
繰り返しを行う時に使うのは while
isok = False
while isok == False:
b = input('数を入力してね')
if len(b) != 4:
print('4桁の数字を入力してください')
else:
isok = True
最終的に isok が False でなくなるので
繰り返しが終わるようにできた。
これでおk。
数字が入力されていることの判断
各桁が数字であることは
各桁の数が0以上9以下であるということ。
それ以外のものが入力されたときに
エラーを出せばいいというわけだ。
if (b[0] < '0') or (b[0] > '9'):
print('数字ではありません')
どちらかでも満たしたらアウトなので
and ではなく or を使う。
あと、入力されたもの(b[0]やb[1])は
文字列であって数字ではないので
比べることができるように
0や9も文字列にしている。
ここ間違えやすいから注意。
上に書いたやつは
1桁分しかできてないから
4桁ぶん書けばok
if (b[0] < '0') or (b[0] > '9'):
print('数字ではありません')
if (b[1] < '0') or (b[1] > '9'):
print('数字ではありません')
elif (b[2] < '0') or (b[2] > '9'):
print('数字ではありません')
elif (b[3] < '0') or (b[3] > '9'):
print('数字ではありません')
これはループ処理で短縮できる。
4桁ぶん繰り返しているだけだから
for i in range(4):でおk。
kazuok = True
for i in range(4):
if (b[i] < '0') or (b[i] > '9'):
print('数字ではありません')
kazuok = False
break
数字を正しく入力してもらおうパートをまとめると
以下の通りになる。
isok = False
while isok == False:
b = input('数を入力してね')
if len(b) != 4:
print('4桁の数字を入力してください')
else:
kazuok = True
for i in range(4):
if (b[i] < '0') or (b[i] > '9'):
print('数字ではありません')
kazuok = False
break
if kazuok: #kazuok = Trueということ(?)
isok = True
ヒットとブロー判定
最後にヒットとブローの判定をする。
ヒットの判定
ヒットの判定は結構単純。
a[0] == b[0] のように
[]の中の数字が同じ時
同じ値であることが言えればいい。
hit = 0
if a[0] == int(b[0]):
hit = hit + 1
これ for 使えばいけるな。
hit = 0
for i in range(4):
if a[i] == int(b[i]):
hit = hit + 1
これでおk。
ブロー判定
ブローは
「位置は正しくないが、その数字が含まれている」状態。
考えるのがちょっとややこしい。
まずは単純なものから考えて
あとから複雑な条件を足していくっ。
↑魚捌く人リスペクト
blow = 1
for i in range(4):
if int(b[0]) == a[i]:
blow = blow + 1
break
ブローを重複して数えないように
breakで止めておくことを忘れずに。
ブローかつヒットをはぶく
ブローかつヒットのやつをはぶくために
ブロー判定のifの条件を変更する。
わかりやすいように
まずはb[0]の判定のみの文を書く。
if (int(b[0]) == a[i])) and (a[i] != int(b[i])) and (a[0] != int(b[0]))
(a[i] != int(b[i])) は
i 番目のときにヒットになったら
ブローにしないようにする。
(a[0] != int(b[0])) は
1桁目のときにヒットになったら
ブローにしないようにする、ということ。
これも4桁ぶん繰り返しているだけなので
頑張れば書き換えることができる。
blow = 0
for j in range(4):
for i in range(4):
if (int(b[j] == a[i])) and (a[i] != int(b[i])) and (a[j] != int(b[j]))
blow = blow + 1
break
ヒットが4つになったら終わり
ヒットが4になったら
当たりという文字を表示させればいい。
ここまでのことを思うと
とても簡単に思える。
if hit == 4:
print('当たり!')
break
ついに完成!
#coding:utf-8
import random
a = [random.randint(0,9), #a[0]の値
random.randint(0,9), #a[1]の値
random.randint(0,9), #a[2]の値
random.randint(0,9)] #a[3]の値
while True:
isok = False
while isok == False:
b = input('数を入力してね')
if len(b) != 4:
print('4桁の数字を入力してください')
else:
kazuok = True
for i in range(4):
if (b[i] < '0') or (b[i] > '9'):
print('数字ではありません')
kazuok = False
break
if kazuok:
isok = True
hit = 0
for i in range(4):
if a[i] == int(b[i]):
hit = hit + 1
blow = 0
for j in range(4):
for i in range(4):
if (int(b[j] == a[i])) and (a[i] != int(b[i])) and (a[j] != int(b[j]))
blow = blow + 1
break
#ヒット数とブロー数を表示
print('ヒット' + str(hit))
print('ブロー' + str(blow))
if hit == 4:
print('当たり!')
break
終わりに
お、終わった…。
ちょっとインデントがずれてたり
色がついてなかったりするかもしれないけれど
自分でもよく頑張ったと思う。
すでに書き始めてから
2時間が経過している。
復習としては
効率の悪いことこの上ない気がする…。
趣味半分と言うことで
自分を納得させることにしよう。
冒頭で
前回の記事の倍以上の文量になるんじゃないかと書いたけど
倍どころじゃなかったわ。
現時点で約4,300字ある。
ぐうの音も出ません。
というわけで
そろそろ終わりにしようと思う。
Twitterを見てくれている人は
気づいているかもしれないけれど
実は今使っている教材は
いったん学習が終わっていて
Progateというやつを使って
今は勉強をしている。
そっちの学習内容を
ブログにまとめるかは
…まだ考え中。
というわけで、この章はおわり。
以上。