見出し画像

農家は Replace() されました 攻略してみる

拡張しても移動・収穫・植え付けをしている間に育ち切ってしまうため、ドローンが増えるまでは、ある程度までしか拡張するメリットはない。畑サイズの変更のアンロックがかなり先なので、無駄に拡張しまくるとデバッグが大変になる。

Pythonライクらしい。スネークケースが一番の敵。

すぐ生えてくるので畑を拡張すればcan_harvest()の判定は必要ない。マップ端でループするので一方向に進めばよい。

while True:
	move(North)
	harvest()

木は隣接すると成長速度が遅くなるため、格子状に植える。畑を拡張すればcan_harvest()の判定は必要ない。

while True:
	for i in range(get_world_size()):	
		for j in range(get_world_size()):
			harvest()
			if ((i+j)%2)==0:
				plant(Entities.Tree)
			move(North)
		move(East)

ニンジン

上記から西の3列だけニンジンにしたバージョン。農場が広ければ水やりは必要ない。

for _ in range(get_pos_y()):
	move(South)
for _ in range(get_pos_x()):
	move(West)

while True:
	for i in range(get_world_size()):	
		for j in range(get_world_size()):
			harvest()
			if i<3:
				if get_ground_type() != Grounds.Soil:
					till()
				plant(Entities.Carrot)
				if (get_water()<0.5):
					use_item(Items.Water)
			elif ((i+j)%2)==0:
				plant(Entities.Tree)
			move(North)
		move(East)

ヒマワリ

パワー(?)を収穫出来て一定時間超スピードになる最重要作物。花びら枚数の最適化の必要性を感じていないため今のところ保留。ランダムで肥料を追加し、Weird  substance(奇妙な物質?)を回収する。

for _ in range(get_pos_y()):
	move(South)
for _ in range(get_pos_x()):
	move(West)

while True:
	for i in range(get_world_size()):	
		for j in range(get_world_size()):
			harvest()
			if i<6:
				if get_ground_type() != Grounds.Soil:
					till()
				plant(Entities.Carrot)
				if (get_water()<0.5):
					use_item(Items.Water)
					if random()<0.1:
						use_item(Items.Fertilizer)
			elif i<9:
				if get_ground_type() != Grounds.Soil:
					till()
				plant(Entities.Sunflower)
			elif ((i+j)%2)==0:
				plant(Entities.Tree)
			move(North)
		move(East)

農場全体を埋め尽くすパンプキン

最初に(0,0)地点に行き、1行をループし続け全て収穫可能になったら次の行へ、を繰り返し最後の行がすべて収穫可能になったら収穫する作戦。効率は多分よくない。

change_hat(Hats.Brown_Hat)
plant_in_pass_x = False
world_size = get_world_size()

def plant_pumpkin():
	global plant_in_pass_x
	if get_ground_type() != Grounds.Soil:
		till()
	if not can_harvest():
		plant(Entities.Pumpkin)
		plant_in_pass_x = True

def plant_pumpkins():
	global plant_in_pass_x 
	posX=get_pos_x()
	posY=get_pos_y()
	# --- パスの開始: ドローンを左下の角(0,0)に移動 ---
	for _ in range(posY):
		move(South)
	for _ in range(posX):
		move(West)
	#1行をループし続け、全て収穫可能になったら1つ北へ
	while True:
		plant_in_pass = False
	
		while True:
			posX=get_pos_x()
			posY=get_pos_y()
			if posX==0 :
				plant_in_pass_x = False

			plant_pumpkin()
			if (get_water()<0.2):
					use_item(Items.Water)
			move(East)
			
			if not plant_in_pass_x and posX==world_size-1:
				if posY!=world_size-1:
					move(North)
				break

		if posY==world_size-1:
			break

while True:
	plant_pumpkins()
	harvest()

シンプル版パンプキン。収穫可能なパンプキン数を1個ずつカウントして植え直しがあったらリセット、ワールドサイズを超えたら収穫。6×6以上は効率が上がらないのでset_world_size(6)でいいかもしれない

change_hat(Hats.Straw_Hat)
count = 0
world_size = get_world_size()

def plant_pumpkin():
	global count
#パンプキンを1個ずつカウントしていく。植え直しがあったらリセット
	if get_ground_type() != Grounds.Soil:
		till()
	if not can_harvest():
		plant(Entities.Pumpkin)
		count = 0 
	else:
		count += 1

def plant_pumpkins():
	global count
	count=0 
	
	while True:
		plant_pumpkin()
		move(North)
		if get_pos_y()==0:
			move(East)
		#収穫可能なパンプキン数がワールドサイズを超えたら終わり
		if count>world_size*world_size:
			break

