What is the Optimal Method to Mine in Minecraft

To answer this question we must first collect data. To do this I created a minecraft mod that randomly teleports the player, samples a 500x50x500 (X,Y,Z) set of blocks around the player and logs those blocks into a csv. It repeats this a total of 10 times creating 10 samples of 500x50x500 blocks

The mod can be seen here: https://github.com/JPrier/MinecraftBlocksDistribution

With this we get 128 million blocks from a single seed, doing this on multiple seeds will explode the data size

Data

Here we will use Pandas to read in the data to be used to visualize distributions.

import pandas as pd
import plotly.express as px
from IPython.display import HTML

Visualize Distributions

Here we want to visualize the blocks and their frequency

# Adjust samples to be same distance from player
df["XFromPlayer"] = df["playerX"] - df["X"]
df["ZFromPlayer"] = df["playerZ"] - df["Z"]

# Get blocks that we care about
importantBlocks = ['coal_ore', 'gold_ore', 'iron_ore', 'diamond_ore', 'lapis_ore', 'redstone_ore', 'emerald_ore']
specialBlocks = ['diamond_ore', 'lapis_ore', 'redstone_ore', 'emerald_ore']
df_blocks = df.loc[df['Block'].isin(importantBlocks)]
df_special_blocks = df.loc[df['Block'].isin(specialBlocks)]

# Get blocks for only 1 sample
df_blocks_sample_0 = df_blocks.loc[df_blocks['sample'] == 0]
df_special_sample_0 = df_special_blocks.loc[df_special_blocks['sample'] == 0]
# Create distribution plots of block vs Y level

fig = px.histogram(df_blocks, x="Y", color="Block")
# HTML(fig.to_html(include_plotlyjs='cdn'))
# HeatMaps of blocks

fig1 = px.density_heatmap(df_special_blocks, x="XFromPlayer", y="Y", title="YvsX all samples")
fig2 = px.density_heatmap(df_special_blocks, x="ZFromPlayer", y="Y", title="YvsZ all samples")
fig3 = px.density_heatmap(df_special_blocks, x="XFromPlayer", y="ZFromPlayer", title="XvsZ all samples")
fig4 = px.density_heatmap(df_special_sample_0, x="XFromPlayer", y="Y", title="YvsX sample 0")
fig5 = px.density_heatmap(df_special_sample_0, x="ZFromPlayer", y="Y", title="YvsZ sample 0")
fig6 = px.density_heatmap(df_special_sample_0, x="XFromPlayer", y="ZFromPlayer", title="XvsZ sample 0")

From these heatmaps we can see that generally all the special blocks are located around the same Y level

# 3D Scatter plot of special blocks
fig = px.scatter_3d(df_special_sample_0, x='XFromPlayer', y='ZFromPlayer', z='Y', color='Block')
fig1 = px.scatter_3d(df_special_blocks, x='XFromPlayer', y='ZFromPlayer', z='Y', color='Block')

What can we see from the Data

Looking at the graphs we can get an idea for the distribution of different blocks.

With the heatmaps we can see that the blocks we normally want to mine for stick generally to a specific set of Y values

What is the best method

Now that we have the data and have seen the distributions of blocks through our samples lets see how different methods of mining do.

Naive way

The naive and simple way to pick the best mining strat is to find the Y levels where the block you want is highest and mine there. Additionally looking at the distributions we can see that most of the blocks are distributed fairly even so strip mining would be the simpilest way to mine. But we will continue to see if those naive assumptions will hold up.

Calculating the best method

We will compare each of the methods based on these data points:

  • Number of blocks mined
  • Number of desired blocks mined
  • Reward value for blocks mined
    • Ex: reward = 10*numberOfDiamonds + 0.1*numberOfIron - 20*LavaPoolsRunInto

TODO (What to figure out)

  • Should methods be done on every level and each be compared?
  • If a player sees diamonds they will mine all of them, need to grab all visible ore
# Starting from the player calculate each of the methods at different starting levels. save each into a dataframe
def strip_mining():
    # +250X @ Y, Y+1, -250X @ Y, Y+1 -- repeat for +2Z, -2Z
    # 
    # Get range of coords. Should be an O(1) process by just selecting a set of blocks from coords given the player's starting location
    #
    # Create tuples [X, Y, Z] and get the blocks at those coords. Need to also grab all "visible" blocks (need a method to "mine")
    #
    #
    # Strip 1 xRange = [0, 250], yRange = [0, 1], zRange = [0]
    # repeat each 3 Z s.t. there are 2 blocks in between strips
    # Need zRange = [0, 3, 6, 9, ..., Z<=250]
    pass
    
# Calculate the frequency of blocks seen with each method at different levels
# Show the "Scores"