前回までの「Python初体験」の続きです。(そして取り敢えず最終回となりました。)
今回も西瓜割ゲームのコードのリファクタリング(改良)ですが、纏められるところを関数に纏めましょう、というテーマです。
先ずはリファクタリング対象のコードを紹介します。
【オリジナル】
import random
import math
BOARD_SIZE = 5 #ボードの初期サイズ
def calc_distance(pos1, pos2): #解説:これは関数の定義でしたね。
#2点間の距離を求める
diff_x = pos1[0] - pos2[0]
diff_y = pos1[1] - pos2[1]
return math.sqrt(diff_x**2 + diff_y**2)
#リファクタリング対象1
suika_pos = (random.randrange(0, BOARD_SIZE), random.randrange(0, BOARD_SIZE)) #スイカの位置
player_pos = (random.randrange(0, BOARD_SIZE), random.randrange(0, BOARD_SIZE)) #プレイヤーの位置
#スイカとプレイヤーの位置が異なる間、処理を繰り返す
while (suika_pos != player_pos):
#スイカとプレイヤーの距離を表示する
distance = calc_distance(suika_pos, player_pos)
print("スイカへの距離:", distance)
#リファクタリング対象2
#キー入力に応じて、プレイヤーを移動する
c = input("n:北に移動 s:南に移動 e:東に移動 w:西に移動")
current_x, current_y = player_pos
if c == "n":
current_y = current_y - 1
elif c == "s":
current_y = current_y + 1
elif c == "w":
current_x = current_x - 1
elif c == "e":
current_x = current_x + 1
player_pos = (current_x, current_y)
print("スイカを割りました!")
最初にリファクタリング対象となるのは、同じコードを書いている乱数による位置決めの部分です。
これは次の関数を定義することでまとめられます。
#0以上size未満の範囲で、x座標とy座標を生成する
def generate_position(size):
x = random.randrange(0, size) # x座標
y = random.randrange(0, size) # y座標
これを定義すると↑のコードが、↓の様になります。
suika_pos = generate_position(BOARD_SIZE) #スイカの位置
player_pos = generate_position(BOARD_SIZE) #プレイヤーの位置
次の対象は移動の為のキー入力部分です。
#direction にしたがって、posを移動する
def move_position(direction, pos):
current_x, current_y = pos #このposは↓の戻り値と同じタプルである。
if direction == "n":
current_y = current_y - 1
elif direction == "s":
current_y = current_y + 1
elif direction == "w":
current_x = current_x - 1
elif direction == "e":
current_x = current_x + 1
return (current_x, current_y) #戻り値はタプル
このように関数化すると、メインのコードは次のように簡素化されます。(第二引数はタプルです。)
move_position('n', (1, 1)) #(1, 1) から、北に移動
最後に残ったメインのコードも関数化すると、次の通りとなります。
def suika_wari():
suika_pos = generate_position(BOARD_SIZE) # スイカの座標
player_pos = generate_position(BOARD_SIZE) # プレイヤーの座標
#スイカとプレイヤーの位置が異なる間、処理を繰り返す
while (suika_pos != player_pos):
#スイカとプレイヤーの距離を表示する
distance = calc_distance(player_pos, suika_pos)
print("スイカへの距離:", distance)
#キー入力に応じて、プレイヤーを移動する
c = input("n:北に移動 s:南に移動 e:東に移動 w:西に移動")
player_pos = move_position(c, player_pos)
print("スイカを割りました!")
こうすると(これをライブラリーにする人はいないでしょうが)、西瓜割ゲームが
"suika_wari()"
とPythonに入力するだけで実行できるようになります。即ちこれがPythonの優位性で、ソフトウェア資産がライブラリーとしてどんどんたまってゆくことにより、後人は先人の資産を十二分にエンジョイすることが出来るようになっています。
「さて、次は何をやるのかな?」と思ったら、どうも公開されているコースはこれでおしまいのようです。何か消化不良感がぬぐえませんが、今後の「Python日記」はまた他の教育ソースから面白そうなものを取り上げて書いてみることにします。
#追記:実はPython日記は予め結構書き溜めていたものを後で掲載していました。しかし、突然このコースが(消化不良感満載で)終わってしまったので、中止せざるを得ません。まだ全然Pythonの世界には入れていないのですが、仕方ないですね。
いずれにせよ、Pythonのすごい所は、
(1)C系の言語のような厳密性を緩和して、柔軟であること。
(2)作ったものが皆栄養(ライブラリー)として生かせるので、過去のソフトウェア資産が膨大となりどんどん高度な使用方法が出来ること、でしょうか?
現在はOpenGLに少し嵌っていますが、また落ち着いたらPythonに戻ってこようか(Pythonの新シリーズ)と思います。
それまでご機嫌良う!
So long!
再見!
또 봐요!