while True:
	plant_pumpkins()
	harvest()

サボテンソート

畑の範囲外や植えてない畑との比較・スワップで問題が起きやすいので注意。measure()で数字が返ってくることを期待しているとNoneが返ってくる。

change_hat(Hats.Brown_Hat)
swaps_in_pass_y = False
swaps_in_pass_x = False
world_size = get_world_size()-1

def plant_cuctus():
	global swaps_in_pass_x
	global swaps_in_pass_y 
	if get_entity_type() != Entities.Cactus:
		swaps_in_pass_x = True
		swaps_in_pass_y = True	
		if get_ground_type() != Grounds.Soil:
			till()
		plant(Entities.Cactus)

def swap_cacti(times):
		swap_cacti_dir(measure(),East,get_pos_x())
		swap_cacti_dir(measure(),North,get_pos_y())

def swap_cacti_dir(curr_size,dir,pos):
	#x方向の入れ替えは西に、y軸方向の入れ替えは南に戻る
	global swaps_in_pass_y 
	global swaps_in_pass_x

	if curr_size==None:
		curr_size=0
	# 現在のサボテンが北/東のサボテンより大きい場合スワップ。
	next_size = measure(dir)
	if next_size!=None and pos < world_size:
		if curr_size> next_size:
			swap(dir)
			if dir==North:
				swaps_in_pass_y = True
			else:
				swaps_in_pass_x = True

def sort_cacti():
	global swaps_in_pass_y 
	global swaps_in_pass_x
	# 畑がソートされるまでループ
	while True:
		# --- パスの開始: ドローンを左下の角(0,0)に移動 ---
		for _ in range(get_pos_y()):
			move(South)
		for _ in range(get_pos_x()):
			move(West)
		# --- グリッド全体をスキャン ---
		# 左から右へ、終わったら上の行へと移動。
		max_y=0
		#y軸走査
		while True:
			#x軸走査
			while True:
				swaps_in_pass_y=False
				x=0
				while True:
					swaps_in_pass_x=False
					plant_cuctus()
					swap_cacti(x)
					# 行の終わりに到達したら、次の行の開始位置に移動
					if get_pos_x() >= world_size and not swaps_in_pass_x:
						move(East)
						break
					# 行の次の位置に移動
					if not swaps_in_pass_x:
						if get_pos_x() <= world_size:
							move(East)
					#スワップがあった場合は1つ左に戻る
					else :
						if get_pos_x() > 0:
							move(West)
				# 植えるか南北のスワップがあった場合1つ南の行に戻る。
				if get_pos_y()>0 and swaps_in_pass_y:
					max_y=max(max_y,get_pos_y())
					move(South)
				else:
					break
			# 最北端に到達したら処理終了
			if get_pos_y() >= world_size :
				break
			else:
				# 南に戻ってスワップし終えた場合は元の処理位置まで戻る
				max_y=max(max_y,get_pos_y())
				if max_y==world_size:
					max_y-=1
				for _ in range(max_y-get_pos_y()+1):
					move(North)

		# 1回のパスでスワップが一度も行われなかった場合ソートは完了
		if not swaps_in_pass_y and not swaps_in_pass_x:
			break

while True:
	sort_cacti()
	harvest()

ゲームの仕様上の問題は概ね回避できていると思います。力業での実装ですがパフォーマンスはよさげ。ノームソートというらしい。

curr_size> next_size:の判定を逆にするとSteamの実績の順序間違い(サボテンを逆向きにソート)もクリア可能。

シェーカーソートの方が効率が良さそう。

change_hat(Hats.Green_Hat)
#set_world_size(6)
WORLD_SIZE = get_world_size()

#---行ソート---
def sort_row_shaker(y):
	left = 0
	right = get_world_size() - 1

	while left < right:
		swapped = False
		last_swap = left

		move_to(left, y)
		for x in range(left, right):
			plant_if_needed()
			curr = measure()
			move(East)
			plant_if_needed()
			next_ = measure()
			if curr != None and next_ != None and curr > next_:
				swap(West)
				swapped = True
				last_swap = x + 1
		right = last_swap

		if not swapped:
			break

		swapped = False
		last_swap = right

		move_to(right, y)
		for x in range(right, left, -1):
			plant_if_needed()
			curr = measure()
			move(West)
			plant_if_needed()
			next_ = measure()
			if curr != None and next_ != None and curr < next_:
				swap(East)
				swapped = True
				last_swap = x - 1
		left = last_swap

		if not swapped:
			break
