Skip to content

Instantly share code, notes, and snippets.

@agowa
Created September 7, 2020 02:13
Show Gist options
  • Save agowa/1abceb4e279b5c142c19a769d97609e3 to your computer and use it in GitHub Desktop.
Save agowa/1abceb4e279b5c142c19a769d97609e3 to your computer and use it in GitHub Desktop.
Minecraft sugar cane farm design helper and brute forcing example
enum EnumBlock {
water
sand
}
enum EnumBlockShort {
w
s
}
function New-Board {
[OutputType([EnumBlock[]])]
param(
[Parameter(Mandatory)]$size
)
return [EnumBlock[]]::new($size*$size)
}
function Get-Cell {
param(
[Parameter(Mandatory)]$board,
[Parameter(Mandatory)]$row,
[Parameter(Mandatory)]$column,
[Parameter(Mandatory)]$size
)
return $board[($row-1)*$size + ($column-1)]
}
function Set-BoardRandom {
param(
[Parameter(Mandatory)][ref]$board
)
$max = [Enum]::GetValues([EnumBlock]).Count
foreach ($i in $(0..$($board.Value.Count - 1))) {
$board.Value.SetValue(
[EnumBlock](Get-Random -Minimum 0 -Maximum $max),
$i
)
}
}
function Format-Board {
param(
[Parameter(Mandatory)]$board,
[Parameter(Mandatory)]$size
)
foreach ($i in $(1..$($board.Count))) {
[bool]$notLastColumn = -not ($i % $size -eq 0)
Write-Host -Object "$([EnumBlockShort]$board[$i-1]) " -NoNewline:$notLastColumn
}
}
function Test-Cell {
param(
[Parameter(Mandatory)]$board,
[Parameter(Mandatory)]$size,
[Parameter(Mandatory)]$position
)
# Sand needs to have one water block adjacent to it (diagonal doesn't count)
if ($position -ge $size) {
# Not first row
# So check row above for water
if ($board[$position - $size] -eq [EnumBlock]::water) {return $true}
}
if ($position % 7 -ne 0) {
# Not left column
# So check column to the left for water
if ($board[$position - 1] -eq [EnumBlock]::water) {return $true}
}
if ($position % 7 -ne 6) {
# Not right column
# So checking column to the right for water
if ($board[$position + 1] -eq [EnumBlock]::water) {return $true}
}
if ($position -lt $board.Count - $size) {
# Not last row
# So checking row below for water
if ($board[$i + $size] -eq [EnumBlock]::water) {return $true}
}
return $false
}
function Test-Board {
param(
[Parameter(Mandatory)]$board,
[Parameter(Mandatory)]$size
)
foreach ($i in $(0..$($board.Count - 1))) {
if ($board[$i] -eq [EnumBlock]::sand) {
$cellTest = Test-Cell -board $board -size $size -position $i
if (-not $cellTest) {
return $false
}
}
}
return $true
}
function Get-SandBlockCount {
param(
[Parameter(Mandatory)]$board
)
return $board.Where{$_ -eq [EnumBlock]::sand}.Count
}
# Usage example to brutforce a optimal design for a given size
$size = 7
$board = New-Board -size $size
$boardSandCount = 0
$bestBoard = New-Board -size $size
$bestBoardSandCount = 0
[int]$i = 0
[int]$maxI = 100000
while ($i++ -lt $maxI) {
$percentComplete = ([int]($i*100/$maxI))
Write-Progress -Activity "Search in Progress" -Status "$percentComplete% Complete:" -PercentComplete $percentComplete
Set-BoardRandom -board ([ref]$board)
if (Test-Board -board $board -size $size) {
$boardSandCount = Get-SandBlockCount -board $board
if ($bestBoardSandCount -lt $boardSandCount) {
$bestBoardSandCount = $boardSandCount
$bestBoard = $board.Clone()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment