Author Topic: Help me better myself...  (Read 5166 times)

0 Members and 1 Guest are viewing this topic.

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1382
  • Karma: 83
    • View Profile
Help me better myself...
« on: June 12, 2008 »
Ok I'm starting to release more of my code and gain some confidence in my programming. I'm not yet as good as I want to be with programming in genral. Since I'm releasing source more and more it seems I would like it to be readable to the audiance.

Please provide me with tips to increase readibility. I no doubt have some really bad habits that I'm ignorant of. I'm mostly self taught so I know there are standards that I simply don't know.

Small sample:
Code: [Select]


'...
' Ryan Burnside Dungeon Engine
' Please credit "Ryan Burnside" if possible.
' This dungeon generator is meant to do just that, nothing more and nothing less
' a dungeon holds an array and rooms that overlay spaces in the array
' the dungeon array is simply called "array"
' this array holds values for walls floor and will eventually hold special data for tiles
' it is up to the programmer to defing meaningful conventions for special values
' rooms can be seeded with special values using the "add_value" command
' it is important to note that the add_value command will overwrite values if the random room spot is taken
' because of this you will want to make your stairs last and items and monster values first
'...
Strict
Framework brl.GLMax2D
Import BRL.Random
Import BRL.LinkedList

SeedRnd(MilliSecs())


' A wrapper object for an array and holder object for room instances
Type dungeon
Field array:Byte[,] , rooms:TList = New TList, rooms_maxed:Byte = False, room_count:Int = 0

Method add_room(min_width:Int, min_height:Int, max_width:Int, max_height:Int)
Local array_width:Int = array.dimensions()[0]
Local array_height:Int = array.dimensions()[1]
' first ensure that the room is not larger than the array
If max_width > array_width
max_width = array_width
End If

If max_height > array_height
max_height = array_height
End If

' ensure that the min values are larger than 0
If min_width < 2 min_width = 2
If min_height < 2 min_height = 2
' now set the size of this room
Local width:Int = Rand(min_width, max_width)
Local height:Int = Rand(min_height, max_height)
Local search_width:Int = array_width - width
Local search_height:Int = array_height - height
Local search_x:Int = Rand(0, search_width)
Local search_y:Int = Rand(0, search_height)
Local max_checks:Int = search_width * search_height
Local checked:Int = 0
Local finished:Int = 0
While Not finished
If room_count > 0
Local r:room = New room
r.x = search_x
r.y = search_y
r.x2 = search_x + width - 1
r.y2 = search_y + height - 1
Local collisions:Int = 0
For Local b:room = EachIn(rooms)
If rooms_collide(b, r) = True
collisions:+1
End If
Next
If Not collisions
carve_room(r)
ListAddFirst(rooms, r)
room_count:+1
finished = True
Else
End If
EndIf

If room_count = 0
Local r:room = New room
r.x = search_x
r.y = search_y
r.x2 = search_x + width - 1
r.y2 = search_y + height - 1
carve_room(r)
ListAddFirst(rooms, r)
room_count:+1
finished = True
Exit
EndIf

' add to the index
search_x:+1
If search_x > search_width
search_x = 0
search_y:+1
End If
If search_y > search_height
search_y = 0
End If
checked:+1
If checked = max_checks
finished = True
End If
Wend
End Method

Method carve_room(r:room)
' take a room and carve out the space needed set squares to 0's
For Local x = r.x To r.x2
For Local y = r.y To r.y2
array[x, y] = 0
Next
Next
End Method

Method ready_array(length:Int, height:Int)
' sets all indexes to 1 and readys the array for writing
Local a:Byte[length, height]
array = a
For Local x:Int = 0 To length - 1
For Local y:Int = 0 To height - 1
array[x, y] = 1
Next
Next
End Method

End Type

' A rectangular field that serves as a storage house for seeded values
Type room
Field x:Int, y:Int, x2:Int, y2:Int
End Type

' return if rooms collide (used in create_dungeon)
Function rooms_collide:Int(room1:room, room2:room)
If room1.y2 + 3 < room2.y Return 0
If room1.y - 3 > room2.y2 Return 0
If room1.x2 + 3 < room2.x Return 0
If room1.x - 3 > room2.x2 Return 0

Return 1
End Function

' connect 2 rooms (used in create_dungeon)
Function connect_rooms(room1:room, room2:room, d:dungeon)
' first pick between 2 connection styles
' we always draw from left to right so we must choose what order to process the rooms