#---列ソート---
def sort_column_shaker(x):
	top = 0
	bottom = get_world_size() - 1

	while top < bottom:
		swapped = False
		last_swap = top

		move_to(x, top)
		for y in range(top, bottom):
			plant_if_needed()
			curr = measure()
			move(North)
			plant_if_needed()
			next_ = measure()
			if curr != None and next_ != None and curr > next_:
				swap(South)
				swapped = True
				last_swap = y + 1
		bottom = last_swap

		if not swapped:
			break

		swapped = False
		last_swap = bottom

		move_to(x, bottom)
		for y in range(bottom, top, -1):
			plant_if_needed()
			curr = measure()
			move(South)
			plant_if_needed()
			next_ = measure()
			if curr != None and next_ != None and curr < next_:
				swap(North)
				swapped = True
				last_swap = y - 1
		top = last_swap

		if not swapped:
			break

def shaker_sort_horizontal():
	for y in range(get_world_size()):
		sort_row_shaker(y)

def shaker_sort_vertical():
	for x in range(get_world_size()):
		sort_column_shaker(x)

def sort_cacti_grid():
	shaker_sort_horizontal()
	shaker_sort_vertical()

# --- Utils ---
def move_to(target_x, target_y):
	while get_pos_x() > target_x: 
		move(West)
	while get_pos_x() < target_x: 
		move(East)
	while get_pos_y() > target_y: 
		move(South)
	while get_pos_y() < target_y: 
		move(North)

def plant_if_needed():
	if get_entity_type() != Entities.Cactus:
		if get_ground_type() != Grounds.Soil: 
			till()
		plant(Entities.Cactus)
		return True
	return False

# --- 実行ループ ---
while True:
	sort_cacti_grid()
	harvest()

農場全体を埋め尽くす恐竜ハット

一筆書きで農場全体を周回し続ける作戦です。恐竜ハット装備中は尻尾が付くのでマップ端で反対側にワープできません。

少し改良を加えてショートカットするようにしました。

#clear()
#set_world_size(12)
change_hat(Hats.Dinosaur_Hat)
def MovDino(Dir):
	global Apples
	if move(Dir) :
		return
	else:
		change_hat(Hats.Dinosaur_Hat)
		Apples=0

next_x, next_y = (-1,-1)
Apples=0
worldSize=get_world_size()-1
shortcut_end=get_world_size()**1.72

while True:
	pos_x=get_pos_x()
	pos_y=get_pos_y()
	if get_entity_type()==Entities.Apple and Apples < shortcut_end:
		next_x, next_y = measure()
		Apples += 1
		#リンゴがワールドサイズ2乗の約半分を超えるとショートカットしない方が効率がいい
		if Apples>=shortcut_end:
			next_x, next_y = (-1,-1)
	#一番南の列は西に横断
	if pos_y==0 and can_move(West):
		MovDino(West)
	#偶数列は北に 北の端まで行ったら東に
	elif pos_x%2==0:
		if can_move(North) :
			MovDino(North)
		else:
			MovDino(East)
	#奇数列は南に 
	else:
		#南端の一つ上まで来たら東に リンゴが西にある場合は南→西のルートへ
		if pos_y==1 and pos_x!=worldSize:
			if next_x!=-1 and pos_x>=next_x and can_move(South):
				MovDino(South)
			else:
				MovDino(East)
		#東にリンゴがある場合は東へ(東に行った後、偶数列では尻尾ぶつかり回避のため北に行く)
		elif can_move(East) and next_x!=-1 and (next_y!=-1 and pos_x<next_x and pos_y==next_y or pos_x<next_x-1 or (pos_x<next_x and next_y==0)):
			MovDino(East)
		else:
			MovDino(South)
	#if num_items(Items.Bone) >= 33488928:
	#	break

動きを見るのが早いと思います。

画像
2025/10/15時点

迷路探索(右手法)

while True:
	plant(Entities.Bush)
	substance = get_world_size() * 2**(num_unlocked(Unlocks.Mazes) - 1)
	use_item(Items.Weird_Substance, substance)
	
	directions = [North, East, South, West]
	#最初は北向き
	index = 0 

	while get_entity_type() != Entities.Treasure:
		#まず右を向く
		index = (index + 1) % 4
		#前が壁なら左周りで進める方向を探す
		while not can_move(directions[index]):
			index = (index - 1) % 4
		move(directions[index])
	harvest()

恐らく公式のドキュメントのヒントで紹介されている方法
アルゴロジックという教育ゲームで似たようなことをやった記憶があります。

