
当記事はChatGPTが出力した文章を使用しています。
このゲームの関連記事
前回
関数は“コードを部品化して使い回す”魔法
ギャル視点で、ゲームに即効く形でまとめ&実例置いてくね。
関数ってなに?(超要約)
-
名前のついたミニプログラム。
-
呼ぶたびに同じ仕事をしてくれる。
-
引数=材料を渡す/戻り値=結果を返す。
def move_n_dir(n, dir): # ← 関数の定義(名前・引数)
for _ in range(n):
move(dir) # ← 仕事
# 使う
move_n_dir(3, North) # ← 呼び出し(カッコ必須!)
戻り値(return)
-
returnすると結果が呼び出し元に“返る”よ。 -
返さないときは暗黙に“何もない値(None)”になる。
def at_top(size):
return get_pos_y() == size - 1 # True/False を返す
コツ:条件判定は関数にして名前をつけると読みやすさ爆上がり✨
デフォルト引数(お好み設定の初期値)
-
省略されたときの標準値を用意できる。
def wait_ticks(n=0):
for _ in range(n):
do_a_flip()
# wait_ticks() でも OK(0tick待ち)
# wait_ticks(2) なら2tick待つ
“高レベル関数”の使い方(関数を渡す)
-
関数も“値”だから引数として渡せるのね。汎用化できて超便利。
def repeat(n, action, arg=None):
for _ in range(n):
if arg is None:
action()
else:
action(arg)
repeat(3, move, North) # move(North) を3回
repeat(2, do_a_flip) # do_a_flip() を2回
注意:
repeat(3, move(North))はダメ。「関数そのもの」を渡したいからmoveとNorthを別々に渡すのが正解。
スコープ(届く/届かないの話)
-
関数の中で作った変数はその中だけ有効(ローカル)。
-
外側の値を読むのはOK(書き換えは注意)。
-
迷ったら「必要な値は引数で渡す」が安全だよ👌
実戦テンプレ3つ(コピペで強い)
1) 作業を部品化(草/茂み/ニンジン)
def do_grass():
if can_harvest():
harvest()
def do_bush():
if can_harvest():
harvest()
plant(Entities.Bush)
elif get_entity_type() is None:
plant(Entities.Bush)
def do_carrot():
if can_harvest():
harvest()
if get_entity_type() is None: # 空なら植え戻し
if get_ground_type() == Grounds.Grassland:
till()
if num_items(Items.Hay) >= 1 and num_items(Items.Wood) >= 1:
plant(Entities.Carrot)
2) 列の役割スイッチャー(1列目=🥕 2列目=🌳 3列目=🌿)
lanes = [do_carrot, do_bush, do_grass]
def do_job_for_current_tile():
x = get_pos_x()
job = lanes[x % len(lanes)] # いまの列の仕事関数を選ぶ
job() # 実行!
3) “縦スネーク”1歩進める関数(フラグを返す)
端ガード付きで1tickだけ移動し、次の向きフラグを戻り値で返す。
def snake_step(size, going_right, going_up):
x = get_pos_x(); y = get_pos_y()
if going_up:
if y == size - 1:
if going_right:
if x == size - 1:
going_right = False
move(West)
else:
move(East)
else:
if x == 0:
going_right = True
move(East)
else:
move(West)
going_up = False
else:
move(North)
else:
if y == 0:
if going_right:
if x == size - 1:
going_right = False
move(West)
else:
move(East)
else:
if x == 0:
going_right = True
move(East)
else:
move(West)
going_up = True
else:
move(South)
return going_right, going_up # 方向フラグを返す
使い方(本体は超スッキリに)
size = get_world_size()
going_right, going_up = True, True
while True:
do_job_for_current_tile() # そのマスの仕事を実行
going_right, going_up = snake_step(size, going_right, going_up) # 1歩進む
いい質問〜!結論👉 1)・2)・3)は“役割分担した部品”で、基本はぜんぶ組み合わせて使うのがオススメ💅
-
1) 作業部品 … そのマスで何をするか(草/茂み/ニンジン)
-
2) 列スイッチャー … いまの“列”に合わせて、どの作業部品を呼ぶか決める
-
3) 移動エンジン … 端ガード付きで“1歩だけ”縦スネーク移動させる
この3つをメインループで配線すると、読みやすくて壊れにくい永久運転になるの🧩
フル配線版(そのまま動かせる統合形)

