[Game] Bulldozer

Post your working scripts, libraries and tools
User avatar
TheDewd
Posts: 1076
Joined: 19 Dec 2013, 11:16
Location: USA

[Game] Bulldozer

Post by TheDewd » 05 Jun 2018, 09:42

Bulldozer
Bulldozer is an AutoHotkey recreation of the original Bulldozer 1, Bulldozer 2, and Bulldozer 3 games created by John 'FlyMan' Hattan (The Code Zone).

Bulldozer 1 first appeared in 1994 on the CD-ROM game compilation "24 Games for Windows 95" developed by The Code Zone for Expert Software, Inc. Bulldozer 2 became available in 2000 on "Arcade Magic", also developed for Expert Software, Inc. Bulldozer 1 & Bulldozer 2 were re-released in 2003 on "Blazing Games", a compilation of fifty games developed for Cosmi Europe, Ltd. Bulldozer 3 was completed in 2002, but remained unavailable until the 2008 release of Bulldozer which included all 180 levels from the Bulldozer game series. The 2008 version was created with Adobe Flash and is available on a variety of desktop and mobile platforms. Bulldozer is a variation of the popular Sokoban puzzle game.

The object of Bulldozer is to push all of the rocks to the targets. Move the bulldozer using the keyboard's WASD or arrow keys. The bulldozer can only push one rock at a time, and it cannot pull rocks. You will advance to the next level when each rock has been placed on a target.

:arrow: All credit goes to John Hattan for the original idea of the Bulldozer game series. This project was an exercise in GDI+ and string manipulation, and is intended to pay tribute to the game I played in my youth.

Image Image


Image Download
Revision 14 (2018-08-31)

Code: Select all

; Script Information ===========================================================
; Name:         Bulldozer
; Description:  Bulldozer is an Autohotkey recreation the original Bulldozer 1,
;               Bulldozer 2, and Bulldozer 3 games originally developed by John
;               Hattan (The Code Zone).
; AHK Version:  1.1.23.00+
; OS Version:   Windows XP+
; Language:     English (United States)
; Author:       Weston Campbell <westoncampbell@gmail.com>
; Website:      https://autohotkey.com/boards/viewtopic.php?f=6&t=50139
; ==============================================================================

; Revision History =============================================================
; Revision 14 (2018-08-31)
; * Changed hotkey prevention to use window handle instead of title
; * Fixed levels 64 & 127 not applying "missing target" hotfix after restart
; * Changed Titlebar progress to only check for update when moving an object
; * Added MIDI sound effects
; ------------------------------------------------------------------------------
; Revision 13 (2018-08-28)
; * Added 'Boss Key' hotkey to quickly minimize game window using "Spacebar"
; * Added alternate 'Undo Last Move' hotkey using "Backspace"
; * Added "Page Up" & "Page Down" hotkeys to change levels
; * On-screen level number now indicates level completion status using colors
; * Minor changes to 'Level Select' screen layout
; * Automatically load last played level
; * Show levels from same collection as current level on opening 'Level Select'
; * Added 'Mouse Movement' to control the bulldozer movement with the mouse
; * Fixed level 179 to prevent bulldozer from moving outside of viewable area
; * Improved prevention of unintended tab switching of tab control
; * Fixed tab display issues when toggling menu items while not on game screen
; * Fixed 'Level Select' color status drawing issue
; * Added current level progress in the Titlebar
; ------------------------------------------------------------------------------
; Revision 12 (2018-08-14)
; * Fixed 'Undo Last Move' not working for map strings containing only digits
; ------------------------------------------------------------------------------
; Revision 11 (2018-08-07)
; * Fix memory leak from Level Select status coloring function
; ------------------------------------------------------------------------------
; Revision 10 (2018-08-06)
; * Fixed levels 64 & 127 not showing a target due to bulldozer start location
; * Added level status to the Level Select screen
; ------------------------------------------------------------------------------
; Revision 9 (2018-07-31)
; * Removed password system
; * Improved methods to prevent accidental tab switching
; * Level Select modified to choose any level without password
; * Changed how on-screen level number is displayed
; * Removed save/load
; ------------------------------------------------------------------------------
; Revision 8 (2018-07-26)
; * Fixed inadvertently switching tabs using arrow keys
; * Added additional options to the menus
; ------------------------------------------------------------------------------
; Revision 7 (2018-07-23)
; * Code optimization
; * Background color selection
; * New Fontmap for increased readability of level/password display text
; * Debug Mode
; * Save/Read settings with INI file
; ------------------------------------------------------------------------------
; Revision 6 (2018-06-18)
; * Added 'Undo Last Move' menu option -- Used only after pushing object
; ------------------------------------------------------------------------------
; Revision 5 (2018-06-12)
; * Fixed boundary tile being overwritten when pushing boulder into it
; * Added DPI scaling support
; ------------------------------------------------------------------------------
; Revision 4 (2018-06-11)
; * Added levels from Bulldozer 2 and Bulldozer 3
; * Resized level area for compatibility with maps from Bulldozer 2/Bulldozer 3
; * Optimized level drawing to update changed tiles only.
; * Redesigned 'Level Select' and 'About' menu item contents
; ------------------------------------------------------------------------------
; Revision 3 (2018-06-07)
; * Changed background image update process to prevent flickering
; ------------------------------------------------------------------------------
; Revision 2 (2018-06-06)
; * Fixed font map displaying incorrect character for numbers 8 and 9
; ------------------------------------------------------------------------------
; Revision 1 (2018-06-05)
; * Initial release
; ==============================================================================

; Auto-Execute =================================================================
#SingleInstance, Force ; Allow only one running instance of script
#Persistent ; Keep the script permanently running until terminated
#NoEnv ; Avoid checking empty variables for environment variables
#NoTrayIcon ; Disable the tray icon of the script
#KeyHistory, 0 ; Disable history of keystrokes & mouse clicks
SetWorkingDir, % A_ScriptDir ; Set the working directory of the script
SetBatchLines, -1 ; Run script at maximum speed
SetControlDelay, -1 ; Disable delay to occur after modifying a control
SendMode, Input ; The method for sending keystrokes and mouse clicks
ListLines, Off ; Disable history of executed script lines
CoordMode, Mouse, Client ; Mouse coordinates relative to active window client
OnExit("OnUnload") ; Run function when exiting the script

SetTimer, MenuItemCheck, 250 ; Toggle menu items

#IfWinActive ahk_group Bulldozer
	; Disable tab switching hotkeys
	^Tab::return ; Next tab
	^+Tab::return ; Previous tab
	^PgDn::return ; Next tab
	^PgUp::return ; Previous tab
	^+PgDn::return ; Next tab
	^+PgUp::return ; Previous tab
	^!PgDn::return ; Next tab
	^!PgUp::return ; Previous tab
	^!+PgDn::return ; Next tab
	^!+PgUp::return ; Previous tab
#IfWinActive

return ; End automatic execution
; ==============================================================================