Local x1:Int = (room1.x + room1.x2) / 2.0
Local y1:Int = (room1.y + room1.y2) / 2.0
Local x2:Int = (room2.x + room2.x2) / 2.0
Local y2:Int = (room2.y + room2.y2) / 2.0
' make sure the values for each of the x's and y's are EVEN so no corridors touch
If Float(x1 Mod 2.0)
x1:+1
End If
If Float(x2 Mod 2)
x2:+1
End If
If Float(y1 Mod 2)
y1:+1
End If
If Float(y2 Mod 2)
y2:+1
End If
draw_hori(y1, x1, x2, d)
draw_vert(x2, y1, y2, d)
End Function

' draw a verticle line on the array (used in create_dungeon)
Function draw_vert(x1:Int, y1:Int, y2:Int, d:dungeon)
' see if step multiplier is negative
Local dist:Int = Abs(y1 - y2)
Local mult:Int = 1
If y1 > y2
mult = -1
End If
' draw
For Local i = 0 To dist
d.array[x1, y1 + (i * mult)] = 0
Next
EndFunction

' draw a horizontal line on the array (used in create_dungeon)
Function draw_hori(y1:Int, x1:Int, x2:Int, d:dungeon)
' see if step multiplier is negative
Local dist:Int = Abs(x1 - x2)
Local mult:Int = 1
If x1 > x2
mult = -1
End If
' draw
For Local i = 0 To dist
d.array[x1 + (i * mult), y1] = 0
Next
EndFunction

' *IMPORTANT* lets a programmer seed the dungeon with item, monster and exit values as needed
Function add_value(d:dungeon, value:Int, attempts:Int)
For Local i:Int = 0 To attempts - 1
Local r:room = room(d.rooms.ValueAtIndex(Rand(0, CountList(d.rooms) - 1)))
d.array[Rand(r.x, r.x2), Rand(r.y, r.y2)] = value
Next
End Function

' *IMPORTANT* returns a freshly made dungeon, the workhorse of the program!
Function create_dungeon:dungeon(width:Int, height:Int, room_count:Int, room_min_height:Int, room_max_height:Int, room_min_width:Int, room_max_width:Int)
Local d:dungeon = New dungeon
'ready the array
d.ready_array(width, height)
'add rooms
For Local i = 0 To room_count - 1
d.add_room(room_min_width, room_min_height, room_max_width, room_max_height)
Next
'connect rooms in a loop
Local length:Int = CountList(d.rooms)
 
For Local j:Int = 0 To length
If j + 1 < length
connect_rooms(room(d.rooms.ValueAtIndex(j)) , room(d.rooms.ValueAtIndex(j + 1)) , d)
EndIf
Next
connect_rooms(room(d.rooms.ValueAtIndex(0)) , room(d.rooms.ValueAtIndex(length - 1)) , d)

Return d
End Function


'ENGINE ENDS!


'test here------DELETE THE FOLLOWING TO JUST HAVE THE BASE ENGINE!---------------
Local t:Float = MilliSecs()
' make a new dungeon with our create_dungeon command
Local d:dungeon = create_dungeon(50, 50, 6, 3, 12, 3, 12)
' seed the rooms with about 5 "2", these could be treasure chests if you wanted
add_value(d, 2, 5)
' seed the rooms with 1 stairway, we will call this value "3"
add_value(d, 3, 1)

' test draw dungeon please
AppTitle = "Ryan Burnside Dungeon Engine"
Graphics(640, 480)

Local tt:Int = 0
While Not KeyHit(KEY_ESCAPE)
tt:+1
If tt > 120
tt = 0
End If
' draw the dungeon values as tiles
For Local i = 0 To d.array.dimensions()[0] - 1
For Local j = 0 To d.array.dimensions()[1] - 1
If d.array[i, j]
Select d.array[i, j]
Case 1
SetColor 128, 128, 128
DrawRect(i * 8, j * 8, 7, 7)
Case 2
SetColor 255, 128, 0
DrawRect(i * 8, j * 8, 7, 7)
Case 3
SetColor 0, 128, 255
DrawRect(i * 8, j * 8, 7, 7)
EndSelect
End If

If Not d.array[i, j]
SetColor 200, 200, 200
DrawRect(i * 8, j * 8, 7, 7)
End If
Next
Next

If tt = 0  ' new dungeon!
Cls
d = create_dungeon(50, 50, 6, 3, 12, 3, 12)
add_value(d, 2, 9)
add_value(d, 3, 1)
End If
Flip
Wend
 
