コグノスケ


link 未来から過去へ表示(*)  link 過去から未来へ表示

link もっと前
2026年5月3日 >>> 2026年4月20日
link もっと後

2026年5月3日

農家はREPLACE()されました、を9割クリア

目次: ゲーム

大昔にちょっとだけやって中断していたゲーム「農家はREPLACE()されました」を9割位までクリアしました。


「農家はREPLACE()されました」を9割位までクリア

実績の残り2個はランキングに載れ的なやつで、やる気が起きなかったのでこれでおしまいですね。

全体的な流れ

序盤は適当にループを回して、文法系を全開放(list, dict, set_world_sizeなど)、迷路までの作物、複数ドローンを開放します。中盤は各種作物に最適化して組んだプログラムを動かす&放置&資源がたまったらレベルを適宜開放、を繰り返します。実装したらやることがなくなっちゃう。

プログラムは最大レベル(農場サイズ32x32、ドローン32機)に合わせて決め打ち実装した方が効率的で速いです。が、中盤は農場サイズやドローン数が少なく、32x32決め打ち実装だと動かなくて辛いです。個人的には農場サイズやドローン数が可変にできるように実装した方がゲーム進行的には楽だと思いました。

カボチャとサボテンの実装を紹介しようと思います。一応、カボチャマスターとサボテンマスターは取れるはず、たぶん。

実装紹介(カボチャ)

各ドローンは1機1行を担当します。西から東の一方向にスキャンし続け、割れたカボチャがあったら植え直し、一列全部がきれいなカボチャになったらドローンの処理おしまいです。これを全行に対して実行します。

最初のドローンは北に移動しながらドローンを複製できるだけ複製して、複製の上限に達したら自分も1行担当します。全面カボチャになって、ドローンが最初のドローン1機だけになったら収穫します。

カボチャの実装

def cond():
	a = num_items(Items.Power) > MIN_POWER
	b = num_items(Items.Carrot) > MIN_CARROT
	c = num_items(Items.Pumpkin) < MAX_PUMPKIN
	return a and b and c


def get_pline():
	pline = 0
	for i in range(get_world_size()):
		if get_entity_type() == Entities.Pumpkin:
			pline += 1
		move(North)
	return pline


def drone():
	plist = []
	pnum = 0
	for i in range(get_world_size()):
		plist.append(False)
	while True:
		if get_entity_type() == Entities.Grass:
			till()

		if get_entity_type() == Entities.Pumpkin and can_harvest():
			if not plist[get_pos_x()]:
				plist[get_pos_x()] = True
				pnum += 1
				if pnum == get_world_size():
					return
		else:
			plant(Entities.Pumpkin)
			if get_water() < 0.5:
				use_item(Items.Water)
		move(East)


def pumpkin():
	clear()
	while cond():
		if not spawn_drone(drone):
			drone()
			if get_pline() == get_world_size():
				while num_drones() > 1:
					pass
				harvest()
		move(North)

動作を見たらすぐ気づくと思いますが、効率は良くないです。特に最初のドローンがスキャンする処理が長引くと、複数ドローンが出せない時間も長引いてしまいボトルネックになります。

実装紹介(サボテン)

全面にサボテンを植えて、東北側に大きなサボテン、南西側に小さなサボテンを集めるようにソートし、収穫します。ヒントにある通り、行ごとにソート、列ごとにソートの順に実行すれば全面ソート済みになります。

コードはこんな感じ。もっと短くできそうですけど気にしない。

サボテンの実装

def move_to(x, y):
	ws = get_world_size()
	dirx = East
	if (x - get_pos_x() + ws) % ws > (ws / 2):
		dirx = West
	diry = North
	if (y - get_pos_y() + ws) % ws > (ws / 2):
		diry = South
	while get_pos_x() != x:
		move(dirx)
	while get_pos_y() != y:
		move(diry)


def cond():
	a = num_items(Items.Power) > MIN_POWER
	b = num_items(Items.Pumpkin) > MIN_PUMPKIN
	c = num_items(Items.Cactus) < MAX_CACTUS
	return a and b and c


def is_ready(l):
	for i in range(get_world_size()):
		if l[i] == -1:
			return False
	return True


def is_sorted(l):
	for i in range(get_world_size() - 1):
		if l[i] > l[i + 1]:
			return False
	return True


def get_west_x():
	return (get_pos_x() - 1 + get_world_size()) % get_world_size()
def get_east_x():
	return (get_pos_x() + 1 + get_world_size()) % get_world_size()
def get_south_y():
	return (get_pos_y() - 1 + get_world_size()) % get_world_size()
def get_north_y():
	return (get_pos_y() + 1 + get_world_size()) % get_world_size()


def swap_item(l, a, b, dir):
	t = l[a]
	l[a] = l[b]
	l[b] = t
	swap(dir)


def plant_water():
	if get_entity_type() == Entities.Grass:
		till()
	plant(Entities.Cactus)
	if get_water() < 0.5:
		use_item(Items.Water)


