はじめに
Pythonから半年ほど離れていましたが、中間試験が終わるとすぐにアルゴリズムの初歩に触れることになります。Python的な考え方がアルゴリズムの学習に非常に役立つと感じたので、数時間かけてこのKillAliensという小さなゲームを書きました。
その中で最も重要な2つの部分は、スコアの継続的な読み書きと計算とランダムイベントの生成です。これから、KillAliensというゲーム全体の実装方法と、この2つの部分の実装プロセスについて詳しく説明します。
このKillAliensという小さなゲームは、ずいぶん前に書いた30行にも満たないシンプルなテキストベースのゲーム击杀外星人.pyから着想を得ています。KillAliensでは、击杀外星人.pyにはなかったスコアリングシステムを追加し、辞書を使って、各エイリアンの種類に対応するスコアをキーと値のペアで管理しています。
击杀外星人.pyは私のPython学習リポジトリで見つけることができます。
補足
この小さなゲームは2022年5月14日に初めて書かれました。研究の結果、2022年5月19日にアルゴリズムを修正し、スレッドのパフォーマンスを向上させました。旧コードはリポジトリ内でKillAliens.pyまたはKillAliens_NoComment.pyという名前で、新コードはKillAliens_V2.pyまたはKillAliens_NoComment_V2.pyという名前です。
出力プレビュー
コードプレビュー
コード分析
分析の説明
この記事のコード分析では、主に使用されている主要な構文について説明します。各行のコードの役割を具体的に分析することはせず、ご自身で理解する必要があります。
コメント
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}")
これが実行結果です
上記のコードの最初の行は、Pythonスレッドの実行開始後、すぐに実行され、名前を尋ねます。ユーザーの入力値を受け取った後、2行目のコードが実行されます。Pythonインタープリタは2行目で命令を受け取り、1秒間スリープするよう要求され、スリープします。Pythonスレッドが1秒間スリープした後、ようやく3行目のコードが実行され、名前が出力されます。
辞書とfor文
Pythonでは、辞書は{ }の波括弧で囲まれた内容で、キー(key)と値(value)の2つの要素で構成され、これをキーと値のペアと呼びます。各キーは1つの値に対応します。KillAliensでは、12-17行目が1つの辞書で、18行目が1つの辞書です。これら2つの辞書は記述形式が異なりますが、どちらも辞書であり、違いはありません。12-17行目の記述形式は、見た目の問題を解決するためのものです。つまり、Pythonではコードを規範的に書くことが求められており、これは良い習慣です。
辞書を使用するのは、for文での出力を容易にするためです。辞書とfor文を使った出力を書いて試してみましょう:
学習しやすいように、各キーと値のペアを分けて書きました。実行結果:
for文では、厳密な順序の対応があります。nameはキーに対応し、moneyは値に対応します。そしてitems()は、辞書に出力できるキーと値のペアがなくなるまでループ出力するためのものです。
また、for文内のprintでは、上記のキーと値のペアの命名を使用できます。つまり、nameとmoneyを使って辞書内のキーと値に対応し、読み取ることができます。
for文以外にも、辞書は直接読み書きできますが、これは値の読み書きに限ります。
まず読み取りを見てみましょう
print内で{ }を使用すると、特定の領域の内容を読み取ることを意味し、その中に[ ]を追加すると、特定の領域内の特定の値を読み取ることを意味します。
上記のコードでは、{name_and_money['Mark']}を使用して、name_and_money辞書のMarkというキーに対応する値10を読み取っています。出力結果を見てみましょう
次に書き込みを見てみましょう
出力結果を見てみましょう
注意すべき点として、読み取りの部分とは異なり、この値に引用符' 'を付けていません。これは、引用符を付けると文字列を意味し、計算を続行するには浮動小数点数に変換する必要があるためです。一方、引用符を付けない場合は、純粋な数字を意味し、直接計算できます。
もちろん、これは計算を伴う書き込みですが、直接書き込むこともできます
ここでは彼氏の例を挙げて、キーに対応する値を直接上書きして置き換えました。
ここでの上書きは文字列を使用していますが、数字も同様の考え方です。
注意すべき点として、このような上書きによる変更は永続的です。
どういう意味か見てみましょう
出力結果
Tomは対照群として、変更されていません。彼の彼氏は常にBrownです。一方、Markは変更後、for文で辞書を読み取る際も、変更後の値を読み取ります。
if-elif-else の発展
KillAliensでは、if文の発展形を使用しています。if文の中にif文をネストし、in構文を使用しています。KillAliensから抜粋したコードを修正して説明しましょう。
異なる結果を示すために、複数回実行しました。
1回目の実行では、ifの判断を通過し、ランダムに選ばれた数が対照群state_oneにあったため、成功を返しました。2回目の実行では、elifの判断を通過し、ランダムに選ばれた数が対照群state_oneになかったため、失敗を返しました。3回目の実行では、Magnetoと入力したため、ifとelifの判断のどちらにも適合せず、elseに委ねられ、プロンプトが返されました。
KillAliensでは、これにより、存在しない内容を入力してプログラムがエラーになることを効果的に回避しています。
Whileループ
WhileループはKillAliensでは単純に使用されているだけなので、詳しい説明はしません。Python3 ループ文 | 菜鳥教程 を参照して学習できます。
終わりに
KillAliensは私が書いた比較的複雑なプログラムで、シンプルなテキストベースのミニゲームです。Pythonだけで実装されたスコアリングシステム、判断システム、撃破システムは、どれも完成度が高く比較的シンプルですが、これらのデータはスレッド内にのみ存在するため、まだ大きな