; Functions ====================================================================
OnLoad() {
	Global ; Assume-global mode
	Static Init := OnLoad() ; Call function

	DPI := (A_ScreenDPI / 96) ; Calculate DPI scaling

	; Read values from INI file
	IniRead, BackgroundColor, Bulldozer.ini, Options, BackgroundColor, 808000 ; Olive
	IniRead, Theme, Bulldozer.ini, Options, Theme, Color
	IniRead, UnlimitedUndo, Bulldozer.ini, Options, UnlimitedUndo, 0
	IniRead, Sound, Bulldozer.ini, Options, Sound, 0
	IniRead, LevelNumber, Bulldozer.ini, Options, LevelNumber, 0 ; On-screen level number display
	IniRead, MouseMovement, Bulldozer.ini, Options, MouseMovement, 0
	IniRead, Solved, Bulldozer.ini, Options, Solved, U180 ; Solved level data
	IniRead, LastLevel, Bulldozer.ini, Options, LastLevel, 1 ; Last played level

	Solved := StrSplit(RLE_Decode(Solved)) ; Expand run-length encoded string

	; Overwrite solved level data if corrupted string
	If (Solved.Length() <> 180) {
		IniWrite, U180, Bulldozer.ini, Options, Solved ; Overwrite INI value
		Solved := StrSplit(RLE_Decode("U180")) ; Expand run-length encoded string
	}

	; Level map data
	Maps := [] ; Create array
	Maps[1] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZAAAAAAAAAAAAAAAAAAAAA8A8A8888888888A8A8AA8A8A8889998888A8A8AA8A8A8889198888A8A8AA8A8A8889099998A8A8AA8A8A8999202198A8A8AA8A8A8910259998A8A8AA8A8A8999929888A8A8AA8A8A8888919888A8A8AA8A8A8888999888A8A8AA8A8A8888888888A8A8AAAAAAAAAAAAAAAAAAAAAZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[2] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ888888888888888888888190000000000000000881900000000000000908809000000000002009088090020000000000000880900000050000000908809000000000000009088090000000000020090880900200000000000908800000000000000009188000000000000000091888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[3] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ888888888888888888888D0000000000000000D8880000000009000000888D0009999999000000D8880003000009020000888D0009001059020000D8880009900009020000888D0000900009000000D8880000900009000990888D0000999299000901D88800000000000000118888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[4] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ88888888888888888888888B88999999998888B88B88889000000988B888888B8990CCCC298888B88B88890000C00988B888888B89020020598888B88B88890200C11988B888888B890000C1198888B88B88890000999988B888888B89000098888888B88B88899999988888B88888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[5] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZA888888888888888888A8A8888999998888888A888A88895009888888A88888A889022989998A88888888890209891988888888888999099919888888888888990000198888888888889000900988888888A888900099998A88888A88889999988888A888A8888888888888888A8A888888888888888888AZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[6] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZAAAAAAAAAAAAAAAAAAAAA88AAAAAAAAAAAAAA88AA88AAA9999999AAAA88AAAAAAA900000999AAAAAAAAAA9929990009AAAAAAAAAA9500200209AAAAAAAAAA9011902099AAAAAAAAAA991190009AAAAAAAAAAAA99999999AAAAAAA88AAAAAAAAAAAAAA88AA88AAAAAAAAAAAAAA88AAAAAAAAAAAAAAAAAAAAAZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[7] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZFAFAF8888888888FAFAFAFAFA8888888888AFAFAFAFAF8899998888FAFAFAFAFA8890599988AFAFAFAFAF8890200988FAFAFAFAFA8999090998AFAFAFAFAF8919090098FAFAFAFAFA8912009098AFAFAFAFAF8910002098FAFAFAFAFA8999999998AFAFAFAFAF8888888888FAFAFAFAFA8888888888AFAFAZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[8] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ888888888888888888888C88888888888888C888888C88888888888888C88C88899999999998C888888C99050900009988C88C88902011112009C888888C90029999020988C88C88900098890099C888888C99999889999888C88C88888888888888C888888C88888888888888C888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[9] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ888888888888888888888888A8888888888A8888888AF8889999888FA88888AFA8899009888AFA888AFAF8895209888FAFA88FAFA8899209988AFAF88AFAF8899020988FAFA888AFA8891200988AFA88888AF8891131988FA8888888A8899999988A88888888888888888888888888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[10] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ8888888888888888888888E8888889999888E888888888888900988888888E8E88889920988E8E8888888899911098888888E8E8E890211098E8E8E8888888902905988888888E8E88902000988E8E888888889000999888888888E8889999988888E8888888888888888888888888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[11] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZE888888888888888888EE888889999999888888EE889999000009888888EE889000199909888888EE889090900009988888EE889090202910988888EE889090030090988888EE889019202090988888EE889900009090999888EE888909991050009888EE888900000990009888EE888999999999999888EZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[12] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZF888888888888888888F800999999000999000188009000092000200111880290500000999991118800900999200900999C88029909E902090201C888000909E92000001C8888202909E9020901C888880000099920001C888888129000000009C888888801900000000C8888888F888888888888888888FZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[13] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ888888888888888888888888999998F8F8F8F8F88C889000988F8F8F8F88888892009888F8F8F8888899900299888F8F888888900202098888F888889990C0CC0988899999989000C0CC09999900119890200200000000001198999990CCC095990011988888900000999999999888889999999888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[14] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZE888888888888888888EE899888888888888998EE899888899999998998EE899888990090598998EE899888900090098998EE899888920202098998EE899888902990098998EE899899902090998998EE899891111100988998EE899899999999988998EE899888888888888998EE888888888888888888EZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[15] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ8888888888888888888888AAA8888999999998888A888A888900000598888A888A8889029209988888AAA88889020029888888888888899202098888899999999902090999888911110099020020098889911100002002000988891111009999999999888999999998888888888888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[16] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ888899999988999888888E8891100989959988E888E89110099900098E888888911000002209888888889110090C0209888888889119990C0209888888889999020C2009888888888889002C020988888888888902002009888888E88889009900098E888E8888899999999988E888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[17] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ888888888899999888888B889999999000998B88888990905990220988888B890000200000098B88888900200999000988888B899909999929998B88888902009990119888888B890202020111988B88888900009991119888888B890220989111988B888889009998999998888888899998888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[18] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ8888888888888888888888888888888888888888888A89999999988F888888AF89000050988AF8888AFA89021100998FAF888FAF899911C0098AFA888AFA88899222098FAF8888AF88889000098AF888888A88889999998F8888888888888888888888888888888888888888888888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[19] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ8888899999999998888888F899190000009999F8888991190200209009888889111909902090098888F911111009220009F8888991111200009209888889999099999990098888F900020000000099F8888900209002902099888889029990209022098888F900059009900009F888899999999999999988ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[20] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ8888888888888888888888E888888888888E88888888E899998888888E8888E888900999888E88888888E895000999888E8888E88890C200198E88888888E890202119888E8888E888902019998E88888888E890099988888E8888E888999988888E88888888E888888888888E8888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[21] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZF888888888888888888F8999999999999999999889C1C1C1C1C1C1C1C1988912020202020200009889C0C0C0C0C0C0C0C0988912000002000000029889C0C0C0C0C0C0C0C0988910000000020002009889C0C0C0C0C0C0C0C0988910000000000200059889999999999999999998F888888888888888888FZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[22] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ888899999999988888888EE890000000988A8A888EE8900200029888E888888899990000988A8A88888888890200998888888888999900020988888888889110209909999888888891100299000098888AA891100002000098888AA891999299909598888888919890000099988888889998999999988888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[23] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ888888888888888888888B8889999999888888B88888890005098888888888B889020C0999988B88888889C02C21119888888B8B890002011198B8B88888890CC0209998888888B88900002098888B88888889990000988888888B8888899999988888B88888888888888888888888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[24] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ9999999999999999998890000000000000000998902C00020CC002000098900002CCC0000C02209891CCC000002020CC00999111C00C00C0000C2009911CC22CCCC0200C00099111C00000020CC009999111200CCC00C00009099911002C00CC000CC5098991900000000000000988999999999999999999ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[25] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ999999999998889999999000009000988990000999020090009999002009999902200091190090099002002009911999909990200099911110002209900929000111190902099090090201199929000990900020911900099009900029009999000902999090090000590000009899999999999999999998ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[26] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ999999999999999999999000900009000900095990200000020002000909990999119909990000099000911119290029990990209111190020020209900091111909090202099000991199000929000999299000099009009299900020020000090090099000900009000900000999999999999999999999ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[27] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ8888888888888888888888899999999999988D88888911009000009998888889110090200200988888891100929999009888888911000050990098888889110090900209988888899999909920209888888889020020202098888D8889000090000098888DD8899999999999988888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[28] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ9999999999999999999990090099000090005999990000200009029990099929020992902020000990002900002000000999909900020999009111199090290909090911119990000202090091111998992099900209111199889009020000000099988E900000090900009888E899999999999999988E8EZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[29] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ999999999999999999999500000999000900900990909009002002000009999990000090202929099191190000992020000991111100002000900099911111000099929929999191190000200009000999999000009009200209DDDD9009002000020209DDDD9009009009009009DDDD9999999999999999ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[30] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ999999999999999999999911100099090000900991111000000000209909911119090929992000099111900009000000090999190092090000029909900900902020999002099000002002090090990999090990922902900909900900020209000000999000090000090090005999999999999999999999ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[31] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZC99999999999999C99999000900959099009999990C090020000200C999990C0000CCCCCC0200C9C9000C00C1111C0022009992CC2CC1111C00000099000000C1111CC2CC2999002200C1111C000000990200200C00C00CCC009C999C002000200002009999990900009009000C99999C999999999999999ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[32] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ9999999A9999A99C99999000009A9119A9000009902200999119990025099009099111111900200C900000911111190020099999009991199C99C20990002220911900009009C029000200200220920990090099020099009009902000020CC020000209900900990000990090099999C999999999999999ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[33] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ999999999999999999999000090090900900C00990590C09902000200099999909000090090200099000090990C20C909C0990000002000200020009911C9922C9029C20990991191900902000209009911119022000C9209C99911119009999900000099111999000000000000999999999999999999999ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[34] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ9C9999C9999999C99C99C1111C0000000C00C0099111190C020020000009911110C90029090292099111C000200029002009911C99900C020002200C90000009C9C099C909C9900000000C000C000009909C000900020902020990C900002099020020099000005C00000C000C0C999999C99999C999C9C9ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[35] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ99999999999999999999911119E9000000000009911119E9990900929099911119E9000920020009911119E9000020092299990099E902900920200999009EE9002002009009950099992999299020099900000000900900200999000999009002009999999999E900900900000999999999999999999999ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[36] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZAFFFFFAFFFFFFAFFFFFAF00000F000005F111AFFF00000F000000AA111AFF0A0A0AA2AA0AA01111FF00020F000222001111FAFA2AFA02200AFA0AA1FF00000200A0000F0FFFAF00200A00AFA00A0A00FAA0A2AA000020022000FF00020AA000A00A0A00FF00000F0000F00F0000FAFFFFFAFFFFAFFAFFFFAZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[37] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZC99999C99C99C999999C9000009009111C50000990900000001111C000099002009000C1111C000990992999909C1111C009902000200900C11190099022090009000C022009C9900222900022002009902009009000090290099000290090000000200990090000900009009009C99C9999C9999C99C99CZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[38] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ999999C999C999999999C500000C000C000000099C09C909C009C99090C990000C0900220000000C9009090C0209020990C990000020C009220C000C9009C900C0000009C0C991191C020C002090000C9119190020C09902200991111C90002200200909911111C900000000C00999999999999999999C99ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[39] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZB888999899999999999B88889599919911199009888992001191119000098899000011111190020989900209111119909099890022909999900202098902902000099002200989009009000090200209890002209990929900098902900000020200209989900009000090000998B899999999999999998BZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[40] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ999999999999999999999009000000900090009990290202099111200209900200909911119020099099020991111900020990200009111199020009902990091119000000099000222992990099909990909009000900900009902090020099000000099000090000950000000999999999999999999999ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[41] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ999999999999999999999009009090000900900990002000000202000009990900929992990099099000200000200900200990999299290009020009909000202009999990299020022020095919111990900000900909191119909999999999091111199000000000000911111999999999999999999999ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[42] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ999999999999999999989009000009009900009990290002090000099009902002009119000002099020200911119000909990290091111119990209900090091111900920099020099991190009000999020009909090200299899020000295202900098899000900000009000988899999999999999999ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[43] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ99999999999999999AAA90020001111900009999900000011110000000099090999999999900000990920009000000999119900200092299900091199020999020000000911990209000202090099119900900220902099000999599029002002000009A9900000009900000099AA99999999999999999AAZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[44] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZCCCCCCCCCCCCCCCCCCCCC000000009000950900CC022009229090900990CC009020209220900000CC909009009090900900CC000990000000900000CC000902090009000900CC020920900090020911CC920900999900009111CC002000000000091111CC000900900000911111CCCCCCCCCCCCCCCCCCCCCZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[45] := "XZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ999999999998889999999000009000988990000999020090009999002009999902200091190090099002002009911999909990200099911110002209900929000111190902099090090201199929000990900020911900099009900029009999000902999090090000590000009899999999999999999998ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[46] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ999999999999999999999000900090000900095990002002000009020909992902999090000229099009009199900920200990092911119009099909902009111119900009099920091911119220200990099999911990900909900200000000020999099000900090000000090999999999999999999999ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[47] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZDDDDDDDDDDDDDDDDDDDDD090909000959900090DD000000000000020000DD009929099999020909DD900009911111900900DD929929111119992920DD000909911111900909DD002000099119900900DD020900020002002220DD902002909009002000DD000990009009000000DDDDDDDDDDDDDDDDDDDDDZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[48] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ88888889999999999988888888890000000009888888888900002020098899999989020CCCCC098890000999990200CC29889000000020200000098890000000000990CC098890000995999990CC098890000999988890CC0998911119888888902000989111198888889000009899999988888899999998ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[49] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ999999999999988888889000000000009888888890999022000098888888900090200200988888889002999929999998888890209900000000999998900220200000000111989990990229000001119888909900090000011198889000000900000111988899959999999999999888899998888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[50] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ889999999888888888888890000099999999988888900000900009009988889020009000202009888890020090020990098888902200992020000988889909009909999999888899090099000011198888900920000000111988889000220000001119888890000099590011198888999999999999999988ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[51] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ9999999999999999999990900000900000000009900000002009909990999999900990002002000999119900909020909009911110020000099290999111100299999000929999119090090009002009F9919090020002009059F9002002090009009999F9000000099999999FFFF999999999FFFFFFFFFFZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[52] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ8888888888888888888888A88A88A88A88A88A888888888999998888888888A88999005988888A888888890021099888888888A88900121098888A888888899903209888888888A88889000998888A888888888999998888888888A88A88A88A88A88A888888888888888888888888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[53] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ888888888889999888888BBBB99999990598EEE88BBB8900000200988EE88BB889000299029888E88B88899291119098888888888890211100988888888888909101909988888E8888900090920988B88EE88892002000098BB88EEE889009999999BBB88EEEE89999888888888888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[54] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ999999999999999999999999009009999999999999990090091119999999999002900911100999999990209220111009999999900290091110199999999000902999999999999999200000002020999999990090022090009999999999999009922599999999999990000009999999999999999999999999ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[55] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZDDDD8888888888888888DEED8889999999988888DEED8889000910988888DDDD8899002111988888888888900209319888888888899099290998888888888900020020988888888889000900009888888888899999995098DDDD8888888888899998DEED8888888888888888DEED8888888888888888DDDDZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[56] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ88888888888888888888888E88888888888E8888888E88999999988E8888888E88900C00988E8888888E88902020988E8888888E88901310988E8888888E899C111C988E8888888E89002220988E8888888E89000500988E8888888E89999999988E8888888E88888888888E888888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[57] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ888888888899998888888899999999900998888889900200000020999998890009909900099111988909220202292991119889090005000900011198890029099922000111988902002200209911119889992000000099999998888900999999988888888B899998888888BBBBB888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[58] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ9999999999999999999E9000059900000090009E9000099000020000209E900999111190909009999000911119090902000999909111900900000009E9009919000002000209E9002020999009090999E9020000000909020009E9990200290909090209EEE90000000009090099EEE9999999999999999EZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[59] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ888888888888888888888C88888888888888C888888C88888888888888C88C88888899999988C888888C88999000098888C88C88899102990998C888888C89112020059888C88C88891102020998C888888C89999990098888C88C88888888999988C888888C88888888888888C888888888888888888888ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[60] := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ9999AAAAAAAA999999999009999999999000005990290000900000999999900000099990009009AA999990000000009009AA900020000000009009999002999900900090000990C09009119299900C0990C09209119002002209900000091190090009099000900911900900090999999999999999999999ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	Maps[61] := "888888888888888888888888888888888888888888888BBBB8888888888888888888889998B8888888888999999198B8888888888910020098B8888888888990CCC29888888888888892CCC0998888888888B8906020198888888888B8919999998888888888B8999888888888888888888888BBBB88888888888888888888888888888888888888888888888888888888888888888888888888888888888888"
	Maps[62] := "88888888888888888888800000000000000000088000000000000000000882C09999999999990C0880C09999999999990C0881C09999999999990C0880C09991020999990C0880C09999990999990C0880C09999994099990C0880C09999999099990C0880C09999999099990C1880C09999999099990C0880C09999999299990C28800000000200010000088000000000010000000888888888888888888888"
	Maps[63] := "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA888888888888888888888888888888888888888888899999999999999888888900000000000098888889009999999900988888890090000009009888888900900040090098888889099000000900988888890090000009909888888910200000020198888889999999999999988888888888888888888888BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
	Maps[64] := "8888888888888888888888DDDDDDDDDDDDDDDD8888DEEEEEEEEEEEEEED8888DECCCCCCCCCCCCED8888DEC9999999999CED8888DEC9120000219CED8888DEC9090920909CED8888DEC9090910909CED8888DEC9090490909CED8888DEC9090290909CED8888DEC9120000219CED8888DEC9999999999CED8888DECCCCCCCCCCCCED8888DEEEEEEEEEEEEEED8888DDDDDDDDDDDDDDDD8888888888888888888888"
	Maps[65] := "B888888888888888888BB888888888888888888BB899999999999999998BB890000099790011198BB890002200000011198BB890092000000011198BB899090099000011198BB899090099099999998BB890220099202000098BB890020090020990098BB890200090002020098BB890000090000900998BB890000099999999988BB899999998888888888BB888888888888888888BB888888888888888888B"
	Maps[66] := "AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBB888888888888888888888899999988888888888888900009899998888888889099099900999999988890911100000200009888909919909099000098889001119090200229988890911190922200098888909090909020022988889000000090790009888899999999999999998888888888888888888888AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBB"
	Maps[67] := "FFFFFFFFFFFFFFFFFFFFF888888999999999998FF888888900000000098FF888888900002020098F99999989020CCCCC098F90000999990200CC298F9000000020200000098F9000000000000000098F90000000000990CC098F90000997999990CC098F90000999988890CC099F9111198888889020009F9111198888889000009F9999998888889999999FF888888888888888888FFFFFFFFFFFFFFFFFFFFF"
	Maps[68] := "D88888888A888888888D8D8888888A88888888D888D89998999999988D88888D91989000009998888888919992CCC0959888888891100002000098888888911002CC000098888888911020CC09999888AAAA9999000209AAAAAA8888888902009988888888889999000098D88888888890020002988D8888888D900000009888D88888D89999999998888D888D8888888A88888888D8D88888888A888888888D"
	Maps[69] := "CCCCCCCCCCCCCCCCCCCCC888888888888888888CC888888888899998888CC889999999990099988CC889002020000011988CC889000209900011988CC889000209900011988CC889000029900011988CC889000009900011988CC889990999999999988CC888902999599900988CC888900200000020988CC888902099990020988CC88890009AA90000988CC88899999AA99999988CCCCCCCCCCCCCCCCCCCCC"
	Maps[70] := "EEEEEEEEEEEEEEEEEEEE88888888888BD888EEEE99999999999B8D888EEE90000900009B88D888EE90020900009B888D888E90200900009BB888D88E90020900209BBB888D8E99000200209BBBB888DEE9099900209BBBBBBBBB99020999299999999999902209000000000011199020090000000000111990000900000000001119999499000000000011198899999999999999999988888888888888888888"
	Maps[71] := "DD8888888888888888DDDD8888888888888888DDDD8888888888999888DD999999999999949998DD911100000900000098DD9111000009000CC098DD9111000009220CC0999D9111000000002022009D9999900000000CC0209DDD889999992CCCC2009DDD888890020020C0009DDD888890000220CCC09DDD88889000000000009DDD88889999999999999DDD8888888888888888DDDD8888888888888888DD"
	Maps[72] := "99999EEEEE999999999990009EEEEE900000000990C09999999020C0C00990C1100000000CC0020990C1CCCCCCCC00C0020990C1C020000002CCC209900000CCCCC020C000099991CCCC0CC002720009E90111C000C022290099E911110000C00209999EE91CCCC00CCCC00009EEE91100C00000CCCC09EE999900CCCCC0000009EE902002000C00099999EE90000009000099EEEEEE9999999999999EEEEEEE"
	Maps[73] := "CCCCCCCCCCCCCCCCCCCCC11C0000C0000000000CC1200200C22002CC02CCC12C00CCC00CC0CC000CC00C020C00220002000CC0CCC00C0C00C200CCCCC00CC0C02000C40C000CC020000200CC1CC0020CC00C02C02C0200000CCCC00C00C00C000CCC000CC00CCCCCCCC0C000000CC00000000000C00C1C1CCC2CCCCCCCC2C000111CC00001300C0000CC1C1CC013111300020011111CCCCCCCCCCCCCCCCCCCCC"
	Maps[74] := "88888888888888888888888888888888888CCCC8999998888888888CBBC8900099999999998CBBC8900090000000098CBBC8902200002020098CBBC8902099099999098CBBC8902099290002298CCCC89002990909990988888890000202099909999998900099000000001111989999990000000011119888888900000000111198888889959999999999988888889998888888888888888888888888888888"
	Maps[75] := "888888888888888888888888888888888888888888BBBBBBB9999999998888BFFFFFB9009000098888BBBBBBB900220009888899999999002009998888911100990990995998889111009920020000988891110000220220009888911100990200020098889999999909999099988888888889000002098888888888890990000988888888888900009999888888888889999998888888888888888888888888"
	Maps[76] := "89999999999999888888891111111199998888888911199990900999998889111900999000020988891112200000202009888900190020290200998889111909290002009888891909020002000098888910092999299992988889900900020200009888889009002520090098888890090999902002988888900900009990009888889009022098999998888890090000988888888888999999999888888888"
	Maps[77] := "88888888888888888888889999999998999999988890099000989000009888900020009890999098889000200099902090988890299000000220009888900990009999000098889909999999999995988890299EE9000011999888900099990000119888889002200000001198888890209999000011988888900098890000119888889999988999999998888888888888888888888888888888888888888888"
	Maps[78] := "BC8888888888888888CBBC9999999999999999CBBC9000000000911119CBBC9000020000011119CBBC9999909900911119CBBC9000020909990009CBBC9009900009000009CBBC9909002909099999CBBC8909020209090009CBBC8909002009000009CBBC8909299999999099CBBC8902520200002009CBBC8900200009990009CBBC8999900099899999CBBC8888999998888888CBBC8888888888888888CB"
	Maps[79] := "EEEEEEEEEEEEEEEEEEEEEEEEEEEE99999999999EEEEEEEEE90009000009EE99999EE90000020209EE90009999902990C099EE902099000C09902009EE902006220C09922209EE990CCC000C09900009EE890C000CCC09999929EE990C00000200911119EE900CCC0990209111199E9020002090009112109E9009902090099111109E9999900099999911199EEEEE99999EEEE99999EEEEEEEEEEEEEEEEEEEEE"
	Maps[80] := "FFFFFFFFFFFFFFFFFFFF8888888888888888888899999999999999999999900000900000091119E99000009005000991119990909099299099011119900020900022200111199992999022009990991990000020090000909999900200900999009090099909299000020022000990002099000900909009900000900009009000099999999999999999999988888888888888888888FFFFFFFFFFFFFFFFFFFF"
	Maps[81] := "DDD9999999999DDDDDDDD889000000009999888DD889099999909009988DD889090202020020988DD889000000092000988DD889992002290099988DD888890099090299888DD888899290002079888DD888889002020999888DD888889090002009888DD888889099000909888DD888899009999909888DD888890000000009888DD888891111111999888DD888891111111988888DDDDDD999999999DDDDDD"
	Maps[82] := "99999999EEE999999999999990099999009999999888900025200098888999999202020202999999988990202020209988899999020202020209999998890000000000098889999999999099999999999888888900098888888999999999000999999999988889313131398888899999991313131999999998888931313139888889999999131313199999999888893139313988888999999999999999999999"
	Maps[83] := "8888888888888888888888888888888888888888999999999999999999999090000090000000000990000000200C9099C09999999009C000200200099911990090C020C090099111100200000992C0999111100299C990009299991190C009000C002009E991C090020002009079E9002002090009009999E9000000099999999DDDE999999999DDDDDDDDDD8888888888888888888888888888888888888888"
	Maps[84] := "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00000CCC11CCC00000CC02200CCC11CCC00260CC00C0CC111111C00200CC00000C111111C00200CCCCC00CCC11CCCCCC20CC0002220C11C0000C00CC02C000200200220C20CC00C00CC0200CC00C00CC02000020CC02000020CC00C00CC0000CC00C00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
	Maps[85] := "889999998999999BBBBB889000098900009BBBBB899099099902009BBBBB890220000022009BBBBB8900209909909099999B8909020200009090009B89020020090990900099890090920009909000098999909009999090990988900202990090000009889020200000909099998990990999009001111989000909990009011119890002290004001111198900090000909991111989999999999998999999"
	Maps[86] := "DDDDDDDDDDDDDDDDDDDD8888888888888888888899999999999999999999900900009000090090099000290090000000200990200900900009029009999002229000220020099022090009000902200990200020090091119009909929999099111190099002009000911119000990900000001111900509900000900911190000099999999999999999999988888888888888888888DDDDDDDDDDDDDDDDDDDD"
	Maps[87] := "888888888888888888888888888888888888888899999999999999999999900090091190090009099000000911900900090990909209119002002209909090091192999009099002999900900090000990002000000000900999999990000000009009EE900000099990009009EE9029000090000099999990099999999990000079999988888888999999998888888888888888888888888888888888888888"
	Maps[88] := "88999988888888888888899009988888888888888902009999999999999989000090111111111119899202901CCCCCCC0C19899000990CCCCCCC0C19897222000000000000198900009909999999900989999902200098889999888902000020988888888889020022099888888888890022009988ABAB8888890000099888BABA8888899000998888ABAB8888889999988888BABA8888888888888888888888"
	Maps[89] := "89898989898989898989989898989898989898989999999999999989999990099000000009991119900000099999009111199999029900022091111990090200020900919119909902992099229991199000200020002000000990990990290990900009900020900900009099999900020002099090970990090090090900900009999999999999999999998989898989898989898998989898989898989898"
	Maps[90] := "DDDDDDDDDDDDDDDDDDDD88888888888888888888CCCCCCCCCCCCCCCCCCCCC000000009000900960CC022009229090900990CC009020209220900000CC909009009090900900CC000990000000900000CC000902090009000900CC020920900090020911CC920900999900009111CC002000000000091111CC000900900000911111CCCCCCCCCCCCCCCCCCCCC88888888888888888888DDDDDDDDDDDDDDDDDDDD"
	Maps[91] := "888888888888888888888DDDD8899998DDDDDDD88DDD88990098DDDDDDD88DD889900098DDDDDDD88D889902209888DDDDD88D899020029998888DD88D8900020000999988888D8900999990900999888D8902111190900009888D8909111102000909888D890911319090200988888909990999900999888899299002709999888888900000209998888DD888900099009888DDDDD888999999999888888888"
	Maps[92] := "888888888888888888888888888888888888888888889999999999999998888890900009009000999999900200020000200990200200C00C00CCC0099002200C1111C00000099000000C1111CC2CC299992CC2CC1111C00000099000C00C1111C002200990C0000CCCCCC020099990C0900200002009998890009009094990098888999999999999999988888888888888888888888888888888888888888888"
	Maps[93] := "88888888888888888888BBBBBBBBBBBBBBBBBBBB9999999999999999999B9090090000790000009B900029009999000902999090002091190009900990900902011999290009900929000111190902099020009991111000220990020020099119999099999902200091190090099902009000999900200990000090009BB990000999999999999BBB999999BBBBBBBBBBBBBBBBBBBB88888888888888888888"
	Maps[94] := "99998888888888888888900999999999999998A8900900011911111198A8900909099999011198A899290000111111119888900099299999900999989020900000999999409899209020009999990098900209222990000000989000000C0000C2C299989099990C2222200009889090000200000C00098890900099000000009998909999992999999020989000000009EEEE9000989999999999EEEE999998"
	Maps[95] := "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB9999999999999999999B9009000090990001119990990200000000011119900002999290909111199090000000900009111990992000009029009199902009990202090090099099090090200200000990900920922909909099990000009020200090099700090090000090000999999999999999999999BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
	Maps[96] := "AAAAAAAAAAAAAAAAAAAA8888888888888888888899999999999999999999911119000000090090099111190C020020000009911110CC00290902C2099111900020002900200991199990090200022009900000099990999909999000000009000900000990CC000900020902020990CC000020CC02002009900000790000090009099999999999999999999988888888888888888888AAAAAAAAAAAAAAAAAAAA"
	Maps[97] := "888888888888888888888888888888888888888888999999999999999999899190000000000000099911002C00CC000CC6099111200CCC00C00009099111C00000020CC00999911CC22CCCC0200C00099111C00C00C0000C200991CCC000002020CC0099900002CCC0000C022098902C00020CC00200009890000000000000000998999999999999999999888888888888888888888888888888888888888888"
	Maps[98] := "8888888888888888888888888888888888888888999999999999999999999490009000900009000990900020002000000209900000CCC0CC11CCC09990CCC200C2C1111C00099020200200C1111C020990202090C0C1111C00099000C29000CC11CC0009992C00900CC0000CC299900C009000002002000990000090009000090009999999999999999999998888888888888888888888888888888888888888"
	Maps[99] := "88888888888888888888DDDDDDDDDDDDDDDDDDDD9999999999999999999B9000009900000090009B9050099000020000209B900999111190909009999000911119090902000999909111900900000009A9009919000002000209A9002020999009090999A9020000000909020009A9990200290909090209AAA90000000009090099AAA9999999999999999EFFFFFFFFFFFFFFFFFFFF88888888888888888888"
	Maps[100] := "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB999999999999999999999400000900090000000999099909900999909099900009090022000000099009090902090209909990000020900922090009900999009000000990999119190209002090000991191900209099022009911119900022002009099111119900000000900999999999999999999999BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
	Maps[101] := "EEEEEEEEEEEEEEEEEEEE8888888888888888888899999999999999999998900900000090009000999029020209911120020990020090991111902009909902099111190002099020000911119902000990299009111900000009900022299299009990999090900900090090000990209002009900000009900009000096000000099999999999999999999988888888888888888888EEEEEEEEEEEEEEEEEEEE"
	Maps[102] := "888888888888AAAAAAAA888888888888A8888888999999999999999999999609009090000900900990002000000202000009990C00929C929900C90990002000002009002009909C929C29000902000990C00020200999999029902002202009A9191119999000009009A9191119889999999999A9111119888888888888A9111119AAAAAAAAAAAAA99999998888888888888888888888888888888888888888"
	Maps[103] := "9999999999999998888891111111111001999988911111111112219009889999999999920C00099890000002002001002098900C2CC000C0020C00989000000C000CC00C09989002C00C0CC00CCC09989020C2CCC0000C8C09989990020C00C00CCC0998999000020CC0C00C0998890200C002002020009889002002C22200900098890090020000009999988905990090090098888889999999999999988888"
	Maps[104] := "EEEEEEEEEEEEEEEEEEEE888888888888888888888CCCCCCCCCCCCCCCCC88CC0000000CC000C00CC8C5CC02C00200200000C8C00C00220C020CC000CCC020C0002020C00CC11CC020CCC020002000C11CC002000C22CCC000C11CC0C2000C000000CCC11CC0C0CCCCCCCCCC00000CC000000111100000000CC0000001111C0000CCCCCCCCCCCCCCCCCCCCC88888888888888888888888EEEEEEEEEEEEEEEEEEEE"
	Maps[105] := "888888899998888888888FFFF8890099999888888FFFF889200000998888888889990CC0020998888888890020C0202698888888892000CC099998888888890202C1111988888888992000C1111988888888990220011119888888889000209011198888888890020299999988888888999000988888888888888999029888888888888888890098888FFFF8888888899998888FFFF888888888888888888888"
	Maps[106] := "8888999999999888888888889111100099888888888891C1C00209988888888991111C0C07998888888901111C00C0099888888900000C20CC209888888990CCC002000098888888920020202C009888888890C002020CC098888888900CCC00CC009888888890000CC0CC099888888890020C002009888888889992020009998888888888900999998888888888889999888888888888888888888888888888"
	Maps[107] := "8888888888888888888888888899999999888888899999900000099998888970002020C90000988889920202C29C0C9098888990220091111110999889000900C111111000988900200291111110C09889020C22011111129098899020029C909C900098889020020020020099988890200200200200988888999999000999999888888888899999888888888BBBBB88888888BBBBB888888888888888888888"
	Maps[108] := "8888888888888888888889999988AAAAAAAAAAA889000998888888888888890200999999999888888990C0900000009999998990C0002C29400900098900C0000002090002098900CCC09999999990998900CC0113111110909E8990CC031311313090998902CC099999990992098900200020020000200989009000900090009009899999999999999999998888888888888888888888888888888888888888"
	Maps[109] := "99999999999999999999C9C9C9C9C9C9C9C9C9C9CCCCCCCCCCCCCCCCCCCCC000C000C0000C000C0CC000200200000C020C0CCC2C02CCC0C000022C0CC00C00C1CCC00C20200CC00C2C1111C00C0CCC0CC0200C11111CC0000C0CCC200C1C1111C220200CC00CCCCCC11CC0C00C0CC00200000000020CCC0CC000C000C00000000C5CCCCCCCCCCCCCCCCCCCCC9C9C9C9C9C9C9C9C9C9C99999999999999999999"
	Maps[110] := "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE9999999999999999EEEE9499919911199009EEE99200119111900009EE990000111111900209E9900209111119909099E9002290999990020209E9029020000990022009E9009009000090200209E9000220999092990009E9029000000202002099E990000900009000099EEE9999999999999999EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
	Maps[111] := "888888888888888888888CCCCCCCCCCCC89999988C8888888888889000988C8888889999999090988C8899999952000000988C8890009990299020988888902000020999909889999029009099A990988900000029909999009989099099090020092009890911190900000000098900111009990099999989091119098999988888890909990988888888C889000000098CCCCCCCC889999999998888888888"
	Maps[112] := "888888888889999988888DDDDDD88889111988A88DDDDDD88899111988A88DD888899991111988A88DD899991111119999888DD890000011119009888DD89029990099900998888890090092902020988999909920020000209889002220009090090098890000020290992009988900902020900200298889999000026209200988888890000900990099888888999999999900988888888888888889999888"
	Maps[113] := "8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D999999999999999999999000000900900099000990002009009092002099902220020002000902099009009911990000200999090091111199090009902929991111192992999009009111119900009999090209999909299009900002000000000000099090009949000909090999999999999999999999D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8"
	Maps[114] := "E8888888888888888888E89998888888888CCCC8E89099888899998888C8E8900999999009998888E8900090202202099988E8900207020000200988E8902090920020000988E8900990909990999988E8909900009002009888E89991110990202098C8E89911119900020098C8E89111199020029998C8E89111999002009888C8E891119F9009999888C8E899999F99998888CCC8E8888888888888888888"
	Maps[115] := "AA999998888888888888AA900099999988999998AA902020200999900098A9900CC0CC0990002098A9020020000020200098990000099099002099989022999990999990988890000099709E999299889900209992999002098889990099900090020988888902200090202209888889009900090000098888899991011999999988888891111111119888888888911111111198888888889999999999988888"
	Maps[116] := "899999999999DFDFDFDF891111110009999999998911111100090099000989119990200002000009891110202090009900098911192999990000900989990000900092009209888900220202002990098889002000929209920988899909909000099009888890020209909999998888900002002009888888889900090900098888888889999959999988888888888889998888888888888888888888888888"
	Maps[117] := "99999999999999999999999999999900099999999999999902200900009999999999000209222099999009992020290200999990000000900020009999909999909009992099900100099020020009999991CC099909999909999111100900209902009991110C090220990200999111100920220000009991111997020099220099911119900000990009999111199999999999999999999999999999999999"
	Maps[118] := "CD8989999999999998F88FE8B9000000000099ADB8A98900C002202009E9888F892002C00C0079CB9CB8990C00C020C09988A88F9000200200C098EC89ED9000C02000C09DA8D8C8900202000000989FCBA8900000CC00209CB8888890000CC022C098E8F9999992200090009888E91111900999999998FDC91C1110998B88D898898911110009F88E8C8B8AA9111100098C8B8888AE89999999998D88F8E88D"
	Maps[119] := "88888888888888888888888888888888888888889999999999999E9999999000000000009E9111199909290090999E9111199000200290009E9111199922900200009E9111199002029009209EE900999009002002009EE9009990020992999299990069900200900900000000999999002009009990009E9000009009009E99999E9999999999999EEEEEEE8888888888888888888888888888888888888888"
	Maps[120] := "888888888888888888888FFFFFFFFFFFFFFFFFF88FFFF88888888FFFFFF88FFF88999999888888888888899060099999998899999902CC200002098890020020000022020988902CC00C0CCC0CC009889000020C000020009988992CC02CC2900000988890020200209999999998900C0900C0091111119890000900200911111198902C090CC200111119989900090000900011198889999999999999999988"
	Maps[121] := "88888888888888888888888888888888888888888888899999999998888888888888888888988888888889999999989888888888891000009898888888888999020098988888888888890000989888888888898907009888888888888989002099988888888889890000019888888888898999999998888888888988888888888888888889999999999888888888888888888888888888888888888888888888"
	Maps[122] := "88888888888888888888888AAA8888888AAAA888888A88888888888AA888888A89999999998AA888888889100000098888888888899990CC0998888888888900000020988888888889000040009888888888890200000098888888888990CC099998888888888890000010988888888AA89999999998A888888AA88888888888A888888AAAA8888888AAA8888888888888888888888888888888888888888888"
	Maps[123] := "8888888888888888888888888888888888888888888888888888888888888888899999999999888888888910900000098888888889009000C009888888888930900000298888888889000070000988888888892000009039888888888900C00090098888888889000000901988888888899999999999888888888888888888888888888888888888888888888888888888888888888888888888888888888888"
	Maps[124] := "8888888DDD88888888888888888DDD88888888888888888DDD8888888888888888888888888888888AAAA8899999888888888AAAA8896009888888888AAAA8890229998888888AAAA8891210198BBBB8888888899900098BBBB8888888888900098BBBB8888888888999998BBBB88888888888888888888888888888888FFF88888888888888888FFF88888888888888888FFF88888888888888888888888888"
	Maps[125] := "88888888888888888888888888888888888888888888889999999998888888888890000000988888888888900CCC009888888888889001010098888888888890001000988888888888999000999888888888888890C0988888888888888892229888888888888888907098888888888B888899999888B888888B888888888888B888888B888888888888B88888BBB8888888888BBB8888888888888888888888"
	Maps[126] := "888888888888888888888888BBB88B88888888B888B888BBBB88BBBB888888B888888888888888888888899999999888888888888900000099888B8888BB8901909109888B88888B8900901009888B88888B8902220009888B88888B8900040099888BB8888B8999999998888BB8888B8888888888888888888BBB888888888B88888888B88888BBBBBB88888B88888888B88888888888888888888888888888"
	Maps[127] := "88888888888888888888888888888888888888888AAA899999999998AAA88AAA890243101098AAA88AAA890299209098AAA88AAA890000000098AAA88AAA899902909998AAA88AAA888910909888AAA8888888890000988888888FFF888900009888FFF88FFF888999999888FFF88FFF888888888888FFF88FFF888AAAAAA888FFF88FFF888AAAAAA888FFF88FFF888AAAAAA888FFF888888888888888888888"
	Maps[128] := "FAFAFAFAFAFAFAFAFAFAAFAFAFAFAFAFAFAFAFAFFAFAFAFAFAFAFAFAFAFAAFAFA999999999AFAFAFFAFAF900901209FAFAFAAFAFA900009909AFAFAFFAFAF900000249FAFAFAAFAFA990902099AFAFAFFAFAFA9190909AFAFAFAAFAFAF9100009FAFAFAFFAFAFA9000999AFAFAFAAFAFAF99999FAFAFAFAFFAFAFAFAFAFAFAFAFAFAAFAFAFAFAFAFAFAFAFAFFAFAFAFAFAFAFAFAFAFAAFAFAFAFAFAFAFAFAFAF"
	Maps[129] := "8889999999999999998888888888888888888888898889999999999988898988888888888888888989898999999999998989898989000000000989898989890022522009898989898901111111098989898989000000000989898989890C2C2C2C098989898989000000000989898989899999999999898989888888888888888889898889999999999988898888888888888888888888899999999999999988"
	Maps[130] := "88988888898888889888888888888888888888888888888888889888888888889888888888888988888888999888889888888988899099998888888888888900100999888888888889009002098888888988890190990988889888888990220109888888888888900400098888888888889999999988888888888888888888888988889888888888888888888888888988889888888888888888888888888888"
	Maps[131] := "8888888888888888888888988E8888B8888D888888888888888888888898888F888C8888888A88888D88899999999988888888888901000109888E888888890900990988888888888902200909888C8888B889420001098888888888899999000988888888A88888899999888B88888888888888888888888888888F8888888888888E88C888888888D888F88888888889888888A88888888888888888888888"
	Maps[132] := "AAAAA8888888888AAAAAAA8888888888888888AAA888888888888888888AA888899999999999888AA888890000004009888A8888890001C22209888888888900000002098888888889000999010988888888890C09390C0988888888890109990009888888888900000000098888A888890000C10009888AA888890000000009888AA888899999999999888AAA8888888888888888AAAAAAA8888888888AAAAA"
	Maps[133] := "888888888888888888888888888888888888888888F8AAAAAAAAAAAA8F8888F8A8888888888A8F8888F8A8999999998A8F8888F8A8910990098A8F8888F8A8900992098A8F8888F8A8900901098A8F8888F8A890000C098A8F8888F8A892CC02098A8F8888F8A8942113098A8F8888F8A8999999998A8F8888F8A8888888888A8F8888F8AAAAAAAAAAAA8F888888888888888888888888888888888888888888"
	Maps[134] := "8888888888888888888888888888888EEEEEEEE88888889999888888888888888990099999999988899999000000000009988911099000CC0CC0009889110992C2202422C09889110000C0000000C0988911000000CCC2C0209889110099220000000098899999990000000099988888888999999900988888888888888889999888888888888888888888888EEEEEEE88888888888888888888888888888888"
	Maps[135] := "8888888888888888888889988888888888888888899888888888888899888888899888888888998888888998999998888888888888889007988888888888889992C098888888888888900120988899888888889000199888998889988890200988888888899888910099888888888888889999988998888888888888888889988888888998888888888888888889988888888888888888888888888888888888"
	Maps[136] := "88888888888888888888888E88999999888E8888888E88900009888E8888888E88902009888E8888888E88999009888E8888888E88889099988E8888888E88899000988E8888888E88890020988E8888888E88890000988E8888888E88899229988E8888888E88894200988E8888888E88892110988E8888888E88891111988E8888888E88899999988E88888888888888888888888888888888888888888888"
	Maps[137] := "8888888888888888888889999989998999989998899888888888888899888988AA899999999899988998AA890210009888988898AA890CC2019889988998888900C0C19899988998899900C0C0988888899899000000009899988998900092CC20989988888890099411209898888998999999999998999889988888888888889998899999999889899889888899988999998999999888888888888888888888"
	Maps[138] := "888888888888888888888BB88888888888888BB88BB88888888888888BB888888999999999988888888889000110009888888888890C0000C2988888888889000CC2C09888888888890C0CC0009888888888891C0200C1988888888889120990009888888888892099990098888888888949988990988888888889998888999888888BB88888888888888BB88BB88888888888888BB888888888888888888888"
	Maps[139] := "888888888888888888888888888888888888888888EEEEEE8999998EE88888EEEEEE8940098EE88888EE88888922298EE88888EE8899990C098EE88888EE8990000C098EE88888EE8902C001098EE88888888930CC0C098EE888888889100C0C098EE888888889900001198EE888888888999999998EE888888888888888888EE88888EEEEEEEEEEEEEEE88888EEEEEEEEEEEEEEE88888888888888888888888"
	Maps[140] := "8888888888888888888888889999999999998888888890000000009888888888909203900988A888888890002430988A888888889000120988A8A8888888901000988A8A8888888890910988A8A8888888889000988A8A88A8888888900988A8A88A8888888890988A8A88A8888888889988A8A88A88A8888888988A8A88A88A8888888888A8A88A88A8A8888888888888888888888888888888888888888888"
	Maps[141] := "888888888888888888888AAAAAAA8888888888888A8888888888888888888A8888888888888888888A8888899999999888888A8889990000009888888A8889012013209888888A8889070CC000988888888889001102209888A8888889000000999888A8888889999999988888A8888888888888888888A8888888888888888888A8888888888888888888A8888888888888AAAAAAA888888888888888888888"
	Maps[142] := "99999999999999999999999899888899989998899898998998898898998998988889988988988989989999999999989889999999990011009998899999989900991098998899998889029030989998999999890200249898889999998990000998988899998889999999999999999889998989998999999998999989898889988899988889898889889899999998998999999888898999999999999999999999"
	Maps[143] := "8888888888888888888888AA88888AA88888AA8888AA88888AA88888AA8888888888888888888888888888999999998888888888889000000988888888888890C2000988888888AA8890205C1988AA8888AA88992C100988AA888888888900001988888888888889999999888888888888888888888888888888888888888888888888AA88888AA88888AA8888AA88888AA88888AA8888888888888888888888"
	Maps[144] := "8C8C8C8C8C8C8C8C8C8CC8C8C8C8C8C8C8C8C8C88C8C8C8C8C8C8C8C8C8CC8C8C8C8C8C8C8C8C8C88C8C8C899999999C8C8CC8C8C99943110098C8C88C8C89090090919C8C8CC8C8C90022009098C8C88C8C89000020009C8C8CC8C8C99999090098C8C88C8C8C8C8999999C8C8CC8C8C8C8C8C8C8C8C8C88C8C8C8C8C8C8C8C8C8CC8C8C8C8C8C8C8C8C8C88C8C8C8C8C8C8C8C8C8CC8C8C8C8C8C8C8C8C8C8"
	Maps[145] := "888888888E888888888888888888E8888888B8888D88888E8888888B888888D88888888888B88888888D8899999888888888888888900099888888888888889000099888888888888890C0249988D8888888889002C209888D8888C888990101098888D8888C88890091998888888888C889999998888888888888888888888F88888888A888888888F88888888A888888888F88888888A88888888888888888"
	Maps[146] := "88888888B888888888888D88888A8888C8888A88888C888888E888889888F8888888888888888888888889999999999888888888890000900098888888B8890CC31CC0988D88888889010C0030988888898889003423209888888888890000000098F88888E8899999999998888888888888888888888888888888888888F8988B8888D888A88888888888888888888888C8888E888888888888888888888888"
	Maps[147] := "8888888888888888888888999889999988899988889898891209888989888899988900098889998888888889909988888888889999990009999999888890099011160090198888920000C0C0C00029888891099020202090098888999999990099999988888888889909988888888899988899099889998888989888900098898988889998889021988999888888888899999888888888888888888888888888"
	Maps[148] := "8888888888888888888888888888888888888888888888888888888888888AAAA8999999988AAAA88A88A8907000988A88A88A88A8902910988A88A88A88A8900020988A88A88A88A8900909988A88A88A88A8900919888A88A88A88A8900029888A88A88A88A8900109888A88A88AAAA8999999888AAAA888888888888888888888888888888888888888888888888888888888888888888888888888888888"
	Maps[149] := "88888888888888888888888888B888888888888888888BB88888888888888888BBB8888BBBB88888888BBBB9999999B8888888888899000409B8888888888890203209B888888888889020900988888888888B9009900988888888888B9011109988888888888B9999999BBBB88888888BBBB8888BBB88888888888888888BB888888888888888888B8888888888888888888888888888888888888888888888"
	Maps[150] := "88888888888888888888888888AAAA8888888888888888A88A8888AA88888A88A888888888A888888AAAA899999988A8888888888891019998AA88888888889190209888888888888890000098888888888888902920988888888AA88899007998888AA888A888899999888888A888A888888888888888A88AA88888888A88A88AA88888AAAA888AAAA888888888A88A88888888888888888888888888888888"
	Maps[151] := "9999999999999999999990000002190000000009909999999909999999099098999999099998890990989000000000988909909890C2CCC020988909909890C1112204988909909890C111C0209889099098902111C200988909909899992CC020988909909888890000009889099098BA8999999998890990988888888888888909909999999999999999099000000000000000000999999999999999999999"
	Maps[152] := "88888A8A88888AA888888AA88A8A8888A8888888888A88A888888AA888888AA8888888888888888888888899999988888AA88888899001099888A88888A88902290098888AA88A8A89102001988888888A8A890090909888888888888990127998888888888888999999888888888A8A8888888888888A888A8A8888AA888888A8A888A8888888A88888A8A888888888AA888888888888888888888888888888"
	Maps[153] := "888888888888B88888888888888BB888BBB8888888BB8888B88888B8888888B88888BB88888888888BB8888999998888888888888899000998888BB888888890002098888B888888889100039888BB888888889192909888888888888890040098888888888888999999988888888888B88888888888888888BBB8B88888BB8BB88888B888BBB888B888B88888888888B88BB888BB8888888888888888888888"
	Maps[154] := "88888888888889999999899999988888890000098999999899999910CC198999999890000002003989999998900999029009899999989009890090098888888890098999999988899999900988888888999910400009888888889001200900099999999990C0099900000000000990202019999990002C0999990009888891C002098889999989989001C2998988888889989100009088888888888899999990"
	Maps[155] := "8888888888888888888888888EE8FFF8BB88888888888EE8FFF8BB8888888888888888888888888888BB89999999998EE88888BB89011002498EE8888888890092990988888888FF89900099998FF88888FF89039031098FF8888888890020000988888888EE89009000998BB88888EE89999999988BB8888888888888888888888888888BB8FFF8EE88888888888BB8FFF8EE88888888888888888888888888"
	Maps[156] := "88888888888888888888888E888888888888E888888888888888888888888E8E8E88999999E8E8E888888888900009888888888E888890120988E88888888899999209888888888888900002198888888888889002C0198888888888889990CC19888888888E8890124C0988E888888888900000098888888E8E8E99999999E8E8E888888888888888888888888E888888888888E88888888888888888888888"
	Maps[157] := "88888888888888888888888999999999999998888889999999999999988888888888888888888888888999999999999998888889999999999999988888899900142010099888888999029020200998888889990191039909988888899901000002099888888999999999999998888889999999999999988888888888888888888888888999999999999998888889999999999999988888888888888888888888"
	Maps[158] := "888888888888888888888EE888888889988888888EE888CC888998888888888888CC88888888FF888888888888999988FF8888888888999009888888888888999002098888888888889060000988888888888890C12299888888888888910010988888888888889999999888888888888888888888BB8888888DD888888888BB8888888DD8888AA888888888888888888AA88888888888888888888888888888"
	Maps[159] := "8888888888888B8888888C888D8888E8888C88D8888888888888888888888B88899999999988F888888889000000098888A888E889000000098888888888899990CC098888888888999000C009888E888F889002C000099888888888902022911198888888889000259101988888888899900999999888A8888888999988888888888C888888888888D8888888888888F888B8888888888A8888888888888888"
	Maps[160] := "88888888888888888888888AAA888888888BBB88888AAA888888888BBB88888AAA888888888BBB88888888999988888888888888889069888888888888DDD89129888888888888DDD89009988888888888DDD890219999888888888888902000098888888999889901000988EEE88999888999999988EEE88999888888888888EEE8888888888FFF88888888888888888FFF88888888888888888FFF88888888"
	Maps[161] := "888888888888888888888AA89999999998888FF88AA89111111199998FF88AA89111199990098FF88AA89991119002098FF88AA88892009090098FF88AA89990020002098FF88AA89020200202098FF88AA89090990220098FF88AA89092992002098FF88AA89090000999998FF88AA89000299988888FF88AA89990098888888FF88AA88940098FFFFFFFF88AA88999998FFFFFFFF888888888888888888888"
	Maps[162] := "8888888888888888888888888CC899999998888888888888911111988CC88C8889999111119888888C8889409211999888888888890290009888888888CC890099299998888888888902200000988C8888888990CC0C20988C8888888900C00C00988888CC88890220CC009888888888890002CC20988888888C8902200009988888888C8900090009888CC8888889999999998C8888888888888888888C8888"
	Maps[163] := "888D889999999998888888D8899888888899888888889988999998899888888998899000998898888899889900213998988888988991001210989888889899002321209898888898900036300098988888989021232009989888889890121001998898888898993120099889988888988990009988998888889988999998899888888889988888889988D888888899999999988D888888888888888888888888"
	Maps[164] := "8888888888888888888888999999999999999998889888888888888888988898999999999999989888989000000000009898888890CCCC0CCCC098888899900000C0000099988890011332C2331100988890C00000000000C09888900C2CCCCCCC2C0098889900102060201009988899999999999999999888888888888888888888889999999999999999988888888888888888888888888888888888888888"
	Maps[165] := "888888888B88888888888B88888888888888888888888B8888888888888888888889999998B888B88888888904009888888888888899229098B888888888889030919888888888B8889000919888888888888890000198888B88888888999921988888888888888890209888888888888888900098888888B88888889999988888888888B888888888B88888888888888888888888B8888888888B8888888888"
	Maps[166] := "88888888888888A8888888A888A88888888888888888888889999988888888888888890009888888888889999900498888A888A889000000398888888888891900091988888888888900000909888888888889020099098A888888888999029009888888888888892090098888A88A888889001009888888888888899999998A8888888A88888888888888888888888A8888888888A8888888888888A8888888"
	Maps[167] := "88888888888888888888888888888888888AAAA88888BBBBBBBBBB88AAA88888B888888888B88AA88888B8999999888B88A88888B8911109998B88888888B8904C20098B88888888B8902020098B88888888B8900090098B88888888B8999999998B88888888B8888888888B88888A88BBBBBBBBBBBB88888AA888888888888888888AAA88888888888888888AAAA88888888888888888888888888888888888"
	Maps[168] := "88888888DDDD8888888888888888888888B8888888888B88888888B88888888BBBBB88888BBB888888888B88999988B88888D8888899900999B8888DD888889001010988888DD8888890C12C0988888DD888889420020988888DD8888B9990099988888D88888B88999988B888888888BBB88888BBBBB88888888B88888888B8888888888B888888888888888888888888888888888888888888DDDD88888888"
	Maps[169] := "99999999999999999999999899888899989998899898998998898898998998988889988988988989989999999999989889999999990Y11009998899999989900991098998899998889029030989998999999890200249898889999998990000998988899998889999999999999999889998989998999999998999989898889988899988889898889889899999998998999999888898999999999999999999999"
	Maps[170] := "89999899999998999988898898910101989889888988989101019898898889889890191098988988899998910001989999888888889111119888888888899999292999998888888900202020200988888889020202020209888888890020202020098888888900000400000988888889999909099999888888888890202098888888899998921212989999888988989101019898898889999899999998999988"
	Maps[171] := "8888888888888888888888DDDDDD888DDDDDD88888D88888DDD88888D88888D8DDDD888DDDD8D88888D8D888888888D8D88888D8D899999988D8D88888D8D894300998D8D888888D88922200988D8888888D88910090988D888888D8D890001198D8D88888D8D899999998D8D88888D8D888888888D8D88888D8DDDD888DDDD8D88888D88888DDD88888D88888DDDDDD888DDDDDD88888888888888888888888"
	Maps[172] := "AA8AA8FF8888FF8AA8AAAA8AA8FFFFFFFF8AA8AA88888888888888888888FF8FF8999999998FF8FFFF8FF8900090098FF8FFF888F8902091198F888FF8A8F8900221198F8A8FF8A8F89420C1198F8A8FF8A8F8900221198F8A8FF8A8F8902090098F8A8FF888F8900299998F888FFF8FF8900098888FF8FFFF8FF8999998888FF8FF88888888888888888888AA8AA8FFFFFFFF8AA8AAAA8AA8FF8888FF8AA8AA"
	Maps[173] := "888888888888888888888A8A8A8888888888988888A8A8888888888888888A8A888889999888989888A888899900988888888A88889901029988988888888890091009888888888888902009098888888888889909100988888888888889620099888888888988890099988888A888888889999888888A888989888888888888A8A8888888888888888A8A8888898888888888A8A8A888888888888888888888"
	Maps[174] := "8888888888888888888888B888888888888888888B8B88888888888888888B8888999999998888888B8B899000011988888888B88902090009888888888889002999198888888888894300000988888888888999900209888888888888889200998888888888888890199888888888888888999988AAAA888888888888888888A888888888888888888A888888888888888888AAAA8888888888888888888888"
	Maps[175] := "88888888888888888888888888888888888888888888888888888888898888888899999988889988888888942119998999888888889022300989998888888899902C0989998888888889900109899988888888890200998999888888888900C198899988888888890010988999888888888999999889998888888888888888899988888888999999999999888888899999999999998888888888888888888888"
	Maps[176] := "88889998888888888888899899999999999899988999988888888888999889998899999999989988899988999999999898888888889900001998998889998999110209989998888989902299999899988899899000999998899889998990C49988888998899889900099888888888999899999998888998888898999999989999988899988888888899998888899889999999989988888888888888888888888"
	Maps[177] := "8888888888888888888888B888888888889999988B8B889999999999009888B88891190020000098888888911900020200988888889111122C2C0998888999911110000209888889021CCC3999999988899902CC001988888888890020200C1999888888890020002C100988888889904022201C0988888888902000291009888B888899999009999988B8B888888999998888888B8888888888888888888888"
	Maps[178] := "888999999999999999888889AAA9EEEEE9AAA9888889A99999999999A9888889A9B9009009B9A988888999990000099999888889E90032C03009E9888889E90003132009E9888889E990C171C099E9888889E90023130009E9888889E90030C23009E988888999990000099999888889A9B9009009B9A9888889A99999999999A9888889AAA9EEEEE9AAA9888889999999999999998888888888888888888888"
	Maps[179] := "A888888889999888888A888888899900998888888888889902020998888888888990200120998888888899021C1012099888888990212101012099888899021012121212098888902121212121C6299888900010100010120098889920C1212121212098888902121212101009988889902101012120998888889902101C120998888888899021002099888888888899020209988888A888888990099988888AZZZZZZZZZAA" ; Extra characters at end to close open area
	Maps[180] := "88888888888888888888888888888888888888888999999999999999999889888888888888888898898999999999999998988989420021103120989889890200031213009898898990202110312098888888900203121300998988989020211031200989889890020312130009898898999999999999998988988888888888888889889999999999999999998888888888888888888888888888888888888888"

	; Theme data
	Themes := [] ; Create array
	Themes["Color"] := "iVBORw0KGgoAAAANSUhEUgAAAeAAAAAgCAMAAAD9lVunAAAAHlBMVEVHcEz////AwMCAgIAAAAD/AAD//wCAgACAAAAAgIBYQi54AAAAAXRSTlMAQObYZgAACJRJREFUeAHEmAGa6yYMhCNpFrz3v3AfCGsEIXbS7fbNfqkDg4DyVyLuQ26lpcip9k2ly5/2Trxexf9lPSbhFLtu/J8LF6L9Iup+etFJltoirR0iJsrsl+M/9cU+9OczU6gL7L72f4DvHFFeCs22JkxTsft2kQBcVWvtB2KtwQO9kpmleO0d9q/jpYwctxx/s7/Zb1PqS183Pkk0dqIY6JkcV/69YDCoQqcPDIPZJZ4pVVFDYDdws4j4wc0HYupd0gG5T9F3QN03r7j9r6cJ4/Um/vSJnevTn4HtfQ+efdr0jX6AcN93BQWT9M7/AWAU5JFqiIeLqQrUEqrA6PYp/hfAHU18LAPWm3h1ka+tgC72N/Ptcy6+1gs/ShwBAqat2a17/7cBu8wyYDO43gGca9bmzpM5hybfYCPeRIzdTZ/Fd6tI9WgNuW9NsCH4N6GvNfjN8ff+yE4D0v6kf5Czt/tHl7rCp9z/DDBcK2B2q3pMI/v1R+2p6t1vAXZdAXb5HehPkpQtx4YjGyIN35DnqjHetQXgPuFSIqfP8KrrBLf+ebsqbOzMBztUZ+T+H3RfXY1x+FT2PwFsTf2pZvAHuyfAPv+HgG3W0g7AtoAPwHkUxy3x8iQzxs9LXe4HaTB9RsM4w86378V/+MmOqquDsShUPEmb3xynN3TEAYdmn4Bfa85g1KSc2C5V5yvSCKvmEn25iLwjDYlmjYMmX1JuKC7ekCwAT1K1uZOjF21eobUqMM87aa48Qw/0tvemQoK2aY0Mcr7S1QlC3T+1+g8KfUvYtFBw/SOKGWxWyhGAzXIGXy6iTfX1C6eINF+eclhY7LzgTnLCES86jagagNP6IkWjc9rPZn7JA+pJBTgnpk2fov9AA9v/0KCN+1fhNrrvfCXUCJ6+69l/AjwUrROwqwGkzNY7GCjHESkMzIA5rSsDrgHUT3tt82Tou6yJh7f6BkS855da/v084rkeS/S6H1Zaqoi6z//EAIgGYbez7+gq19cG0gu/zoKJAqpwP/j5wwkDAXjnB99ay5Nq7TAK8h1LKa8Akhx3fAecujvP/RpogOM1J+DUqhJtlrbZD0xqIjvfXY93dksdPkcUoRx16ETksChWliZh/rbmt9Vz6poHs6nJh51lyD99n+c3KLrfEnhwGyQ9hUHAz37wLV3u5Tcds7cAdxFwU0Hq7jsk37xOxX8BWH4E2LvLCri0rsgrwxXgMTsA76mcO/vuqX5z7x8C/hraA6a/ATwcIq6dH0mtgNcSvQJmd/9WiXcoANvLEt1FfLOfCq3I3jcE/gG4c2ujCJgJW9YM9jGElcV9Wc5flzGH6VO8JZyRbiqEqMeg+eS7Eh6A934CPND0MfsMNuN7Ln9EvQWYGTyv44BfvwDP/6ZVF3/N4EX1dPUEHNj4I2sf3y0SegG4jKjMN41nFOvzjNF92No/MljaU9B9AhQhwO4TMP0VcKAREl7vYCCXV+AC8HFs7mDnO63jgPcvnGyzFG50DklnZNnFGR8l2vERga/ABUwpe0s+KfN3M/28q2mUQdX/obOiRDf/IDlyPFii934CnJL7BIzmZVL5PZfdvGyD39F8doMX/byOLyL30qS6ApbtOxLdqUSXFTBH2JL/dG8U8/WYNavTO3Tymzl8GDQJ/NI3hu7vATb/TcDp5FfAGWAGvNzBDvjwBJ4zmICndRzwm/+r8iVCSBuy528wtQmw/FO8Gei2DcNANOIRVff/PzyA9skXljHTad04YIV3oe3sVTKpkwE4gTB/MD+bGpgwLP8mxXpg4zzVVBfpg7M22DflG6QeI3Q9haNqYJukI7iagkN/c4qW//nPcop+aJ+rI1in8M8ImcLzFJ2uo4BnMsinAqZejDECLvQ5M2AAyCP4/GeRbFzHGDI+RwVYziVV9Tz4qS54py3dDe65SHcHp+jQXxVZ/naRJZGKrKbPfS7CmA9URVa+DgHPeX11nMfq56puhdkwhui4dGDlfyj8DLhci54CeHpdRbObkzEMnZ9PfR76L30IL90j+/izAqvY8tDrNin0N9ukxFfapKZKbtoobZPSdX4csBeARwH4zmyg31vXVrxfJax8qQdhRXfqAdgbwF4udGTA/UKH4NUR3C1kdAshOoLTdQhYv3s9RYteT9GodAdMp+ihMlDbhaA0kx88UmABhp4u8VVdQvSHn094xGi1FB56vVRptr1U2Y/gBnC/VPlWkQUrg4AGUGoL8GqF5qgA935wui1ek7rM0ld9ZVlnqE670FahpV+ddmFtNoS+bzbwhqTPlSKqMSNas6H1g8uVLAhgACg6JYdD/WCk8Fd+MCT0/KkGzn7wSRjiKn3V+awR/RwifjVQkELLH6eObAdS37ULtYhin6tFVGMn9nbhN/vgutMFsJ69c/GV/MwXlR/MLTuVH7w+Ip8uHebV/954yqoHQcc54+AgjUX5QcL+bOjD/rLhbyZ9rhRRzYaA3vBvlyrzTlNVYb5II5GH5steqvWX5Nd24RUIntyAz5+mARKU/ugd/YRwSFjrpMKPvwG6JYf67pYddZOkQFI3qdnS023ZyX7w4e+uY21wVFc/WIgOHEwBr/K5H5L5rR/MOVWGq4QtnZ8H+cVxp8f5SdAcLLLAmtplGIZyAFB9e9OdAmafq4CbTXkt4GQXwuJ4WGkXqk5EK/8I/ry1Gy3nEzA7YLk+08Ccm2MAwS/pM+sm5yeGAxlcBrErJo9JM+td9IC7bbHNttp/DthvAXOTxQvAqAFPS/dnr/SzGsn6fNZtKuAjPAMmv17fBNwUUduAs/8rx4DUv446NB9H/Gl+wI2Q/Lv7sy864N7ren9a6sYzBvEBHTy9vvHqSvdqSvNqS//qSltkgVFz+on8jWP4N/WLBKfp4Uqv13dePmtfLutfTmsu0vjBwqUBtZ//f44LFg0r1fejfz3U7/C18Rta4pqH7xv2iAAAAABJRU5ErkJggg=="
	Themes["Monochrome"] := "iVBORw0KGgoAAAANSUhEUgAAAeAAAAAgAgMAAAC3JUMGAAAACVBMVEVHcEz///8AAADmzmMiAAAAAXRSTlMAQObYZgAABMxJREFUeAF9lwmOq8wOha1oTPZBpJf92AI0vX+gpK5V9CaMutB0J1DKq/ztAgMNSo7EPamezv1qsAvARbLoPH4vALjJE8D9qJsU/XiIjXY/ERYxFrWn8Vldv3OAy4QE4O4Sk+Zcsej/FV1EPrmGhxRBk1KyZwmK+hmxOYznn/GHx50D/A8Zf4C7K/VE1HzdNM70+ZCrxsvzx71j5j6sxAuFhKBxpMSpSBQMaQp7Yd45ACOGGtwPwXeAa139H6CiEbHl+suDncSDGgU05D4UFeL2OzHFZnN4MFJP4P4q+CGokufXS+JOcZH2xBS/EXfN0G8OrCRIoB6zuWY8d8EPsWB5VoTtiO+IWUdDTn2HqlDghmT/iEo9cQjj5he2H+QfF44iY/+j7OMfW3BFFXHNtQbHbMEviXE2ZlTljTiKimxpU8ph9Ss1FlxfMYpkrhXYNrPvaiWuEGt5PgSltan2XY2LnBhxtkJMU7QFH9gOlohknHde3LxCkxKhMIkFm+vhwv9DRXD3TaXE0hox6M9c8RPSIidOZBYTz1MuyTZRUg3Jt9fQ+Gf1Cok1mCrKiJEJLuafGhxlpB9331QVTdIPGnzjVrIGh2BJ22bqmpIy9V1QTTEEJZ6MbrJZ1ydECpN5COpcZoZ6jiNxO/VwM/+hUKZ2qsjciO8yfXE9jGj6/4mYZ89KjKjEikMfiB8rMSfBlM1V2QtN4JZjpjHAzfwHVLaXEIMHP+Qu8iXPhGjfqd8QW+GYogLZ0Z5WYgqCIZqrYtgFi5Rgcw0mESsp21RbMNcJ0b5TvyVuV2LKK3EzZG4GdRurYxGlSCKcCR7mT6ha6UcN9vO7C7bvvCWmqMQ+duJOP6hNXSiaeAnmSDmWYHMNjsK5rPEYc+vBZY3tO2+Jm0GJfezEnEQpU+ZkUu+WqY7t2I45wMO8BMsH/t8KiLS1rXElUus5vqJ9pz6f45lwdGIfY2vEiDGggefo/yGlteOU5mDaB2cNfogF2xpbMNdzcK5Plcun0Il9HGJSUWgTN6wHrE2mwaa60eiwTHXYTbXMU32XXqfYp1wRSvCxVjtxVuIoRiySkz6aZX0h6epqTFSfC43tINTd10vZXGG3ucQ2l59f32QJ0b7zllhEiYNkiiIrcWOTm8RcJX6caDlOdDxOvqn8WPlxekMcxIhbg90TR2ua2VyV07gEj3MBoWMB8cLhhcQLyJmYzOLktdq700o8JFti85TUq47YgqtSMkc6lkwn9mAvmed+jGZD8lrt/XgltiMck3kwnwOwvs5Noj42CWsOMmxT7U3iRLyWQhbVRuytsLE6LWH1ayH5qK+lLX6c2yKhiJJ6e/S2+LofB1Ht+nGDi2IIefNLh8hKfMHSr88XAbFgefqFwC8C534shpcTD6La9WNGSy/LMCisO2Rvc3ZK1A9XH7/y+BXIrz6nWh2iTeHkU7/147A+U5w2h3s5UZ/w0ADzw2XPz69f+jz4TFxIt82mT5T0TVl2Dlekcsu8DpO5y4N9U/k19zVxudXRnljkO3GUncPFgmtwPwb7pjoFO8Ygs8qn83ivIe8cgLGhH+B+CL75q4u/yvw4EsuiV+P9M+3c3plIJ9L9+NLmL2v+8gbHXe1B5/F76RyL5bkf5a+n/roKi/4DXnx6iqqx+9YAAAAASUVORK5CYII="

	; Fontmap data
	Fontmaps := [] ; Create array
	Fontmaps["Orange"] := "iVBORw0KGgoAAAANSUhEUgAAAPAAAAAYAgMAAAC5LJjuAAAACVBMVEVHcEz/vQAnIyM7NDiMAAAAAXRSTlMAQObYZgAAAJZJREFUeAHN1IURwkAUBNAdykk9eAlUcZ3gtlVysjB7uFvybebFEzQkOUGLhGpFLWQVg09+iTudTjfi5QiqFeOi2uIw2OSnuEseMFOtqCU2+0huI451mV/F5IdxrGqMCxjANazLsLWLZFHYJn+CdW5+2ez87Zw1fxWTNW5ex4jtB/GVF0P4+tX+Fb78GUq41DapP0M/xDvAHFBgsabpAgAAAABJRU5ErkJggg=="
	Fontmaps["Green"] := "iVBORw0KGgoAAAANSUhEUgAAAPAAAAAYAgMAAAC5LJjuAAAACVBMVEVHcEwnIyNr22/DZy3FAAAAAXRSTlMAQObYZgAAAJZJREFUeAHN1IURg1AQRdFNEfRDB9Eb6ysdxKvM8m0ecTdYmzk4WAXQsw5YqlNMC6Cx1skv8X6/3zmeLyzVKfoSa42rWiY/xTsoGLxOMS1AjjB27HWcX8XwYexVG9sFbGZXcbwMY7lIEiPWyb/geG562ZAz1HMGXsfQxtXr2Lz9ML7wYkR87Wr/FF/4DAUca5lALZMf4gN4Q/I35hKgZAAAAABJRU5ErkJggg=="

	; Icon data
	Icons := [] ; Create array
	Icons["Bulldozer16"] := "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAG1BMVEVHcEzAwMAAAAD//wCAgID/AACAgACAAAD///9wWJvwAAAAAXRSTlMAQObYZgAAAF9JREFUeNptjgEKwDAIA9Wkc/9/8TQiY7ADaXoE1AIfwqJxahoTTo2QvcTkcA9CsLOEj/ARZDcyq9HZZJHnJDqvOMUKcoXy27jV2LX1P7uW9aIM4J3/DzPT5cpz/6D8AFCgAnWwfBuRAAAAAElFTkSuQmCC"
	Icons["Bulldozer32"] :="iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAG1BMVEVHcEzAwMAAAAD//wD/AACAgACAgICAAAD///+ovIncAAAAAXRSTlMAQObYZgAAALdJREFUeAGVk2GOhjAIRHFE9P4nXiETYqF1P9+fJsxLaUBFBC+Ig30JJMCxAEIQmG1mPNhgBHeCPBKQKmQdWwAZWzzqZHwq+g3AsScH0G4w2x+Y1Rvu4ylEwflFIE0oLfiG84ZvqC2AyGkATRBErqpu9EFRUMeF2agjp5H1KpBvAnGB8aWrNzC/pi3AFp5rmwMneUZ+KSfZd5EXcBd93Rq8rZs5hW9f1L/f5PAHTv8L1mhPRl0A+QMfTwmTv+zr5gAAAABJRU5ErkJggg=="

	; Background colors data
	BackgroundColors := [] ; Create array
	BackgroundColors["Aqua"] := "00FFFF"
	BackgroundColors["Black"] := "000000"
	BackgroundColors["Blue"] := "0000FF"
	BackgroundColors["Fuchsia"] := "FF00FF"
	BackgroundColors["Gray"] := "808080"
	BackgroundColors["Green"] := "008000"
	BackgroundColors["Lime"] := "00FF00"
	BackgroundColors["Maroon"] := "800000"
	BackgroundColors["Navy"] := "000080"
	BackgroundColors["Olive"] := "808000" ; Default
	BackgroundColors["Purple"] := "800080"
	BackgroundColors["Red"] := "FF0000"
	BackgroundColors["Silver"] := "C0C0C0"
	BackgroundColors["Teal"] := "008080"
	BackgroundColors["White"] := "FFFFFF"
	BackgroundColors["Yellow"] := "FFFF00"

	; GDI+ Startup
	hGdip := DllCall("Kernel32.dll\LoadLibrary", "Str", "Gdiplus.dll") ; Load module
	VarSetCapacity(GdiplusStartupInput, (A_PtrSize = 8 ? 24 : 16), 0) ; GdiplusStartupInput structure
	NumPut(1, GdiplusStartupInput, 0, "UInt") ; GdiplusVersion
	DllCall("Gdiplus.dll\GdiplusStartup", "PtrP", pToken, "Ptr", &GdiplusStartupInput, "Ptr", 0) ; Initialize GDI+

	; Midi Startup
	hMidi := DllCall("Kernel32.dll\LoadLibrary", "Str", "Winmm.dll")
	VarSetCapacity(strh_MIDIOut, (A_PtrSize = 8 ? 24 : 16), 0)
	DllCall("Winmm.dll\midiOutOpen", "UInt", &strh_MIDIOut, "UInt", 0, "UInt", 0, "UInt", 0, "UInt", 0, "UInt")
	h_MIDIOut := NumGet(strh_MIDIOut)

	; Create HICON from Base64 encoded data strings
	pIcon16 := GdipCreateFromBase64(Icons["Bulldozer16"], true) ; 16x16
	pIcon32 := GdipCreateFromBase64(Icons["Bulldozer32"], true) ; 32x32

	; Create BITMAP from Base64 encoded data strings
	pFontmap := GdipCreateFromBase64(Fontmaps["Orange"])

 	; Create a Bitmap object
	DllCall("Gdiplus.dll\GdipCreateBitmapFromScan0", "Int", (640 * DPI), "Int", (512 * DPI), "Int", 0, "Int", 0x26200A, "Ptr", 0, "PtrP", pBackgroundImage)

	; Create a Graphics object associated with pBackgroundImage
	DllCall("Gdiplus.dll\GdipGetImageGraphicsContext", "Ptr", pBackgroundImage, "PtrP", pBackgroundGraphics)

	; Set the rendering quality of the pBackgroundGraphics Graphics object
	DllCall("Gdiplus.dll\GdipSetSmoothingMode", "Ptr", pBackgroundGraphics, "Int", 3) ; None

	; Set the interpolation mode of the pBackgroundGraphics Graphics object
	DllCall("Gdiplus.dll\GdipSetInterpolationMode", "Ptr", pBackgroundGraphics, "Int", 5) ; NearestNeighbor

	; Create a SolidBrush object for the background color of the game
	DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", "0xFF" BackgroundColor, "PtrP", pBackgroundBrush)

	; Set tray icon options
	Menu, Tray, Icon, % "HICON:*" pIcon16 ; Tray icon
	Menu, Tray, Tip, Bulldozer ; TrayTip Text
	Menu, Tray, NoStandard ; Remove non-custom menu items
	Menu, Tray, Add, E&xit, MenuHandler ; Exit script
}