def drone_x(st):
	move_to(0, st)
	xlist = []
	for i in range(get_world_size()):
		xlist.append(-1)

	while cond() and not is_ready(xlist):
		plant_water()
		xlist[get_pos_x()] = measure()
		move(East)

	move_to(0, st)
	vmax = get_world_size() - 1
	while cond():
		if is_sorted(xlist):
			return
		for i in range(vmax):
			if get_pos_x() > 0 and xlist[get_west_x()] > xlist[get_pos_x()]:
				swap_item(xlist, get_west_x(), get_pos_x(), West)
			move(East)
		for i in range(vmax):
			if get_pos_x() < get_world_size() - 1 and xlist[get_east_x()] < xlist[get_pos_x()]:
				swap_item(xlist, get_east_x(), get_pos_x(), East)
			move(West)
		move(East)
		vmax -= 2


def drone_y(st):
	move_to(st, 0)
	ylist = []
	for i in range(get_world_size()):
		ylist.append(-1)

	while cond() and not is_ready(ylist):
		ylist[get_pos_y()] = measure()
		move(North)

	vmax = get_world_size() - 1
	while cond():
		if is_sorted(ylist):
			return
		for i in range(vmax):
			if get_pos_y() > 0 and ylist[get_south_y()] > ylist[get_pos_y()]:
				swap_item(ylist, get_south_y(), get_pos_y(), South)
			move(North)
		for i in range(vmax):
			if get_pos_y() < get_world_size() - 1 and ylist[get_north_y()] < ylist[get_pos_y()]:
				swap_item(ylist, get_north_y(), get_pos_y(), North)
			move(South)
		move(North)
		vmax -= 2


def area(func, start, end):
	for i in range(start, end):
		spawn_drone(func, i + 1)
	func(start)
	while num_drones() > 1:
		pass


def cactus():
	clear()
	while cond():
		for i in range(0, get_world_size() - 1, max_drones()):
			area(drone_x, i, min(get_world_size() - 1, i + max_drones() - 1))
		for i in range(0, get_world_size() - 1, max_drones()):
			area(drone_y, i, min(get_world_size() - 1, i + max_drones() - 1))
		harvest()

ソートアルゴリズムは何でも良いですが、このゲームの大きな制約が2つあって、

  • 隣接するサボテン同士しか交換できない
  • ドローンの移動が遅い

おそらくバブルソート系のアルゴリズムを選択せざるを得ないでしょう。上記の実装ではシェイカーソートを使いました。シェイカーソートの存在は知ってましたが、実用的じゃないので実装したことなかったです。改めて実装してみるとなかなか新鮮でした。

編集者:すずき(2026/05/06 19:16)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2026年4月29日

ぽこあポケモンをクリア

目次: ゲーム

1日だけやって放置していたぽこあポケモンをクリア(=スタッフロールが流れるイベントを終わらせた)しました。プレイ時間カウントを確認すると65時間でしたが、絶対そんなにやってないぞ……夜に始めて寝落ちして、何度か長時間放置してしまった影響が大きいかも。

ぽこあポケモンの感想

地形を構成するブロックを壊したり積んだり、湧いてくるアイテムを集めて他のアイテムを作ったりします。ポケモンたちのお願いを叶えて住みよい環境にすることも重要です。一応クリアはあるものの、基本的には何をしても良く、終わりがありません。無限です。

マインクラフトはほぼやったことないので間違ってるかもですが、基本的なシステムは一緒だと思います。マインクラフトはキャラクターがあまりかわいくないデザインですが、ぽこポケは主人公のメタモンもかわいいし、懐いてくるポケモン達がかわいいです。あと戦いの要素がありません。ゾンビに突然攻撃されて死んだりする不快な現象は発生しません。

ゲームってなんだっけ……?

そういえば、マインクラフトを初めて見たときは自分の中のゲームの定義が揺らぎました。私はゲーム=ルール+目的のセットだと認識していたので、例えば「積み木ゲーム」なら「積み木(=ルール)で〇〇を作ろう(=目的)」みたいなもんを想像するんです。

しかしマインクラフトやぽこポケは「積み木」だけそのまま渡されたようなもので、とても斬新でしたし、これで何をするのでしょう……?とわからない不思議なゲームでもありました。今だにマインクラフトはペイントツールもしくはシミュレータの類と言ってくれたほうがしっくりきます。

でもそれは街作りシミュレータだって一緒でしょ、何が違うの?と言われるとうまく説明できないんですけど、自由度の差なんですかね?

編集者:すずき(2026/05/06 02:41)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2026年5月3日 >>> 2026年4月20日
link もっと後

管理用メニュー

link 記事を新規作成

<2026>
<<<05>>>
-----12
3456789
10111213141516
17181920212223
24252627282930
31------

