見出し画像

Pythonでpopタイピングのスコアを計算するツールを作ろう

さて、今回はちょっと数学系から離れます。
皆さんはpopタイピングというタイピングゲームをご存じでしょうか?やったことない方はとりあえず下のリンクからやってみましょう!

さて、このゲームには称号なるものがあります。その中には777粒ピッタリと7777粒ピッタリというものが。調べれば攻略法なんぞ簡単にでてきますが、今回は遊びで10000ピッタリを見てみたい!などという方の望みをかなえるプログラム、つまりスコアとして出したい粒を指定すればそのやり方を出してくれるプログラムを作っていきます。


スコア計算

このタイピングのスコアの計算の法則は次のようになります。

【スコアの上がり方】
・1打ごとに召喚Lvの数だけポップコーンが出現
 (Lv10であれば1打につき10粒出現)
・そのタイプでLvが上がった場合は上がる前のLvで出現
 (Lv10→11に上がったタイプでは10粒出現)
【召喚Lvの上がり方】
・n回連続でタイプすると1タイプにつき右のゲージがn溜まる
 (スタートから3回連続で正しくタイプ→ゲージは1+2+3=6)
・ただし、ミスタイプした場合次のタイプはn=1になる
・どれだけ連続で正しくタイプしてもnの上限は100
・ゲージ>200になると召喚Lvが1上がり、ゲージがリセット
 (ゲージ=200のときは上がらない)

このような感じになります。これをもとにプログラムを組んでいきます。

組み方のイメージ

まずはプログラムをイメージしてみましょう。
それを書き出してみると次のような感じになります。

①まずはノーミスで達成できるかをやってみる
 達成できたら終了、達成できなかったら次の手順へ
②1粒打って1ミス、そこからはノーミスで達成できるかをやる
 達成できたら終了、達成できなかったら次の手順へ
③2粒打って1ミス、そこからはノーミスで達成できるかをやる
 達成できたら(以下略
④3粒打って1ミス、そこからは(以下略
⑤4粒打って1ミス、そこからは(以下略
⑥5粒打って(以下略
⑦6粒打っ(以下略
etc……

やっていることは単純なので、プログラムも割と単純になります。

プログラムコード

今回はいつもと違って単純でわかりやすいです。

###変数の初期化
nowscore = 0
level = 1
xp = 0
xp_speed = 1

###スコアの増え方に基づいてノーミスタイプ
def typing():
    global nowscore,level,xp,xp_speed
    nowscore += level
    xp += xp_speed
    xp_speed += 1
    if xp_speed >= 100:
        xp_speed = 100
    if xp > 200:
        xp -= 200
        level += 1


###説明
print("""
このプログラムは、popタイピングで特定のスコアを出すやりかたを表示するものです。
'pop()'とプロンプトに打つことで実行できます。
なお、繰り返しの数は多いほど正確な値になりますが、その分処理に時間がかかります。
(100回が初期値です)
""")

###制御部分
def pop():
    global nowscore,level,xp,xp_speed
    ###変数設定
    n = 1000
    m = 0
    range_number = 100
    ###入力部分
    try:
        n = int(input("出したいスコアを入力してください>>>"))
    except:
        print("正の数以外の値が入力されたため初期値の1000に設定します")
    try:
        range_number = int(input("繰り返しの数を入力してください>>>"))
    except:
        print("正の数以外の値が入力されたため初期値の100に設定します")

    score = -100
    counts = 0
    ###制御処理
    while counts < range_number:
        nowscore = 0
        level = 1
        xp = 0
        xp_speed = 1
        count = 0
        ###規定値(m)までノーミス
        while count < m:
            typing()
            count += 1
        miss_score = nowscore
        ###ミスタイプ
        xp_speed = 1
        ###今のスコア≧出したいスコアになるまで繰り返す
        while nowscore < n:
            typing()
        score = nowscore
        ###出したいスコアならループを抜ける
        if nowscore == n:
            break
        else:
            m += 1
            counts += 1

    ###出力部分
    if score != n:
        print("""
指定範囲内に%s粒を出すやり方が見つかりませんでした。
繰り返しの数などを変更してもう一度お試しください。
"""% n)
    else:
        if miss_score == 0:
            ###ノーミス時の処理
            print("""
%s粒は、ずっとノーミスで入力すると出せます。
"""% score)
        else:
            print("""
%s粒を出すには、%s粒までノーミスで入力した後1ミスし、そこからまたノーミスで入力してください。
"""%(score,miss_score))

ほぼ上の項のイメージをそのままプログラムにしています。

動作確認

最後に動作確認をします。
まずは手始めに777粒と7777粒でやってみましょう。
ネットで調べてみると777は5粒のとき、7777は19粒の時に1ミスするといけるようです(実際に検証済み)。
これをプログラムに入力してみましょう。

実行結果

ちゃんと出してくれました。一応ほかのスコアでもプレイしつつ検証しましたが完璧だったので大丈夫だと思います。

最後にこの記事の最初でも触れた10000粒を入力してみましょう。

実行結果。100回では足りない場合は1000を入力する。

このプログラムによると、7807粒のタイミングで1ミスすればいいようです。実際にやってみましょう。

召喚Lvは最終的には89。7807と10000で止めるのが地味に大変

10000に限らず、1000ピッタリや11111などのゾロ目でもできるのでぜひやってみてください!

この記事が気に入ったらサポートをしてみませんか?