OnUnload(ExitReason, ExitCode) {
	Global ; Assume-global mode

	; Release resources used by the Image objects
	DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr", pTheme)
	DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr", pFontmap)
	DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr", pBackgroundImage)

	; Delete Graphics objects
	DllCall("Gdiplus.dll\GdipDeleteGraphics", "Ptr", pBackgroundGraphics)
	DllCall("Gdiplus.dll\GdipDeleteGraphics", "Ptr", pControlGraphics)

	; Delete Brush objects
	DllCall("Gdiplus.dll\GdipDeleteBrush", "Ptr", pBackgroundBrush)

	; Clean up resources used by GDI+
	DllCall("Gdiplus.dll\GdiplusShutdown", "Ptr", pToken)

	; Free module from memory
	DllCall("Kernel32.dll\FreeLibrary", "Ptr", hGdip)

	; Destroy icons and free memory
	DllCall("User32.dll\DestroyIcon", "Ptr", pIcon16)
	DllCall("User32.dll\DestroyIcon", "Ptr", pIcon32)

	; Free module from memory
	DllCall("Kernel32.dll\FreeLibrary", "UInt", hMidi)

	; Midi Shutdown
	DllCall("Winmm.dll\midiOutClose", "UInt", h_MIDIOut)

	; Write values to INI file
	IniWrite, % BackgroundColor, Bulldozer.ini, Options, BackgroundColor
	IniWrite, % Theme, Bulldozer.ini, Options, Theme
	IniWrite, % UnlimitedUndo, Bulldozer.ini, Options, UnlimitedUndo
	IniWrite, % Sound, Bulldozer.ini, Options, Sound
	IniWrite, % LevelNumber, Bulldozer.ini, Options, LevelNumber
	IniWrite, % MouseMovement, Bulldozer.ini, Options, MouseMovement
	IniWrite, % LevelNum, Bulldozer.ini, Options, LastLevel

	StringSolved := ST_Glue(Solved, "") ; Run-length encoded solved level data
	IniWrite, % RLE_Encode(StringSolved), Bulldozer.ini, Options, Solved
}

