Created
September 7, 2020 02:13
-
-
Save agowa/1abceb4e279b5c142c19a769d97609e3 to your computer and use it in GitHub Desktop.
Minecraft sugar cane farm design helper and brute forcing example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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