# ── 1) 作業部品 ──────────────────────────
def do_grass():
if can_harvest():
harvest()
def do_bush():
if can_harvest():
harvest()
plant(Entities.Bush)
elif get_entity_type() == None: # 環境によっては is None でもOK
plant(Entities.Bush)
def do_carrot():
if can_harvest():
harvest()
if get_ground_type() == Grounds.Grassland:
till() # 必要時だけ耕す(トグル事故回避)
if num_items(Items.Hay) >= 1 and num_items(Items.Wood) >= 1:
plant(Entities.Carrot)
elif get_entity_type() == None: # 初回の空きタイル対策(資材があるときだけ)
if get_ground_type() == Grounds.Grassland:
till()
if num_items(Items.Hay) >= 1 and num_items(Items.Wood) >= 1:
plant(Entities.Carrot)
# ── 2) 列スイッチャー ────────────────────────
lanes = [do_carrot, do_bush, do_grass] # 1列目=🥕 2列目=🌳 3列目=🌿 の順に循環
def do_job_for_current_tile():
x = get_pos_x()
job = lanes[x % len(lanes)] # 現在列の担当作業を決定
job() # 実行!
# ── 3) 移動エンジン(端ガード付き・1歩だけ進む) ───────
def snake_step(size, going_right, going_up):
x = get_pos_x(); y = get_pos_y()
if going_up:
if y == size - 1:
if going_right:
if x == size - 1:
going_right = False
move(West)
else:
move(East)
else:
if x == 0:
going_right = True
move(East)
else:
move(West)
going_up = False
else:
move(North)
else:
if y == 0:
if going_right:
if x == size - 1:
going_right = False
move(West)
else:
move(East)
else:
if x == 0:
going_right = True
move(East)
else:
move(West)
going_up = True
else:
move(South)
return going_right, going_up
# ── メイン(配線) ───────────────────────────
size = get_world_size()
going_right, going_up = True, True
while True:
do_job_for_current_tile() # そのマスでの作業
going_right, going_up = snake_step(size, going_right, going_up) # 1歩だけ移動
どうして“分けて”使うの?
-
読みやすい:仕事・選択・移動が混ざらないから、後で見返しても一発で分かる👌
-
差し替えが楽:列の配分を変えたい時は
lanes = [...]だけ触ればOK(例:木不足なら[do_carrot, do_bush, do_bush])。 -
再利用しやすい:移動はそのままで「行ベースにしたい」「待ちtick入れたい」なども 3) だけ直せば済む。
じゃあ“まとめない”ケースは?
-
今日は草だけ刈りたいみたいな超単純運用なら、1)の一個を直接書き込んでもOK。
-
でも長期運転・調整・拡張を考えるなら、3部品に分けて使うのが結局ラクだよ💪
よくあるつまずき💣
-
カッコ忘れ:
moveとmove()は別物!呼ぶ時は必ず()。 -
インデント:関数内は1段深く。Tab/Space混在はエラー。
-
戻り値の受け取り忘れ:
a, b = f()みたいにちゃんと左側に受ける。 -
デフォルト引数の順序:デフォルトありは後ろ側に置く。
-
重複呼び出し:毎tick同じ重い処理を何度も呼ばない(
size = get_world_size()は外に出して共有が◎)。
まとめ(ギャル要点)
-
関数=名前のついた仕事。
-
引数で材料を渡し、returnで結果を返す。
-
“判定”“作業”“移動 1歩”を分けて関数化すると、読みやすくてミスらない。
-
高機能はあとから足すだけで全体が育つのが関数の強み✨
続き