0
2

More than 1 year has passed since last update.

【解説付き】Python3でHit&Blowを作ってみた

Posted at

Hit & Blow(ヒット アンド ブロー)とは?

Hit & Blowとは、数当てゲームの1種です。

プレイヤーが提出した数字と秘密の数字を比較し、次の2つの要素を確認します。
ヒット(Hit):数字と位置が正確に一致する桁の数。
ブロー(Blow):数字は正しいが、位置が異なる桁の数。
このhit数とblow数を参考に、プレイヤーが秘密の数を当てます。

例) 秘密の数字が1234で、プレイヤーが1245と言った場合、
・どちらも同じ桁に「1」と「2」があるので、2hit
・どちらの数にも「4」が含まれるので、1blow

Pythonで書いてみる

基本設定:
・randomモジュールなどを使って、4桁の重複しない整数を設定
・HBというクラスを作成し、その中のhit関数とblow関数で、hit数とblow数をカウント。

まず、完成形がこちら

Hit_and_Blow.py
import random    # ランダムモジュールをインポート


class HB:    # ヒットアンドブローのクラス
    def __init__(self, ans, num, times):
        self.ans = str(ans)
        self.num = str(num)
        self.times = times

    def hit(self):    # hit関数で、ヒット数をカウント
        hits = 0
        for i in range(0, 4):
            if self.ans[i] == self.num[i]:
                hits += 1
        print(str(hits) + "H", end="")
        if hits == 4:   # ヒット数が4になったらクリア
            return print(f"\nおめでとうございます! あなたは{self.times}手でクリアしました!")

    def blow(self):    # blow関数でblow数をカウント
        blows = 0
        for l1 in range(0, 4):
            for l2 in range(0, 4):
                if l1 != l2:
                    if self.ans[l1] == self.num[l2]:
                        blows += 1
        return print(str(blows) + "B")


a = random.randint(1, 8)    # 0から始まることがなく、かつ、どの桁も重複しない4桁の整数を生成
ints_list = [str(a)]
one_to_ten = [i for i in range(9)]
del one_to_ten[a]
random.shuffle(one_to_ten)
for i in range(3):
    ints_list.append(str(one_to_ten[i]))
ints = "".join(ints_list)
ints = int(ints)


t = 0    # 無限ループして代入
while True:
    try:
        t += 1
        hb = HB(ints, int(input(">>>")), t)
        hb.hit()
        hb.blow()
    except:
        print("エラー:4桁の数字を正しく入力してください")

もっと詳しく

①ここで、クラスHBの中にhit数とblow数をカウントする関数を入れます。
hit関数の中身は、
まず、for文でself.ansとself.numのi番目がそれぞれ一致したら変数hitsに1を足します。
そして、hitsが4になったらprintでメッセージを出力します。
blow関数の中身は、
hitではないときl1 != l2に、self.ansのl1番目とself.numのl2番目が一致するとき、blowに1を足します。

class HB:    # ヒットアンドブローのクラス
    def __init__(self, ans, num, times):
        self.ans = str(ans)
        self.num = str(num)
        self.times = times

    def hit(self):    # hit関数で、ヒット数をカウント
        hits = 0
        for i in range(0, 4):
            if self.ans[i] == self.num[i]:
                hits += 1
        print(str(hits) + "H", end="")
        if hits == 4:   # ヒット数が4になったらクリア
            return print(f"\nおめでとうございます! あなたは{self.times}手でクリアしました!")

    def blow(self):    # blow関数でblow数をカウント
        blows = 0
        for l1 in range(0, 4):
            for l2 in range(0, 4):
                if l1 != l2:
                    if self.ans[l1] == self.num[l2]:
                        blows += 1
        return print(str(blows) + "B")

②ここで、桁が重複しない4桁の整数を生成します。
aに、1~8までも乱数を代入し、リストints_listの最初の数字に設定します。
one_to_tenリストに、1~9までの数を1つずつ入れ、重複しないようにaを削除します。
one_to_tenをシャッフルし、for文で、one_to_tenリストの最初の3つをints_listに追加します。
次に、joinを使って、ints_listをintsに代入します。
こうすることにより、変数intsに、桁が重複しない4桁の整数が代入されます。

a = random.randint(1, 8)
ints_list = [str(a)]
one_to_ten = [i for i in range(9)]
del one_to_ten[a]
random.shuffle(one_to_ten)
for i in range(3):
    ints_list.append(str(one_to_ten[i]))
ints = "".join(ints_list)
ints = int(ints)

③最後に、クラスHBに必要な変数を代入します。
エラーが発生したらもう一度実行します。

t = 0    # 無限ループして代入
while True:
    try:
        t += 1
        hb = HB(ints, int(input(">>>")), t)
        hb.hit()
        hb.blow()
    except:
        print("エラー:4桁の数字を正しく入力してください")

実行結果

pycharmで実行

C:\Users\****\OneDrive\ドキュメント\****\****\venv\Scripts\python.exe C:\Users\****\OneDrive\ドキュメント\****\****\_PyCharm\Code9_Hit&Blow.py 
>>>1234
2H0B
>>>5634
1H1B
>>>1437
2H1B
>>>1834
2H0B
>>>1536
2H1B
>>>1936
2H0B
>>>1035
3H0B
>>>1036
2H0B
>>>1735
4H
おめでとうございます! あなたは9手でクリアしました!
0
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2