Challenge Trophies Won:

Offline benny!

  • Senior Member
  • DBF Aficionado
  • ********
  • Posts: 4384
  • Karma: 228
  • in this place forever!
    • View Profile
    • bennyschuetz.com - mycroBlog
Re: Help me better myself...
« Reply #1 on: June 12, 2008 »
Hmm ... code structure looks fine so far. Maybe it would be better to
export functions / set of functions, types in external files and include
them in main programm.

Furthermore, when looking at your variables you might add something
like a notation to them. E.g. Hungarian notation - or you can of course
make up your own.

I do not know if Blitz (this is the language you are coding in, eh ?)
supports object orientation - but if so - writing an complex programm
(e.g. engine) using some OO-design patterns helps a lot with logical
structuring/encapsulation of you code.
[ mycroBLOG - POUET :: whatever keeps us longing - for another breath of air - is getting rare ]

Challenge Trophies Won:

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1382
  • Karma: 83
    • View Profile
Re: Help me better myself...
« Reply #2 on: June 12, 2008 »
Thanks for the advice Benny. Most of the time my games and demos are small enough to fit into a single file. I would be willing to adopt a better structure if needed or advised to. I've never been a fan of Hungarian notation myself but would be willing to adopt depending on popularity. Again I've never really had a proper class in programming so I don't want to look like a moron with sub-par formatting.
« Last Edit: June 12, 2008 by Pixel_Outlaw »
Challenge Trophies Won:

Offline benny!

  • Senior Member
  • DBF Aficionado
  • ********
  • Posts: 4384
  • Karma: 228
  • in this place forever!
    • View Profile
    • bennyschuetz.com - mycroBlog
Re: Help me better myself...
« Reply #3 on: June 12, 2008 »
....
Most of the time my games and demos are small enough to fit into a single file.
...

True. Code of a small app/game can still be readable if all functions, types are
included in one source code.

However, seperating parts of the source has another advantage -> reusability.
Thats one key thing about classes/oo-design. Re-use classes as often as possible
and code them in a general way for several purposes.

E.g. if you have written a pngLoader function e.g. it makes sense to seperate
it in an external file and just include it so you can access it from several pro-
jects.

If you work on this loader and maybe fix bugs in it - you just have to fix those
bugs in one single file - and not in all projects which has the complete function
in it.
[ mycroBLOG - POUET :: whatever keeps us longing - for another breath of air - is getting rare ]

Challenge Trophies Won:

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1382
  • Karma: 83
    • View Profile
Re: Help me better myself...
« Reply #4 on: June 13, 2008 »

I must ask, have I commented too much here? Most people seem to comment less.
Challenge Trophies Won:

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
Re: Help me better myself...
« Reply #5 on: June 13, 2008 »
Comments are okay enough to get the point accross, I would use a smaller tab size though. maybe half the size

Challenge Trophies Won:

Offline Motorherp

  • C= 64
  • **
  • Posts: 57
  • Karma: 8
    • View Profile
    • Shmup Dev
Re: Help me better myself...
« Reply #6 on: June 13, 2008 »

I must ask, have I commented too much here? Most people seem to comment less.

It's more of a personal thing unless you're coding in a large group of programmers where other people will have to understand your code.  Just put in comments which will remind you of what's going on and how you did things at a glance for when you come back to that code months later and have forgotten the specifics of the implementation.  More important though can be to write self commenting code.  That is to always label functions correctly so that they accurately describe what they do without any hidden functionality.  The same for variables, dont use random letters and things.  Those things will help you the most when you wish to re-use all or parts of the code at a later date.

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: Help me better myself...
« Reply #7 on: June 13, 2008 »
it doesnt really matter how code is written (unless it is specifically to teach others),

as long as it work's. in time you will fall into your own style which will probably be made up from the way other folks write code you will take note of the way someone writes something and the way another person writes something else. and of course you will do stuff that no one else does.

at the end of the day there is one person that need's to be confortable with your code first and foremost and thats you...
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Help me better myself...
« Reply #8 on: June 13, 2008 »
I think you can forget hungarian notation in blitz - there's only a couple of types anyway - but if you end up coding Windows then you'll see it everywhere.  I think, in general, your code style is pretty good.  No need to change it unless you're working with another group of people with different coding rules.

If your code is small enough and concise enough then there's little need for comments.  In the amazingly large codebase I'm working in at the moment, I'm the exception that puts in the comments, just because everything is tiny.

Jim
Challenge Trophies Won: