0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

YamashitaAdvent Calendar 2024

Day 25

[Python] mathの関数を使ったバトルゲームを作ってみる

Last updated at Posted at 2024-12-22

仕事で math の関数を使い、以下の記事を書きました。
[Python] math : sqrt / pow / ceil / floor / fabs
[Python] math : factorial / log / gcd / degrees / radians
[Python] math : isqrt / prod / comb / perm / fsum

せっかくここまで書いたので、これらの関数を使って、バトルゲームを作ることに。(全部は使わないけど)

要件

  • プレイヤーがモンスターと戦う
  • プレイヤーは数学を駆使して攻撃をする
  • モンスターはsinを使って攻撃をしてくる
  • どんな数字がダメージの計算に使われるかは、ランダムである
  • HPが先に 0 になった方が負け

ゲームの概要

プレイヤーが数学を武器にしてモンスターと戦うバトルゲーム。
プレイヤーは4種類の数学的攻撃を選択し、モンスターにダメージを与える。モンスターも反撃してくる。先に相手のHPを0にした方が勝ち。

ゲームの流れ

  1. 初期化: プレイヤーとモンスターのHPが設定される
  2. プレイヤーのターン:
    • プレイヤーの現在のHPとモンスターのHPが表示される
    • 4種類の攻撃(平方根、階乗、組み合わせ、べき乗)から一つを選択する
    • 選択した攻撃に基づいてダメージが計算され、モンスターのHPが減少
  3. モンスターのターン:
    • モンスターがsin関数に基づいた攻撃を行い、プレイヤーにダメージを与える
  4. 勝敗判定: プレイヤーまたはモンスターのHPが0以下になると、ゲームが終了

各攻撃の詳細

  • 平方根攻撃 (sqrt):
    ランダムな数値の平方根を計算し、その値がダメージになる

  • 階乗攻撃 (factorial):
    ランダムな小さい整数の階乗を計算し、その値がダメージになる

  • 組み合わせ攻撃 (comb):
    ランダムなnkを選び、nCk (n 個から k 個を選ぶ組み合わせの数) を計算

  • べき乗攻撃 (pow):
    ランダムな底と指数を選び、べき乗を計算

  • モンスターの攻撃:
    ランダムな角度(度数法)と防御値を選び、sin(角度) * 防御値を計算

コード

main.py
import math
import random
import time

def math_battle():
    """数学バトルゲーム"""

    player_hp = 50
    monster_hp = 70

    print("\n数学バトル開始!")
    time.sleep(1)

    while player_hp > 0 and monster_hp > 0:
        print(f"\n--- プレイヤーのターン ---")
        print(f"プレイヤーHP: {player_hp}")
        print(f"モンスターHP: {monster_hp}")
        time.sleep(1)

        # プレイヤーの攻撃選択
        print("\n攻撃を選択してください:")
        print("1: 平方根攻撃 (sqrt)")
        print("2: 階乗攻撃 (factorial)")
        print("3: 組み合わせ攻撃 (comb)")
        print("4: べき乗攻撃 (pow)")

        while True:
            try:
                choice = int(input("> "))
                if 1 <= choice <= 4:
                    break
                else:
                    print("無効な入力です。1〜4の数字を入力してください。")
                    time.sleep(1)
            except ValueError:
                print("無効な入力です。数字を入力してください。")
                time.sleep(1)


        # 攻撃の実行
        if choice == 1:  # 平方根攻撃
            base = random.randint(100, 400)
            damage = int(math.sqrt(base))
            print(f"平方根攻撃!√{base} = {damage} のダメージ!")
            time.sleep(1)
            print("豆知識:平方根は、2乗すると元の数になる値のこと。古代バビロニアの時代から研究されているらしい。。")
            time.sleep(1)

        elif choice == 2:  # 階乗攻撃
            num = random.randint(3, 5)
            damage = math.factorial(num)
            print(f"階乗攻撃!{num}! = {damage} のダメージ!")
            time.sleep(1)
            print("豆知識:階乗は、1からその数までのすべての整数を掛け合わせたもの。順列や組み合わせの計算でよく使われるとか。。")
            time.sleep(1)

        elif choice == 3:  # 組み合わせ攻撃
            n = random.randint(5, 10)
            k = random.randint(1, min(n, 4))  # kはnを超えないようにする
            damage = math.comb(n, k)
            print(f"組み合わせ攻撃!comb({n}, {k}) = {damage} のダメージ!")
            time.sleep(1)
            print(f"豆知識:{n}個の中から{k}個を選ぶ組み合わせの数は、nCk = n! / (k! * (n-k)!) で計算できる。確率や統計で重要らしい。。")
            time.sleep(1)


        elif choice == 4:  # べき乗攻撃
            base = random.randint(2, 4)
            exponent = random.randint(2, 3)
            damage = int(math.pow(base, exponent))
            print(f"べき乗攻撃!{base}^{exponent} = {damage} のダメージ!")
            time.sleep(1)
            print("豆知識:べき乗は、同じ数を繰り返し掛け合わせる演算。指数法則を理解すると、複雑な計算も簡単にできると言われている。。")
            time.sleep(1)


        monster_hp -= damage

        # モンスターの攻撃
        if monster_hp > 0:
            defense_value = random.randint(10, 30)
            degrees = random.randint(0, 90)
            radians = math.radians(degrees)
            monster_damage = int(math.sin(radians) * defense_value)
            print(f"\nモンスターの攻撃!sin({degrees}°) * {defense_value} = {monster_damage} のダメージ!")
            time.sleep(1)
            player_hp -= monster_damage

    if player_hp <= 0:
        print("\n敗北…")
    else:
        print("\n勝利!")