ThemeSet(Tileset, Update := 0) {
	Global ; Assume-global mode

	ThemeMatch := "" ; Initialize variable

	For ThemeName, ThemeString In Themes {
		If (ThemeName = (Theme := Tileset)) {
			Menu, ThemesMenu, Check, % (ThemeMatch := ThemeName)
		} Else {
			If (!FileExist(Tileset)) {
				Menu, ThemesMenu, Check, Color
			}

			Menu, ThemesMenu, Uncheck, % ThemeName
		}
	}

	pTheme := (FileExist(Tileset) ? GdipCreateFromPNG(Tileset) : GdipCreateFromBase64(Themes[(ThemeMatch ? ThemeMatch : (Theme := "Color"))]))

	Menu, ThemesMenu, % (!ThemeMatch && FileExist(Tileset) ? "Check" : "Uncheck"), &Custom...

	If (Update) {
		BackgroundLoad(TempMap)
	}
}

BackgroundColorSet(ColorHex) {
	Global ; Assume-global mode

	ColorMatch := ""

	; Set brush color
	DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", "0xFF" (BackgroundColor := ColorHex), "PtrP", pBackgroundBrush)

	BackgroundLoad(TempMap) ; Generate background with new color

	For ColorName, ColorCode In BackgroundColors {
		If (ColorCode = BackgroundColor) {
			Menu, ColorsMenu, Check, % (ColorMatch := ColorName)
		} Else {
			Menu, ColorsMenu, Uncheck, % ColorName
		}
	}

	Menu, ColorsMenu, % (!ColorMatch ? "Check" : "Uncheck"), &Custom...
}

