スイカ割りゲーム はとりあえず動き、ゲームを実行できるようになりました。
しかし、プログラムの書き方としては今一つな点があります。本格的な改善はこの講座の範囲を超えますが、いくつか簡単なポイントを改善してみましょう。
このように、プログラムの機能はそのままで、書き方を改善することを リファクタリング といいます。
マジックナンバーを避ける¶
このプログラムでは、スイカとプレイヤーの初期位置は 5×5 の範囲内としています。この範囲は、generate_position(5)
のように、引数として指定しています。
suika_pos = generate_position(5) # スイカの位置
player_pos = generate_position(5) # プレイヤーの位置
しかし、あとからこのプログラムを読むとき、いきなり 「5」という数字だけが書いてあった場合、この数値がどんな意味の値なのか、覚えていられるでしょうか?
運良く覚えていられるかもしれないし、忘れているかもしれませんが、忘れていても問題ないように、ちゃんと意味がわかるようにしておきましょう。こういう場合、直接 5
という数字を書くのではなく、わかりやすい名前をつけた変数に代入してして使用するようにします。
この場合だと、5
はこのゲームのボードのサイズですから、BOARD_SIZE
という名前にしましょう。Pythonの慣例で、このような定数値の変数名は小文字のboard_size
ではなく、BOARD_SIZE
のようにすべて大文字にします。
BOARD_SIZE = 5 # ボードの初期サイズ
suika_pos = generate_position(BOARD_SIZE) # スイカの位置
player_pos = generate_position(BOARD_SIZE) # プレイヤーの位置
こうしておけば、BOARD_SIZE
という名前を手がかりに、どんな意味を持つ値なのか、きっと思い出すことができるでしょう。また、サイズを変更する場合は BOARD_SIZE
の値を修正するだけで済むようになります。
この 5
のように、プログラム中にいきなり出てくる意味のわからない数字は、一般に マジックナンバー といいます。基本的には、マジックナンバーは、値を直接書くのではなく、その値の意味がわかるように、常に 変数に代入してから利用するようにします。
マジックナンバーを変数に代入せず、あっちこっちで使ってしまうと、あとでその値の意味がわからなくなってしまったり、値を変更するときに修正漏れが発生したりします。
ということで、5
という数字を直接使うのはやめて、BOARD_SIZE
に代入して使用するように変更を加えると、次のようになります。
import random
import math
BOARD_SIZE = 5 # ボードの初期サイズ
def calc_distance(x1, y1, x2, y2):
# 2点間の距離を求める
diff_x = x1 - x2
diff_y = y1 - y2
return math.sqrt(diff_x**2 + diff_y**2)
suika_x = random.randrange(0, BOARD_SIZE) # スイカのx座標 <- この行を修正
suika_y = random.randrange(0, BOARD_SIZE) # スイカのy座標 <- この行を修正
player_x = random.randrange(0, BOARD_SIZE) # プレイヤーのx座標 <- この行を修正
player_y = random.randrange(0, BOARD_SIZE) # プレイヤーのy座標 <- この行を修正
# スイカとプレイヤーの位置が異なる間、処理を繰り返す
while (suika_x != player_x) or (suika_y != player_y):
# スイカとプレイヤーの距離を表示する
distance = calc_distance(player_x, player_y, suika_x, suika_y)
print("スイカへの距離:", distance)
# キー入力に応じて、プレイヤーを移動する
c = input("n:北に移動 s:南に移動 e:東に移動 w:西に移動")
if c == "n":
player_y = player_y - 1
elif c == "s":
player_y = player_y + 1
elif c == "w":
player_x = player_x - 1
elif c == "e":
player_x = player_x + 1
print("スイカを割りました!")