迷路の再利用(use_item(Items.Weird_Substance, substance))をすると壁が一部消えて右手法(左手法)ではいつか攻略が出来なくなるので、DFS(深さ優先探索)アルゴリズムを考える必要がありそうです。試しに作ってみましたが、かろうじて動くものの酔っ払い運転になっています。

DFS探索(*未完成*)

def dfs():
	global count

	pos = (get_pos_x(), get_pos_y())
	if pos in visited:
		return False
	visited.add(pos)
	if get_entity_type() == Entities.Treasure:
		if count>300:
			harvest()
		else:
			use_item(Items.Weird_Substance, substance)
		count+=1
		return True
	for dir in directions:
		if can_move(dir):
			move(dir)
			if dfs():
				return True
			move(opposite(dir))
	return False
def opposite(dir):
	return {North: South, South: North, East: West, West: East}[dir]

while True:
	
	plant(Entities.Bush)
	substance = get_world_size() * 2**(num_unlocked(Unlocks.Mazes) - 1)
	use_item(Items.Weird_Substance, substance)
	
	visited = set()
	directions = [North, East, South, West]

	dfs()


裏技?

画像
手動で攻略

左上の実行ボタンを押してドローンの手動操作が可能。

ドローン増やしてみた

world_size=get_world_size()
half_world_size=get_world_size()/2
max_drone = world_size**2 // 32

def AutoCarrot():
	for i in range(world_size):	
		for j in range(world_size):
			if can_harvest():
				harvest()
			elif get_entity_type()!=None:
				do_a_flip()
			if ((i+j)%half_world_size)>half_world_size*0.6:
				plant_crops(Entities.Carrot)
			elif ((i+j)%half_world_size)>half_world_size*0.4:
				plant_crops(Entities.Sunflower)
			elif ((i+j)%half_world_size)==0:
				plant_crops(Entities.Tree)
			else:
				if get_ground_type() == Grounds.Soil:
					till()
			move(North)
		move(East)
		if num_drones()<max_drone:
			spawn_drone(auto_carrot)

def plant_crops(ent):
	if get_ground_type() != Grounds.Soil:
		till()
	plant(ent)
	if (get_water()<0.2):
		use_item(Items.Water)
		if random()<0.05:
			use_item(Items.Fertilizer)

def auto_carrot():
	for _ in range(get_pos_y()):
		move(South)
	for _ in range(get_pos_x()):
		move(West)
	while True:
		AutoCarrot()
		
auto_carrot()

東に移動するタイミングで召喚。can_harvest()がfalseの時はdo_a_flipで遅延を入れて重ならずに収穫を行えるようにしています。

32*32畑+32機のドローンでヒマワリ自動栽培

clear()
change_hat(Hats.Green_Hat)

def setup_farm():
	row = num_drones() - 1
	move_to(0, row)
	auto_farm(row)

def auto_farm(row):
	world_size=get_world_size()
	half_world_size=get_world_size()/4
	
	while True:
		col= get_pos_x()
		pos=row+col
		if can_harvest():
			harvest()
		if ((pos)%half_world_size)>half_world_size*0.85:
			plant_crops(Entities.Carrot)
		elif ((pos)%half_world_size)>half_world_size*0.1:
			plant_crops(Entities.Sunflower)
		elif ((pos)%world_size)==0:
			plant_crops(Entities.Tree)
		else:
			if get_ground_type() == Grounds.Soil:
				till()
		move(East)
		
def plant_crops(ent):
	if get_ground_type() != Grounds.Soil:
		till()
	plant(ent)
	if (get_water()<0.4):
		use_item(Items.Water)
		if random()<0.03:
			use_item(Items.Fertilizer)
	
def move_to(x, y):
	size = get_world_size()
	curr_x = get_pos_x()
	curr_y = get_pos_y()

	dx = (x - curr_x + size) % size
	dy = (y - curr_y + size) % size

	# 最短距離で移動(x方向)
	if dx <= size // 2:
		for _ in range(dx):
			move(East)
	else:
		for _ in range(size - dx):
			move(West)

	# 最短距離で移動(y方向)
	if dy <= size // 2:
		for _ in range(dy):
			move(North)
	else:
		for _ in range(size - dy):
			move(South)

def main():
	for _ in range(get_world_size()):
		spawn_drone(setup_farm)
		#1tickの遅延
		get_time() 
	auto_farm(0)

main()


段々動けばいいやというメンタルになってくる。現実に支障が出るかもしれない…。


いいなと思ったら応援しよう!

コメント

コメントするには、 ログイン または 会員登録 をお願いします。
農家は Replace() されました 攻略してみる|Rafull=Eraser
word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word

mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1