GuiCreate() {
	Global ; Assume-global mode
	Static Init := GuiCreate() ; Call function

	; Initialize variables
	ColorMatch := "", ThemeMatch := ""

	; Game ---------------------------------------------------------------------
	Menu, GameMenu, Add, &Restart Level`tF2, MenuHandler
	Menu, GameMenu, Add, &Level Select`tF3, MenuHandler
	Menu, GameMenu, Add, &Undo Last Move`tCtrl+Z, MenuHandler
	Menu, GameMenu, Add ; Separator
	Menu, GameMenu, Add, E&xit`tAlt+F4, MenuHandler

	; Options > Background Color -----------------------------------------------
	For ColorName, ColorCode In BackgroundColors {
		Menu, ColorsMenu, Add, % ColorName, MenuHandler

		If (ColorCode = BackgroundColor) {
			Menu, ColorsMenu, Check, % (ColorMatch := ColorName)
		}
	}

	Menu, ColorsMenu, Add ; Separator
	Menu, ColorsMenu, Add, &Custom..., MenuHandler
	Menu, ColorsMenu, % (!ColorMatch ? "Check" : "Uncheck"), &Custom...

	; Options > Theme ---------------------------------------------------------
	For ThemeName, ThemeString In Themes {
		Menu, ThemesMenu, Add, % ThemeName, MenuHandler

		If (ThemeName = Theme) {
			Menu, ThemesMenu, Check, % (ThemeMatch := ThemeName)
		}
	}

	Menu, ThemesMenu, Add ; Separator
	Menu, ThemesMenu, Add, &Custom..., MenuHandler

	Menu, ThemesMenu, % (!ThemeMatch ? "Check" : "Uncheck"), &Custom...

	; Options ------------------------------------------------------------------
	Menu, OptionsMenu, Add, &Background Color, :ColorsMenu
	Menu, OptionsMenu, Add, &Theme, :ThemesMenu
	Menu, OptionsMenu, Add ; Separator
	Menu, OptionsMenu, Add, Sound Effects, MenuHandler
	Menu, OptionsMenu, Add, Level Number, MenuHandler
	Menu, OptionsMenu, Add, Unlimited Undo, MenuHandler
	Menu, OptionsMenu, Add, Mouse Movement, MenuHandler

	Menu, OptionsMenu, % (Sound ? "Check" : "Uncheck"), Sound Effects
	Menu, OptionsMenu, % (LevelNumber ? "Check" : "Uncheck"), Level Number
	Menu, OptionsMenu, % (UnlimitedUndo ? "Check" : "Uncheck"), Unlimited Undo
	Menu, OptionsMenu, % (MouseMovement ? "Check" : "Uncheck"), Mouse Movement

	; Help ---------------------------------------------------------------------
	Menu, HelpMenu, Add, &About Bulldozer`tF1, MenuHandler

	; MenuBar ------------------------------------------------------------------
	Menu, MenuBar, Add, &Game, :GameMenu
	Menu, MenuBar, Add, &Options, :OptionsMenu
	Menu, MenuBar, Add, &Help, :HelpMenu

	Gui, Menu, MenuBar

	; Gui Window ---------------------------------------------------------------
	Gui, +LastFound +OwnDialogs -Resize +HwndhBulldozer
	Gui, Margin, 0, 0
	Gui, Color, 000000 ; Black

	Gui, Add, Tab2, x0 y0 w0 h0 +Theme -Wrap vTab HwndhTab, Game|LevelSelect|About

	Gui, Tab ; Not part of any tab
	Gui, Add, Edit, x-8 y-8 w0 h0 vCtlFocus +0x800 HwndhCtlFocus ; Catch keypresses

	; About --------------------------------------------------------------------
	Gui, Tab, About

	Gui, Font, c404040 S18 Bold, Arial
	Gui, Add, Text, x0 y20 w640 r1 0x201, Bulldozer

	Gui, Font, c404040 S11 Norm, Arial
	Gui, Add, Text, xp y+10 wp r1 0x201, Revision 13 (2018-08-31)

	Gui, Add, Text, xp y+40 wp hp 0x201, Bulldozer is a clone of the original Bulldozer 1, Bulldozer 2, and Bulldozer 3
	Gui, Add, Text, xp y+10 wp hp 0x201, games created by John Hattan (The Code Zone).
	Gui, Add, Text, xp y+40 wp hp 0x201, Developed for AutoHotkey by:
	Gui, Add, Text, xp y+10 wp hp 0x201, Weston Campbell <westoncampbell@gmail.com>
	Gui, Add, Text, xp y+40 wp hp 0x201, Special thanks to:
	Gui, Add, Text, xp y+10 wp hp 0x201, just me, jeeswg, SpeedMaster

	Gui, Font ; Reset font options
	Gui, Add, Text, x-20 y448 w680 h1 0x10 ; Divider
	Gui, Add, Button, x20 y468 w80 h24 vAboutWebsite gControlHandler, Website
	Gui, Add, Button, x540 y468 w80 h24 vAboutOK gControlHandler, OK

	; Level Select -------------------------------------------------------------
	Gui, Tab, LevelSelect

	Gui, Font, c303030 S12 Bold, Arial

	Loop, 60 {
		Row := (63 * (Ceil(A_Index / 10) - 1) + 10)
		Col := (63 * ((!(M := Mod(A_Index, 10)) ? 10 : M) - 1) + 10)

		Gui, Add, Picture, % "x" Col " y" Row " w" 53 " h" 53 " vLSf_" A_Index " +AltSubmit 0x4E HwndhLSb_" A_Index
		Gui, Add, Picture, % "x" Col + 4 " y" Row + 4 " w" 45 " h" 45 " vLSb_" A_Index " +AltSubmit 0x4E HwndhLSf_" A_Index ; Fill
		Gui, Add, Text, % "x" Col " y" Row " w" 53 " h" 53 " vLS_" A_Index " +Border gControlHandler 0x201 +BackgroundTrans", % A_Index
	}

	Gui, Font, c757575 S14 Bold, Arial
	Gui, Add, Text, x10 y+11 w116 h48 0x201 gControlHandler vLSPrev +Border, < Prev

	Gui, Font, c303030 S14 Bold, Arial
	Gui, Add, Text, x+10 yp w368 h48 0x201 vLSCollection gControlHandler +Border, Bulldozer 1
	Gui, Add, Text, x+10 yp w116 h48 0x201 gControlHandler vLSNext +Border, Next >

	Gui, Font ; Reset font options
	Gui, Add, Text, x-20 y448 w680 h1 0x10 ; Divider
	Gui, Add, Button, x540 y468 w80 h24 vLevelSelectCancel gControlHandler, Cancel

	; Game ---------------------------------------------------------------------
	Gui, Tab, Game
	Gui, Add, Picture, % "x" 0 " y" 0 " w" (640 * DPI) " h" (512 * DPI) " HwndhBackground 0xE" ; Background image

	; Get pointer to control graphics image
	DllCall("Gdiplus.dll\GdipCreateFromHWND", "Ptr", hBackground, "PtrP", pControlGraphics)

	SubclassControl(hBackground, "BgSubclassProc") ; Subclass static image

	ThemeSet(Theme)
	MapSet(LastLevel)

	Gui, Show, Center w640 h512, % "Bulldozer - Level " LevelNum " (" PercentText "%) [" RemainderText "]"

	; Add Bulldozer to a window group
	GroupAdd, Bulldozer, ahk_id %hBulldozer%

	; WM_SETICON - Set icons (TitleBar, Taskbar, ...)
	SendMessage, 0x80, 0, pIcon16,, ahk_id %hBulldozer% ; ICON_SMALL (16x16)
	SendMessage, 0x80, 1, pIcon32,, ahk_id %hBulldozer% ; ICON_BIG (32x32)
}

MenuItemCheck() {
	Global ; Assume-global mode

	; Enable/Disable 'Undo Last Move' menu item
	Menu, GameMenu, % (UndoArray.MaxIndex() ? "Enable" : "Disable"), &Undo Last Move`tCtrl+Z
	UndoState := (UndoArray.MaxIndex() ? 1 : 0)
}

