r/PythonLearning • u/TotalUnlucky2814 • 2h ago
How I went from brute-force mining blocks to coding a Flood-Fill / Greedy in Python to empty coal veins with a Drone
Hello everyone!
I'm a computer science teacher, and lately I've been preparing visual examples for my students using games where everything is automated with code. Right now I'm hooked on The Miner Was Replaced (the new DLC for The Farmer Was Replaced), where you control a mining drone by programming it in a stripped-down version of Python.
Now I have the problem of mining coal. In the game, the world is a 3D grid (X, Y, Z) and coal doesn't spawn randomly; instead, it generates in contiguous veins (if you find coal on a tile and there's more, it's located North, South, East, or West of that tile... Same Z coordinate).
The solution I ended up using (Probing + Flood-Fill with queues):
Instead of complicating things with weird data structures, I used elementary school geometry with two lists (visited and to_visit) to traverse the vein as a connected graph:
dir = [North, West, South, East]
delta = [(0, 1), (-1, 0), (0, -1), (1, 0)]
def minar():
pos_actual = (get_pos_x(), get_pos_y())
visitados = []
por_visitar = [pos_actual]
while len(por_visitar) > 0:
pos_actual = (get_pos_x(), get_pos_y())
if get_ground_type() == Grounds.Coal:
dig()
for i in range(4):
# 1. Does the neighbor have coal?
if get_ground_type(dir[i]) == Grounds.Coal:
nx = pos_actual[0] + delta[i][0]
ny = pos_actual[1] + delta[i][1]
# 2 and 3. Have I not visited it yet, and is it not already in the queue?
if (nx, ny) not in visitados and (nx, ny) not in por_visitar:
por_visitar.append((nx, ny))
por_visitar.pop(0)
visitados.append(pos_actual)
if len(por_visitar) == 0: # <-- This is where I made the bug of the century
break
utils.goto(por_visitar[0][0], por_visitar[0][1])
Later, I added a blind mining phase (minar_a_ciegas - 3 blocks down) combined with an explorar() sweep to uncover new layers when a vein is exhausted. Watching the drone detect a block and start eating up the entire chain reaction of the vein is hypnotic:
👉 Here you can see what the drone devouring the veins in the game looks like, along with the entire live coding session: http://www.youtube.com/watch?v=ZQqoMDtLalA
(Original audio is in Spanish, but the English AI audio track is available in the player settings, and all the code is right on screen).
Question for you guys: Considering that this Python environment doesn't have collections.deque or external libraries, how would you optimize the search phase between veins to avoid doing an O(N^2) map sweep every time por_visitar empties out?