April 02, 2020, 11:29:33 AM

Author Topic: C# to BMax  (Read 226 times)

Offline _PJ_

  • Jr. Member
  • **
  • Posts: 53
C# to BMax
« on: February 15, 2020, 07:43:42 PM »
There is a youtube animation that details a simple, naive cell automata algorithm for generating "caves"

I copied the essence of the code to BMax with only one significant alteration (in the video the content creator is manipulating the data whilst it is iterated - in my version the applicaiotn is made after all results are in) which seems to improve things slightly in my version.
Other than this, I'm nott really sure there should be anything different in the code execution, however, the results are radically dissimilar - is anyone able to shed light on possible reason for the differences?


The YouTube video is found here:


My BMax version (with the amendment noted above) is here:
Code: [Select]
SuperStrict

Global G:TGraphics

Global Cave:TCave

Const CAVE_WIDTH:Int=128
Const CAVE_HEIGHT:Int=72
Const CAVE_SCALE:Int = 4
Const CAVE_SMOOTHING:Int = 5
Const CAVE_FILL_PERCENTAGE:Int = 47
Const CELL_CUTOFF:Int = 4

RunTime

Function RunTime()
Initialise
Loop
CloseDown
End Function

Type TCave
Field Map:Int[0,0]

Field RandomSeed:Int

Function Create:TCave(W:Int,H:Int,Seed:Int=0)
Local NewCave:TCave= New TCave
If (Seed=0)
Seed=MilliSecs()
End If

NewCave.RandomSeed=Seed
NewCave.GenerateMap(W,H)

Return NewCave
End Function

Method GenerateMap(W:Int,H:Int)
Self.Map:Int[] = New Int[W,H]
RandomiseMap

Local Iter:Int
For Iter=1 To CAVE_SMOOTHING
SmoothMap
Next
End Method

Method RandomiseMap()
SeedRnd Self.RandomSeed
Local W:Int=Self.Map.Dimensions[0]
Local H:Int=Self.Map.Dimensions[1]

Local X:Int
Local Y:Int

For Y = 0 To H-1
For X = 0 To W-1
Self.Map[X,Y]= ( Rand(100) <= CAVE_FILL_PERCENTAGE )
Next
Next

End Method


Method SmoothMap()
Local W:Int=Self.Map.Dimensions[0]
Local H:Int=Self.Map.Dimensions[1]

Local X:Int
Local Y:Int

Local iX:Int
Local iY:Int

Local Walls:Int

Local Change:Int[W,H]

For Y = 0 To H-1
For X = 0 To W-1

Walls = WallCount(X,Y)

If (Walls = CELL_CUTOFF)
Change[X,Y]=Self.Map[X,Y]
Else
Change[X,Y]=(Walls > CELL_CUTOFF)
End If

Next
Next
X=0
Y=0
For Y=0 To H-1
For X=0 To W-1
Map[X,Y]=Change[X,Y]
Next
Next

End Method

Method WallCount:Int(X:Int,Y:Int)
Local iX:Int
Local iY:Int

Local W:Int=Self.Map.Dimensions[0]
Local H:Int=Self.Map.Dimensions[1]

Local Count:Int

For iY = Y-1 To Y+1
For iX = X-1 To X+1

If ((iX<1) Or (iX>=(W-1)) Or (iY<1) Or (iY>=(H-1)) )
Count:+1
Else
If ( (iX <> X) And ( iY <> Y ) )
Count:+Self.Map[iX,iY]
End If
End If

Next
Next

Return Count
End Method

Method Display(oX:Int=0,oY:Int=0,ScaleX:Int=1,ScaleY:Int=1)
Local W:Int=Self.Map.Dimensions[0]
Local H:Int=Self.Map.Dimensions[1]

Local X:Int
Local Y:Int

For Y = 0 To H-1
For X = 0 To W-1
If (Self.Map[X,Y])
DrawRect oX+(X * ScaleX), oY + (Y * ScaleY), ScaleX, ScaleY
End If
Next
Next

DrawText Self.RandomSeed,0,GraphicsHeight()-TextHeight("|")
End Method
End Type

Function Initialise()
InitialiseGPU
InitialiseCave
End Function

Function Loop()
While Not (KeyHit(KEY_ESCAPE))
Cls
Update
Flip
Wend
End Function

Function Update()
UpdateCave
End Function

Function UpdateCave()
Cave.Display((GraphicsWidth()*0.5)-((CAVE_WIDTH*CAVE_SCALE)*0.5),(GraphicsHeight()*0.5)-((CAVE_HEIGHT*CAVE_SCALE)*0.5),CAVE_SCALE,CAVE_SCALE)
End Function

Function InitialiseCave()
Cave = TCave.Create(CAVE_WIDTH,CAVE_HEIGHT)
End Function

Function InitialiseGPU()
G:TGraphics = Graphics(DesktopWidth(),DesktopHeight(),0,60,GRAPHICS_BACKBUFFER,0,0)
Cls
End Function

Function UnInitialise()
UnInitialiseCave
UnInitialiseGPU
End Function

Function UnInitialiseCave()
Cave.Map=Null
Cave=Null
End Function

Function UnInitialiseGPU()
EndGraphics
End Function

Function CloseDown()
UnInitialise
End
End Function


Offline _PJ_

  • Jr. Member
  • **
  • Posts: 53
Re: C# to BMax
« Reply #1 on: February 16, 2020, 08:41:12 AM »
I feel silly.
I should give myself the fresh approach of a new day before I post these things :)

It was a very basic mistake (aren't they always?)
The error was here:
Code: [Select]
If ( (iX <> X) And ( iY <> Y ) )
Count:+Self.Map[iX,iY]
End If
Which ONLY counted those cases where iX != X and iY<>Y (essentially just the four neighbouring corners) instead of a more correct:
Code: [Select]
If ( (iX = X) And ( iY =Y ) )
' Ignore the central case X,Y
Else
Count:+Self.Map[iX,iY]
End If



 

SimplePortal 2.3.6 © 2008-2014, SimplePortal