MenuHandler(ItemName, ItemPos, MenuName) {
	Global ; Assume-global mode

	ItemNameP := StrReplace(((ItemTab := InStr(ItemName, "`t")) ? SubStr(ItemName, 1, ItemTab - 1) : ItemName), "&")

	GuiControlGet, CurrentTab,, Tab ; Get name of current tab

	If (MenuName = "GameMenu") {
		If (InStr(ItemName, "&Restart Level")) {

			; HOTFIX: Levels where bulldozer begins on target tile
			If (LevelNum = "64" || LevelNum = "127") {
				Maps[LevelNum] := MapBackup ; Replace level data
			}

			MapSet(LevelNum)

			If (CurrentTab <> "Game") {
				GuiSelectTab("Game")
				GuiControl, Focus, CtlFocus
			}
		} Else If (InStr(ItemName, "&Level Select")) {
			If (CurrentTab <> "LevelSelect") {
				GuiSelectTab("LevelSelect", "FFFFFF")
				GuiControl, Focus, LevelSelectCancel
				GuiControl, +Default, LevelSelectCancel
				LSSelectPage(LevelNum >= 1 && LevelNum <= 60 ? 1 : LevelNum >= 61 && LevelNum <= 120 ? 2 : 3)
			}
		} Else If (InStr(ItemName, "&Undo Last Move")) {
			If (CurrentTab <> "Game") {
				GuiSelectTab("Game")
				GuiControl, Focus, CtlFocus
			}

			UndoMove()
		} Else If (InStr(ItemName, "E&xit")) {
			ExitApp ; Terminate the script unconditionally
		}
	} Else If (MenuName = "ColorsMenu") {
		If (InStr(ItemName, "&Custom...")) {
			BackgroundColorSet(ChooseColor("0x" BackgroundColor, hBulldozer))

			If (CurrentTab <> "Game") {
				GuiSelectTab("Game")
				GuiControl, Focus, CtlFocus
			}
		} Else {
			BackgroundColorSet(BackgroundColors[ItemName])

			If (CurrentTab <> "Game") {
				GuiSelectTab("Game")
				GuiControl, Focus, CtlFocus
			}
		}
	} Else If (MenuName = "ThemesMenu") {
		If (InStr(ItemName, "&Custom...")) {
			FileSelectFile, CustomTheme, 3,, Select image..., PNG (*.png)

			If (ErrorLevel) {
				return
			}

			ThemeSet(CustomTheme, true)

			If (CurrentTab <> "Game") {
				GuiSelectTab("Game")
				GuiControl, Focus, CtlFocus
			}
		} Else {
			ThemeSet(ItemName, true)

			If (CurrentTab <> "Game") {
				GuiSelectTab("Game")
				GuiControl, Focus, CtlFocus
			}
		}
	} Else If (MenuName = "OptionsMenu") {
		If (InStr(ItemName, "Level Number")) {
			LevelNumber := !LevelNumber
			Menu, OptionsMenu, % (LevelNumber ? "Check" : "Uncheck"), Level Number

			If (CurrentTab <> "Game") {
				GuiSelectTab("Game")
				GuiControl, Focus, CtlFocus
			}

			BackgroundLoad(TempMap)
		} Else If (InStr(ItemName, "Sound Effects")) {
			Sound := !Sound
			Menu, OptionsMenu, % (Sound ? "Check" : "Uncheck"), Sound Effects
		} Else If (InStr(ItemName, "Unlimited Undo")) {
			UnlimitedUndo := !UnlimitedUndo
			LastUndo := UndoArray.Pop()
			UndoArray := []
			UndoArray.Push(LastUndo)
			Menu, OptionsMenu, % (UnlimitedUndo ? "Check" : "Uncheck"), Unlimited Undo
		} Else If (InStr(ItemName, "Mouse Movement")) {
			MouseMovement := !MouseMovement
			Menu, OptionsMenu, % (MouseMovement ? "Check" : "Uncheck"), Mouse Movement
		}
	} Else If (MenuName = "HelpMenu") {
		If (InStr(ItemName, "&About Bulldozer")) {
			If (CurrentTab <> "About") {
				GuiSelectTab("About", "FFFFFF")
				GuiControl, Focus, AboutOK
				GuiControl, +Default, AboutOK
			}
		}
	} Else If (MenuName = "Tray") {
		If (InStr(ItemName, "E&xit")) {
			ExitApp ; Terminate the script unconditionally
		}
	}
}

ControlHandler() {
	Global ; Assume-global mode

	; Initialize variables
	Static LSCurrent := "1", LSLVCurrent := "1"

	GuiControlGet, CurrentTab,, Tab ; Get name of current tab

	If (CurrentTab = "LevelSelect") {
		If (InStr(A_GuiControl, "LS_")) {
			GuiControlGet, LSLVCurrent,, % A_GuiControl
			MapSet(StrReplace(LSLVCurrent, "LS_"))
			GuiSelectTab("Game")
			GuiControl, Focus, CtlFocus
		} Else If (A_GuiControl = "LSNext") {
			GuiControlGet, CollectionName,, LSCollection
			Collection := SubStr(CollectionName, 0, 1) + 1

			If (Collection > 3) {
				return
			}

			LSSelectPage(Collection)
		} Else If (A_GuiControl = "LSPrev") {
			GuiControlGet, CollectionName,, LSCollection
			Collection := SubStr(CollectionName, 0, 1) - 1

			If (Collection < 1) {
				return
			}

			LSSelectPage(Collection)
		} Else If (A_GuiControl = "LevelSelectCancel") {
			GuiSelectTab("Game")
			GuiControl, Focus, CtlFocus
		}
	} Else If (CurrentTab = "About") {
		If (A_GuiControl = "AboutOK") {
			GuiSelectTab("Game")
			GuiControl, Focus, CtlFocus
		} Else If (A_GuiControl = "AboutWebsite") {
			Run, https://autohotkey.com/boards/viewtopic.php?f=6&t=50139
		}
	}
}

LSSelectPage(PageNum) {
	Global ; Assume-global mode

	Collection := PageNum

	GuiControl,, LSCollection, % "Bulldozer " Collection

	CheckFlag()

	Loop, 60 {
		GuiControl,, % "LS_" A_Index, % (60 * Collection - 60) + A_Index
		GuiControl, +Redraw, % "LS_" A_Index
	}

	If (Collection = 1) {
		; Previous - "Disabled" appearance
		Gui, Font, c757575 S14 Norm Bold, Arial
		GuiControl, Font, LSPrev

		; Next - "Enabled" appearance
		Gui, Font, c303030 S14 Norm Bold Underline, Arial
		GuiControl, Font, LSNext
	} Else If (Collection = 2) {
		; Previous - "Enabled" appearance
		Gui, Font, c303030 S14 Norm Bold Underline, Arial
		GuiControl, Font, LSPrev

		; Next - "Enabled" appearance
		Gui, Font, c303030 S14 Norm Bold Underline, Arial
		GuiControl, Font, LSNext
	} Else If (Collection = 3) {
		; Previous - "Enabled" appearance
		Gui, Font, c303030 S14 Norm Bold Underline, Arial
		GuiControl, Font, LSPrev

		; Next - "Disabled" appearance
		Gui, Font, c757575 S14 Norm Bold, Arial
		GuiControl, Font, LSNext
	}
}

GuiSelectTab(TabName, GuiColor := 000000) {
	Global ; Assume-global mode

	; RGB to BGR conversion
	BtnCol := SubStr(GuiColor, 5, 2) . SubStr(GuiColor, 3, 2) . SubStr(GuiColor, 1, 2)

	Gui, Color, % GuiColor ; Set background color of Gui
	GuiControl, ChooseString, Tab, % TabName ; Change tab
}

MouseMovement() {
	Global ; Assume-global mode

	MouseGetPos, MouseX, MouseY
	ColClick := Ceil(MouseX / (32 * DPI))
	RowClick := Ceil(MouseY / (32 * DPI))

	BDPos := RegExMatch(TempMap, "(4|5|6|7)")
	BDCol := Mod(BDPos, 20)
	BDRow := Floor(BDPos / 20) + 1

	If (ColClick < BDCol) { ; Left
		Move(-1, 0)
	} Else If (ColClick > BDCol) { ; Right
		Move(1, 0)
	} Else If (RowClick < BDRow) { ; Up
		Move(0, -1)
	} Else If (RowClick > BDRow) { ; Down
		Move(0, 1)
	}
}

