コグノスケ


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/06/24 01:09)

コメント一覧

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



2026年4月29日

ぽこあポケモンをクリア

目次: ゲーム

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

ぽこあポケモンの感想

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

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

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

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

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

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

編集者:すずき(2026/06/24 01:10)

コメント一覧

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



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

管理用メニュー

link 記事を新規作成

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

最近のコメント5件

  • link 26年7月26日
    すずきさん (08/06 12:27)
    「ダイバート便以外もバスなんですよねえ。私...」
  • link 26年7月26日
    hdkさん (08/06 08:41)
    「あの規模の空港だとダイバート便にまでボー...」
  • link 26年7月14日
    すずきさん (07/31 11:48)
    「補充して乗れるのはまあそうなんですけど、...」
  • link 26年7月14日
    hdkさん (07/22 08:37)
    「冷却水漏れなんて、修理するまでは補充して...」
  • link 26年1月23日
    すずきさん (01/29 09:48)
    「おおー、そんな昔からなんですね。歴史感じ...」

最近の記事20件

  • link 21年12月28日
    すずき (09/02 23:13)
    「[ゲーム - まとめリンク] 目次: ゲームNintendo DSを買ったパネルでポンDS最近の朝はパネポンDS聖剣伝説DSチ...」
  • link 26年4月11日
    すずき (09/02 23:12)
    「[デヴィエーション・ゲームでAIと勝負] 目次: ゲームお台場の日本科学未来館に行ってきました。どの展示も面白いんですけど、一...」
  • link 26年6月3日
    すずき (09/02 23:07)
    「[台風6号と大雨] 台風6号の影響でめちゃくちゃ雨が降っていました。Yahooの河川情報を見ると、氾濫寸前の川がチラホラしてお...」
  • link 26年9月1日
    すずき (09/02 01:42)
    「[誕生日のパラドックス] Twitter…じゃなくてXで「QuizKnockの誕生日のパラドックスの計算式が間違...」
  • link 26年8月8日
    すずき (08/10 03:22)
    「[NTPの時刻同期状況] 目次: 自宅サーバーNTPの動作状況を見るときに使うコマンドのメモです。よく使うのはntpq -pで...」
  • link 23年6月1日
    すずき (08/10 02:38)
    「[自宅サーバー - まとめリンク] 目次: 自宅サーバーこの日記システム、Wikiの話。カウンターをPerlからPHPに移植日...」
  • link 23年5月15日
    すずき (08/06 01:27)
    「[車 - まとめリンク] 目次: 車三菱 FTO GPX '95の話。群馬県へのドライブ1群馬県へのドライブ2将来車を買い替え...」
  • link 26年7月30日
    すずき (08/06 01:27)
    「[ジャガーさんのオイル漏れ] 目次: 車会社の同僚の方(整備士)から、ジャガーの下見たらオイル漏れしてたと教えてもらいました。...」
  • link 26年7月27日
    すずき (08/06 00:49)
    「[ジャガーさんの冷却水漏れ修理が終わった] 目次: 車正確には昨日ですけど、成田からの帰りに修理をお願いした整備工場(カスタム...」
  • link 26年7月26日
    すずき (08/06 00:05)
    「[北海道から東京へ] GWからだいぶずれちゃいましたが北海道に帰省していました。涼しくて最高だった北海道を出て、灼熱の東京へ戻...」
  • link 26年7月22日
    すずき (07/22 03:04)
    「[ジャガーさんの冷却水漏れの修理見積もり] 目次: 車先週、冷却水がほぼなくなってしまい修理工場にレッカーしたジャガーさんです...」
  • link 26年7月14日
    すずき (07/22 02:37)
    「[ジャガーさんの冷却水漏れ] 目次: 車朝、出勤しようと思ってエンジンをかけたところ冷却水不足と表示されました。わぁ、ついに出...」
  • link 26年7月19日
    すずき (07/20 04:04)
    「[ゲームを買ったら遊びましょう4] 目次: ゲーム前回の振り返り(2025年12月22日の日記参照)から半年経ちました。Swi...」
  • link 26年7月13日
    すずき (07/19 23:33)
    「[Flightradar24のcontributorになる方法] 目次: 自宅サーバーADS-Bを受信できる環境があればFli...」
  • link 23年9月11日
    すずき (07/15 12:18)
    「[Windows - まとめリンク] 目次: WindowsWindows XPのブリッジ機能colinuxとWindowsの...」
  • link 25年1月31日
    すずき (07/15 12:18)
    「[Windowsの日本語フォントはみな長生き] 目次: WindowsGNOME48からフォントが変わるニュースを見ていて、フ...」
  • link 26年7月11日
    すずき (07/12 01:26)
    「[Timberborn、トロフィーコンプ] 目次: ゲームTimberbornのトロフィーをコンプリートしました。アーリーアク...」
  • link 24年2月7日
    すずき (07/11 13:05)
    「[複数の音声ファイルのラウドネスを統一したい] 目次: PythonPCやデジタル音楽プレーヤーで音楽を聞いていると、曲によっ...」
  • link 26年6月27日
    すずき (07/08 01:45)
    「[ジャガーさんのバンパー修理] 目次: 車以前(2025年11月21日の日記参照)、ジャガーさんの左前をぶつけてバンパーをガリ...」
  • link 26年7月3日
    すずき (07/08 00:42)
    「[ADS-Bを受信して飛行機の位置を見よう] 目次: 自宅サーバー空を飛ぶ飛行機は離陸直後や着陸寸前でもない限り飛んでいる姿は...」
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

最終更新: 09/02 23:13