最近のコメント5件

  • link 26年1月23日
    すずきさん (01/29 09:48)
    「おおー、そんな昔からなんですね。歴史感じ...」
  • link 26年1月23日
    hdkさん (01/27 19:53)
    「#! はUNIX v8からだったってWi...」
  • link 24年12月9日
    すずきさん (01/18 15:45)
    「Thank you for your i...」
  • link 24年12月9日
    Up2Uさん (01/15 12:57)
    「Hi I also find the p...」
  • link 25年12月18日
    すずきさん (12/23 23:51)
    「良く見たらksys_read()でfil...」

最近の記事20件

  • link 21年12月28日
    すずき (05/06 19:21)
    「[ゲーム - まとめリンク] 目次: ゲームNintendo DSを買ったパネルでポンDS最近の朝はパネポンDS聖剣伝説DSチ...」
  • link 26年5月3日
    すずき (05/06 19:16)
    「[農家はREPLACE()されました、を9割クリア] 目次: ゲーム大昔にちょっとだけやって中断していたゲーム「農家はREPL...」
  • link 26年4月29日
    すずき (05/06 02:41)
    「[ぽこあポケモンをクリア] 目次: ゲーム1日だけやって放置していたぽこあポケモンをクリア(=スタッフロールが流れるイベントを...」
  • link 26年4月7日
    すずき (04/07 23:02)
    「[ジャガーさんのエンジンオイル交換] 目次: 車買ってから6,000kmくらい走ったのでエンジンオイル&オイルフィルターを交換...」
  • link 23年5月15日
    すずき (04/07 21:52)
    「[車 - まとめリンク] 目次: 車三菱 FTO GPX '95の話。群馬県へのドライブ1群馬県へのドライブ2将来車を買い替え...」
  • link 26年2月8日
    すずき (04/07 21:51)
    「[ジャガーさんの修理……のはずが雪] 目次: 車以前(2025年11月21日の日記参照)、ジャガー...」
  • link 26年4月4日
    すずき (04/07 21:51)
    「[ジャガーさんのワイパー交換] 目次: 車以前からジャガーのワイパーは中央部分だけ拭き取れておらず、前が見づらかったです。最近...」
  • link 26年4月5日
    すずき (04/07 00:04)
    「[ドラクエ2リメイク、トロフィーコンプ] 目次: ゲームSteamで買ったドラクエ1&2 HDリメイク、ついにドラクエ2もトロ...」
  • link 26年3月20日
    すずき (03/26 01:31)
    「[Upload Labs、トロフィーコンプ] 目次: ゲーム先月、Upload Labsのトロフィーをコンプリートしましたが、...」
  • link 26年3月6日
    すずき (03/19 02:54)
    「[CRCの計算その2 - 最上位ビットの省略] 目次: ベンチマーク前回、CRCの筆算とMSBに寄せていくCRCの計算方法を紹...」
  • link 21年5月22日
    すずき (03/19 02:54)
    「[ベンチマーク - まとめリンク] 目次: ベンチマーク色々なベンチマーク、コードゴルフ。USB HDD RAIDのベンチマー...」
  • link 26年3月2日
    すずき (03/19 02:53)
    「[CRCの計算その1 - 筆算] 目次: ベンチマーク令和の時代に今更ですがCRCについて調べてました。CRCのベースになる数...」
  • link 26年3月10日
    すずき (03/13 00:54)
    「[誕生日] 43歳になりました。昨年の日記(2025年3月10日の日記参照)を見ると、転職して半年というのもあって通勤の話をし...」
  • link 22年4月13日
    すずき (03/12 23:48)
    「[C言語とlibc - まとめリンク] 目次: C言語とlibcC言語について。C++言語もたまに。プログラムの落とし穴、演算...」
  • link 07年11月1日
    すずき (03/12 23:47)
    「[netcatとsigned charとunsigned char] 目次: C言語とlibcGNU netcat 0.7.1...」
  • link 20年10月23日
    すずき (03/12 23:32)
    「[ARM - まとめリンク] 目次: ARMROCK64のブート、オーディオ。ROCK64購入ROCK64とU-Bootのdi...」
  • link 18年7月21日
    すずき (03/12 23:31)
    「[Bluetooth UART変換] 目次: ARMUARTをBluetoothに変換してくれるHC-06(モジュールの販売サ...」
  • link 02年11月22日
    すずき (03/12 23:28)
    「[ハフマン符号化プログラム] 目次: ベンチマークハフマン符号化プログラムですが、メモリ節約バージョンが完成しました。技術が足...」
  • link 22年11月11日
    すずき (03/12 23:26)
    「[手動の最適化 対 コンパイラの最適化] 目次: ベンチマークポッキーの日だそうですが、1(と0)といえば2進数、2進数といえ...」
  • link 07年11月2日
    すずき (03/12 23:25)
    「[ビット演算の極み(ハッカーのたのしみ)] 目次: ベンチマーク今日はコードを2つ紹介(出典: ハッカーのたのしみ, Henr...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 2025年
open/close 2026年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www2.katsuster.net
RDFファイル RSS 1.0

最終更新: 05/06 19:21