WM_LBUTTONDOWN(wParam, lParam, Msg, Hwnd) {
	Global ; Assume-global mode
	Static Init := OnMessage(0x0201, "WM_LBUTTONDOWN")

	If (MouseMovement) {
		GuiControlGet, MouseDownTab,, Tab ; Get name of current tab

		If (MouseDownTab = "Game") {
			KeyWait, LButton, T0.4
			SetTimer, MouseMovement, % (ErrorLevel ? 160 : "Off")
		}
	}
}

WM_LBUTTONUP(wParam, lParam, Msg, Hwnd) {
	Global ; Assume-global mode
	Static Init := OnMessage(0x0202, "WM_LBUTTONUP")

	SetTimer, MouseMovement, Off

	If (MouseMovement) {
		If (MouseDownTab = "Game") {
			MouseMovement()
		}
	}
}

WM_RBUTTONDOWN(wParam, lParam, Msg, Hwnd) {
	Global ; Assume-global mode
	Static Init := OnMessage(0x0204, "WM_RBUTTONDOWN")

	If (MouseMovement) {
		GuiControlGet, MouseDownTab,, Tab ; Get name of current tab

		If (MouseDownTab = "Game") {
			KeyWait, RButton, T0.4

			SetTimer, UndoMove, % (ErrorLevel && UndoState ? 160 : "Off")
		}
	}
}

WM_RBUTTONUP(wParam, lParam, Msg, Hwnd) {
	Global ; Assume-global mode
	Static Init := OnMessage(0x0205, "WM_RBUTTONUP")

	SetTimer, UndoMove, Off

	If (MouseMovement) {
		If (MouseDownTab = "Game") {
			If (UndoState) {
				UndoMove()
			}
		}
	}
}

WM_CTLCOLORBTN(wParam, lParam, Msg, Hwnd) {
	Global ; Assume-global mode
	Static Init := OnMessage(0x0135, "WM_CTLCOLORBTN")

	; Paint button border color to match Gui background color
	return DllCall("Gdi32.dll\CreateSolidBrush", "UInt", "0x" BtnCol, "UPtr")
}

GuiClose(GuiHwnd) {
	Global ; Assume-global mode

	If (GuiHwnd = hBulldozer) {
		ExitApp ; Terminate the script unconditionally
	}
}

WM_KEYDOWN(wParam, lParam, Msg, Hwnd) {
	Global ; Assume-global mode
	Static Init := OnMessage(0x0100, "WM_KEYDOWN") ; Call function
	KF_REPEAT := (lParam & 0x40000000)

	GuiControlGet, CurrentTab,, Tab ; Get name of current tab
	GuiControlGet, FocusedControl, FocusV ; Get current focused control

	VK := Format("{:x}", wParam) ; Get virtual-key code

	If (CurrentTab <> "Game") {
		If (VK = "1B") { ; ESC
			GuiSelectTab("Game")
			GuiControl, Focus, CtlFocus
		} Else If (VK = "9") { ; Tab
			If (GetKeyState("Right", "P") = 0) && (GetKeyState("Down", "P") = 0) && (GetKeyState("Up", "P") = 0) && (GetKeyState("Left", "P") = 0) {
				If (FocusedControl = "AboutOK") {
					Send, {Left}
				} Else If (FocusedControl = "AboutWebsite") {
					Send, {Right}
				} Else If (FocusedControl = "LevelSelectCancel") {
					return 0
				} Else {
					Send, {Tab}
				}
			}

			return 0
		} Else If (VK = "25") { ; Left
			If (GetKeyState("Right", "P") = 0) && (GetKeyState("Down", "P") = 0) && (GetKeyState("Up", "P") = 0) && (GetKeyState("Tab", "P") = 0) {
				If (FocusedControl = "AboutOK") {
					Send, {Left}
				} Else If (FocusedControl = "AboutWebsite") {
					Send, {Right}
				} Else If (FocusedControl = "LevelSelectCancel") {
					return 0
				} Else {
					Send, {Tab}
				}
			}

			return 0
		} Else If (VK = "27") { ; Right
			If (GetKeyState("Left", "P") = 0) && (GetKeyState("Down", "P") = 0)	&& (GetKeyState("Up", "P") = 0) && (GetKeyState("Tab", "P") = 0) {
				If (FocusedControl = "AboutOK") {
					Send, {Left}
				} Else If (FocusedControl = "AboutWebsite") {
					Send, {Right}
				} Else If (FocusedControl = "LevelSelectCancel") {
					return 0
				} Else {
					Send, {Tab}
				}
			}

			return 0
		} Else If (VK = "26") { ; Up
			If (GetKeyState("Left", "P") = 0) && (GetKeyState("Down", "P") = 0)	&& (GetKeyState("Right", "P") = 0) && (GetKeyState("Tab", "P") = 0) {
				If (FocusedControl = "AboutOK") {
					Send, {Left}
				} Else If (FocusedControl = "AboutWebsite") {
					Send, {Right}
				} Else If (FocusedControl = "LevelSelectCancel") {
					return 0
				} Else {
					Send, {Tab}
				}
			}

			return 0
		} Else If (VK = "28") { ; Down
			If (GetKeyState("Left", "P") = 0) && (GetKeyState("Right", "P") = 0) && (GetKeyState("Up", "P") = 0) && (GetKeyState("Tab", "P") = 0) {
				If (FocusedControl = "AboutOK") {
					Send, {Left}
				} Else If (FocusedControl = "AboutWebsite") {
					Send, {Right}
				} Else If (FocusedControl = "LevelSelectCancel") {
					return 0
				} Else {
					Send, {Tab}
				}
			}

			return 0
		} Else If (VK = "20") { ; Spacebar
			WinMinimize
			return 0
		}
	} Else {
		GuiControl, Focus, CtlFocus ; Set focus to hidden edit control

		If (VK = "26" || VK = "57") { ; UP ARROW/W
			Move(0, -1)
		} Else If (VK = "25" || VK = "41") { ; LEFT ARROW/A
			Move(-1, 0)
		} Else If (VK = "28" || VK = "53") { ; DOWN ARROW/S
			Move(0, 1)
		} Else If (VK = "27" || VK = "44") { ; RIGHT ARROW/D
			Move(1, 0)
		} Else If (VK = "1B") { ; ESC
			ExitApp ; Terminate the script unconditionally
		} Else If (VK = "9") { ; Tab
			return 0 ; Prevent tab switching
		} Else If (VK = "20") { ; Spacebar
			WinMinimize
			return 0
		} Else If (VK = "8") { ; Backspace
			If (UndoState) {
				UndoMove()
			}
		} Else If (VK = "21") { ; Page Up
			MapSet(LevelNum+1)
		} Else If (VK = "22") { ; Page Down
			MapSet(LevelNum-1)
		}
	}
}

UndoMove() {
	Global ; Assume-global mode

	If (Undo := UndoArray.Pop()) {
		TempMap := Undo[Undo.MaxIndex(), "M"]
		BackgroundUpdate(Undo)
	}
}

ProgressCheck() {
	Global ; Assume-global mode
	Static PrevLevel := ""

	If (PosChrX1 = "2" || PosChrX1 = "3" || PrevLevel <> LevelNum) {
		StrReplace(TempMap, "3", "3", BoulderTargetCount)
		PercentText := Round((BoulderTargetCount / (InitTargetCount + InitBoulderTargetCount) * 100), 0)
		RemainderText := (BoulderTargetCount "/" (InitTargetCount + InitBoulderTargetCount))
	}

	PrevLevel := LevelNum
}

LevelClearCheck(Wait := 0) {
	Global ; Assume-global mode

	ProgressCheck()

	; Update window title
	DllCall("User32.dll\SetWindowText", "UInt", hBulldozer, "Str", "Bulldozer - Level " LevelNum " (" PercentText "%) [" RemainderText "]")

	If (!InStr(TempMap, "2")) { ; If all boulders moved to targets
		Solved[LevelNum] := "S" ; Add flag
		LevelNum++ ; Increment level number + 1
		Sleep, % Wait ; Delay before changing level
		MapSet(LevelNum) ; Load next level
	}
}

MapSet(LevelNo) {
	Global ; Assume-global mode

	MapBackup := "" ; Initialize variable
	UndoArray := [] ; Initialize array to store 'Undo' data

	; Level number validation
	LevelNum := (LevelNo > Maps.MaxIndex() ? "180" : LevelNo < Maps.MinIndex() ? "1" : LevelNo)

	; HOTFIX: Levels where bulldozer begins on target tile
	If (LevelNum = "64" || LevelNum = "127") {
		MapBackup := Maps[LevelNum] ; Backup map
	}

	TempMap := Maps[LevelNum] ; Define TempMap data
	BackgroundLoad(TempMap) ; Generate background image

	; HOTFIX: Levels where bulldozer begins on target tile
	If (LevelNum = "64" || LevelNum = "127") {
		Maps%LevelNum% := StrReplace(TempMap, "4", "1") ; Replace level data
	}

	StrReplace(LevelNum = "64" || LevelNum = "127" ? Maps%LevelNum% : Maps[LevelNum], "1", "1", InitTargetCount)
	StrReplace(LevelNum = "64" || LevelNum = "127" ? Maps%LevelNum% : Maps[LevelNum], "3", "3", InitBoulderTargetCount)

	ProgressCheck()

	; Update window title
	DllCall("User32.dll\SetWindowText", "UInt", hBulldozer, "Str", "Bulldozer - Level " LevelNum " (" PercentText "%) [" RemainderText "]")
}

Move(X, Y) {
	Global ; Assume-global mode

	; Get position of bulldozer
	PosNum := RegExMatch(TempMap, "(4|5|6|7)")

	; Get positions of next characters
	PosNumX1 := (PosNum + (Y ? Y * 20 : X))
	PosNumX2 := (PosNum + (Y ? (Y + Y) * 20 : (X + X)))

	; Get character string value of next positions
	PosChrX1 := SubStr(TempMap, (PosNum + (Y ? Y * 20 : X)), 1)
	PosChrX2 := SubStr(TempMap, (PosNum + (Y ? (Y + Y) * 20 : (X + X))), 1)

	; Replace character with value from original map
	Char := SubStr(LevelNum = "64" || LevelNum = "127" ? Maps%LevelNum% : Maps[LevelNum], PosNum, 1)
	ReplaceChar := (RegExMatch(Char, "(2|4|5|6|7)") ? "0" : RegExMatch(Char, "(1|3)") ? "1" : Char)

	; Face bulldozer in direction of requested movement
	Bulldozer := (PosNumX1 = PosNum - 1 ? "6" : PosNumX1 = PosNum + 1 ? "7" : PosNumX1 = PosNum - 20 ? "4" : "5")

	If (RegExMatch(PosChrX1, "(8|9|A|B|C|D|E|F)")) { ; Boundaries
		MidiSound(9, 86)
		MapUpdate(Bulldozer "|" PosNum)
		return
	}

	If (PosChrX1 = "3") { ; Target+Boulder
		If (RegExMatch(PosChrX2, "(2|3|8|9|A|B|C|D|E|F)")) { ; Boundaries
			MidiSound(9, 86)
			MapUpdate(Bulldozer "|" PosNum)
			return
		}

		; Target / Everything else
		MidiSound(9, PosChrX2 = "1" ? 81 : 70)
		MapUpdate((PosChrX2 = "1" ? "3" : "2") "|" PosNumX2, Bulldozer "|" PosNumX1, ReplaceChar "|" PosNum)
		return
	}

	If (PosChrX1 = "2") { ; Boulder
		If (RegExMatch(PosChrX2, "(2|3|8|9|A|B|C|D|E|F)")) { ; Boundaries
			MidiSound(9, 86)
			MapUpdate(Bulldozer "|" PosNum)
			return
		}

		; Target / Everything else
		MidiSound(9, PosChrX2 = "1" ? 81 : 70)
		MapUpdate((PosChrX2 = "1" ? "3" : "2") "|" PosNumX2, Bulldozer "|" PosNumX1, ReplaceChar "|" PosNum)
		return
	}

	; Everything else
	MidiSound(9, 85) ; Empty space
	MapUpdate(Bulldozer "|" PosNumX1, ReplaceChar "|" PosNum)
}

MapUpdate(PosReplace*) {
	Global ; Assume-global mode

	Update := [] ; Initialize the update array
	Undo := [] ; Initialize the undo array
	UndoMap := TempMap ; Backup previous TempMap value to UndoMap

	For K, V In PosReplace {
		Replacement := SubStr(V, 1, InStr(V, "|") - 1)
		Position := SubStr(V, InStr(V, "|") + 1)
		Current := SubStr(TempMap, Position, 1)
		Before := SubStr(TempMap, 1, Position - 1)
		After := SubStr(TempMap, Position + 1, StrLen(TempMap) - Position)

		TempMap := Before . Replacement . After
		Undo.Push({I: Position, C: Current, M: UndoMap})
		Update.Push({I: Position, C: Replacement})
	}

	If (TempMap "" <> UndoMap "") { ; TempMap changed
		UndoArray.Push(Undo)
	}

	If (!UnlimitedUndo) { ; If option enabled
		If (UndoArray.MaxIndex() > 1) { ; Number of times to allow 'Undo'
			UndoArray.RemoveAt(1)
		}
	}

	BackgroundUpdate(Update) ; Generate background image

	LevelClearCheck(500) ; Check for remaining boulders
}

BackgroundLoad(MapData) {
	Global ; Assume-global mode

	; Clear graphic to specific color
	DllCall("Gdiplus.dll\GdipGraphicsClear", "Ptr", pBackgroundGraphics, "UInt", "0xFF" BackgroundColor)

	; Generate image using tileset coordinates from map data
	Loop, % StrLen(MapData) {
		If (TileCol := InStr("89BCDEFA2317456", RegExReplace(SubStr(MapData, A_Index, 1), "(Z|X)", "8"), 1)) {
			DllCall("Gdiplus.dll\GdipDrawImageRectRect", "Ptr", pBackgroundGraphics, "Ptr", pTheme, "Float", ((32 * ((!(M := Mod(A_Index, 20)) ? 20 : M) - 1)) * DPI), "Float", ((32 * (Ceil(A_Index / 20) - 1)) * DPI), "Float", (32 * DPI), "Float", (32 * DPI), "Float", ((TileCol - 1) * 32), "Float", 0, "Float", 32, "Float", 32, "Int", 2, "Ptr", 0, "Ptr", 0, "Ptr", 0)
		}
	}

	; Write text to image
	If (LevelNumber) { ; If option enabled

		pFontmap := GdipCreateFromBase64(Fontmaps[(Solved[LevelNum] = "S" ? "Green" : "Orange")])

		Loop, Parse, % Format("{: 3}", LevelNum)
		{
			If (FontCol := InStr("0123456789", A_LoopField, 1)) {
				DllCall("Gdiplus.dll\GdipDrawImageRectRect", "Ptr", pBackgroundGraphics, "Ptr", pFontmap, "Float", ((((24 * A_Index) - 24) + 564) * DPI), "Float", (4 * DPI), "Float", (24 * DPI), "Float", (24 * DPI), "Float", ((FontCol - 1) * 24), "Float", 0, "Float", 24, "Float", 24, "Int", 2, "Ptr", 0, "Ptr", 0, "Ptr", 0)
			}
		}
	}

	; Redraw background image
	GuiControl, +Redraw, % hBackground
}

BackgroundUpdate(arrUpdate) {
	Global ; Assume-global mode

	For K, V In arrUpdate {
		DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pBackgroundGraphics, "Ptr", pBackgroundBrush, "Float", ((32 * ((!(M := Mod(V.I, 20)) ? 20 : M) - 1)) * DPI), "Float", ((32 * (Ceil(V.I / 20) - 1)) * DPI), "Float", (32 * DPI), "Float", (32 * DPI))

		If (TileCol := InStr("89BCDEFA2317456", V.C, 1)) {
			DllCall("Gdiplus.dll\GdipDrawImageRectRect", "Ptr", pBackgroundGraphics, "Ptr", pTheme, "Float", ((32 * ((!(M := Mod(V.I, 20)) ? 20 : M) - 1)) * DPI), "Float", ((32 * (Ceil(V.I / 20) - 1)) * DPI), "Float", 32 * DPI, "Float", 32 * DPI, "Float", (TileCol - 1) * 32, "Float", 0, "Float", 32, "Float", 32, "Int", 2, "Ptr", 0, "Ptr", 0, "Ptr", 0)
		}
	}

	; Redraw background image
	GuiControl, +Redraw, % hBackground
}

GdipCreateFromBase64(strB64, HICON := 0) {
	DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &strB64, "UInt", 0, "UInt", 0x01, "Ptr", 0, "UIntP", B64Len, "Ptr", 0, "Ptr", 0)
	VarSetCapacity(B64Dec, B64Len, 0) ; pbBinary size
	DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &strB64, "UInt", 0, "UInt", 0x01, "Ptr", &B64Dec, "UIntP", B64Len, "Ptr", 0, "Ptr", 0)
	pStream := DllCall("Shlwapi.dll\SHCreateMemStream", "Ptr", &B64Dec, "UInt", B64Len, "UPtr")
	DllCall("Gdiplus.dll\GdipCreateBitmapFromStreamICM", "Ptr", pStream, "PtrP", pBitmap)

	If (HICON) {
		DllCall("Gdiplus.dll\GdipCreateHICONFromBitmap", "Ptr", pBitmap, "PtrP", hBitmap, "UInt", 0)
	}

	ObjRelease(pStream)
	return (HICON ? hBitmap : pBitmap)
}

