前言#
Python を手放してから半年が経ちました。中間試験の後、すぐにアルゴリズムの初歩に取り組むことになり、Python の思考を通じてアルゴリズムの学習に非常に顕著な助けがあると感じたので、数時間をかけてこの KillAliens という小さなゲームを書きました。
その中で最も重要な 2 つの部分は、それぞれスコアの持続的な読み書きと演算
とランダムイベントの生成
です。次に、KillAliens という小さなゲーム全体の実装方法とこれら 2 つの部分の実装プロセスについて詳しく説明します。
基づいて
この KillAliens という小さなゲームは、私がずっと前に書いたシンプルな撃殺外星人.py
という 30 行にも満たないシンプルなテキスト表現のゲームからインスパイアを受けています。KillAliens では、スコアシステムが撃殺外星人.py
にはなく、辞書を使用して、キーと値のペアを用いて各種の Alien にそれぞれのスコアを割り当てています。
撃殺外星人.py
は私の Python 学習リポジトリ内で見つけることができます。
補足#
この小さなゲームは 2022 年 5 月 14 日に初めて書かれ、研究の後、2022 年 5 月 19 日にアルゴリズムを修正し、スレッド性能を向上させました。古いコードはリポジトリ内でKillAliens.py
またはKillAliens_NoComment.py
という名前で見つけることができ、新しいコードはリポジトリ内でKillAliens_V2.py
またはKillAliens_NoComment_V2.py
という名前で見つけることができます。
出力プレビュー#
あなたの名前:
Magneto
こんにちは、Magneto。次に、ゲームに登場するAlienとその対応するスコアを紹介します!
ビッグエイリアンを撃破すると10ポイントが得られます
ミドルエイリアンを撃破すると5ポイントが得られます
Aエイリアンを撃破すると2ポイントが得られます
スモールエイリアンを撃破すると1ポイントが得られます
現在のあなたのスコアは0ポイントです
ゲームを終了したい場合は「quit」と入力してください。ゲームを終了するか、他の任意の値を入力してゲームを開始(続行)します。
開始
撃破したいエイリアンの名前を入力してください。撃破に成功すると指定されたスコアが得られます。
名前:ビッグエイリアン
対応スコア:10
名前:ミドルエイリアン
対応スコア:5
名前:Aエイリアン
対応スコア:2
名前:スモールエイリアン
対応スコア:1
注意してください。エイリアンを撃破できない確率があり、その場合ゲームが終了します。また、対応するスコアが高いほど、撃破確率は低くなります。
対応する名前を入力してください:
スモールエイリアン
あなたはスモールエイリアンを選択しました
おめでとうございます、Magneto。撃破に成功し、1ポイントを獲得しました
現在の合計スコア:1ポイント
現在のあなたのスコアは1ポイントです
ゲームを終了したい場合は「quit」と入力してください。ゲームを終了するか、他の任意の値を入力してゲームを開始(続行)します。
続行
撃破したいエイリアンの名前を入力してください。撃破に成功すると指定されたスコアが得られます。
名前:ビッグエイリアン
対応スコア:10
名前:ミドルエイリアン
対応スコア:5
名前:Aエイリアン
対応スコア:2
名前:スモールエイリアン
対応スコア:1
注意してください。エイリアンを撃破できない確率があり、その場合ゲームが終了します。また、対応するスコアが高いほど、撃破確率は低くなります。
対応する名前を入力してください:
スモールエイリアン
あなたはスモールエイリアンを選択しました
おめでとうございます、Magneto。撃破に成功し、1ポイントを獲得しました
現在の合計スコア:2ポイント
現在のあなたのスコアは2ポイントです
ゲームを終了したい場合は「quit」と入力してください。ゲームを終了するか、他の任意の値を入力してゲームを開始(続行)します。
続行
撃破したいエイリアンの名前を入力してください。撃破に成功すると指定されたスコアが得られます。
名前:ビッグエイリアン
対応スコア:10
名前:ミドルエイリアン
対応スコア:5
名前:Aエイリアン
対応スコア:2
名前:スモールエイリアン
対応スコア:1
注意してください。エイリアンを撃破できない確率があり、その場合ゲームが終了します。また、対応するスコアが高いほど、撃破確率は低くなります。
対応する名前を入力してください:
ビッグエイリアン
あなたはビッグエイリアンを選択しました
残念ながら、Magneto、ビッグエイリアンを撃破することに失敗しました。スコアはリセットされ、ゲームを終了します。
プロセスが終了しました。終了コード0
コードプレビュー#
############################
### 日付 2022年5月14日 ###
### 著者 Magneto ###
### 名前 KillAliens <——>
### 環境 Windows 11 ###
### 言語 Python ###
############################
import random
import time
aliens_name_and_mark = {
'ビッグエイリアン': 10,
'ミドルエイリアン': 5,
'Aエイリアン': 2,
'スモールエイリアン': 1
}
Data = {'名前': '', 'スコア': 0}
state_one = ['1', '2', '3', '4', '5']
print("KillAliens小ゲームへようこそ。辞書が初期化されました。\n次に内容を入力してください。\n")
Data['名前'] = input("あなたの名前:\n\t")
print(f"こんにちは \033[94m{Data['名前']}\033[0m。次に、ゲームに登場するエイリアンとその対応するスコアを紹介します!\n")
time.sleep(1)
for name, marks in aliens_name_and_mark.items():
print(f"\t{name}を撃破すると{marks}ポイントが得られます")
time.sleep(1)
while True:
print(f"\n現在のあなたのスコアは\033[35m{Data['スコア']}\033[0mポイントです")
exit_the_game = input("\nゲームを終了したい場合は「quit」と入力してください。ゲームを終了するか、他の任意の値を入力してゲームを開始(続行)します。\n\t")
if exit_the_game == 'quit':
break
print("撃破したいエイリアンの\033[94m名前\033[0mを入力してください。撃破に成功すると指定されたスコアが得られます。")
for name, marks in aliens_name_and_mark.items():
print(f"\t名前:{name}\n\t\t対応スコア:{marks}")
print("注意してください。エイリアンを撃破できない確率があり、その場合ゲームが終了します。また、対応するスコアが高いほど、撃破確率は低くなります。")
time.sleep(1)
ChoiseAliens = input("対応する名前を入力してください:\n\t")
if ChoiseAliens == 'スモールエイリアン':
state_two = ['1', '2', '3', '4', '5', '6', '7', '8']
The_Random = random.choice(state_two)
print("あなたはスモールエイリアンを選択しました")
if The_Random in state_one:
print(f"おめでとうございます、\033[94m{Data['名前']}\033[0m。撃破に成功し、1ポイントを獲得しました")
Data['スコア'] += aliens_name_and_mark['スモールエイリアン']
print(f"現在の合計スコア:\033[35m{Data['スコア']}\033[0mポイント\n\n\n")
else:
print(f"残念ながら\033[94m{Data['名前']}\033[0m、スモールエイリアンを撃破することに失敗しました。スコアはリセットされ、ゲームを終了します。")
break
elif ChoiseAliens == 'Aエイリアン':
state_two = ['1', '2', '3', '6', '7', '8']
The_Random = random.choice(state_two)
print("あなたはAエイリアンを選択しました")
if The_Random in state_one:
print(f"おめでとうございます、\033[94m{Data['名前']}\033[0m。撃破に成功し、2ポイントを獲得しました")
Data['スコア'] += aliens_name_and_mark['Aエイリアン']
print(f"現在の合計スコア:\033[35m{Data['スコア']}\033[0mポイント\n\n\n")
else:
print(f"残念ながら\033[94m{Data['名前']}\033[0m、Aエイリアンを撃破することに失敗しました。スコアはリセットされ、ゲームを終了します。")
break
elif ChoiseAliens == 'ミドルエイリアン':
state_two = ['1', '2', '6', '7', '8']
The_Random = random.choice(state_two)
print("あなたはミドルエイリアンを選択しました")
if The_Random in state_one:
print(f"おめでとうございます、\033[94m{Data['名前']}\033[0m。撃破に成功し、5ポイントを獲得しました")
Data['スコア'] += aliens_name_and_mark['ミドルエイリアン']
print(f"現在の合計スコア:\033[35m{Data['スコア']}\033[0mポイント\n\n\n")
else:
print(f"残念ながら\033[94m{Data['名前']}\033[0m、ミドルエイリアンを撃破することに失敗しました。スコアはリセットされ、ゲームを終了します。")
break
elif ChoiseAliens == 'ビッグエイリアン':
state_two = ['1', '6', '7', '8']
The_Random = random.choice(state_two)
print("あなたはビッグエイリアンを選択しました")
if The_Random in state_one:
print(f"おめでとうございます、\033[94m{Data['名前']}\033[0m。撃破に成功し、10ポイントを獲得しました")
Data['スコア'] += aliens_name_and_mark['ビッグエイリアン']
print(f"現在の合計スコア:\033[35m{Data['スコア']}\033[0mポイント\n\n\n")
else:
print(f"残念ながら\033[94m{Data['名前']}\033[0m、ビッグエイリアンを撃破することに失敗しました。スコアはリセットされ、ゲームを終了します。")
break
else:
print("対応する\033[94m名前\033[0mを入力する必要があります。他の内容ではありません。")
コード分析#
分析説明#
この記事のコード分析は、主に使用されている主要な構文について説明し、各行のコードの役割を具体的に分析することはしません。これは自分で理解する必要があります。
コメント#
Python では、コメントは井号
、つまり#
で識別されます。井号の後の内容はPythonインタプリタ
によって無視されます。この記事に添付されたコードには機能的なコメントはなく、著者のコメントのみです。
モジュールのインポート
コードの9-10行目
では、random
モジュールとtime
モジュールがそれぞれインポートされています。
import random
import time
これらの 2 つのモジュールの役割は、それぞれランダム処理と Python スレッドを指定された時間だけスリープさせることです。
random
の使い方は、Python 学習日記 – 座標移動 #random モジュールで説明されているので、ここでは多くを語りません。
time
の役割は、Python スレッドを指定された時間だけスリープさせることです。この時間は秒単位で、試してみましょう:
name = input("あなたの名前:")
time.sleep(1)
print(f"こんにちは{name}")
これは実行結果です。
あなたの名前:Magneto
こんにちはMagneto
上記のコードの最初の行は、Python スレッドが実行を開始した後、すぐに実行され、名前を尋ねます。ユーザーが入力した値を得た後、2 行目のコードが実行され、Python インタプリタは 2 行目で指示を受け取り、1 秒間スリープするように要求します。Python スレッドが 1 秒間スリープした後、3 行目のコードが続けて実行され、名前が出力されます。
辞書と for 文#
Python では、辞書は{}
の波括弧で囲まれた内容で、2 つの内容、すなわちキー(key)と値(value)を含んでいます。これをキーと値のペアと呼びます。KillAliens では、12-17行目
が辞書であり、18行目
も辞書です。この 2 つの辞書の書き方は異なりますが、どちらも辞書であり、違いはありません。12-17行目
の書き方は美観のためであり、Python ではコードの書き方を規範化することが求められています。これは良い習慣です。
辞書を使用することで、for 文の出力が便利になります。辞書と for 文の出力を試してみましょう:
name_and_money = {
'Mark': '10',
'Tom': '20',
}
for name, money in name_and_money.items():
print(f"{name}は{money}元持っています。")
学習を容易にするために、各キーと値のペアを分けて書きました。実行結果は次のとおりです。
Markは10元持っています。
Tomは20元持っています。
for 文では、厳密な順序が対応しており、name
はキーに、money
は値に対応しています。また、items()
はループ出力のために使用され、辞書にもうこれ以上のキーと値のペアがない場合にループを終了します。
for 文内のprint
では、上記のキーと値の命名を使用できます。つまり、辞書内のキーと値に対応するname
とmoney
を使用して読み取ることができます。
for 文の他にも、辞書は直接読み書きすることもできますが、これは値の読み書きにのみ該当します。
まずは読み取りを見てみましょう。
# まず辞書を定義します
name_and_money = {
'Mark': '10',
'Tom': '20',
}
# 辞書を読み取ります
print(f"彼は{name_and_money['Mark']}元持っています")
print
内で{}
を使用することで特定の領域の内容を読み取り、その中に[]
を追加することで特定の領域内の特定の値を読み取ります。
上記のコードでは、{name_and_money['Mark']}
を使用してname_and_money
辞書内のMark
というキーに対応する値 10 を読み取っています。出力結果を見てみましょう。
彼は10元持っています
次に書き込みを見てみましょう。
# まず辞書を定義します
name_and_money = {
'Mark': 10,
'Tom': 20,
}
# 元の辞書を読み取ります
print(f"彼は元々{name_and_money['Mark']}元持っていました")
# 数字+1、つまり演算を行います
name_and_money['Mark'] += 1
# 新しい辞書を読み取ります
print(f"しかし彼は今{name_and_money['Mark']}元持っています")
出力結果を見てみましょう。
彼は元々10元持っていました
しかし彼は今11元持っています
注意すべき点は、読み取り部分とは異なり、この値には引用符' '
を付けていないことです。引用符を付けると文字列として扱われ、浮動小数点数に変換する必要がありますが、引用符を付けないと純粋な数字として扱われ、直接演算できます。
もちろん、これは演算書き込みであり、直接書き込むこともできます。
# まず辞書を定義します
name_and_boyfriend = {
'Mark': 'Williams',
'Tom': 'Brown',
}
# 元の辞書を読み取ります
print(f"彼の元彼は{name_and_boyfriend['Mark']}です")
# 値を上書きします
name_and_boyfriend['Mark'] = 'Wilson'
# 新しい辞書を読み取ります
print(f"彼の現彼は{name_and_boyfriend['Mark']}です")
ここでは、彼の元彼の例を挙げて、キーに対応する値を直接上書きしました。
彼の元彼はWilliamsです
彼の現彼はWilsonです
ここでの上書きは文字列を使用しており、数字も同様の理屈です。
このように上書きした変更は永続的です。
これが意味することを見てみましょう。
# まず辞書を定義します
name_and_boyfriend = {
'Mark': 'Williams',
'Tom': 'Brown',
}
# for文ループ
for name, boyfriend in name_and_boyfriend.items():
print(f'{name}の元彼は{boyfriend}です')
# 元の辞書を読み取ります
print(f"彼の元彼は{name_and_boyfriend['Mark']}です")
# 値を上書きします
name_and_boyfriend['Mark'] = 'Wilson'
# 新しい辞書を読み取ります
print(f"彼の現彼は{name_and_boyfriend['Mark']}です")
# for文ループ
for name, boyfriend in name_and_boyfriend.items():
print(f'{name}の今の彼は{boyfriend}です')
出力結果は次のとおりです。
Markの元彼はWilliamsです
Tomの元彼はBrownです
彼の元彼はWilliamsです
彼の現彼はWilsonです
Markの今の彼はWilsonです
Tomの今の彼はBrownです
Tom は対照群として、変わっていないことがわかります。彼の彼はずっと Brown でしたが、Mark は変更後、for 文で辞書を読み取ると変更された値が読み取られます。
if-elif-else の進化#
KillAliens では、if 文の進化を使用し、if 文内にネストされた if 文を使用し、in 構文を使用しています。KillAliens から抜粋したコードを使用して、修正後に説明しましょう。
# randomモジュールをインポート
import random
# 対照数字
state_one = ['1', '2', '3', '4', '5']
# 対応する名前を入力します。ここでは以下のif文に対応する名前を書いています
ChoiseAliens = input("対応する名前を入力してください:\n\t")
# if文の判断。ChoiseAliensの値がスモールエイリアンであれば、if文内の内容を実行します
if ChoiseAliens == 'スモールエイリアン':
# 実験群、The_Randomをランダム処理に移行します。
state_two = ['1', '2', '3', '4', '5', '6', '7', '8']
The_Random = random.choice(state_two)
print("あなたはスモールエイリアンを選択しました")
# ネストされたif文、生成されたランダム数が対照群に含まれていれば、次の値を返します
if The_Random in state_one:
print(f"おめでとうございます、撃破に成功し、1ポイントを獲得しました")
# ネストされたif文、子文、生成されたランダム数が対照群に含まれていなければ、次の値を返します
else:
print(f"残念ながら、あなたはスモールエイリアンを撃破することに失敗しました")
# if文、子文の判断。ChoiseAliensの値がAエイリアンであれば、実行します
elif ChoiseAliens == 'Aエイリアン':
# 実験群、The_Randomをランダム処理に移行します。
state_two = ['1', '2', '3', '6', '7', '8']
The_Random = random.choice(state_two)
print("あなたはAエイリアンを選択しました")
# ネストされたif文、生成されたランダム数が対照群に含まれていれば、次の値を返します
if The_Random in state_one:
print(f"おめでとうございます、撃破に成功し、2ポイントを獲得しました")
else:
# ネストされたif文、子文、生成されたランダム数が対照群に含まれていなければ、次の値を返します
print(f"残念ながら、あなたはAエイリアンを撃破することに失敗しました")
# if文、子文の判断。どちらの内容もifとelifに該当しない場合、次の値を返します
else:
print("指定された名前を入力する必要があります。他の内容ではありません。")
異なる結果を示すために、何度も実行しました。
# 最初の実行
対応する名前を入力してください:
スモールエイリアン
あなたはスモールエイリアンを選択しました
おめでとうございます、撃破に成功し、1ポイントを獲得しました
# 2回目の実行
対応する名前を入力してください:
Aエイリアン
あなたはAエイリアンを選択しました
残念ながら、あなたはAエイリアンを撃破することに失敗しました
# 3回目の実行
対応する名前を入力してください:
Magneto
指定された名前ではなく、他の内容を入力する必要があります。
最初の実行では、if
の判断を通過し、ランダムに選ばれた数が対照群state_one
に含まれていたため、成功が返されました。2 回目の実行では、elif
の判断を通過し、ランダムに選ばれた数が対照群state_one
に含まれていなかったため、失敗が返されました。3 回目の実行では、Magneto を入力し、if
とelif
の判断がどちらも一致しなかったため、else
が処理を引き受け、メッセージが返されました。
KillAliens では、このようにして存在しない内容の入力によるプログラムのエラーを効果的に回避しています。
While ループ#
While ループは KillAliens で簡単に使用されており、詳細な説明は行いません。学習するにはPython3 のループ文 | 菜鳥教程を参照してください。
尾声#
KillAliens は私が書いた比較的複雑なプログラムで、シンプルなテキストゲームです。Python を使用して完成させたスコアシステム、判断システム、撃破システムはすべて非常に整っており、比較的シンプルですが、これらのデータはスレッド内にのみ存在し、依然として大きな課題があります。
この記事はMix Spaceによって xLog に同期更新されています。原始リンクはhttps://fmcf.cc/posts/technology/Python_Notes_4です。