if __name__ == "__main__":
    math_battle()

実行結果

$ python main.py
数学バトル開始!

--- プレイヤーのターン ---
プレイヤーHP: 50
モンスターHP: 70

攻撃を選択してください:
1: 平方根攻撃 (sqrt)
2: 階乗攻撃 (factorial)
3: 組み合わせ攻撃 (comb)
4: べき乗攻撃 (pow)
> 1
平方根攻撃!√317 = 17 のダメージ!
豆知識:平方根は、2乗すると元の数になる値のこと。古代バビロニアの時代から研究されているらしい。。

モンスターの攻撃!sin(23°) * 18 = 7 のダメージ!
--- プレイヤーのターン ---
プレイヤーHP: 43
モンスターHP: 53

攻撃を選択してください:
1: 平方根攻撃 (sqrt)
2: 階乗攻撃 (factorial)
3: 組み合わせ攻撃 (comb)
4: べき乗攻撃 (pow)
> 2
階乗攻撃!4! = 24 のダメージ!
豆知識:階乗は、1からその数までのすべての整数を掛け合わせたもの。順列や組み合わせの計算でよく使われるとか。。

モンスターの攻撃!sin(67°) * 29 = 26 のダメージ!
--- プレイヤーのターン ---
プレイヤーHP: 17
モンスターHP: 29

攻撃を選択してください:
1: 平方根攻撃 (sqrt)
2: 階乗攻撃 (factorial)
3: 組み合わせ攻撃 (comb)
4: べき乗攻撃 (pow)
> 3
組み合わせ攻撃!comb(7, 2) = 21 のダメージ!
豆知識:7個の中から2個を選ぶ組み合わせの数は、nCk = n! / (k! * (n-k)!) で計算できる。確率や統計で重要らしい。。

モンスターの攻撃!sin(14°) * 23 = 5 のダメージ!
--- プレイヤーのターン ---
プレイヤーHP: 12
モンスターHP: 8

攻撃を選択してください:
1: 平方根攻撃 (sqrt)
2: 階乗攻撃 (factorial)
3: 組み合わせ攻撃 (comb)
4: べき乗攻撃 (pow)
> 4
べき乗攻撃!3^3 = 27 のダメージ!
豆知識:べき乗は、同じ数を繰り返し掛け合わせる演算。指数法則を理解すると、複雑な計算も簡単にできると言われている。。

勝利!

無事に勝利しました!

まとめ

今回は、mathの関数を使って、バトルゲームを作ってみました。
こうやって数学の勉強をするのも楽しいかもしれませんね。

また何か思いついたら、作ってみます:grinning:

0
0
0

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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?