0から始める文系男子のプログラミング -Python-

文系の学生がプログラミングを学び、エンジニアの肩書きを持つ前の過程。

5章:奇跡のスピードで完成 “数当てゲーム”

この章だけで

“数当てゲーム”を完成させます。

f:id:study-study-blog:20190327224019p:plain

 

こんばんは。

 

 

あいさつをいったん変えてみたものの

今まで「こんにちは」でやってきたのだから

それを貫き通した方が良かったのではないか。

 

そう思い始めたゲンキです。

 

f:id:study-study-blog:20190327224107p:plain

↑あいさつに葛藤するゲンキ

 

 

 

今回はかなりぶっとんだ章になってしまいます。

 

というのも

昨日はプログラミングの勉強を

サボらずやったくせに

 

ブログを書いていないことに

23時くらに気づいてしまい

 

「もう今日は書かなくていいや」

 

f:id:study-study-blog:20190328010421p:plain

 

となってしまったため、

2日分の勉強内容の

アウトプットを書かなければなりません。

 

 

前回の文字数の倍以上は

いくんじゃねえかな…。

 

 

 

一応目次

 

 

 

今回の目標

 

今回の目標は

<数当てゲーム>をつくること。

 

 

数当てゲームの内容は以下の通り。

 

 

①親は「0」~「9」の数字を使って、4桁の数字を考えます。その際、同じ数字を2個以上使っても構いません。

 

②子は、その数字を予想して親に提示します。

 

③親は②で提示された数字を判定し、ヒットとブローの数を子に提示します。

・数字と位置が正しい場合=ヒット

・位置は正しくないが、その数字が含まれている=ブロー

 

④②~③を繰り返し、子はヒットとブローの結果を参考にして、親が考えた4桁の数字を当てます。

 

 

ヌメロンっていうゲームを知っていたら

ほぼそれみたいな感じ。

 

f:id:study-study-blog:20190328010526p:plain

 

テレビでもやってたね。

個人的にはオリラジ対決が好き。

 

 

 

 

今回の章はこれを作り始めてから

作り終えるまでのアウトプット。

 

 

この章で

このゲーム作り終えまーす。

 

なんだか楽しくなってきたぞ~!

 

f:id:study-study-blog:20190327230334p:plain



 

 

ランダムな値の生成 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から始まるのは直感的でない。

注意しよう。

 

f:id:study-study-blog:20190328010928p:plain



 

これでランダムな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も文字列にしている。

 

ここ間違えやすいから注意。

f:id:study-study-blog:20190328011210p:plain


 

上に書いたやつは

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

 

f:id:study-study-blog:20190328011417p:plain



 

ヒットとブロー判定

最後にヒットとブローの判定をする。

 

ヒットの判定

ヒットの判定は結構単純。

 

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。

 

 

ブロー判定

ブローは

「位置は正しくないが、その数字が含まれている」状態。

 

考えるのがちょっとややこしい。

 

まずは単純なものから考えて

あとから複雑な条件を足していくっ。

 

f:id:study-study-blog:20190328002142j:plain

↑魚捌く人リスペクト

 

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

 

f:id:study-study-blog:20190328012049p:plain



 

 

ヒットが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

 

 

 

終わりに

お、終わった…。

 

f:id:study-study-blog:20190328005537p:plain

 

ちょっとインデントがずれてたり

色がついてなかったりするかもしれないけれど

自分でもよく頑張ったと思う。

 

 

すでに書き始めてから

2時間が経過している。

 

復習としては

効率の悪いことこの上ない気がする…。

f:id:study-study-blog:20190328012217p:plain

f:id:study-study-blog:20190328012238p:plain

 

趣味半分と言うことで

自分を納得させることにしよう。

 

 

 

冒頭で

前回の記事の倍以上の文量になるんじゃないかと書いたけど

 

倍どころじゃなかったわ。

 

 

 

現時点で約4,300字ある。

 

f:id:study-study-blog:20190328005944p:plain


ぐうの音も出ません。

 

 

 

というわけで

そろそろ終わりにしようと思う。

 

 

Twitterを見てくれている人は

気づいているかもしれないけれど

 

実は今使っている教材は

いったん学習が終わっていて

 

Progateというやつを使って

今は勉強をしている。

 

 

そっちの学習内容を

ブログにまとめるかは

 

…まだ考え中。

 

 

 

というわけで、この章はおわり。

 

 

以上。