GdipCreateFromPNG(File) {
	If (!A_IsUnicode) {
		VarSetCapacity(wFile, 1024)
		DllCall("Kernel32.dll\MultiByteToWideChar", "UInt", 0, "UInt", 0, "Ptr", &File, "Int", -1, "Ptr", &wFile, "Int", 512)
		DllCall("Gdiplus.dll\GdipCreateBitmapFromFile", "Ptr", &wFile, "PtrP", pBitmap)
	} Else {
		DllCall("Gdiplus.dll\GdipCreateBitmapFromFile", "Ptr", &File, "PtrP", pBitmap)
	}

	return pBitmap
}

ChooseColor(StartColor, hOwner := 0) {
	rgbResult := ((StartColor & 0xFF) << 16) + (StartColor & 0xFF00) + ((StartColor >> 16) & 0xFF)

	VarSetCapacity(CUSTOM, 64, 0)
	NumPut(VarSetCapacity(CHOOSECOLOR, (A_PtrSize * 9), 0), CHOOSECOLOR, 0)
	NumPut(hOwner, CHOOSECOLOR, A_PtrSize)
	NumPut(rgbResult, CHOOSECOLOR, (A_PtrSize * 3))
	NumPut(&Custom, CHOOSECOLOR, (A_PtrSize * 4))
	NumPut(0x103, CHOOSECOLOR, (A_PtrSize * 5))

	RetVal := DllCall("Comdlg32.dll\ChooseColor", "Ptr", &CHOOSECOLOR)

	If (ErrorLevel <> 0 || RetVal == 0) {
		return Format("{:06X}", StartColor)
	}

	rgbResult := NumGet(CHOOSECOLOR, (A_PtrSize * 3))
	RetCol := Format("{:06X}", (rgbResult & 0xFF00) + ((rgbResult & 0xFF0000) >> 16) + ((rgbResult & 0xFF) << 16))

	return RetCol
}

SubclassControl(HCTL, FuncName, Data := 0) {
	Static ControlCB := []

	If (Controls.HasKey(HCTL)) {
		DllCall("Comctl32.dll\RemoveWindowSubclass", "Ptr", HCTL, "Ptr", ControlCB[HCTL], "Ptr", HCTL)
		DllCall("Kernel32.dll\GlobalFree", "Ptr", Controls[HCTL], "Ptr")
		Controls.Delete(HCTL)

		If (FuncName = "") {
			return true
		}
   }

	If (!DllCall("User32.dll\IsWindow", "Ptr", HCTL, "UInt"))
	|| (!IsFunc(FuncName) || (Func(FuncName).MaxParams <> 6))
	|| (!CB := RegisterCallback(FuncName,, 6)) {
		return false
	}

	If (!DllCall("Comctl32.dll\SetWindowSubclass", "Ptr", HCTL, "Ptr", CB, "Ptr", HCTL, "Ptr", Data)) {
		return (DllCall("Kernel32.dll\GlobalFree", "Ptr", CB, "Ptr") & 0)
	}

	return (ControlCB[HCTL] := CB)
}

BgSubclassProc(hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData) {
	Global pControlGraphics, pBackgroundImage

	If (uMsg = 0x0014) { ; WM_ERASEBKGND
		return 1 ; Do nothing
	}

	If (uMsg = 0x000F) { ; WM_PAINT
		; Draw the background image
		VarSetCapacity(PAINTSTRUCT, 60 + A_PtrSize, 0)
		DllCall("User32.dll\BeginPaint", "Ptr", hWnd, "Ptr", &PAINTSTRUCT, "UPtr")
		DllCall("Gdiplus.dll\GdipDrawImage", "Ptr", pControlGraphics, "Ptr", pBackgroundImage, "Float", 0, "Float", 0)
		DllCall("User32.dll\EndPaint", "Ptr", hWnd, "Ptr", &PAINTSTRUCT, "UPtr")
		return 0
	}

	If (uMsg = 0x0002) { ; WM_DESTROY
		SubclassControl(hWnd, "") ; Remove the Subclass
	}

	; Pass all other messages to DefSubclassProc
	return DllCall("Comctl32.dll\DefSubclassProc", "Ptr", hWnd, "UInt", uMsg, "Ptr", wParam, "Ptr", lParam, "Ptr")
}

CheckFlag() {
	Global ; Assume-global mode

	Loop, 60 {
		Index := (Collection = 1 ? A_Index : Collection = 2 ? A_Index + 60 : A_Index + 120)

		If (Solved[Index] = "S" && Index <> LevelNum) { ; Complete
			CreatePixel("55AE59", hLSf_%A_Index%)
			CreatePixel("55AE59", hLSb_%A_Index%)
		} Else If (Solved[Index] = "S" && Index = LevelNum) { ; Complete/Current
			CreatePixel("55AE59", hLSf_%A_Index%)
			CreatePixel("FD9912", hLSb_%A_Index%)
		} Else If (Solved[Index] <> "S" && Index = LevelNum) { ; Current
			CreatePixel("FD9912", hLSf_%A_Index%)
			CreatePixel("FD9912", hLSb_%A_Index%)
		} Else { ; Everything else
			CreatePixel("FFFFFF", hLSf_%A_Index%)
			CreatePixel("FFFFFF", hLSb_%A_Index%)
		}

		GuiControl, +Redraw, % hLSf_%A_Index%
		GuiControl, +Redraw, % hLSb_%A_Index%
	}
}

RLE_Encode(Message) {
	StringLeft, Previous, Message, 1
	StringRight, Last, Message, 1

	Message .= Asc(Chr(Last) + 1)
	Count := 0

	Loop, Parse, Message
	{
		If (Previous == A_LoopField) {
			Count += 1
		} Else {
			output .= Previous . Count
			Previous := A_LoopField
			Count := 1
		}
	}

	return output
}

RLE_Decode(Message) {
	Pos := 1

	While(Item := RegExMatch(Message, "\D", Char, Pos)) {
		DigPos := RegExMatch(Message, "\d+", Dig, Item)

		Loop, % Dig {
			Output .= Char
		}

		Pos := DigPos
	}

	return Output
}

ST_Glue(Array, Delim := "`n") {
	For K, V In Array {
		New .= V . Delim
	}

	return Trim(New, Delim)
}

CreatePixel(Color, Handle) {
	Static CreatePixelBitmapDB := {}

	If (CreatePixelBitmapDB[Handle]) {
		hBitmap := CreatePixelBitmapDB[Handle]
	} Else {
		hBitmap := DllCall("Gdi32.dll\CreateBitmap", "Int", 1, "Int", 1, "UInt", 1, "UInt", 24, "Ptr", 0, "Ptr")
		hBitmap := DllCall("User32.dll\CopyImage", "Ptr", hBitmap, "UInt", 0, "Int", 0, "Int", 0, "UInt", 0x2008, "Ptr")
		CreatePixelBitmapDB[Handle] := hBitmap
	}

	VarSetCapacity(BMBITS, 4, 0), Numput("0x" . Color, &BMBITS, 0, "UInt")
	DllCall("Gdi32.dll\SetBitmapBits", "Ptr", hBitmap, "UInt", 3, "Ptr", &BMBITS)
	DllCall("User32.dll\SendMessage", "Ptr", Handle, "UInt", 0x0172, "Ptr", 0, "Ptr", hBitmap)
}

MidiSound(Channel, Note, Velocity := 127) {
	Global ; Assume-global mode

	If (!Sound) {
		return
	}

	; Prevent repeating sound on boundary
	If (KF_REPEAT && (RegExMatch(PosChrX2, "(2|3|8|9|A|B|C|D|E|F)") || RegExMatch(PosChrX1, "(8|9|A|B|C|D|E|F)"))) {
		return
	}

	Volume := (100 / 100) * 0xFFFF

	DllCall("Winmm.dll\midiOutSetVolume", "UInt", h_MIDIOut, "UInt", Volume | Volume << 16)
	DllCall("Winmm.dll\midiOutShortMsg", "UInt", h_MIDIOut, "UInt", 0x90 | Channel | (Note << 8) | (Velocity << 16), "UInt")
}
; ==============================================================================
Image All revisions can be found on the BulldozerAHK Github repository.


Image Screenshots
Image Image Image


Image Themes
ImageBulldozer Color (Bulldozer 1)
Image

ImageBulldozer Monochrome (Bulldozer 1)
Image

ImageMonochrome (TheDewd)
Image

ImageMonochrome Black (TheDewd) *Transparent - See the background color
Image

ImageMonochrome White (TheDewd) *Transparent - See the background color
Image

ImageMonochrome Black (Inverted) (TheDewd) *Transparent - See the background color
Image

Image8-bit Fantasy (TheDewd) [Resource]
Image

ImageRacecar 1 (TheDewd) [Resource]
Image

ImageRacecar 2 (TheDewd) [Resource]
Image

ImageChip's Challenge (TheDewd) [Resource]
Image

ImageMario (TheDewd) [Resource]
Image

ImageZelda (TheDewd) [Resource]
Image

ImageNeko (TheDewd) [Resource]
Image

ImageMario Bros. (TheDewd) [Resource]
Image

ImageKid Icarus (TheDewd) [Resource]
Image

ImageAhkban (SpeedMaster)
Image

ImageNeon Rainbow (TheDewd)
Image

ImageTanks (TheDewd) [Resource]
Image

Image Submit your themes to have them featured here! Image
Last edited by TheDewd on 24 Sep 2018, 16:19, edited 94 times in total.
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
User avatar
Nextron
Posts: 1217
Joined: 01 Oct 2013, 08:23
Location: Netherlands OS: Win7 x64 AHK: Unicode x32

Re: [GAME] Bulldozer

Post by Nextron » 05 Jun 2018, 09:47

TheDewd wrote:Please share any suggestions for improvement!
Pics! :monkeysee:
User avatar
TheDewd
Posts: 1076
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [GAME] Bulldozer

Post by TheDewd » 05 Jun 2018, 09:51

Nextron wrote:
TheDewd wrote:Please share any suggestions for improvement!
Pics! :monkeysee:
Updated first post with screenshot. I plan to add more information later. I just wanted to go ahead and share the game so far.
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
User avatar
jeeswg
Posts: 5112
Joined: 19 Dec 2016, 01:58
Location: UK

Re: [GAME] Bulldozer

Post by jeeswg » 05 Jun 2018, 10:50

- Game looks phenomenal cheers. The 2 things to mention are that it flashes black each time you move, and that you can't hold down the arrow keys, you have to press repeatedly. But all of the key stuff is done, cheers again.
User avatar
TheDewd
Posts: 1076
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [GAME] Bulldozer

Post by TheDewd » 05 Jun 2018, 11:10

jeeswg wrote:it flashes black each time you move
You're correct! The issue only occurs for me when using the classic Windows interface. On Windows 7/Windows 10 using themed interface the issue is non-existent. I'm currently implementing a working solution to this for the next update by using BitBlt.
jeeswg wrote:you can't hold down the arrow keys, you have to press repeatedly
I disabled the repeat initially to allow the script time to fully update the background image and other things so that the player doesn't notice the "lag" between updates.
Last edited by TheDewd on 05 Jun 2018, 22:32, edited 1 time in total.
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
need4speed
Posts: 41
Joined: 22 Apr 2016, 06:50

Re: [GAME] Bulldozer

Post by need4speed » 05 Jun 2018, 15:57

wow, impressive. :thumbup:
you could add an small animation and play a sound when a level is completed.
User avatar
SpeedMaster
Posts: 221
Joined: 12 Nov 2016, 16:09

Re: [GAME] Bulldozer

Post by SpeedMaster » 05 Jun 2018, 19:44

Nice and concise game script. :thumbup:
The game plays well on windows 7 (no flickering background exept on windows 10)
This game is almost identical to the original. :clap:
Thanks for sharing.
tmplinshi
Posts: 1260
Joined: 01 Oct 2013, 14:57

Re: [GAME] Bulldozer

Post by tmplinshi » 06 Jun 2018, 01:09

It's getting harder for me from level 10, then I look at how many levels.. 61 maps! oh no.. you are wasting my time.. Nice script.

No flickering background on windows 10 x64.
Helgef
Posts: 3185
Joined: 17 Jul 2016, 01:02
Contact:

Re: [GAME] Bulldozer

Post by Helgef » 06 Jun 2018, 02:51

Impressive stuff :shock: :clap: . Less impressive, I failed level 2 twice :facepalm:

Thanks for sharing, cheers.
User avatar
nnnik
Posts: 3312
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: [GAME] Bulldozer

Post by nnnik » 06 Jun 2018, 02:55

I have yet to completely read the entire source but it looks promising.
You should probably rather draw an entire picture and display the whole game as one picture instead of using seperate picture controls.
Recommends AHK Studio
User avatar
derz00
Posts: 495
Joined: 02 Feb 2016, 17:54
GitHub: derz00
Location: Middle of the round cube

Re: [GAME] Bulldozer

Post by derz00 » 06 Jun 2018, 06:39

excuse my ignorance of games, but what does this password do?
try it and see
...
User avatar
TheDewd
Posts: 1076
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [GAME] Bulldozer

Post by TheDewd » 06 Jun 2018, 06:53

derz00 wrote:excuse my ignorance of games, but what does this password do?
There is a "Level Select" menu item in the "Game" menu in the menubar, or press F3. Enter the password to load a specific level.
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
User avatar
derz00
Posts: 495
Joined: 02 Feb 2016, 17:54
GitHub: derz00
Location: Middle of the round cube

Re: [GAME] Bulldozer

Post by derz00 » 06 Jun 2018, 07:12

OK that makes sense :)

Good job on the game. Level 6 took me about 6-8 tries. The rest were pretty easy except I lost my motivation at level 10 :) Now I wish I had noted the password for that level.
try it and see
...
User avatar
TheDewd
Posts: 1076
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [GAME] Bulldozer

Post by TheDewd » 07 Jun 2018, 16:12

Updated: Background flicker should now be eliminated.

Revision 3 (2018-06-07)
  • Changed background image update process to prevent flickering
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
just me
Posts: 5510
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: [GAME] Bulldozer

Post by just me » 08 Jun 2018, 05:04

Just one more: "Impressive, thanks for sharing!"

Your script doesn't run on AHK Basic. So you don't need those (A_PtrSize ? "UPtr" : "UInt"). You can safely use "UPtr" or "UPtr*/"UPtrP".

Some thoughts on BackgroundLoad():
  • As far as i can see the tile images will never be changed. So you need to load them into pTilemap only once when the script starts or the tile map will be changed (e.g. in OnLoad()) and destroy the current tile map in OnUnload().
  • Also, you can reuse the GDIP background image and its graphics. They also can be created in OnLoad() and destroyed in OnUnload(). (This would even allow to update only the tiles of interest, 3 at most.)
  • Code: Select all

    	; Create brush
    	DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0XFF808000, (A_PtrSize ? "UPtr*" : "UInt*"), pBrush)
    	; Fill bitmap graphic with brush color
    	DllCall("Gdiplus.dll\GdipFillRectangle", (A_PtrSize ? "UPtr" : "UInt"), G, (A_PtrSize ? "UPtr" : "UInt"), pBrush, "Float", 0, "Float", 0, "Float", 640, "Float", 384)
    	; Delete brush
    	DllCall("Gdiplus.dll\GdipDeleteBrush", (A_PtrSize ? "UPtr" : "UInt"), pBrush)
    
    might be replaced by

    Code: Select all

       DllCall("Gdiplus.dll\GdipGraphicsClear", "Ptr", G, "UInt", 0XFF808000)
brutus_skywalker
Posts: 175
Joined: 24 Dec 2016, 13:16
Location: Antarctica

Re: [GAME] Bulldozer

Post by brutus_skywalker » 09 Jun 2018, 10:58

You Sir Most Certainly Are TheDewd , FREAKING AWESOME DUDE!
Outsourcing Clicks & Presses Since 2004.
User avatar
Gio
Posts: 467
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: [GAME] Bulldozer

Post by Gio » 09 Jun 2018, 13:04

Nice script, thanks for sharing :D

The level-select password system seems to be not working here. Rev 3. Windows 8.1 Single Language (64 bits).
"What is suitable automation? Whatever saves your day for the greater matters."
Barcoder - Create QR Codes and other Barcodes using only Autohotkey !!
User avatar
TheDewd
Posts: 1076
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [GAME] Bulldozer

Post by TheDewd » 11 Jun 2018, 23:59

Revision 4 (2018-06-11)
  • Added levels from Bulldozer 2 and Bulldozer 3
  • Resized level area for compatibility with maps from Bulldozer 2/Bulldozer 3
  • Optimized level drawing to update changed tiles only
  • Redesigned 'Level Select' and 'About' menu item contents
Note: The passwords are different from the previous versions due to changing the formatting of the level data for compatibility with the larger maps added for levels 61-180. I apologize for any inconvenience.

I hope you all enjoy the game!
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
burque505
Posts: 571
Joined: 22 Jan 2017, 19:37

Re: [GAME] Bulldozer

Post by burque505 » 12 Jun 2018, 07:27

:bravo: Wow, what a difference! It's really smooth, no flickering, repeat works great.
Those changes in BackgroundLoad(MapData) worked wonders.
Thanks for sharing this.
Regards,
burque505
rommmcek
Posts: 372
Joined: 15 Aug 2014, 15:18

Re: [GAME] Bulldozer

Post by rommmcek » 12 Jun 2018, 14:00

Great, great, great! Very smooth, some constellations are really not too easy!

P.s.: Level 24, wall seems to be rock (not bulldozer alone) permeable at least at coordinats 2,4; 3,6; 4,5; 4,7; where 0,0; being upper left corner.
Post Reply

Return to “Scripts and Functions”