April 02, 2020, 11:29:33 AM

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

#### _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]
`SuperStrictGlobal G:TGraphicsGlobal Cave:TCaveConst CAVE_WIDTH:Int=128Const CAVE_HEIGHT:Int=72Const CAVE_SCALE:Int = 4Const CAVE_SMOOTHING:Int = 5Const CAVE_FILL_PERCENTAGE:Int = 47Const CELL_CUTOFF:Int = 4RunTimeFunction RunTime() Initialise Loop CloseDownEnd FunctionType 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 MethodEnd Type Function Initialise() InitialiseGPU InitialiseCaveEnd FunctionFunction Loop() While Not (KeyHit(KEY_ESCAPE)) Cls Update Flip WendEnd FunctionFunction Update() UpdateCaveEnd FunctionFunction 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 FunctionFunction InitialiseCave() Cave = TCave.Create(CAVE_WIDTH,CAVE_HEIGHT)End FunctionFunction InitialiseGPU() G:TGraphics = Graphics(DesktopWidth(),DesktopHeight(),0,60,GRAPHICS_BACKBUFFER,0,0) ClsEnd FunctionFunction UnInitialise() UnInitialiseCave UnInitialiseGPUEnd FunctionFunction UnInitialiseCave() Cave.Map=Null Cave=NullEnd FunctionFunction UnInitialiseGPU() EndGraphicsEnd FunctionFunction CloseDown() UnInitialise EndEnd Function `

#### _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