# How to calculate the area of a region of any shape (Minecraft Java Edition 1.18)

There is an armorstand on one of the red regions. How to count blocks that are including to the region the armorstand stands on? The result has to be stored to a scoreboard. Red regions can have any shape and size, and also have some number of holes.

The illustration of it is below:

• Can the shape be 3D? Jun 7 at 21:02
• No, the shape can be 2D only. Jun 7 at 21:34
• I've made a small beta that gets basic x and z but not indents in them but thats all I've been able to do youtube.com/watch?v=eIjxiOSDnB4 Jun 27 at 1:11

My idea is to use a flood fill algorithm

Before we start the loop, we do

1. Spawn a temporary armor stand (called "filled") on the start tile (if the starting point is allowed to be outside the red region, you need to add an `if` to the execute command

``````execute as @e[tag=,type=minecraft:armor_stand] at @s run summon minecraft:armor_stand ~ ~ ~ {Tags:[filled]}
``````
2. Start an loop executing every tick

``````setblock ~ ~ ~1 minecraft:redstone_block
``````
3. Reset scoreboard to 0

``````/scoreboard players set count region 0
``````

In the loop, do:

1. For each cardinal direction, try to spawn a new armor stand, if the location is not occupied and the new location is above a red wool block
``````execute as @e[tag=filled,type=minecraft:armor_stand] at @s positioned ~-1 ~ ~ unless entity @e[type=minecraft:armor_stand,tag=filled,distance=...9] if block ~ ~-1 ~ minecraft:red_wool run summon minecraft:armor_stand ~ ~ ~ {Tags:[filled]}
execute as @e[tag=filled,type=minecraft:armor_stand] at @s positioned ~1 ~ ~ unless entity @e[type=minecraft:armor_stand,tag=filled,distance=...9] if block ~ ~-1 ~ minecraft:red_wool run summon minecraft:armor_stand ~ ~ ~ {Tags:[filled]}
execute as @e[tag=filled,type=minecraft:armor_stand] at @s positioned ~ ~ ~1 unless entity @e[type=minecraft:armor_stand,tag=filled,distance=...9] if block ~ ~-1 ~ minecraft:red_wool run summon minecraft:armor_stand ~ ~ ~ {Tags:[filled]}
execute as @e[tag=filled,type=minecraft:armor_stand] at @s positioned ~ ~ ~-1 unless entity @e[type=minecraft:armor_stand,tag=filled,distance=...9] if block ~ ~-1 ~ minecraft:red_wool run summon minecraft:armor_stand ~ ~ ~ {Tags:[filled]}
``````
2. Use comparators to monitor the spawning process, if no armorstands are spawned, we have filled the area

After the loop, we need to cleanup:

1. Update the scoreboard
``````execute as @e[type=minecraft:armor_stand,tag=filled] run scoreboard players add count region 1
``````
2. Cleanup the progress armorstands
``````execute as @e[type=minecraft:armor_stand,tag=filled] run kill @s
``````
3. Stop the repeating clock
``````setblock ~ ~ ~-11 air
``````

• I know how to improve this mechanism and remove all the redstone, but the algorithm is absolutely correct. Excellent! 20 hours ago
• You could post your improved version of the algorithm in a new self-answer. It would benefit the future readers. I am not that familiar with all the command block "code golf" tricks 17 hours ago

I've created a datapack that solves this problem by the @Ferrybig's algorithm but with no redstone, functions only.

# Setup

First of all, it creates a scoreboard that will be displayed at the sidebar.

setup.mcfunction

``````scoreboard objectives add area_counter dummy
scoreboard objectives setdisplay sidebar area_counter
``````

# Main

Next, we need to set the initial value of the main counter variable. The only way to loop a mcfunction code fragment I know is by recursion, so we create another function `count_area`.

NB. I replaced most `armor_stand` with `area_effect_cloud` for optimization.

main.mcfunction

``````scoreboard players set count area_counter 0

execute as @e[tag=,type=minecraft:armor_stand] at @s run summon minecraft:area_effect_cloud ~ ~ ~ {Tags:[filled], Duration:1000}

execute as @e[tag=filled,type=minecraft:area_effect_cloud] at @s if block ~ ~-1 ~ minecraft:red_wool run function ac:count_area

execute as @e[tag=filled,type=minecraft:area_effect_cloud] run scoreboard players add count area_counter 1

kill @e[tag=filled,type=minecraft:area_effect_cloud]
``````

# Count_area

This is the most difficult part of the solution. First, we set the initial values for following variables:

count_area.mcfunction. 1/3

``````scoreboard players set has_been_executed area_counter 0
scoreboard players set north area_counter 0
scoreboard players set south area_counter 0
scoreboard players set east area_counter 0
scoreboard players set west area_counter 0
``````

Next, we check every cardinal direction for red wool block exactly like in @Ferrybig's answer.

count_area.mcfunction. 2/3

``````execute store success score north area_counter as @e[type=minecraft:area_effect_cloud,tag=filled] at @s positioned ~ ~ ~-1 unless entity @e[type=minecraft:area_effect_cloud,tag=filled,distance=...9] if block ~ ~-1 ~ minecraft:red_wool run summon minecraft:area_effect_cloud ~ ~ ~ {Tags:[filled], Duration:1000}
execute store success score south area_counter as @e[type=minecraft:area_effect_cloud,tag=filled] at @s positioned ~ ~ ~1 unless entity @e[type=minecraft:area_effect_cloud,tag=filled,distance=...9] if block ~ ~-1 ~ minecraft:red_wool run summon minecraft:area_effect_cloud ~ ~ ~ {Tags:[filled], Duration:1000}
execute store success score east area_counter as @e[type=minecraft:area_effect_cloud,tag=filled] at @s positioned ~1 ~ ~ unless entity @e[type=minecraft:area_effect_cloud,tag=filled,distance=...9] if block ~ ~-1 ~ minecraft:red_wool run summon minecraft:area_effect_cloud ~ ~ ~ {Tags:[filled], Duration:1000}
execute store success score west area_counter as @e[type=minecraft:area_effect_cloud,tag=filled] at @s positioned ~-1 ~ ~ unless entity @e[type=minecraft:area_effect_cloud,tag=filled,distance=...9] if block ~ ~-1 ~ minecraft:red_wool run summon minecraft:area_effect_cloud ~ ~ ~ {Tags:[filled], Duration:1000}
``````

Finally, we sum every successful summoning to the `has_been_executed` and check for it actually has. If it has, the function runs itself.

count_area.mcfunction. 3/3

``````scoreboard players operation has_been_executed vars += north area_counter
scoreboard players operation has_been_executed vars += south area_counter
scoreboard players operation has_been_executed vars += east area_counter
scoreboard players operation has_been_executed vars += west area_counter

execute unless score has_been_executed area_counter matches 0 run function ac:count_area
``````