summaryrefslogtreecommitdiff
path: root/bubbob/levels
diff options
context:
space:
mode:
authorDiego Roversi <diegor@tiscali.it>2019-09-08 18:12:27 +0200
committerDiego Roversi <diegor@tiscali.it>2019-09-08 18:12:27 +0200
commit1d9925c287b318ec21343e2682b51ab6a36ae8db (patch)
tree17d1c0ac21eea6f291146520afa8381db4586fb4 /bubbob/levels
initial commit from cvs 1.6.2
Diffstat (limited to 'bubbob/levels')
-rw-r--r--bubbob/levels/Arena.binbin0 -> 164736 bytes
-rw-r--r--bubbob/levels/CompactLevels.py1902
-rw-r--r--bubbob/levels/HouseOfFun.binbin0 -> 196096 bytes
-rw-r--r--bubbob/levels/Levels.binbin0 -> 178432 bytes
-rw-r--r--bubbob/levels/LostLevels.binbin0 -> 178432 bytes
-rw-r--r--bubbob/levels/README.txt23
-rw-r--r--bubbob/levels/RandomLevels.py362
-rw-r--r--bubbob/levels/rnglevel1276
-rw-r--r--bubbob/levels/scratch.py2301
9 files changed, 5864 insertions, 0 deletions
diff --git a/bubbob/levels/Arena.bin b/bubbob/levels/Arena.bin
new file mode 100644
index 0000000..73db756
--- /dev/null
+++ b/bubbob/levels/Arena.bin
Binary files differ
diff --git a/bubbob/levels/CompactLevels.py b/bubbob/levels/CompactLevels.py
new file mode 100644
index 0000000..e48908a
--- /dev/null
+++ b/bubbob/levels/CompactLevels.py
@@ -0,0 +1,1902 @@
+#
+# A series of compact levels.
+#
+
+import boarddef, mnstrmap, random
+from boarddef import LNasty, LMonky, LGhosty, LFlappy
+from boarddef import LSpringy, LOrcy, LGramy, LBlitzy
+from boarddef import RNasty, RMonky, RGhosty, RFlappy
+from boarddef import RSpringy, ROrcy, RGramy, RBlitzy
+
+
+class level01(boarddef.Level):
+ a = LNasty
+ b = RNasty
+
+ walls = """
+#############################
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## a b ##
+#### ############### ####
+## ##
+## ##
+## ##
+## a b ##
+#### ############### ####
+## ##
+## ##
+## ##
+## a b ##
+#### ############### ####
+## ##
+## ##
+## ##
+## ##
+#############################
+"""
+
+
+class level02(boarddef.Level):
+ a = LNasty
+ b = RNasty
+ g = RGhosty
+
+ walls = """
+#############################
+## # ##
+## # ##
+## # ##
+## # g ##
+## g # ##
+## # ##
+## # ##
+#### ############### ####
+## # # ##
+## # # ##
+## # # ##
+## # a b # ##
+#### ############### ####
+## ##
+## ##
+## ##
+## ##
+#### ####
+## ##
+## ##
+## ##
+## ##
+#############################
+"""
+
+
+class level03(boarddef.Level):
+ a = LNasty
+ b = RNasty
+
+ letter = 1
+
+ walls = """
+######### ### #########
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+##b # # # # a ##
+###### ##### ##### ######
+## ##
+## ##
+## ##
+## #b # # # # a # ##
+## ##### ##### ##### ##
+## # # ##
+## # # ##
+## # # ##
+##b # # a ##
+####### # b # #######
+## ####### ##
+## # ##
+## # ##
+## # ##
+## # ##
+## # ##
+######### ### #########
+""" #|# #|# #|# """
+
+
+class level04(boarddef.Level):
+ a = LNasty
+ b = RNasty
+ g = LOrcy
+
+ fire = 1
+
+ walls = """
+######### ### #########
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+##b # # # # a ##
+###### ##### ##### ######
+## ##
+## ##
+## ##
+## #b # #gg # # a # ##
+## ##### ##### ##### ##
+## # # ##
+## # # ##
+## # # ##
+##b # # a ##
+####### # b # #######
+## ####### ##
+## # ##
+## # ##
+## # ##
+## # ##
+## # ##
+######### ### #########
+""" #|# #|# #|# """
+
+class level05(boarddef.Level):
+ a = LNasty
+ b = RNasty
+ g = LOrcy
+ f = RFlappy
+
+ water = top = letter = 1
+
+ walls = """
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+##b # # # # a ##
+#### # ##### ##### # ####
+## ##
+## ##
+## ##
+## #b # #gg # # a # ##
+## # ### ## ## ### # ##
+## # # ##
+## # # ##
+## # f # ##
+##b # # a ##
+####### # b # #######
+## # ### # ##
+## ##
+## ##
+## ##
+## ##
+## ##
+######### #########
+""" #|# #|# #|# """
+
+ winds = """
+>> <<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+"""
+
+class level06(boarddef.Level):
+ a = LNasty, RNasty, LMonky
+
+ letter = fire = 1
+
+ walls = """
+#############################
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ### ##
+## # ## ##
+## ## # ## # ##
+## # # ## # # ##
+## ## # # # # # ##
+## # #### # # #a ##
+## a #### #############
+## #### ##
+#### ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+#############################
+""" #|# #|# #|# """
+
+class level07(boarddef.Level):
+ g = LGhosty, LGhosty, LGhosty, LGhosty
+ h = RGhosty, RGhosty, RGhosty, RGhosty
+
+ letter = lightning = 1
+
+ walls = """
+## ##
+## ##
+## # # ##
+## # # ##
+## # # ##
+## ### ### ##
+##h # # # # #g ##
+## # # # # # # # ##
+##### #### # #### #####
+## # # # ### # # # ##
+## # # # # # # ##
+## ### # # # ### ##
+## # #### #### # ##
+## # # # # # ##
+## # # # # ##
+## ### ##
+## # ##
+## # # # ##
+## # # # ##
+## # # ##
+## ### ### ##
+## # # # # ##
+## # # # # # # ##
+## #### #### #### #### ##
+""" #|# #|# #|# """
+
+class level08(boarddef.Level):
+ s = LSpringy
+ r = RSpringy
+ f = LFlappy
+ g = RFlappy
+
+ walls = """
+#############################
+## ##
+## g f ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## # ##
+## ##
+## ### ##
+## ##
+## ##### ##
+## ##
+## ####### ##
+## ##
+## ######### ##
+## sssrrr ##
+## ########### ##
+## ##
+## ##
+## ##
+## ##
+#############################
+""" #|# #|# #|# """
+
+class level09(boarddef.Level):
+ m = (LMonky, RMonky,)*5
+ g = LGhosty
+
+ walls = """
+####### #### #### #######
+####### #### #### #######
+## ## ## ##
+## ## ## ##
+## g ## ## g ##
+## ## ## ##
+## ## ## ##
+#### ##### ##### ####
+#### ##### ##### ####
+## ##
+## ## #### #### ## ##
+## ## #### #### ## ##
+## ## ## ##
+#### ## ## ####
+#### ## m ## ####
+## ## ### ## ##
+## ## ## ### ## ## ##
+## ## ## ### ## ## ##
+## ## ### ## ##
+#### ## ## ####
+#### ## ## ####
+## ## ## ##
+## ## #### #### ## ##
+####### #### #### #######
+""" #|# #|# #|# """
+
+class level10(boarddef.Level):
+ n = LNasty
+
+ fire = top = 1
+
+ walls = """
+## ##### ## ##
+## ##nn ## ##
+## ####### ##
+## ##
+## ##
+## ## ##### ##
+## ##nn ## ##
+## ####### ##### ## ##
+## ##nn ## ##
+## ####### ##
+## ##
+## ##
+## ## ##### ##
+## ##nn ## ##
+## ####### ##
+## ##
+## ##### ## ##
+## ##nn ## ##
+## ####### ##
+## ##
+## ##
+## ##
+## ##
+#############################
+""" #|# #|# #|# """
+
+ winds = """
+>> <<
+>>> >>v xxx <<<
+>>^ ^<<
+>>^ v<<<^<<
+>>^ ^<<
+>>^ ^<<
+>>^ xxx v<< ^<<
+>>^ ^<<
+>>^>>>v >>v xxx ^<<
+>>^ ^<<
+>>^ >v ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ xxx v<< ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ xxx ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+"""
+
+class level11(boarddef.Level):
+ o = LOrcy
+ p = ROrcy
+
+ letter = fire = water = lightning = top = 1
+
+ walls = """
+## ##
+## ##
+### ###
+## # # ##
+## # # ##
+## # # ##
+## # # # # ##
+## # ##
+## o p o # # #p o p ##
+####### #### # #### #######
+## # ##
+## # ##
+## # ##
+## # # # ##
+## # # # ##
+## # # # ##
+## # # # ##
+## # # # ##
+## # # # ##
+## # # # ##
+## # # # ##
+## # # # # # # ##
+## # # ##
+###### ###### ###### ######
+""" #|# #|# #|# """
+
+class level12(boarddef.Level):
+ o = LGramy
+
+ walls = """
+## #### ##
+## # # ##
+## #### ##
+## # # ##
+## # o ##
+## #################
+## # # ##
+## #### ##
+## o # # # ##
+## ######### #### ##
+## # # # # ##
+## #### # o ##
+## # # ############
+## #### # # ##
+## # # #### ##
+## o # # # ##
+############ #### ##
+## # # # # ##
+## #### o # ##
+## # # ######## ##
+## #### ##
+## # # ##
+## ##
+#############################
+""" #|# #|# #|# """
+
+class level13(boarddef.Level):
+ n = LNasty
+ m = LMonky
+ g = LGhosty
+ f = LFlappy
+ s = LSpringy
+ o = LOrcy
+ r = LGramy
+ b = LBlitzy
+
+ walls = """
+## # #### ##
+## f ## ## #### ##
+## #### ## ## ##
+## #### # ##
+## #### f ###### ##
+## ## ## f ###### ##
+## # #### #### #### ##
+## ###### ###### ##
+## ###### ###### ##
+## #### #### # ##
+## ## ## f ##
+## #### ##
+## f ##
+## #### ##
+## ###### ##
+## #### ###### ##
+## ## ## # #### ##
+## # #### f ## ## ##
+## ###### #### ##
+## ###### ##
+## #### ##
+## ##
+## #### ##
+###### ###### #####
+""" #|# #|# #|# """
+
+class level14(boarddef.Level):
+ o = LOrcy
+ r = LGramy
+
+ walls = """
+#############################
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ### ### ##
+## ## ## ##
+## # # ##
+## ### ### ##
+## ## ## ##
+## # # ##
+## ## ## ##
+## ## ## ##
+## ### ### ##
+## ## ## ##
+## ## ## ##
+## ##or or ## ##
+#############################
+""" #|# #|# #|# """
+
+class level15(boarddef.Level):
+ s = LSpringy
+ g = LGhosty
+
+ walls = """
+#############################
+## ##
+## ##
+## ##
+## s s ##
+## s s ##
+## s s ##
+## ###s #####s ### ##
+## # ## ####### ## # ##
+## # ### ### # ##
+## ## ### ### ## ##
+## # ### g ### # ##
+## # ### ### # ##
+## # ### ### # ##
+## # ## ####### ## # ##
+## ### ##### ### ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+#############################
+""" #|# #|# #|# """
+
+class level16(boarddef.Level):
+ l = LBlitzy, LGramy
+ r = RBlitzy, RGramy
+
+ letter = 1
+
+ walls = """
+#############################
+## l r ##
+## #### ## ##
+## #### ## #### ## ##
+## #### ## #### ## ##
+## l ## ## #### ## ##
+## #### ## ## l ##
+## #### ## ## #### ##
+## ## ## ## #### ##
+## #### ## ## ##
+## #### ## ## #### ## ##
+## ## #### ## ##
+## ## #### ## ##
+## ## #### #### l ## ## ##
+## ## #### ## ## ##
+## ## ## ## ##
+## ## ## r ## ##
+## #### ## ## ## ##
+## #### ## #### ## ## ##
+## ## #### ## ## ##
+## #### ## ## ##
+## #### ## ##
+## ##
+#############################
+""" #|# #|# #|# """
+
+class level17(boarddef.Level):
+ m = LMonky
+ j = RMonky
+ g = LGhosty
+ h = RGhosty
+ b = LBlitzy
+
+ walls = """
+############ ##
+## # ##
+## g # ##
+## ##### # ########### ##
+## # # # # # ##
+## # ## # # g # ##
+## # #j # # ##### # ##
+## # ##### # # # # ##
+## # # # ## # ##
+## #b # # #j # ##
+## ########### # ##### ##
+## # ##
+## # ##
+## ########### # h ##
+## # # # ##### ##
+## # h # # # # ##
+## # ##### # # ## # ##
+## # # # # # m # # ##
+## # ## # # ##### # ##
+## # m # # # # ##
+## ##### # # b # ##
+## # ########### ##
+## b # ##
+############ ##
+""" #|# #|# #|# """
+
+class level18(boarddef.Level):
+ o = (ROrcy,)*10
+
+ walls = """
+############# #############
+## ##
+## # ##
+## ##
+## # # ##
+## ##
+## ##
+## # # ##
+## ##
+## # ####### # ##
+## # # ##
+## ## ## ##
+## # ### ### # ##
+## ## ## ##
+## # # ##
+## # ####### # ##
+## # # ##
+## ## ## ##
+## ###### ###### ##
+## ### ### ##
+## ## o ## ##
+## ## ####### ## ##
+## ## ## ##
+############# #############
+""" #|# #|# #|# """
+
+class level19(boarddef.Level):
+ n = LNasty
+ g = RGhosty
+ f = LFlappy
+ s = LSpringy
+
+ walls = """
+## ### ### ### ##
+## # # # # # # ##
+## # #### #### # ##
+## #n # #n # #n # ##
+## ### ### ### ##
+## # # ##
+## # # ##
+## ### f ### ##
+## # # g # # ##
+## # # f # # ##
+## #n # g #n # ##
+## ### ### ##
+## # # ##
+## # # ##
+## ### ### ### ##
+## # #s # #s # # ##
+## # #### #### # ##
+## #n # #n # #n # ##
+## ### ### ### ##
+## ##
+## ##
+## ##
+## ##
+#############################
+""" #|# #|# #|# """
+
+class level20(boarddef.Level):
+ s = LSpringy, RSpringy
+
+ letter = fire = top = 1
+
+ walls = """
+### ###
+### ###
+## ##
+## ##
+##ss ss # # ss ss ##
+## # # # # # # ##
+## # # ##### # # ##
+## # # # # ##
+## # # # # ##
+## # # ##
+## # # ##
+## # # ##
+## ##
+## ##
+## ##
+## ##
+## # # ##
+## # # ##
+## # # ##
+## ##
+## ##
+## ##
+## ##
+## ######### ######### ##
+""" #|# #|# #|# """
+
+class level21(boarddef.Level):
+ n = (RNasty,)*12
+
+ letter = 1
+
+ walls = """
+#############################
+## ##
+##n ##
+######################### ##
+## ##
+## ##
+## #########################
+## ##
+## ##
+######################### ##
+## ##
+## ##
+## #########################
+## ##
+## ##
+######################### ##
+## ##
+## ##
+## #########################
+## ##
+## ##
+## ##
+## ##
+#############################
+""" #|# #|# #|# """
+
+class level22(boarddef.Level):
+ n = LNasty
+ m = LMonky
+ g = LGhosty
+ f = LFlappy
+ s = LSpringy
+ o = LOrcy
+ r = LGramy
+ b = LBlitzy
+
+ walls = """
+## ### ### ### ##
+## # # # # # # ##
+## # #### #### # ##
+## #o # #b # #r # ##
+## ### ### ### ##
+## # # ##
+## # # ##
+## ### ### ##
+## # # # # ##
+## # # # # ##
+## #g # #f # ##
+## ### ### ##
+## # # ##
+## # # ##
+## ### ### ### ##
+## # # # # # # ##
+## # #### #### # ##
+## #m # #s # #n # ##
+## ### ### ### ##
+## ##
+## ##
+## ##
+## ##
+#############################
+""" #|# #|# #|# """
+
+class level23(boarddef.Level):
+ m = LMonky
+
+ water = top = 1
+
+ walls = """
+###### # # ######
+###### # # ######
+## # m # ##
+## ######## ##### ######## ##
+## ######## ##### ######## ##
+## ######## ##### m ## ##
+## ######## ########### ## ##
+## m ######## ## ##
+## ########### ######## ## ##
+## ########### m ## ##
+## ################ ###### ##
+## ################ ###### ##
+## ######## m ##
+## ######## ############## ##
+## ######## ############## ##
+## ########m ########### ##
+## m ##### ##### m ##
+######## ##### ##### ########
+######## m m ########
+############## ##############
+#############################
+## ##
+## ##
+###### ######### ######
+""" #|# #|# #|# """
+
+class level24(boarddef.Level):
+ g = RGhosty
+ f = RFlappy
+ s = LSpringy
+ t = RSpringy
+
+ walls = """
+#############################
+## ##
+## ##
+## s t ##
+## s t ##
+## s t ##
+###### ######
+## ##
+## ##### ##### ##### ##
+## # # # ##
+## #g # #g ##
+## # #f # ##
+## # # # ##
+## ##
+## ##
+## ##### ##### ##### ##
+## # # # ##
+## # #g # ##
+## #f # #f ##
+## # # # ##
+## ##
+## ##
+## ##
+#############################
+""" #|# #|# #|# """
+
+class level25(boarddef.Level):
+ s = LSpringy
+ t = RSpringy
+
+ letter = lightning = 1
+
+ walls = """
+############# #############
+## ##
+## # ##
+## # ##
+## s t ##
+## # # # # ##
+## # # # # ##
+## ##
+## # ##
+## # ##
+## t s ##
+## # # # # ##
+## # # # # ##
+## ##
+## # ##
+## # ##
+## s t ##
+## # # # # ##
+## # # # # ##
+## ##
+## # ##
+## # ##
+## ##
+############# #############
+""" #|# #|# #|# """
+
+class level26(boarddef.Level):
+ s = LSpringy
+
+ fire = 1
+
+ walls = """
+####### #######
+## ##
+## ##
+##s s ##
+##s ####### ####### s ##
+##s s ##
+#### ####
+## ##
+## ## ## ##
+## ##
+## ## ## ##
+## ##
+## ### ##
+## ##
+##s s ##
+#### ## ## ####
+## ##
+## ##
+## ##
+## ##
+## s s ##
+## ## ## ##
+## ##
+#############################
+""" #|# #|# #|# """
+
+class level27(boarddef.Level):
+ s = LSpringy
+
+ fire = 1
+
+ walls = """
+## ##
+## ##
+## # s # ##
+##s # # s # # s ##
+## # #s # # ##
+## # # # # ##
+### # ###
+## ### ##
+### # ###
+## # # # # # ##
+## #s # # #s # ##
+## # # # # ##
+## # # ##
+## ### ### ##
+## # # ##
+## # # ##
+## s #s # s ##
+## # # # # # # ##
+## # # # # # ##
+## # ### # ##
+## ### # ### ##
+## # # ##
+## ##
+#############################
+""" #|# #|# #|# """
+
+class level28(boarddef.Level):
+ f = LFlappy
+
+ walls = """
+#############################
+######### ###########
+## ## f #### ##
+##f ## ff #### f ##
+##f f ## ### ####f f ##
+## f ## ### #### f ##
+##### ## ### ###### ##
+##### ## ### ###### ##
+##### ## #### ###### ##
+##### ## #### ###### ##
+## #### ##
+## ##
+## ##
+## ## ######## ### ##
+## ## ######## ### ##
+## ## ######## ### ##
+## ## ### ### ##
+## ## ### ### ##
+## ## ### ### ##
+## ##### ### ##### ##
+## ##### ### ##### ##
+## ### ##
+## ### ##
+#############################
+""" #|# #|# #|# """
+
+class level29(boarddef.Level):
+ f = LFlappy, RFlappy
+
+ top = water = 1
+
+ walls = """
+## ##################### ##
+## ##
+## f f ##
+## ##################### ##
+## ##################### ##
+## ##
+## f f ##
+## ##################### ##
+## ##################### ##
+## ##
+## f f ##
+## ##################### ##
+## ##################### ##
+## ##
+## f f ##
+## ##################### ##
+## ##################### ##
+## ##
+## f f ##
+## ##################### ##
+## ##################### ##
+## ##
+## f f ##
+## ##################### ##
+""" #|# #|# #|# """
+
+class level30(boarddef.Level):
+ g = RGhosty
+ h = RGhosty
+ i = LGhosty
+ j = LGhosty
+
+ walls = """
+#############################
+## ##
+## ##
+## ##
+## ####g # ##
+## ###### ##
+## j ###### ##
+## ####### ##
+## ###### ##
+## ######h ##
+## # #### ##
+## i ##
+## ##
+## ##
+## ####g # ####g # ##
+## ###### ###### ##
+## j ###### j ###### ##
+## ####### ####### ##
+## ###### ###### ##
+## ######h ######h ##
+## # #### # #### ##
+## i i ##
+## ##
+#############################
+""" #|# #|# #|# """
+
+class level31(boarddef.Level):
+ o = LGramy, RGramy
+ r = LOrcy
+ s = ROrcy
+
+ top = letter = lightning = fire = 1
+
+ walls = """
+## ######## ######## ##
+## ##
+## ##
+## r s ##
+## ######## ######## ##
+##o o ##
+###### ######
+## ##
+##o s # #r o ##
+############# #############
+## ##
+## ##
+## ##################### ##
+## ##
+## ##
+## ####### ####### ##
+## ##
+##o o ##
+########## # # ##########
+## # # ##
+## ## ## ##
+## ##
+## ##
+############# #############
+""" #|# #|# #|# """
+
+class level32(boarddef.Level):
+ n = LNasty, RNasty
+ f = (LFlappy, RFlappy) * 2
+
+ walls = """
+############# #############
+## ## ## ##
+## f ## ##f ##
+## ## ## ##
+## ## ## ##
+## ## ## ##
+## ## ## ##
+## ## ## ##
+##n ## ## n ##
+#############################
+#############################
+## ##
+## f ##
+##n n ##
+#############################
+#############################
+## ## ## ##
+## ## ## ##
+## ## ## ##
+## ## ## ##
+## ## ## ##
+## ## ## ##
+## ## ## ##
+############# #############
+""" #|# #|# #|# """
+
+ winds = """
+>> ^ <<
+>>>>>>>>>>>>> ^ <<<<<<<<<<<<<
+>>^ ^ ^<<
+>>^ ^ ^<<
+>>^ ^ ^<<
+>>^ ^ ^<<
+>>^ ^ ^<<
+>>^ ^ ^<<
+>>^ ^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ xxx ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+"""
+
+class level33(boarddef.Level):
+ monsters = [mnstrmap.Gramy(14, -2, 1),
+ mnstrmap.Gramy(13, -2, 0)] * 10
+ top = 1
+
+ walls = """
+## ## ## ##
+## ## ## ##
+## ## ## ##
+## ####### ####### ##
+## # # ##
+## # # ##
+## # ########### # ##
+## # # ##
+## # # ##
+## ####### ####### ##
+## # # ##
+## # # ##
+## # ########### # ##
+## # # ##
+## # # ##
+## ####### ####### ##
+## # # ##
+## # # ##
+## # ########### # ##
+## # # ##
+## # # ##
+## ####### ####### ##
+## ## ## ##
+############# #############
+""" #|# #|# #|# """
+
+ winds = """
+>> <<
+>>>xxxxxxxxxxxxxxxxxxxxxxx<<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+"""
+
+class level34(boarddef.Level):
+ n = LNasty
+ N = RNasty
+ m = LMonky
+ M = RMonky
+ g = LGhosty
+ G = RGhosty
+ o = LOrcy
+ O = ROrcy
+ r = LGramy
+ R = RGramy
+ b = LBlitzy, RBlitzy
+
+ top = water = letter = 1
+
+ walls = """
+##### # ############# # #####
+## # # # ##
+## # # # ##
+## # # # ##
+## r #R ##
+############# # #############
+## # ##
+##G # # # g ##
+## # # # ##
+## # # # ##
+## #O b o # ##
+##### # ############# # #####
+## # # ##
+## # # # ##
+## # # # ##
+## # # # ##
+##M # m ##
+############# # #############
+## # ##
+## # # # ##
+## # # # ##
+## # # # ##
+## # n #N # ##
+##### # ############# # #####
+""" #|# #|# #|# """
+
+class level35(boarddef.Level):
+ g = (RGhosty,)*3
+ h = (LGhosty,)*3
+
+ walls = """
+############# #############
+## h ##
+#############################
+##g ##
+#############################
+## h ##
+############# #############
+##g ##
+#############################
+## h ##
+#############################
+##g ##
+############# #############
+## h ##
+#############################
+##g ##
+#############################
+## h ##
+############# #############
+##g ##
+#############################
+## ##
+## ##
+############# #############
+""" #|# #|# #|# """
+
+class level36(boarddef.Level):
+ f = LFlappy
+ r = RSpringy
+
+ top = fire = letter = 1
+
+ walls = """
+## # # # # # # ##
+## f # # r # # f ##
+## # # #f r # # # ##
+## # # r # # ##
+## f # # # f # # # f ##
+## # # # # ##
+## f # # # f # # # f ##
+## # # f # # ##
+## # # # # # # ##
+## f # # f # # f ##
+## # # # f # # # ##
+## # # f # # ##
+## # # # # # # ##
+## # # f f # # ##
+## # # # # # # ##
+## # # # # ##
+## # # # f # # # ##
+## # # # # ##
+## # # # f # # # ##
+## # # f # # ##
+## # # # f # # # ##
+## # # # # ##
+## # # # f # # # ##
+#############################
+""" #|# #|# #|# """
+
+class level37(boarddef.Level):
+ n = LNasty
+ m = RMonky
+ o = (RFlappy,) * 5
+ s = LSpringy
+ t = RSpringy
+
+ walls = """
+####### ######### #######
+## ##
+## ##
+## ##
+## #s t s t # ##
+## ##################### ##
+## # # ##
+## # # ##
+## # o # ##
+## # # ##
+## # # ##
+## # #n m # # ##
+## # ####### # ##
+## # # # ##
+## # # # ##
+## # # # ##
+## # # # ##
+## # # # ##
+## ##################### ##
+## # # # ##
+## # ##
+## # ##
+## # ##
+####### ######### #######
+""" #|# #|# #|# """
+
+class level38(boarddef.Level):
+ f = LFlappy
+ b = (LBlitzy, RBlitzy) * 2
+
+ water = 1
+
+ walls = """
+############# #############
+## ##
+## ##
+## ##
+## b b b ##
+## ######### ######### ##
+## ######### ######### ##
+## ######### ######### ##
+## ### ### ##
+## ### f f f f ### ##
+## ### ### ##
+## ### ### ### ### ##
+## ### ### ### ### ##
+## ### ### ### ### ##
+## ### ### ### ### ##
+## ### ### ##
+## ### f f f f ### ##
+## ######### ######### ##
+## ######### ######### ##
+## ######### ######### ##
+## ##
+## ##
+## ##
+############# #############
+""" #|# #|# #|# """
+
+class level39(boarddef.Level):
+ monsters = []
+ mnstrclasses = ([mnstrmap.Nasty] * 10 +
+ [None] * 30 +
+ [mnstrmap.Monky] * 7 +
+ [None] * 30 +
+ [mnstrmap.Orcy] * 5)
+ for i in range(len(mnstrclasses)):
+ if mnstrclasses[i]:
+ left = random.randrange(2)
+ x = random.choice([7,14,21])
+ monsters.append(mnstrclasses[i](x-left, -2*i, left))
+
+ walls = """
+###### #### #### ######
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+###### ######### ######
+## ##
+## ##
+## ##
+## ##
+#############################
+""" #|# #|# #|# """
+
+class level40(boarddef.Level):
+ g = LGhosty
+
+ top = fire = 1
+
+ walls = """
+## ##
+## ##
+## # ## ##
+## ## ### # ##
+## # ## ##
+## ##
+## ##
+## # ##
+## # #### ##
+## ### ##
+## # # g ##
+## # ##
+## ### # ##
+## # # ### ##
+## ### g # ##
+## # ##
+## g ##
+## # ## ##
+## # # ### ##
+## ### # ##
+## # g ##
+## g # # ##
+## ## # ## ##
+## # ### ## ## ##
+""" #|# #|# #|# """
+
+ winds = """
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>>>>>>>>>>>vvxvv<<<<<<<<<<<<
+>>>>>>>>>>>>vvxvv<<<<<<<<<<<<
+>>>>>>>>>>>>vxxxv<<<<<<<<<<<<
+>>>>>>>>>>>>vxxxv<<<<<<<<<<<<
+>>>>>>>>>>>>vxxxv<<<<<<<<<<<<
+>>>>>>>>>>>>xxxxx<<<<<<<<<<<<
+>>>>>>>>>>>>xxxxx<<<<<<<<<<<<
+>>>>>>>>>>>>xxxxx<<<<<<<<<<<<
+>>>>>>>>>>>>xxxxx<<<<<<<<<<<<
+>>>>>>>>>>>>xxxxx<<<<<<<<<<<<
+>>>>>>>>>>>>xxxxx<<<<<<<<<<<<
+>>>>>>>>>>>>xxxxx<<<<<<<<<<<<
+>>>>>>>>>>>>xxxxx<<<<<<<<<<<<
+>>>>>>>>>>>>xxxxx<<<<<<<<<<<<
+>>>>>>>>>>>>xxxxx<<<<<<<<<<<<
+>>>>>>>>>>>>xxxxx<<<<<<<<<<<<
+>>>>>>>>>>>>xxxxx<<<<<<<<<<<<
+>>>>>>>>>>>>xxxxx<<<<<<<<<<<<
+>>>>>>>>>>>>xxxxx<<<<<<<<<<<<
+>> <<
+"""
+
+class level41(boarddef.Level):
+ f = RFlappy
+ j = LFlappy
+ b = RBlitzy
+ d = LBlitzy
+
+ top = 1
+
+ walls = """
+############# #############
+##b d ##
+##### db #####
+## ############# ##
+## ## ## ##
+### ### jfjfjfjf ### ###
+## ## fjfjfjfj ## ##
+#### ##### ##### ####
+## ##
+### ###
+#### ####
+#b d ##
+###### ######
+### ###
+####### #######
+##### #####
+##b d ##
+########## ###########
+##### #####
+#### ####
+####### #######
+## ##
+## ##
+############# #############
+""" #|# #|# #|# """
+
+ winds = """
+>> <<
+>>v<<<<<<<<<<<<>>>>>>>>>>>v<<
+>>v>>>>>>>>vvvvvvv<<<<<<<<v<<
+>>v>>>>>>>>vvvvvvv<<<<<<<<v<<
+>>v>>>>>>>>xxxxxxx<<<<<<<<v<<
+>>v v<<
+>>v v<<
+>>v v<<
+>>v v<<
+>>v v<<
+>>v v<<
+>>v v<<
+>>v v<<
+>>v v<<
+>>v v<<
+>>v v<<
+>>v v<<
+>>v v<<
+>>v v<<
+>>v v<<
+>>v v<<
+>>v v<<
+>>> vvv <<<
+>>> vvv <<<
+"""
+
+class level42(boarddef.Level):
+ l = LOrcy, LOrcy
+ r = ROrcy, ROrcy
+ b = ROrcy, LOrcy, ROrcy, LOrcy
+
+ top = 1
+ water = 1
+ letter = 1
+
+ walls = """
+## # ##
+## l r ##
+## ## ## ##
+## ##
+## #### ### ##
+## # ##
+## # # ##
+## # # r ##
+## # ## ##
+## r # # ##
+## ## # # ##
+## # # ##
+## r # # ##
+## # # ## # ##
+## # # b # ##
+## # ## # ##
+## # r # ##
+## # ## # ##
+## # ##
+## # # ##
+## b ##
+## ## # ##
+## # ##
+## ### ## # ##
+""" #|# #|# #|# """
+
+ winds = """
+>>>vvvvvvvvvvvvvvvvvvvvvvv<<<
+>>>vvvvvvvvvvvvvvvvvvvvvvv<<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+"""
+
+class level43(boarddef.Level):
+ s = LSpringy, RSpringy, LSpringy, RSpringy
+ f = LFlappy
+ g = RFlappy
+
+ walls = """
+## # # ##
+## #g f # ##
+## ##
+## # # ##
+## # # ##
+##s # # # # s ##
+## # # # # ##
+## # # # ##
+## # ##
+## # s #s # ##
+## # # # # # ##
+## # # # # # # # # # ##
+## # # # # # # # # # # # ##
+## # # # # # # # # # # # ##
+## # # # # # # # # ##
+## # # # # # # ##
+## # # # # # # ##
+## # # ##
+## # # ##
+## # # ##
+## # # # # ##
+## # # # # ##
+## # # # # # # # ##
+## # # # # # # # # # # # # ##
+""" #|# #|# #|# """
+
+class level44(boarddef.Level):
+ o = LGramy
+ p = RGramy
+ g = RFlappy
+ h = LFlappy
+
+ top = 1
+
+ walls = """
+## ##
+## ##
+## ##
+######## ## ##
+## h ## ## ##
+## g ## ## ###### ##
+## h ## ## ## ## ##
+## g ## ## ## ## ##
+## h ## ## ## ## ##
+## g ## ## ## ## ##
+## ## ## ## ## ##
+## ## ## ## ## h ##
+## ## ## ## ## g ##
+## ## ## ## ## h ##
+## ## ## ## ## g ##
+## ###### ## ## h ##
+## ## ## g ##
+## ## ########
+## ##
+## ##
+## ##
+## ##
+## p o p o p o ##
+#############################
+""" #|# #|# #|# """
+
+ winds = """
+>>>vvvvvvvvvvvvvvvvvvvvvvv<<<
+>>>>>>>>vv<<<<<vv<<<>>>vvv<<<
+>>^ vv ^<<
+>>^ vv ^<<
+>>^ vv ^<<
+>>^ vv ^<<
+>>^ vv >< ^<<
+>>^ vv ^^ ^<<
+>>^ vv ^^ ^<<
+>>^ vv ^^ ^<<
+>>^ vv ^^ ^<<
+>>^ vv ^^ ^<<
+>>^ vv ^^ ^<<
+>>^ vv ^^ ^<<
+>>^ >< ^^ ^<<
+>>^ ^<<<>>>^ ^^ ^<<
+>>^ ^^ ^<<
+>>^ ^^ ^<<
+>>^ >>>>>^^<<<<<^<<
+>>^ ^<<
+>>^ ^<<
+>>^vvvvvvvvvvvvvvvvvvvvvvv^<<
+>>^vvvvvvvvvvvvvvvvvvvvvvv^<<
+>>^vvvvvvvvvvvvvvvvvvvvvvv^<<
+"""
+
+class level45(boarddef.Level):
+ b = LBlitzy, RBlitzy
+
+ top = 1
+ water = 1
+
+ walls = """
+## ##
+## ## ## ##
+## ## ## # # ## ## ##
+## # # # # # # ##
+## # # #bb # # # ##
+## #bb # ## ## #bb # ##
+## ## ## ## ## ##
+## ## ## ##
+## ## ## # # ## ## ##
+## # # # # # # ##
+## # # # # # # ##
+## #bb # # # #bb # ##
+## ## ## #bbbb # ## ## ##
+## ## ## ##
+## ## ## ## ## ##
+## # # ## ## # # ##
+## # # # # # # ##
+## #bb # # # #bb # ##
+## ## ## #bb # ## ## ##
+## ## ## ##
+## ##
+## ##
+## ##
+### ##################### ###
+""" #|# #|# #|# """
+
+ winds = """
+>>>vvvvvvvvvvvvvvvvvvvvvvv<<<
+>>>>>>>>>>>>>xxx<<<<<<<<<<<<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+>>xxxxxxxxxxxxxxxxxxxxxxxxx<<
+"""
+
+class level46(boarddef.Level):
+ m = LMonky, RGramy
+ n = LGramy, RMonky
+ g = [RGhosty] * 4
+ h = [LGhosty] * 4
+
+ letter = 1
+ fire = 1
+
+ walls = """
+############# #############
+## ##
+## ##
+## ##
+############# #############
+## ## ## ##
+## g ## ## h ##
+## ## mnmnm ## ##
+## ########### ##
+## ##
+## ##
+## ##
+######## ### ########
+## ## # ## ##
+## ## # ## ##
+##mnm ## # ##mnm ##
+######## ##### ########
+## # ##
+## # ##
+## ####### ##
+## ##
+## ##
+## # # # ##
+############ ############
+""" #|# #|# #|# """
+
+ winds = """
+>>> ^ <<<
+>>>>>>>>>>>>>>^<<<<<<<<<<<<<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ x ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+"""
+
+class level47(boarddef.Level):
+ l = LOrcy
+ r = ROrcy
+ n = LNasty
+ m = RNasty
+
+ top = 1
+ lightning = 1
+
+ walls = """
+## ################### ##
+## ################### ##
+## # ##
+## # ##
+## ##
+## ##
+## ##
+###### #### #### ######
+## # # ##
+## # # ##
+## # # ##
+## ##### ####### ##### ##
+## ##
+## ##
+## ##
+##### ###### ###### #####
+## # # ##
+## # # ##
+##rmr # lr # lnl ##
+######### ####### #########
+## # # # ##
+## # # # ##
+## #rmrmrmr #lnlnlnl # ##
+## ################### ##
+""" #|# #|# #|# """
+
+ winds = """
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>>>>>>vvvvvvvvvvvvvvv<<<<<<<
+>>>>>>>>^^^^^^^^^^^^^<<<<<<<<
+>>>>>>>>^^^^^^^^^^^^^<<<<<<<<
+>>>>>>>>^^^^^^^^^^^^^<<<<<<<<
+>>^ ^<<
+"""
+
+class levelFinal(boarddef.Level):
+
+ walls = """
+############# #############
+## ##
+## ##
+## ##
+## ##
+## ##
+#### ################# ####
+## ### ### ##
+## ## ## ##
+####### ##### #######
+## ##
+## ##
+## ##
+## ##
+######### #########
+## ##
+## ##
+## ##
+########## ##########
+## ##
+## ##
+## ##
+## ##
+############# #############
+""" #|# #|# #|# """
+# nb.: the previous line has no purpose
+# other than helping with wall alignment
diff --git a/bubbob/levels/HouseOfFun.bin b/bubbob/levels/HouseOfFun.bin
new file mode 100644
index 0000000..838344f
--- /dev/null
+++ b/bubbob/levels/HouseOfFun.bin
Binary files differ
diff --git a/bubbob/levels/Levels.bin b/bubbob/levels/Levels.bin
new file mode 100644
index 0000000..fd176d1
--- /dev/null
+++ b/bubbob/levels/Levels.bin
Binary files differ
diff --git a/bubbob/levels/LostLevels.bin b/bubbob/levels/LostLevels.bin
new file mode 100644
index 0000000..a09e365
--- /dev/null
+++ b/bubbob/levels/LostLevels.bin
Binary files differ
diff --git a/bubbob/levels/README.txt b/bubbob/levels/README.txt
new file mode 100644
index 0000000..544b571
--- /dev/null
+++ b/bubbob/levels/README.txt
@@ -0,0 +1,23 @@
+===============================
+How to make your own level sets
+===============================
+
+The .bin files are MacBinary files from the original MacOS9 game. The
+.py files are the levels that we did ourselves. To make new levels, you
+need to make a new .py file in the current directory (bubbob/levels/).
+
+For an example, open CompactLevels.py with any text editor. The
+structure should be fairly simple to understand even without knowledge
+about Python. (Just don't try to look at RandomLevels.py first: it is a
+full Python program that generates the levels completely randomly.)
+
+To get started, copy CompactLevels.py to a new name, like MyLevels.py,
+and start editing it. You can remove or change levels, but the last one
+should always be called LevelFinal and have no monster in it. All other
+levels should have monsters, otherwise they'll be considered as the
+final level.
+
+Also note that all levels need to have the same size (width and height),
+but different level sets can have different sizes. For example, the
+levels in CompactLevels.py are a bit smaller than the ones in the .bin
+files, and the levels in scratch.py are a bit larger.
diff --git a/bubbob/levels/RandomLevels.py b/bubbob/levels/RandomLevels.py
new file mode 100644
index 0000000..5c0f77d
--- /dev/null
+++ b/bubbob/levels/RandomLevels.py
@@ -0,0 +1,362 @@
+#
+# Second try at automatically generating levels that are
+# a bit more related to each other instead of being completely independent.
+#
+
+from __future__ import generators
+import sys, random, math
+from random import uniform, choice, randrange
+
+
+class Parameter(object):
+ def __init__(self, name, rng):
+ self.name = name
+ self.rng = rng
+ def __get__(self, instance, cls):
+ assert self.name not in instance.__dict__
+ value = self.rng()
+ setattr(instance, self.name, value)
+ return value
+
+class ChoiceParameter(Parameter):
+ def __init__(self, name, list):
+ Parameter.__init__(self, name, lambda : choice(list))
+
+class BoolParameter(Parameter):
+ def __init__(self, name, prob=0.5):
+ Parameter.__init__(self, name, lambda : random.random() < prob)
+
+def flat(mean,var):
+ return randrange(mean-var,mean+var+1)
+
+def dice(n,sides,orig=1):
+ result = 0
+ for i in range(n):
+ result += orig+randrange(sides)
+ return result
+
+def fork(choice1, prob, choice2):
+ if random.random() < prob:
+ return choice1()
+ else:
+ return choice2()
+
+MnstrCategory = {
+ "Nasty": 0,
+ "Monky": 0,
+ "Ghosty": 1,
+ "Flappy": 1,
+ "Springy": 2,
+ "Orcy": 0,
+ "Gramy": 0,
+ "Blitzy": 2}
+MnstrNames = MnstrCategory.keys()
+Bonuses = ['letter', 'fire', 'lightning', 'water', 'top']
+
+def mnstrclslist(name):
+ import boarddef
+ classname1 = 'L' + name
+ classname2 = 'R' + name
+ return [getattr(boarddef, classname1), getattr(boarddef, classname2)]
+
+class Shape:
+ basemnstr = ChoiceParameter('basemnstr', MnstrNames)
+ extramnstr = ChoiceParameter('extramnstr', range(4))
+ samemnstr = BoolParameter('samemnstr')
+ baseshape = ChoiceParameter('baseshape', ' ODBGMPRWZS')
+ rooms = BoolParameter('rooms')
+ holes = BoolParameter('holes')
+ lines = ChoiceParameter('lines', ' -/|')
+ platforms = BoolParameter('platforms')
+ platholes = BoolParameter('platholes')
+ platfull = BoolParameter('platfull')
+ mess = ChoiceParameter('mess', ' ....!')
+ closed = BoolParameter('closed', 0.95)
+ bonuses = ChoiceParameter('bonuses', xrange(3**len(Bonuses)))
+ smooth = ChoiceParameter('smooth', range(4))
+ startplats = BoolParameter('startplats', 0.98)
+ makespace = BoolParameter('makespace', 0.8)
+ straightfall = BoolParameter('straightfall', 0.8)
+ mirrored = BoolParameter('mirrored', 0.4)
+ enlargeholes = BoolParameter('enlargeholes', 0.9)
+
+ all_parameters = [name for name in locals().keys()
+ if not name.startswith('_')]
+
+ def __init__(self, shape=None):
+ if shape:
+ self.__dict__.update(shape.__dict__)
+ self.modified = 0
+
+ def set_gens(self, rooms=0, platforms=0, holes=0, smooth=0, mess=' ', lines=' '):
+ self.rooms = rooms
+ self.platforms = platforms
+ self.holes = holes
+ self.smooth = smooth
+ self.mess = mess
+ self.lines = lines
+
+ def reset(self, attrname=None):
+ if attrname:
+ try:
+ del self.__dict__[attrname]
+ except KeyError:
+ pass
+ else:
+ self.__dict__.clear()
+ self.modified = 1
+
+ def __eq__(self, other):
+ return (self.__class__ is other.__class__ and
+ self.__dict__ == other.__dict__)
+
+ def test_similar_parameters(self, prevlist):
+ similarity = 0
+ rprevlist = prevlist[:]
+ rprevlist.reverse()
+ for param in Shape.all_parameters:
+ accum = 0
+ for prev in rprevlist:
+ if getattr(self, param) != getattr(prev, param):
+ break
+ else:
+ accum += 1
+ similarity += accum
+ minimum = min(4*len(prevlist), 7)
+ if not (minimum <= similarity <= 17):
+ self.reset()
+
+ def test_not_too_often(self, prevlist):
+ for param, bad_value, delay in [
+ ('mess', '.', 2),
+ ('mess', '!', 11),
+ ('holes', 1, 1),
+ ]:
+ if getattr(self, param) == bad_value:
+ for prev in prevlist[-delay:]:
+ if getattr(prev, param) == bad_value:
+ self.reset(param)
+
+ def test_mess_hole(self, prevlist):
+ if self.mess == '!':
+ self.holes = 1
+
+ all_tests = [value for (name, value) in locals().items()
+ if name.startswith('test_')]
+
+ def accept(self, lvl):
+ f = lambda d=self.difficulty : randrange(3, 4+int(9*d))
+ lvl.mlist = [(mnstrclslist(self.basemnstr), f)]
+ repeat = choice([2,2,3]) - self.extramnstr
+ if repeat > 1:
+ lvl.mlist *= repeat
+ if self.extramnstr:
+ othermnstr = [name for name in MnstrNames if name!=self.basemnstr]
+ if self.samemnstr:
+ othermnstr = [name for name in othermnstr
+ if MnstrCategory[name]==MnstrCategory[self.basemnstr]]
+ random.shuffle(othermnstr)
+ for name in othermnstr[:self.extramnstr]:
+ lvl.mlist.append((mnstrclslist(name), f))
+
+ lvl.genwalls = []
+
+ if self.baseshape == 'G':
+ lvl.genwalls.append((RandomLevel.grids,
+ uniform(0.7,0.8),
+ uniform(0.7,0.8)))
+ self.set_gens()
+ if self.baseshape == 'P':
+ lvl.genwalls.append((RandomLevel.pegs,
+ uniform(0.1,0.2),
+ uniform(0.45,0.7),
+ choice([0,1,1,1])))
+ self.set_gens(smooth=3)
+ self.closed = random.random() < 0.80
+ if self.baseshape == 'B':
+ nr = choice([0,0,1])
+ lvl.genwalls.append((RandomLevel.bouncers,
+ dice(1, 100) + 250 - nr*200, # length
+ uniform(0.7, 1.7),
+ nr))
+ self.set_gens(smooth=3)
+ if self.baseshape == 'W':
+ nr = dice(1, 3) + 2
+ lvl.genwalls.append((RandomLevel.walkers,
+ dice(2, 100) + 100, # length
+ nr, nr + dice(2, 3),
+ choice([0,1])))
+ self.set_gens()
+ if self.baseshape == 'R':
+ lvl.genwalls.append((RandomLevel.rivers,
+ randrange(3,(lvl.WIDTH-4)/4), # the number of rivers
+ uniform(0.3, 1.4), # the side stepping threshold
+ 10)) # the max side stepping size
+ self.set_gens()
+ if self.baseshape == 'Z':
+ lvl.genwalls.append((RandomLevel.zigzag,))
+ self.set_gens()
+ if self.baseshape == 'M':
+ lvl.genwalls.append((RandomLevel.mondrian,))
+ self.set_gens()
+ if self.baseshape == 'O':
+ lvl.genwalls.append((RandomLevel.remove_joined_blocks,))
+ self.set_gens()
+ if self.baseshape == 'S':
+ lvl.genwalls.append((RandomLevel.platforms_reg,))
+ self.set_gens()
+ self.makespace = random.random() < 0.1
+ if self.closed:
+ self.startplats = 0
+ if self.baseshape == 'D':
+ lvl.genwalls.append((RandomLevel.discrete_blocks,))
+ self.set_gens()
+ self.makespace = random.random() < 0.1
+ if self.closed:
+ self.startplats = 0
+
+ if self.rooms:
+ nr = dice(2, 6)
+ lvl.genwalls.append((RandomLevel.rooms,
+ lambda : flat(9-nr,2), # the half size of the room
+ lambda : uniform(0.8,1.2), # the excentricity of the room
+ nr)) # the number of rooms
+ if self.lines != ' ':
+ rng_angle = {
+ '-': lambda : 0,
+ '/': None, # default
+ '|': lambda : math.pi/2,
+ }
+ lvl.genwalls.append((RandomLevel.lines,
+ lambda : dice(8,3), # line length
+ dice(2,4), # number of lines
+ rng_angle[self.lines]))
+ if self.platforms:
+ nplat = dice(2,4,0)
+ if nplat: space = flat((lvl.HEIGHT-1)/nplat/2,(lvl.HEIGHT-1)/nplat/2-1)
+ else: space = 1
+ if self.platholes:
+ nholes = lambda : dice(1,3)
+ else:
+ nholes = lambda : 0
+ wholes = lambda : dice(2,3)
+ full = self.platfull
+ lvl.genwalls.append((RandomLevel.platforms,
+ (nplat,space), # number of platform and spacing
+ (nholes,wholes), # number of holes and width
+ full)) # full width platform
+ if self.mess != ' ':
+ threshold = {
+ '.': 0.02 + 0.08*random.random(), # normal
+ '!': 0.25 + 0.2 *random.random(), # super-filled
+ }
+ lvl.genwalls.append((RandomLevel.mess, threshold[self.mess]))
+ if self.holes:
+ nh = choice([1,1,2,2,2,3,3,3,4,5])
+ lvl.genwalls.append((RandomLevel.holes,
+ lambda : flat(9-nh,2), # radius of the holes
+ lambda : uniform(0.9,1.1), # excentricity
+ nh, # number of holes
+ lambda : choice([0,0,0,1]))) # circle or rectangle
+ if self.closed:
+ lvl.genwalls.append((RandomLevel.close,))
+ if self.smooth > 0:
+ # smooth away all lone empty spaces
+ lvl.genwalls.append((RandomLevel.smooth, 1.0, 1))
+ # possibly smooth away some lone bricks
+ if self.smooth == 2:
+ lvl.genwalls.append((RandomLevel.smooth, 0.25, 0))
+ elif self.smooth == 3:
+ lvl.genwalls.append((RandomLevel.smooth, 0.75, 0))
+ if self.startplats:
+ lvl.genwalls.append((RandomLevel.startplatform, ))
+ lvl.genwalls.append((RandomLevel.openstartway, ))
+
+ if self.makespace:
+ lvl.genwalls.append((RandomLevel.make_space, ))
+
+ if self.straightfall:
+ lvl.genwalls.append((RandomLevel.prevent_straight_fall, ))
+
+ if self.mirrored:
+ lvl.genwalls.append((RandomLevel.mirror, ))
+
+ if self.enlargeholes:
+ lvl.genwalls.append((RandomLevel.enlarge_tiny_holes, ))
+
+ lvl.genwalls.append((RandomLevel.generate_wind, ))
+ b = self.bonuses
+ for name in Bonuses:
+ setattr(lvl, name, (b % 3) == 1)
+ b = b // 3
+ lvl.autogen_shape = self
+
+
+def generate_shape(prevlist):
+ tests = Shape.all_tests
+ s = Shape()
+ for i in range(100):
+ s1 = Shape(s)
+ random.shuffle(tests)
+ for test in tests:
+ test(s1, prevlist)
+ if not s1.modified and s1 == s:
+ break
+ s = s1
+# else:
+# sys.stdout.write('*')
+ del s.modified
+ return s
+
+def makeshapes(nblevels=25):
+ shapelist = []
+ for i in range(nblevels):
+ s = generate_shape(shapelist)
+ s.difficulty = float(i+1)/nblevels
+ yield s
+ shapelist.append(s)
+ if len(shapelist) == 10:
+ del shapelist[:]
+
+def GenerateLevels():
+# print 'generating levels',
+ Levels = []
+ for s in makeshapes():
+ class level(RandomLevel):
+ WIDTH = 28
+ HEIGHT = 23
+ def enter(self, *args, **kw):
+ result = RandomLevel.enter(self, *args, **kw)
+ params = self.autogen_shape.__dict__.items()
+ params.sort()
+# for keyvalue in params:
+# print '%20s: %s' % keyvalue
+ return result
+ s.accept(level)
+ Levels.append(level)
+# sys.stdout.write('.')
+# sys.stdout.flush()
+# print
+ class levelfinal(RandomLevel):
+ WIDTH = level.WIDTH
+ HEIGHT = level.HEIGHT
+ genwalls = [(RandomLevel.platforms,(5,3),(lambda:flat(2,1),lambda:flat(6,2)),1),
+ (RandomLevel.close,)]
+ Levels.append(levelfinal)
+ return Levels
+
+def GenerateSingleLevel(width, height):
+ [s] = makeshapes(1)
+ class level(RandomLevel):
+ WIDTH = width
+ HEIGHT = height
+ s.accept(level)
+ return level
+
+if __name__ == '__main__':
+ for s in makeshapes():
+ print s.__dict__
+else:
+ rnglevel = {}
+ execfile('levels/rnglevel', rnglevel)
+ RandomLevel = rnglevel['RandomLevel']
diff --git a/bubbob/levels/rnglevel b/bubbob/levels/rnglevel
new file mode 100644
index 0000000..cfa6ec0
--- /dev/null
+++ b/bubbob/levels/rnglevel
@@ -0,0 +1,1276 @@
+from random import *
+from math import *
+
+import boarddef
+from boarddef import LNasty, LMonky, LGhosty, LFlappy
+from boarddef import LSpringy, LOrcy, LGramy, LBlitzy
+from boarddef import RNasty, RMonky, RGhosty, RFlappy
+from boarddef import RSpringy, ROrcy, RGramy, RBlitzy
+
+def flat(mean,var):
+ return randrange(mean-var,mean+var+1)
+
+def dice(n,sides,orig=1):
+ result = 0
+ for i in range(n):
+ result += orig+randrange(sides)
+ return result
+
+def fish(mu):
+ def fact(n):
+ r = 1.
+ for i in range(1,n+1):
+ r *= i
+ return r
+ scale = fact(0)/exp(-mu)
+ dens = []
+ while 1:
+ x = len(dens)
+ dens.append(int(scale*exp(-mu)*pow(mu,x)/fact(x)+0.5))
+ if x > mu and dens[-1] == 0:
+ break
+ table = []
+ x = 0
+ for d in dens:
+ for i in range(d):
+ table.append(x)
+ x += 1
+ return choice(table)
+
+
+class RandomLevel(boarddef.Level):
+ WIDTH = 32
+ HEIGHT = 28
+ MAXTRY = 1000
+ # parameters of the 'mess generator'
+ # mess_prob : the probability that a cell turn into a wall
+
+ def __init__(self,num):
+ if hasattr(self.__class__, 'walls'):
+ #print 'Reusing previously generated level'
+ #print self.__class__.walls
+ self.walls = self.__class__.walls
+ boarddef.Level.__init__(self,num)
+ return
+
+ #print 'Generating a new level'
+ self.reset(fill=False)
+
+ self.windmap = [ [' ' for x in range(self.WIDTH)] for y in range(self.HEIGHT) ]
+
+ if hasattr(self, 'auto'):
+ self.generate()
+ self.do_bonuses()
+
+ for gw in self.genwalls:
+ gw[0](self,*gw[1:])
+
+ if hasattr(self, 'mlist'):
+ self.do_monsters()
+
+ self.dig_vertical_walls()
+ self.do_walls()
+ self.walls = self.__class__.walls
+ #print self.walls
+
+ self.do_winds()
+ self.winds = self.__class__.winds
+
+ boarddef.Level.__init__(self,num)
+
+ def reset(self, fill=False):
+ if fill:
+ w = '#'
+ f = 0
+ else:
+ w = ' '
+ f = 1
+ # map for the walls
+ self.wmap = [ [w for x in range(self.WIDTH)] for y in range(self.HEIGHT) ]
+ # map of the free cells
+ self.fmap = [ [f for x in range(self.WIDTH)] for y in range(self.HEIGHT) ]
+
+ def setw(self,x,y,c='#'):
+ if x > self.WIDTH-1 or x < 0 or y > self.HEIGHT-1 or y < 0:
+ return
+ if self.fmap[y][x]:
+ self.wmap[y][x] = c
+ self.fmap[y][x] = 0
+
+ def getw(self,x,y):
+ if x > self.WIDTH-1 or x < 0 or y > self.HEIGHT-1 or y < 0:
+ return '#'
+ return self.wmap[y][x]
+
+ def clrw(self,x,y):
+ if x > self.WIDTH-1 or x < 0 or y > self.HEIGHT-1 or y < 0:
+ return
+ self.wmap[y][x] = ' '
+ self.fmap[y][x] = 1
+
+ def lockw(self,x,y,c=0):
+ if x > self.WIDTH-1 or x < 0 or y > self.HEIGHT-1 or y < 0:
+ return
+ self.fmap[y][x] = c
+
+ def setwind(self,x,y,c=' '):
+ if x > self.WIDTH-1 or x < 0 or y > self.HEIGHT-1 or y < 0:
+ return
+ self.windmap[y][x] = c
+
+ def getwind(self,x,y):
+ if x > self.WIDTH-1 or x < 0 or y > self.HEIGHT-1 or y < 0:
+ return ' '
+ return self.windmap[y][x]
+
+ def wind_rect(self,x,y,w,h,ccw=0):
+ "Set a wind in a rectangle which will move the bubbles cw or ccw"
+ if w < 1 or h < 1:
+ return
+ if ccw == 1:
+ for dx in range(w):
+ self.setwind(x+dx+1, y, '<')
+ self.setwind(x+dx, y+h, '>')
+ for dy in range(h):
+ self.setwind(x, y+dy, 'v')
+ self.setwind(x+w, y+dy+1, '^')
+ else:
+ for dx in range(w):
+ self.setwind(x+dx, y, '>')
+ self.setwind(x+dx+1, y+h, '<')
+ for dy in range(h):
+ self.setwind(x, y+dy+1, '^')
+ self.setwind(x+w, y+dy, 'v')
+
+ def mirror(self):
+ "Mirror the level vertically."
+ for y in range(self.HEIGHT):
+ for x in range(self.WIDTH/2):
+ self.wmap[y][x] = self.wmap[y][self.WIDTH-x-1]
+
+ def dig_well_until_space(self, x=1, yadj=1):
+ "Digs a well either up or down and stops when it encounters first empty wall space."
+ if yadj == 1:
+ y = 0
+ else:
+ yadj = -1
+ y = self.HEIGHT-1
+ while (y < self.HEIGHT) and (y >= 0):
+ self.clrw(x,y)
+ self.clrw(x+1,y)
+ y += yadj
+ if ((self.getw(x,y) == ' ') and (self.getw(x+1,y) == ' ')):
+ break
+
+ def enlarge_tiny_holes(self):
+ "Makes one-block size holes wider."
+ for x in range(self.WIDTH):
+ for y in range(self.HEIGHT):
+ if self.wmap[y][x] == ' ':
+ single = 0
+ for dx in range(x-1,x+2):
+ for dy in range(y-1,y+2):
+ if self.getw(dy,dx) == '#':
+ single = single + 1
+ if single == 8:
+ if x > (self.WIDTH / 2):
+ self.clrw(x-1,y)
+ else:
+ self.clrw(x+1,y)
+
+ def make_space(self, gens=-1):
+ "Removes walls from a level, to make it more playable."
+ if gens == -1:
+ gens = randint(0,62)+1
+ if gens & 1: # top
+ for x in range(self.WIDTH):
+ self.clrw(x,1)
+ if random() < 0.5:
+ self.clrw(x,2)
+ if gens & 2: # bottom
+ for x in range(self.WIDTH):
+ self.clrw(x,self.HEIGHT-1)
+ if random() < 0.5:
+ self.clrw(x,self.HEIGHT-2)
+ if gens & 4: # middle
+ y = randint(0,self.HEIGHT/10) + (self.HEIGHT/2)
+ for x in range(self.WIDTH):
+ self.clrw(x,y)
+ if random() < 0.5:
+ self.clrw(x,y-1)
+ if random() < 0.5:
+ self.clrw(x,y+1)
+ if gens & 8: # left
+ x = randint(0,self.WIDTH/4)
+ self.dig_well_until_space(x, 1)
+ self.dig_well_until_space(x, -1)
+ if gens & 16: # right
+ x = randint(0,self.WIDTH/4)
+ self.dig_well_until_space(self.WIDTH-x-2, 1)
+ self.dig_well_until_space(self.WIDTH-x-2, -1)
+ if gens & 32: # center
+ self.dig_well_until_space(self.WIDTH/2, 1)
+ self.dig_well_until_space(self.WIDTH/2, -1)
+
+ def generate_wind1(self, rndchoice=1, choices=[' ',' ',' ','x','>','<','^','^','v'], xsize=-1,ysize=-1):
+ """Makes a random wind pattern. Parameters:
+ 0: if 1=randomly select from choices, else select in order
+ 1: a list of the choices that are allowed.
+ 2: horizontal size of wind blocks
+ 3: vertical size of wind blocks
+ """
+ choicenum = 0
+ if xsize == -1:
+ xsize = randint(1, self.WIDTH)
+ if ysize == -1:
+ ysize = randint(1, self.HEIGHT)
+ if xsize < 1:
+ xsize = 1
+ elif xsize > self.WIDTH:
+ xsize = self.WIDTH
+ if ysize < 1:
+ ysize = 1
+ elif ysize > self.HEIGHT:
+ ysize = self.HEIGHT
+ for x in range((self.WIDTH/xsize)+1):
+ for y in range((self.HEIGHT/ysize)+1):
+ if rndchoice == 1:
+ wdir = choice(choices)
+ else:
+ wdir = choices[choicenum]
+ choicenum = (choicenum + 1) % len(choices)
+ for dx in range(xsize+1):
+ for dy in range(ysize+1):
+ self.setwind(x*xsize+dx,y*ysize+dy,wdir)
+ # make sure that the special bubbles can come into screen
+ for x in range(self.WIDTH):
+ self.setwind(x, 0, ' ')
+ self.setwind(x, self.HEIGHT-1, ' ')
+
+ def wind_sidewalls(self):
+ """Make sure the left and side walls have updraft next to them
+ """
+ for y in range(self.HEIGHT):
+ self.setwind(0,y,'^')
+ self.setwind(self.WIDTH-1,y,'^')
+
+ def wind_wallblocking(self, winddirs):
+ """Sets up wind depending on the number of walls around each place.
+ winddirs is an array of 16 wind chars.
+ directions with walls count as: 1=N, 2=E, 4=S, 8=W
+ 16th place is used if there is wall at the position.
+ """
+ for x in range(self.WIDTH):
+ for y in range(self.HEIGHT):
+ walld = 0
+ if self.getw(x,y) == '#':
+ walld = 16
+ else:
+ if self.getw(x,y-1) == '#':
+ walld = walld + 1
+ if self.getw(x+1,y) == '#':
+ walld = walld + 2
+ if self.getw(x,y+1) == '#':
+ walld = walld + 4
+ if self.getw(x-1,y) == '#':
+ walld = walld + 8
+ wnd = winddirs[walld]
+ self.setwind(x,y,wnd)
+
+ def wind_wallblocking256(self, winddirs):
+ """Sets up wind depending on the number of walls around each position.
+ winddirs is an array of 257 wind chars (one of ' x<>^v-'), where '-' means
+ to use '>' or '<', pointing towards center of level.
+ directions with walls count as: 1=N, 2=NE, 4=E, 8=SE, 16=S, 32=SW, 64=W, 128=NW
+ 257th place is use if there is wall at the position.
+ """
+ mdirs = [(0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1)]
+ for x in range(self.WIDTH):
+ for y in range(self.HEIGHT):
+ windd = 0
+ if self.getw(x,y) == '#':
+ windd = 256
+ else:
+ for d in range(8):
+ dx = x + mdirs[d][0]
+ dy = y + mdirs[d][1]
+ if self.getw(dx, dy) == '#':
+ windd = (1 << d)
+ wd = choice(winddirs[windd])
+ if wd == '-':
+ if x < self.WIDTH / 2:
+ wd = '>'
+ else:
+ wd = '<'
+ self.setwind(x,y, wd)
+
+ def generate_wind(self, gens = -1):
+ """Chooses one of the wind pattern generators and uses that to generate the winds.
+ 0: choose what generator to use.
+ """
+ if gens == -1:
+ gens = choice([1,1,2,3,4,4,4,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19])
+ if gens == 1: # totally random pattern
+ self.generate_wind1()
+ elif gens == 2: # wind "layers"
+ self.generate_wind1(0, ['x','^','^','^'],self.WIDTH,1)
+ self.wind_sidewalls()
+ elif gens == 3: # "wiggly" winds
+ self.generate_wind1(1, ['^','<','^','>'],1,1)
+ self.wind_sidewalls()
+ elif gens == 4: # "normal" wind pattern
+ self.wind_sidewalls()
+ dx = (self.WIDTH/2)
+ if random() < 0.7:
+ dy = 1 # usual height where bubbles collect
+ else:
+ dy = randint(1, self.HEIGHT-1)
+ for x in range(dx-3, dx+3):
+ self.setwind(x,dy,'x')
+ for x in range(dx-2):
+ self.setwind(x,dy,'>')
+ self.setwind(self.WIDTH-x-1,dy,'<')
+ elif gens == 5: # bubbles are stopped by horizontal walls
+ self.wind_sidewalls()
+ for x in range(self.WIDTH):
+ for y in range(self.HEIGHT-2):
+ if self.getw(x,y) == '#':
+ if self.getw(x,y+1) == ' ':
+ self.setwind(x,y+1,'x')
+ elif gens == 6: # bubbles move next the walls, rotating cw or ccw
+ if random() < 0.5: #clockwise
+ winddirs = [' ','>','v','v','<',' ','<','<','^','>',' ','v','^','>','^','x','x']
+ else:
+ winddirs = [' ','<','^','<','>',' ','^','<','v','v',' ','v','>','>','^','x','x']
+ self.wind_wallblocking(winddirs)
+ elif gens == 7: # bubbles move up in column(s) that zig-zag left and right
+ wid = choice([self.WIDTH, randint(2, self.WIDTH), randint(2, self.WIDTH)])
+ xofs = (self.WIDTH % wid) / 2
+ ofs = choice([0,1])
+ for dx in range(0, self.WIDTH-wid+1, wid):
+ for x in range(wid):
+ for y in range(self.HEIGHT):
+ if (y+ofs) & 1:
+ self.setwind(x+dx+xofs,y,'<')
+ if x == 0:
+ self.setwind(x+dx+xofs,y,'^')
+ else:
+ self.setwind(x+dx+xofs,y,'>')
+ if x == wid-1:
+ self.setwind(x+dx+xofs,y,'^')
+ elif gens == 8: # bubbles move towards the map centerline at random height
+ for x in range(self.WIDTH):
+ y = randint(1, self.HEIGHT-1)
+ if x < (self.WIDTH/2):
+ self.setwind(x,y,'>')
+ else:
+ self.setwind(x,y,'<')
+ self.setwind(x,0,'v')
+ self.setwind(x,self.HEIGHT-1,'^')
+ for y in range(self.HEIGHT):
+ self.setwind(self.WIDTH/2,y,'x')
+ elif gens == 9: # bubbles move towards the side walls at random height
+ for x in range(self.WIDTH):
+ y = randint(1, self.HEIGHT-1)
+ if y & 1:
+ self.setwind(x,y,'>')
+ else:
+ self.setwind(x,y,'<')
+ self.setwind(x,0,'v')
+ self.setwind(x,self.HEIGHT-1,'^')
+ for y in range(self.HEIGHT):
+ self.setwind(0,y,'x')
+ self.setwind(self.WIDTH-1,y,'x')
+ elif gens == 10: # bubbles move up-down
+ ofs = choice([0,1])
+ dir_l = choice(['>', '>', '<'])
+ dir_r = choice(['<', '<', '>'])
+ for x in range(self.WIDTH):
+ if x < (self.WIDTH / 2):
+ self.setwind(x, 0, dir_r)
+ self.setwind(x,self.HEIGHT-1,dir_l)
+ else:
+ self.setwind(x, 0, dir_l)
+ self.setwind(x,self.HEIGHT-1,dir_r)
+ for x in range(self.WIDTH):
+ for y in range(self.HEIGHT):
+ if (x+ofs) & 1:
+ self.setwind(x,y+1,'^')
+ else:
+ self.setwind(x,y-1,'v')
+ elif gens == 11: # bubbles rotate
+ self.wind_sidewalls()
+ for z in range(20):
+ wid = randint(2,self.WIDTH/2)
+ hei = randint(2,self.HEIGHT/2)
+ y = randint(1, self.HEIGHT - hei - 1)
+ x = randint(1, self.WIDTH - wid - 1)
+ ok = 1
+ for dx in range(wid):
+ if self.getwind(x+dx+1, y) != ' ':
+ ok = 0
+ if self.getwind(x+dx, y+hei) != ' ':
+ ok = 0
+ for dy in range(hei):
+ if self.getwind(x, y+dy) != ' ':
+ ok = 0
+ if self.getwind(x+wid, y+dy+1) != ' ':
+ ok = 0
+ if ok == 1:
+ self.wind_rect(x,y,wid,hei, random() < 0.5)
+ elif gens == 12: # bubbles gravitate towards a certain spot
+ dx = randint(1,self.WIDTH-1)
+ dy = randint(1,self.HEIGHT-1)
+ for x in range(self.WIDTH):
+ for y in range(self.HEIGHT):
+ ax = abs(dx - x)
+ ay = abs(dy - y)
+ sx = cmp(dx - x, 0)
+ sy = cmp(dy - y, 0)
+ winds = [' ',' ',' ']
+ if ax < 2 and ay < 2:
+ winds = ['x']
+ else:
+ if sx < 0:
+ winds += ['<']
+ elif sx > 0:
+ winds += ['>']
+ else:
+ if sy > 0:
+ winds = ['v']
+ elif sy < 0:
+ winds = ['^']
+ else:
+ winds = ['x']
+ if sy < 0:
+ winds += ['^']
+ elif sy > 0:
+ winds += ['v']
+ else:
+ if sx > 0:
+ winds = ['>']
+ elif sx < 0:
+ winds = ['<']
+ else:
+ winds = ['x']
+ self.setwind(x,y,choice(winds))
+ elif gens == 13: # bubbles stop at some random positions
+ self.generate_wind1(1, [' ',' ',' ',' ',' ',' ',' ','x'],1,1)
+ self.wind_sidewalls()
+ elif gens == 14: # bubbles move cw and ccw in alternating rectangles
+ m = max(self.WIDTH / 2, self.HEIGHT / 2)
+ cwofs = choice([0,1])
+ thk = choice([1,1,2,2,3,4,randint(1,m/2)])
+ for dx in range(m):
+ cw = ((dx / thk) + cwofs) % 2
+ self.wind_rect(dx,dx, self.WIDTH-(dx*2), self.HEIGHT-(dx*2), cw)
+ elif gens == 15: # bubbles move cw or ccw in rectangles
+ m = max(self.WIDTH / 2, self.HEIGHT / 2)
+ cw = choice([0,1])
+ for dx in range(m):
+ self.wind_rect(dx,dx, self.WIDTH-(dx*2), self.HEIGHT-(dx*2), cw)
+ elif gens == 16:
+ xs = randint(2, (self.WIDTH/2)-1)
+ ys = randint(2, (self.HEIGHT/2)-1)
+ rx = (self.WIDTH / xs) + 1
+ ry = (self.HEIGHT / ys) + 1
+ cwchanges = choice([0,0,0,0,0,0,0,0,1,1,1,1,2,2,3])
+ if cwchanges == 0:
+ cw = random() < 0.5
+ for x in range(rx):
+ if cwchanges == 1:
+ cw = random() < 0.5
+ for y in range(ry):
+ if cwchanges == 2:
+ cw = random() < 0.5
+ maxd = max((xs / 2), (ys / 2))
+ for d in range(maxd):
+ if cwchanges == 3:
+ cw = random() < 0.5
+ self.wind_rect(xs*x+d, ys*y+d, xs-2*d-1, ys-2*d-1, cw)
+ elif gens == 17: # bubbles bounce between walls
+ if random() < 0.5: # horizontal
+ winddirs = [' ',' ','<','<',' ',' ','<','<','>','>',' ',' ','>','>',' ',' ','x']
+ else: # vertical
+ winddirs = [' ','v',' ','v','^',' ','^',' ',' ','v',' ','v','^',' ','^',' ','x']
+ self.wind_wallblocking(winddirs)
+ elif gens == 18: # generate winds based on a random 3x3 matrix ruleset
+ winddirs = []
+ for z in range(257):
+ winddirs.append(choice([' ',' ',' ','x','^','v','-']))
+ winddirs[0] = ' '
+ winddirs[256] = choice(['x',' '])
+ self.wind_wallblocking256(winddirs)
+ elif gens == 19: # bubbles will move downwards in a zig-zag pattern
+ y = 0
+ x1 = randint(0, self.WIDTH-1)
+ while y < self.HEIGHT:
+ x2 = randint(0, self.WIDTH-1)
+ if x1 < x2:
+ self.setwind(x1,y, '>')
+ else:
+ self.setwind(x1,y, '<')
+ dy = choice([1,1,1,2])
+ self.setwind(x2,y, 'v')
+ y += dy
+ x1 = x2
+
+ def smooth(self, threshold, rev):
+ """Remove wall blocks that are surrounded by 4 empty places.
+ 0: probability which a wall cell is turned into space
+ 1: smooth away walls or smooth away empty spaces?
+ """
+ # make a copy of self.wmap and adds '#' at the end of line, for
+ # the overflowing indexing below: [x-1] and [x+1]
+ tmpwmap = [ line + ['#'] for line in self.wmap ]
+ if rev == 0:
+ chr = ' '
+ else:
+ chr = '#'
+ for x in range(self.WIDTH):
+ for y in range(1,self.HEIGHT-1):
+ count = 0
+ if tmpwmap[y+1][x] == chr:
+ count = count + 1
+ if tmpwmap[y-1][x] == chr:
+ count = count + 1
+ if tmpwmap[y][x+1] == chr:
+ count = count + 1
+ if tmpwmap[y][x-1] == chr:
+ count = count + 1
+ if (count >= 4) and (random() < threshold):
+ if rev == 0:
+ self.clrw(x,y)
+ else:
+ self.setw(x,y)
+
+ def mess(self, threshold):
+ """Random fill of the board with walls.
+ Only one argument, the probability that
+ a cell turns out to be a wall.
+ """
+ for x in range(self.WIDTH):
+ for y in range(self.HEIGHT):
+ if random() < threshold:
+ self.setw(x,y)
+
+ def zigzag_lr(self):
+ """Generate the level with random left-right zig-zags.
+ """
+ first = 1
+ self.reset(fill=False)
+ y = choice([0,0,2,3,3,4])
+ while y < (self.HEIGHT-2):
+ if first == 1:
+ first = 0
+ x1 = x2 = randint(2, self.WIDTH-3)
+ else:
+ x2 = randint(2, self.WIDTH-3)
+ while (x2 > (x1-3)) and (x2 < (x1+3)):
+ x2 = randint(2, self.WIDTH-3)
+ for dx in range(min(x1,x2+1), max(x1,x2+1)):
+ self.setw(dx,y)
+ dy = choice([2,2,3,3,3,4])
+ for dy in range(dy+1):
+ self.setw(x2,y+dy)
+ y = y + dy
+ x1 = x2
+
+ def zigzag_ud(self):
+ """Generate the level with random up-down zig-zags.
+ """
+ first = 1
+ self.reset(fill=False)
+ x = -1
+ while x < self.WIDTH:
+ if first == 1:
+ first = 0
+ y1 = y2 = randint(2, self.HEIGHT-1)
+ else:
+ y2 = randint(2, self.HEIGHT-1)
+ while (y2 > (y1-2)) and (y2 < (y1+2)):
+ y2 = randint(2, self.HEIGHT-1)
+ for dy in range(min(y1,y2+1), max(y1,y2+1)):
+ self.setw(x,dy)
+ dx = choice([3,4,4,4,5,6])
+ for dx in range(dx+1):
+ self.setw(x+dx,y2)
+ x = x + dx
+ y1 = y2
+
+ def zigzag(self):
+ """Generate a level with a random zig-zag form.
+ """
+ if random() < 0.5:
+ self.zigzag_lr()
+ else:
+ self.zigzag_ud()
+
+ def platforms(self, (nplat, space), (rng_holes, rng_width), full=1):
+ """Place random platforms.
+ args is a tuple with the following fields:
+ 0: a tuple containing the number of platforms and
+ the minum space between two platforms,
+ 1: a tuple indicating in order:
+ - the rng for the number of holes per platform
+ - the rng for the width of the holes,
+ 2: a flag indicating whether the platform should cross
+ the whole level or not.
+ """
+ plat = []
+ for i in range(nplat):
+ ntry = 100
+ while ntry:
+ y = randint(0,self.HEIGHT-1)
+ found = 0
+ for old in plat:
+ if abs(old-y) <= space:
+ found = 1
+ break
+ if not found:
+ plat.append(y)
+ break
+ ntry -= 1
+ if not ntry:
+ continue # ignore platform
+ if full:
+ x = 0
+ w = self.WIDTH
+ else:
+ x = randint(0,self.WIDTH-1)
+ w = randint(0,self.WIDTH-1)
+ s = choice([-1,1])
+ if s == -1:
+ w = min(w,x)
+ x -= w
+ else:
+ w = min(w,self.WIDTH-x)
+ for x1 in range(x,x+w):
+ self.setw(x1,y)
+ for i in range(rng_holes()):
+ hx = randint(x,x+w)
+ hw = rng_width()
+ for h in range(hx-hw/2,hx+hw/2):
+ self.clrw(h,y)
+
+ def remove_joined_blocks(self):
+ """Removes randomly placed, random sized blocks of walls.
+ The blocks are usually joined, or if not, they're offset so that
+ it's possible to move from one block to another by jumping.
+ """
+ self.reset(fill=True)
+ nrooms = randint(1, 4)
+ while nrooms:
+ nrooms -= 1;
+ x = 0
+ while x < self.WIDTH:
+ wid = randint(2,8)
+ hei = randint(2,6)
+ y = randint(2, self.HEIGHT - hei - 1)
+ for dx in range(wid):
+ for dy in range(hei):
+ self.clrw(x+dx, y+dy)
+ x += wid + choice([-2,-2,-1,-1,0]);
+
+ def discrete_blocks(self, blocks = -1):
+ """Put certain size blocks randomly, but so that they don't touch each other.
+ """
+ self.reset(fill=False)
+ if blocks == -1:
+ if random() < 0.75:
+ blocks = [(4,2),(2,4)] # CompactLevels, level 16
+ if random() < 0.30:
+ blocks.append((2,2))
+ if random() < 0.20:
+ blocks.append((6,2))
+ if random() < 0.10:
+ blocks.append((8,2))
+ else:
+ blocks = []
+ while len(blocks) == 0:
+ for bz in range(10):
+ if random() < 0.3:
+ blocks.append((bz+1,1))
+ ntry = 300
+ while ntry:
+ ntry -= 1
+ doput = 1
+ block = choice(blocks)
+ wid = block[0]
+ hei = block[1]
+ x = randint(0,self.WIDTH-wid-2)
+ y = randint(1,self.HEIGHT-hei-3)
+ for dx in range(x,x+wid+2):
+ for dy in range(y,y+hei+2):
+ if self.getw(dx,dy) == '#':
+ doput = 0
+ if doput:
+ for dx in range(x+1,x+wid+1):
+ for dy in range(y+1,y+hei+1):
+ self.setw(dx,dy)
+
+ def lines(self, rng_len, nlines, rng_angle=None):
+ """Generate a set of lines in any direction. It takes three
+ arguments, a rng for the length the lines, the number of lines,
+ and a rng for the angle.
+ """
+ if rng_angle is None:
+ rng_angle = lambda : choice([0]+[pi/i for i in range(3,21)]+[-pi/i for i in range(3,21)])
+ for i in range(nlines):
+ len = rng_len()
+ angle = rng_angle()
+ ntry = self.MAXTRY
+ while ntry:
+ sx = randint(0,self.WIDTH-1)
+ sy = randint(0,self.HEIGHT-1)
+ dx = int(sx + len*cos(angle) + 0.5)
+ dy = int(sy + len*sin(angle) + 0.5)
+ if dx < self.WIDTH and dy < self.HEIGHT and dx >= 0 and dy >= 0:
+ break
+ ntry -= 1
+ if ntry == 0:
+ break
+ if abs(dx-sx) > abs(dy-sy):
+ for x in range(dx-sx+1):
+ y = (2*(dy-sy)*x/(dx-sx)+1)/2
+ self.setw(sx+x,sy+y)
+ else:
+ for y in range(dy-sy+1):
+ x = (2*(dx-sx)*y/(dy-sy)+1)/2
+ self.setw(sx+x,sy+y)
+
+ def rooms(self, rng_radius, rng_e, n_rooms):
+ """Generate rooms. It takes the following arguments:
+ 0: the rng for the radius of the room
+ 1: the rng for the excentricity of the room
+ 2: the number of rooms
+ """
+ for i in range(n_rooms):
+ cx = randint(0,self.WIDTH-1)
+ cy = randint(0,self.HEIGHT-1)
+ r = rng_radius()
+ e = rng_e()*1.0
+ left = cx-int(r*e+0.5)
+ right = cx+int(r*e+0.5)
+ top = cy-int(r/e+0.5)
+ bottom = cy+int(r/e+0.5)
+ for x in range(left,right+1):
+ self.setw(x,top)
+ self.setw(x,bottom)
+ for y in range(top,bottom+1):
+ self.setw(left,y)
+ self.setw(right,y)
+ for x in range(left+1,right):
+ for y in range(top+1,bottom):
+ self.lockw(x,y)
+
+ def holes(self, rng_radius, rng_e, n_holes, rng_rect):
+ """Generate a set of holes in the level. It takes four args:
+ 0: the rng for the radius of the holes
+ 1: the rng for the excentricity of the holes
+ 2: the number of holes
+ 3: the rng for the shape of the hole 0 for circular, 1 for rectangular
+ """
+ for i in range(n_holes):
+ cx = randint(0,self.WIDTH-1)
+ cy = randint(0,self.HEIGHT-1)
+ r = rng_radius()
+ e = rng_e()*1.0
+ rect = rng_rect()
+ for x in range(cx-int(r*e+0.5),cx+int(r*e+0.5)+1):
+ for y in range(cy-int(r/e+0.5),cy+int(r/e+0.5)+1):
+ if not rect and (((x-cx)/e)**2+((y-cy)*e)**2) > r**2:
+ continue
+ self.clrw(x,y)
+
+ def grids(self, horizchance, vertchance):
+ """Generate a level with a grid of horizontal and vertical lines
+ 0: gaussian chance of each horizontal line part
+ 1: gaussian chance of each vertical line part
+ """
+ self.reset(fill=False)
+ xsize = choice([3,3,3,4,4,4,4,5,6])
+ ysize = choice([2,3,3,4,4,4,4,5])
+ xofs = choice([-1,0,1])
+ yofs = choice([-1,0,1])
+ for x in range((self.WIDTH/xsize)+1):
+ for y in range((self.HEIGHT/ysize)+1):
+ dx = x*xsize + xofs
+ dy = y*ysize + yofs
+ if gauss(0,1) > horizchance:
+ for i in range(0,xsize+1):
+ self.setw(dx+i,dy)
+ if gauss(0,1) > vertchance:
+ for i in range(0,ysize+1):
+ self.setw(dx,dy+i)
+
+ def pegs(self, pegchance, posadj, thick):
+ """Generate a level by putting pegs
+ 0: gaussian level of a peg appearance
+ 1: gaussian level of peg position adjustment
+ """
+ self.reset(fill=False)
+ xdist = choice([3,3,3,4,4,5]) # distance between pegs
+ ydist = choice([2,3,3,3,4,5]) # distance between pegs
+ if not thick:
+ xdist = xdist - randint(0,1)
+ ydist = ydist - randint(0,1)
+ xadj = randint(0,4) - 2
+ yadj = randint(0,4) - 2
+ for x in range(self.WIDTH / xdist):
+ for y in range(self.HEIGHT / ydist):
+ if gauss(0,1) > pegchance:
+ dx = x * xdist + xadj
+ dy = y * ydist + yadj
+ if gauss(0,1) > posadj:
+ dx = dx + randint(0,2) - 1
+ dy = dy + randint(0,2) - 1
+ self.setw(dx,dy)
+ if thick:
+ self.setw(dx+1,dy)
+ self.setw(dx,dy+1)
+ self.setw(dx+1,dy+1)
+
+ def mondrian(self, x1=2,y1=2,x2=-1,y2=-1, horiz=-1, mindepth=3):
+ """Generate a level that looks a bit like a Piet Mondrian painting, or
+ different sized rectangles stacked on top of each other.
+ 0-3: the size of the area to be split
+ 4: whether the first split is horizontal or vertical
+ 5: minimum number of splits to do
+ """
+ if horiz == -1:
+ horiz = choice([0,1])
+ if x2 == -1:
+ x2 = self.WIDTH-2
+ if y2 == -1:
+ y2 = self.HEIGHT-2
+ if (abs(x2-x1) < 6) or (abs(y2-y1) < 5):
+ return
+ mindepth = mindepth - 1
+ if horiz == 1:
+ horiz = 0
+ dy = randint(y1+2,y2-2)
+ for dx in range(min(x1,x2),max(x1,x2)):
+ self.setw(dx,dy)
+ if (random() < 0.75) or (mindepth > 0):
+ self.mondrian(x1,y1,x2,dy, horiz, mindepth)
+ if (random() < 0.75) or (mindepth > 0):
+ self.mondrian(x1,dy,x2,y2, horiz, mindepth)
+ else:
+ horiz = 1
+ dx = randint(x1+3,x2-3)
+ for dy in range(min(y1,y2),max(y1,y2)):
+ self.setw(dx,dy)
+ if (random() < 0.75) or (mindepth > 0):
+ self.mondrian(x1,y1,dx,y2, horiz, mindepth)
+ if (random() < 0.75) or (mindepth > 0):
+ self.mondrian(dx,y1,x2,y2, horiz, mindepth)
+
+ def bouncers(self, length, diradj, rev):
+ """Generate a level using a down and left or right moving walker
+ 0: how many steps does the walker take
+ 1: gaussian level, how often to change moving from left to right
+ 2: fill empty level with wall or reverse?
+ """
+ if rev == 0:
+ self.reset(fill=True)
+ else:
+ self.reset(fill=False)
+ x = randint(0,self.WIDTH-2)
+ y = randint(0,self.HEIGHT-2)
+ lorr = choice([1, -1]) # move left or right
+ for i in range(length):
+ if rev == 0:
+ self.clrw(x,y)
+ self.clrw(x+1,y)
+ self.clrw(x,y+1)
+ self.clrw(x+1,y+1)
+ else:
+ self.setw(x,y)
+ self.setw(x+1,y)
+ x = x + lorr
+ y = y + 1
+ if y > self.HEIGHT:
+ y = 0
+ if x > self.WIDTH - 2:
+ x = self.WIDTH - 2
+ lorr = -lorr
+ elif x < 0:
+ x = 0
+ lorr = -lorr
+ if gauss(0,1) > diradj:
+ lorr = -lorr
+
+
+ def walkers(self, length, minturn, maxturn, isbig):
+ """Generate a level with a walker
+ 0: length of the walker: how many steps it walks
+ 1: minimum length it walks straight, before turning
+ 2: maximum length it walks straight, before turning
+ 3: is the trail is 1 or 2 blocks high
+ """
+ # We start from a full wall
+ self.reset(fill=True)
+ x = randint(0,self.WIDTH-2)
+ y = randint(0,self.HEIGHT-2)
+ dir = randint(0,4)
+ dlen = 0
+ for i in range(length):
+ self.clrw(x,y)
+ self.clrw(x+1,y)
+ if isbig == 1:
+ self.clrw(x,y+1)
+ self.clrw(x+1,y+1)
+ dlen = dlen + 1
+ if dir == 0:
+ x = x - 2
+ if x < 0:
+ x = self.WIDTH-2
+ elif dir == 1:
+ y = y - 1
+ if y < 0:
+ y = self.HEIGHT
+ elif dir == 2:
+ x = x + 2
+ if x > (self.WIDTH - 2):
+ x = 0
+ else:
+ y = y + 1
+ if y > self.HEIGHT:
+ y = 0
+ if dlen > randint(minturn, maxturn):
+ # turn 90 degrees
+ dir = (dir + choice([1,3])) % 4
+ dlen = 0
+
+ def rivers(self, n_flow, side_threshold, side_shift):
+ """Generate flow paths by digging a big wall. The arguments are:
+ 0: the number of parallel flow to dig in the wall
+ 1: side_threshold is a gausian level for doing a step aside
+ 2: side_shift is the maximal size of the side step.
+ """
+ # We start from a full wall
+ self.reset(fill=True)
+ for x in [0, self.WIDTH-2]+[randint(3,self.WIDTH-5) for f in range(max(0, n_flow-2))]:
+ for y in range(self.HEIGHT):
+ self.clrw(x,y)
+ self.clrw(x+1,y)
+ g = gauss(0,1)
+ if abs(g) > side_threshold:
+ # We want to move aside, let's find which side is the best:
+ if self.WIDTH/4 < x < 3*self.WIDTH/4:
+ side = random() > 0.5
+ t = random()
+ if t > x*4/self.WIDTH:
+ side = 1
+ elif t > (self.WIDTH-x)*4/self.WIDTH:
+ side = -1
+ side_step = randint(1,side_shift)
+ if side > 0:
+ for i in range(x+2, min(x+2+side_step,self.WIDTH-1)):
+ self.clrw(i,y)
+ x = max(0,min(x+side_step, self.WIDTH-2))
+ else:
+ for i in range(max(x-side_step,0),x):
+ self.clrw(i,y)
+ x = max(x-side_step, 0)
+
+ def platforms_reg(self):
+ """Generate random platforms at regular y-intervals.
+ """
+ self.reset(fill=False)
+ yadjs = [-2,-1,0,0,0,0,0,0,0,0,1,2]
+ y = randint(2,4)
+ yinc = randint(2,6)
+ yincadj = choice(yadjs)
+ ymax = self.HEIGHT-choice([1,1,1,1,1,2,2,2,3,3,4])-1
+ while y < ymax:
+ holes = randint(choice([0,1,1,1,1]),7)
+ for x in range(0, self.WIDTH):
+ self.setw(x,y)
+ for i in range(holes):
+ x = randint(0, self.WIDTH-2)
+ self.clrw(x,y)
+ self.clrw(x+1,y)
+ y = y + yinc
+ yinc = yinc + yincadj
+ if yinc < 2:
+ yinc = 2
+ yincadj = choice(yadjs)
+ if yinc > 6:
+ yinc = 6
+ yincadj = choice(yadjs)
+
+ def startplatform(self):
+ "Make sure there's free space with wall underneath for dragon start positions"
+ hei = choice([1,1,1,2,2,3])
+ lft = choice([0,1])
+ wid = choice([3,3,3,4,5])
+ for x in range(lft, wid):
+ self.setw(x,self.HEIGHT-1)
+ self.setw(self.WIDTH-x-1,self.HEIGHT-1)
+ for y in range(hei+1):
+ self.clrw(x,self.HEIGHT-2-y)
+ self.clrw(self.WIDTH-x-1,self.HEIGHT-2-y)
+
+ def openstartway(self):
+ "Make sure there is a way from the starting position to the center of the level. Reduces player frustrations."
+ gen = choice([0,0,0,1])
+ if gen == 0: # horizontal open space to middle of level
+ ypos = choice([1,1,1,1,1,2,2,3,4,randint(1,self.HEIGHT/2)])
+ hei = choice([1,1,1,2])
+ for x in range(self.WIDTH/2):
+ for y in range(hei):
+ self.clrw(x, self.HEIGHT-1-ypos-y)
+ ypos = choice([1,1,1,1,1,2,2,3,4,randint(1,self.HEIGHT/2)])
+ hei = choice([1,1,1,2])
+ for x in range(self.WIDTH/2):
+ for y in range(hei):
+ self.clrw(self.WIDTH-x-1, self.HEIGHT-1-ypos-y)
+ elif gen == 1: # open way diagonally to NW or NS, third of a way to the level width
+ ypos = choice([1,1,1,1,1,2,2,3,4])
+ wid = choice([2,2,2,2,2,3,3,4])
+ for x in range(self.WIDTH/3):
+ for z in range(wid):
+ self.clrw(x+z, self.HEIGHT-1-x-ypos)
+ ypos = choice([1,1,1,1,1,2,2,3,4])
+ wid = choice([2,2,2,2,2,3,3,4])
+ for x in range(self.WIDTH/2):
+ for z in range(wid):
+ self.clrw(self.WIDTH-x-1-z, self.HEIGHT-1-x-ypos)
+
+ def close(self):
+ "Just close the level with floor and roof"
+ for x in range(self.WIDTH):
+ self.setw(x,0)
+ self.setw(x,self.HEIGHT)
+
+ def largest_vertical_hole(self, x):
+ "Returns the (start, stop) of the largest range of holes in column x."
+ if not (0 <= x < self.WIDTH):
+ return (0, 0)
+ ranges = []
+ best = 0
+ length = 0
+ for y in range(self.HEIGHT+1):
+ if y < self.HEIGHT and self.getw(x,y) == ' ':
+ length += 1
+ elif length > 0:
+ if length > best:
+ del ranges[:]
+ best = length
+ if length == best:
+ ranges.append((y-length, y))
+ length = 0
+ return choice(ranges or [(0, 0)])
+
+ def dig_vertical_walls(self):
+ "Check that no vertical wall spans the whole height of the level"
+ vwall = []
+ for x in range(self.WIDTH):
+ spaces = 0
+ for y in range(self.HEIGHT-1): # ignore bottom line spaces
+ spaces += self.getw(x,y) == ' '
+ if spaces == 0 or (random() < 0.4**spaces):
+ vwall.append(x)
+ shuffle(vwall)
+ for x in vwall:
+ # look for the longest continuous space in each of the two
+ # adjacent columns, and extend these to the current column
+ def dig(y1, y2):
+ for y in range(y1, y2):
+ self.clrw(x, y)
+ return y1 < y2 and y1 < self.HEIGHT-1
+ progress = False
+ for col in [x-1, x+1]:
+ y1, y2 = self.largest_vertical_hole(col)
+ progress |= dig(y1, y2)
+ while not progress:
+ progress |= dig(randint(0, self.HEIGHT-1),
+ randint(0, self.HEIGHT-1))
+
+ def prevent_straight_fall(self):
+ """Make platforms that prevent falling straight from top to bottom, but
+ still leave space for moving.
+ """
+ falls = []
+ for x in range(self.WIDTH):
+ for y in range(self.HEIGHT):
+ if self.getw(x,y) == '#':
+ break
+ else:
+ falls = falls + [x]
+ y = oldy = -10
+ for x in falls:
+ while (y < oldy+2) and (y > oldy-2):
+ y = randint(2, self.HEIGHT-2)
+ for dy in range(y-1,y+2):
+ for dx in range(x-3, x+4):
+ self.clrw(dx,dy)
+ self.setw(x-1,y)
+ self.setw(x+1,y)
+ self.setw(x,y)
+ oldy = y
+
+ def do_monsters(self):
+ """Create monsters based on the requested settings.
+ mlist is a list of monster setting. Each item is a tuple with:
+ 0: the list of monster to uses (each item might be a tuple)
+ 1: the rng for the number of monsters to pick in the list.
+ """
+ current = 'a'
+ for ms in self.mlist:
+ n_monsters = ms[1]()
+ for idx in range(n_monsters):
+ self.__class__.__dict__[current] = choice(ms[0])
+ ntry = self.MAXTRY
+ while ntry:
+ x = randint(0,self.WIDTH-2)
+ y = randint(0,self.HEIGHT-1)
+
+ if self.getw(x,y) == self.getw(x+1,y) == ' ':
+ self.wmap[y][x] = current
+ break
+ ntry -= 1
+ current = chr(ord(current)+1)
+
+ def do_walls(self):
+ "Build the actual walls map for the game."
+ self.__class__.walls = ''
+ for y in range(self.HEIGHT-1):
+ self.__class__.walls += '##'
+ for x in range(self.WIDTH):
+ self.__class__.walls += self.wmap[y][x]
+ self.__class__.walls += '##\n'
+ self.__class__.walls += '##'
+ for x in range(self.WIDTH):
+ if self.getw(x,0) == '#' or self.getw(x,self.HEIGHT-1) == '#':
+ self.__class__.walls += '#'
+ else:
+ self.__class__.walls += ' '
+ self.__class__.walls += '##\n'
+
+ def do_winds(self):
+ "Build the actual wind map for the game."
+ self.__class__.winds = ''
+ for y in range(self.HEIGHT):
+ self.__class__.winds += '>>'
+ for x in range(self.WIDTH):
+ self.__class__.winds += self.windmap[y][x]
+ self.__class__.winds += '<<' + '\n'
+
+ def do_bonuses(self):
+ self.__class__.letter = choice([0,1])
+ self.__class__.fire = choice([0,1])
+ self.__class__.lightning = choice([0,1])
+ self.__class__.water = choice([0,1])
+ self.__class__.top = choice([0,1])
+
+ def generate(self):
+ "Generate random level settings."
+ assert 0, "--- THIS IS NO LONGER REALLY USED ---"
+ self.mlist = [([
+ LNasty, LMonky, LGhosty, LFlappy, LSpringy, LOrcy, LGramy, LBlitzy,
+ RNasty, RMonky, RGhosty, RFlappy, RSpringy, ROrcy, RGramy, RBlitzy,
+ ],lambda : flat(12,4))]
+ gens = choice([512,512,256,256,128,128,64,64,32,32,16,16,16,16,16,16,20,20,8,8,8,8,4,4,4,4,2,2,2,2,1,1,3,5,6,7])
+ self.genwalls = []
+ if gens & 512:
+ print 'Using grids generator'
+ self.genwalls.append((RandomLevel.grids,
+ uniform(0.0, 0.1),
+ uniform(0.0, 0.1)))
+ if gens & 256:
+ # generate using pegs
+ print 'Using the pegs generator'
+ self.genwalls.append((RandomLevel.pegs,
+ uniform(0.1,0.2),
+ uniform(0.45,0.7),
+ choice([0,1,1,1])))
+ if gens & 128:
+ # generate using a bouncer
+ nr = choice([0,0,1])
+ print 'Using the bouncer generator'
+ self.genwalls.append((RandomLevel.bouncers,
+ dice(1, 100) + 250 - nr*200, # length
+ uniform(0.7, 1.7),
+ nr))
+ if gens & 64:
+ # generate using a walker
+ print 'Using the walker generator'
+ nr = dice(1, 3) + 2
+ self.genwalls.append((RandomLevel.walkers,
+ dice(2, 100) + 100, # length
+ nr, nr + dice(2, 3), # straight walk min, max len
+ choice([0,1])))
+ if gens & 32:
+ # generate rivers
+ print 'Using the rivers generator'
+ self.genwalls.append((RandomLevel.rivers,
+ randrange(2,(self.WIDTH-4)/5), # the number of rivers
+ uniform(0.7, 1.7), # the side stepping threshold
+ 6)) # the max side stepping size
+ if gens & 16:
+ # generate rooms
+ print 'Using the romms generator'
+ nr = choice([1,2,2,2,3,3,4,5])
+ self.genwalls.append((RandomLevel.rooms,
+ lambda : flat(9-nr,2), # the half size of the room
+ lambda : uniform(0.8,1.2), # the excentricity of the room
+ nr)) # the number of rooms
+ if gens & 8:
+ # generate a holes generator
+ # as this is interesting only if the level is filled somehow
+ print 'Using the holes generator'
+ self.genwalls.append((RandomLevel.mess,1-uniform(0.2,0.5)))
+ nh = choice([1,1,2,2,2,3,3,3,4,5])
+ self.genwalls.append((RandomLevel.holes,
+ lambda : flat(9-nh,2), # radius of the holes
+ lambda : uniform(0.9,1.1), # excentricity
+ nh, # number of holes
+ lambda : choice([0,0,0,1]))) # circle or rectangle
+ if gens & 4:
+ # generate a lines generator
+ print 'Using the lines generator'
+ self.genwalls.append((RandomLevel.lines,
+ lambda : dice(7,3), # line length
+ dice(2,3))) # number of lines
+ if gens & 2:
+ # generate a platforms generator
+ print 'Using the platforms generator'
+ nplat = dice(2,4,0)
+ if nplat: space = flat((self.HEIGHT-1)/nplat/2,(self.HEIGHT-1)/nplat/2-1)
+ else: space = 1
+ nholes = lambda : dice(1,3,0)
+ wholes = lambda : dice(2,3)
+ full = randrange(2)
+ self.genwalls.append((RandomLevel.platforms,
+ (nplat,space), # number of platform and spacing
+ (nholes,wholes), # number of holes and width
+ full)) # full width platform
+ if gens & 1:
+ # generate a mess generator
+ print 'Using the mess generator'
+ if gens & ~2:
+ offset = 0
+ scale = 0.05
+ else:
+ offset = 0.05
+ scale = 0.10
+ self.genwalls.append((RandomLevel.mess,offset+random()*scale))
+ if random() < 0.2:
+ self.genwalls.append((RandomLevel.close,))
+ if random() < 0.90:
+ self.genwalls.append((RandomLevel.startplatform,))
+ self.genwalls.append((RandomLevel.generate_wind, ))
+
+
+Levels = []
+for i in range(25):
+ class level(RandomLevel):
+ auto = 1
+ Levels.append(level)
+
+class levelfinal(RandomLevel):
+ genwalls = [(RandomLevel.platforms,(4,3),(lambda:flat(1,1),lambda:flat(4,2)),1)]
+Levels.append(levelfinal)
diff --git a/bubbob/levels/scratch.py b/bubbob/levels/scratch.py
new file mode 100644
index 0000000..a958a28
--- /dev/null
+++ b/bubbob/levels/scratch.py
@@ -0,0 +1,2301 @@
+#
+# An experimental level set.
+#
+
+import boarddef
+from boarddef import LNasty, LMonky, LGhosty, LFlappy
+from boarddef import LSpringy, LOrcy, LGramy, LBlitzy
+from boarddef import RNasty, RMonky, RGhosty, RFlappy
+from boarddef import RSpringy, ROrcy, RGramy, RBlitzy
+
+
+class level01(boarddef.Level):
+ a = LNasty
+ b = RNasty
+
+ walls = """
+####################################
+## ##
+## ##
+## ##
+## ##
+## ##
+## a a b b ##
+#### ###################### ####
+## ##
+## ##
+## ##
+## a a b b ##
+#### ###################### ####
+## ##
+## ##
+## ##
+## a a b b ##
+#### ###################### ####
+## ##
+## ##
+## ##
+## a a b b ##
+#### ###################### ####
+## ##
+## ##
+## ##
+## ##
+####################################
+"""
+
+ winds = """
+>> <<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>> <<
+"""
+
+
+class level02(boarddef.Level):
+ letter = 1
+ lightning = 1
+ top = 0
+
+ a = LNasty
+ b = RNasty
+
+ walls = """
+## ##
+## ##
+##b ##
+############## ##############
+## a ##
+############# #############
+##b ##
+############ ############
+## a ##
+########### ###########
+##b ##
+########## ##########
+## a ##
+######### #########
+##b ##
+######## ########
+## a ##
+####### #######
+##b ##
+###### ## ######
+## a ##
+##### ### ### #####
+## ##
+#### #### #### #### ####
+## ##
+### ######## ###
+## ##
+############ ############
+""" # [] [] [] # """
+
+ winds = """
+>> <<
+>>x<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>x<<
+>> <<
+>> <<
+>>>>>>>>>>>>>>^ ^<<<<<<<<<<<<<<
+>> <<
+>>>>>>>>>>>>>^ ^<<<<<<<<<<<<<
+>> <<
+>>>>>>>>>>>>^ ^<<<<<<<<<<<<
+>> <<
+>>>>>>>>>>>^ ^<<<<<<<<<<<
+>> <<
+>>>>>>>>>>^ ^<<<<<<<<<<
+>> <<
+>>>>>>>>>^ ^<<<<<<<<<
+>> <<
+>>>>>>>>^ ^<<<<<<<<
+>> <<
+>>>>>>>^ ^<<<<<<<
+>> <<
+>>>>>>^ ^<<<<<<
+>> <<
+>>>>>^ ^<<<<<
+>> <<
+>>>>^ ^<<<<
+>> <<
+>>>^ ^<<<
+>> <<
+"""
+
+
+class level03(boarddef.Level):
+ letter = 1
+ fire = 0
+ lightning = 0
+ water = 1
+ top = 1
+
+ a = LNasty, RNasty
+ b = ()
+ c = LMonky, RMonky
+
+ walls = """
+## ##
+## ##
+## # # ##
+## b ##
+## # ##
+## a # # ##
+## # # ##
+## ##
+## b a b ##
+## # # # ##
+## c ##
+## # # c ##
+## # b # ##
+## ##
+## # # # ##
+## ##
+## # # ##
+## # a # ##
+## # b # ##
+## ##
+## c # ##
+## # # b # ##
+## # ##
+## # ##
+## # ##
+## # # ##
+## # ##
+##### # #####
+""" # [] [] [] # """
+
+ winds = """
+>> <<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>> <<
+"""
+
+
+class level04(level03):
+ a = LNasty, RNasty
+ b = LGhosty, RGhosty
+ c = ()
+
+class level05(level03):
+ a = LSpringy, RSpringy
+ b = LSpringy, RSpringy
+ c = ()
+
+
+
+class level06(boarddef.Level):
+ letter = 1
+ fire = 0
+ lightning = 1
+ water = 0
+ top = 0
+
+ a = LSpringy
+ b = RSpringy
+ c = LBlitzy
+
+ walls = """
+## ############## ##
+## ##
+## ##
+## b bcbcbcb bb a a acacaca a ##
+################ ################
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+## ########### ########### ##
+## bababa ##
+## ########################## ##
+## ##
+## ##
+## ##
+########## ##########
+## ##
+## ##
+## ##
+## ##
+## ##
+###### ############## ######
+""" # [] [] [] # """
+
+ winds = """
+>> <<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>>>>>>>>>>>>>>>^^^^<<<<<<<<<<<<<<<<
+>>^ ^<<
+>>^ ^<<<<<<<<<<<<<>>>>>>>>>>>>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>> <<
+"""
+
+
+class level07(boarddef.Level):
+ letter = 0
+ fire = 0
+ lightning = 0
+ water = 0
+ top = 1
+
+ a = LSpringy
+ b = RSpringy
+
+ walls = """
+############ ############# ####
+### ##
+### b ##
+## b ##
+#### b ##
+## # b ##
+## #b ##
+## # ###### ##
+## # b ##
+## # b ##### ##
+## # b ##
+## # b ##
+## # b ##
+## ### ##
+## # ##
+## # b ##
+## # b ##
+## # b ##
+## # b ##
+## #b ##
+## # ##
+## # ##
+## # ##
+## # ##
+## # ##
+## # ##
+## # ##
+############ ############# ####
+""" # [] [] [] # """
+
+ winds = """
+>> <<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>v v<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvv v<<<<<<<<<<<<<<<<<<<<<<<<<<<
+>>vvvvv v<<<<<<<<<<<<<<<<<<<<<<<<<<<
+>>>>>>v v<<<<<<<<<<<<<<<<<<<<<<<<<<<
+>>> v v<<<<<<<<<<<<<<<<<<<<<<<<<<<
+>>> v v<<<<<<<<<<<<<<<<<<<<<<<<<<<
+>>> v v<<<<<<<<<<<<<<<<<<<<<<<<<<<
+>>> xxx v<<<<<<<<<<<<<<<<<<<<<<<<<<<
+>>> v<<<<<<<<<<<<<<<<<<<<<<<<<<<
+>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<
+>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<
+>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<
+>>> ^<<
+>vv ^<<
+>vv ^<<
+>vv ^<<
+>vv ^<<
+>vv ^<<
+>vv ^<<
+>vv ^<<
+>vv ^<<
+>vvvvvvvvvvvvvvvv ^<<
+>vvvvvvvvvvvvvvvv ^<<
+>vvvvvvvvvvvvvvvv ^<<
+>vvvvvvvvvvvvvvvv ^<<
+"""
+
+
+class level08(boarddef.Level):
+ letter = 1
+ fire = 1
+ lightning = 1
+ water = 0
+ top = 0
+
+ a = b = c = d = e = LFlappy
+
+ walls = """
+## ##
+## ##
+#### ## ## ## ## ## ####
+## ##
+## # # # # # # ##
+## # # # # # # ##
+## a b c d e ##
+#### ## ## ## ## ## ####
+## ##
+## # # # # # # ##
+## # # # # # # ##
+## e d c b a ##
+#### ## ## ## ## ## ####
+## ##
+## # # # # # # ##
+## # # # # # # ##
+## a b c d e ##
+#### ## ## ## ## ## ####
+## ##
+## # # # # # # ##
+## # # # # # # ##
+## e d c b a ##
+#### ## ## ## ## ## ####
+## ##
+## # # # # # # ##
+## # # # # # # ##
+## a b c d e ##
+#### ## ## ## ## ## ####
+""" # [] [] [] # """
+
+ winds = """
+>> <<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>> <<
+"""
+
+
+class level09(level08):
+
+ a = ()
+ b = RGhosty
+ c = RBlitzy
+ d = ()
+ e = LBlitzy
+
+
+class level10(boarddef.Level):
+ top = 1
+
+ a = RSpringy
+ b = LSpringy
+ c = LSpringy
+ d = RSpringy
+ e = LSpringy
+
+ walls = """
+## # # # # # # ##
+#### ## ## ## ## ## ####
+## ##
+## # # # # # # ##
+## a b c d e ##
+#### ## ## ## ## ## ####
+## ##
+## # # # # # # ##
+## # # # # # # ##
+## e d c b a ##
+#### ## ## ## ## ## ####
+## ##
+## # # # # # # ##
+## a b c d e ##
+#### ## ## ## ## ## ####
+## ##
+## # # # # # # ##
+## e d c b a ##
+#### ## ## ## ## ## ####
+## ##
+## # # # # # # ##
+## # # # # # # ##
+## ##
+#### ## ## ## ## ## ####
+## ##
+## # # # # # # ##
+## ##
+#### ## ## ## ## ## ####
+""" # [] [] [] # """
+
+ winds = """
+>> <<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>> <<
+"""
+
+
+
+class level11(boarddef.Level):
+ letter = 0
+ fire = 0
+ lightning = 1
+ water = 0
+ top = 0
+
+ a = LSpringy
+ b = RFlappy
+ c = RSpringy
+
+ walls = """
+####################################
+## ##
+## ##
+## ##
+## ##
+## ##
+## b b b b b ##
+## ##
+## b b b b b b ##
+## ##
+## ##
+## ##
+## ##
+####################################
+## ##
+## ##
+## ##
+## ##
+## ##
+## a ##
+## c ##
+## a ##
+## c ##
+## a ##
+## c ##
+## a ##
+## c ##
+####################################
+""" # [] [] [] # """
+
+ winds = """
+>> <<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>> <<
+"""
+
+
+
+class level12(level11):
+ letter = 0
+ fire = 1
+ lightning = 0
+ water = 0
+ top = 1
+
+ a = LGhosty
+ b = RFlappy
+ c = RGhosty
+
+
+class level13(boarddef.Level):
+ letter = 1
+ fire = 0
+ lightning = 1
+ water = 0
+ top = 1
+
+ a = LFlappy
+ b = RFlappy
+
+ walls = """
+########## ###### ##########
+## ###### ##
+## ###### ##
+## ###### ##
+## ###### ##
+## a ###### b ##
+## ###### ##
+## b ###### a ##
+## ###### ##
+## a ###### b ##
+## ###### ##
+## b ###### a ##
+## ###### ##
+## a ###### b ##
+## ##
+## b ###### a ##
+## ###### ##
+## a ###### b ##
+## ###### ##
+## ###### ##
+## ###### ##
+## ###### ##
+## ###### ##
+## ###### ##
+## ###### ##
+## ###### ##
+## ###### ##
+########## ###### ##########
+""" # [] [] [] # """
+
+ winds = """
+>> <<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>> <<<
+>>> <<<
+>>> <<<
+>>> <<<
+>>> <<<
+>>> <<<
+>>> <<<
+>>> <<<
+>>> <<<
+>>> <<<
+>>> <<<
+>>> <<<
+>>> xxxx <<<
+>>> <<<
+>>> <<<
+>>> <<<
+>>> <<<
+>>> <<<
+>>> <<<
+>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<
+>> <<
+"""
+
+
+class level14(boarddef.Level):
+ letter = 0
+ fire = 0
+ lightning = 0
+ water = 0
+ top = 0
+
+ a = RSpringy
+ b = ()
+
+ walls = """
+####################################
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+###a # # #a # ##
+## # # #a # #a # # # # ##
+## # # # # # # # # # ##
+## ## ## ## ## ###
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+####################################
+""" # [] [] [] # """
+
+ winds = """
+>> <<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>> <<
+"""
+
+
+class level15(boarddef.Level):
+ letter = 0
+ fire = 0
+ lightning = 0
+ water = 1
+ top = 0
+
+ f = LFlappy
+ b = RBlitzy
+ a = LOrcy, RMonky
+ g = RGramy
+ h = LGhosty
+ n = LNasty
+ s = LSpringy
+
+ walls = """
+############# ###### f f #########
+## a #b f f f ##
+## # ###### #### #######
+## # a a # # ##
+## ####### ## # # g ##
+## # # # # ##
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+## # n n # n # ##
+## # #### ### ##
+## # # ##
+## s # # ##
+## s # h # ##
+## # # s # h # ##
+## # s # # ##
+## # #### ## # ##
+## # # ##### ### ## ##
+## # # ##
+## # b # ##
+## #### ##
+## ##
+## ##
+## ###### ##
+## # # ##
+## # # ##
+############# ###### f #########
+""" # [] [] [] # """
+
+ winds = """
+>> <<
+>>>>>>>>>>>>>>>>>>vvvv<<<<<<<<<<<<<<
+>>^ vvvv x<<
+>>^ >vvvv< ^<<
+>>^ > xxxx < ^<<
+>>^ >>>>vvv<<< ^<<
+>>^ vv< >>>>>>>>>^<<
+>>^ xx ^ ^<<
+>>^ ^ ^<<
+>>^ ^ ^<<
+>>^ >^ ^<<
+>>^ ^< >^ ^<<
+>>^ ^<<<<<<<>>>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^< ^<<
+>>^ ^< xx ^<<
+>>^ ^ ^^<<<<<<<<<<<< ^<<
+>>^ ^ ^ ^<<
+>>^ ^< >^ ^<<
+>>^ ^<<>>^ ^<<
+>>^ ^<<
+>>^ ^^^^^^ ^<<
+>>^ ^<>vvvv<>^ ^<<
+>>^ ^<>vvvv<>^ ^<<
+>> ^<>vvvv<>^ <<
+"""
+
+
+class level16(boarddef.Level):
+ letter = 1
+ fire = 1
+ lightning = 1
+ water = 0
+ top = 1
+
+ a = LGhosty, RGhosty
+
+ walls = """
+## # ##
+## ## ## ##
+## a a ###### ##
+## ###### # ##
+## ######### ##
+## ############ ##
+## # # ########## a ##
+## a ### ######## ##
+## #### ### ####### ##
+## ######### ### a ##
+## ######### ### # ##
+## ############## ##
+## ############## ##
+## ####### ###### ##
+## ###### ###### a ##
+## ##### ##### ##
+## #### #### a ##
+## ##### ### ##
+## ########### a ##
+## a ### #### ##
+## ## ###### ##
+## ## ##### ##
+## #### ## ##
+## ####### ##
+## ##### ##
+## # #### ##
+## ##
+####################################
+""" # [] [] [] # """
+
+ winds = """
+>> <<
+>>>>>>>>vvvvvvvvvvvvvvvvvvvv<<<<<<<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>> <<
+"""
+
+
+class level17(boarddef.Level):
+ letter = 1
+ fire = 1
+ lightning = 0
+ water = 1
+ top = 0
+
+ a = LGhosty, RFlappy
+
+ walls = """
+## ##### # ##
+## ######## # ##
+## ####### a # # ##
+## ####### # # ##
+## ###### a ## # ##
+## ##### ## # ##
+## ###### # a ### # ####
+## ##### # # ####
+## ########### ####### # #####
+## #### ##### # ## #### # #####
+## #### ###### ### ### # # ###
+## ## # ## # ## ###### # ####
+## ### # ### ## # ####
+## ### ## #### # ## ####
+## ### a ## ### # # ###
+## ### ## ### ## # ###
+## ### ## ### a ## # ###
+## #### # ## ### # ###
+## #### # ### ### # ##
+## ### ### #### # ##
+## #### a ## # #### ##
+## ### ####### ###
+### ### ############ ## # ###
+### ## ########### #### ##
+### ### ### ########## ##
+### ### ################ ##
+## ## ############# ##
+### # ####### ##
+"""
+
+
+class level18(boarddef.Level):
+ letter = 1
+ fire = 0
+ lightning = 0
+ water = 1
+ top = 0
+
+ b = LBlitzy, RBlitzy
+ a = LOrcy
+
+ walls = """
+################# #################
+## # ## ## # ##
+## # ## ## # ##
+## # b b ## ## b b # ##
+## # ####### ####### # ##
+## #b # a #b # ##
+## ## #### ## ##
+## # a # ##
+## # # ##
+## a ##
+## #### ##
+## #a # ##
+## # # ##
+## a ##
+## #### ##
+## # a # ##
+## # # ##
+## a ##
+## #### ##
+## #a # ##
+## # # ##
+## a ##
+## #### ##
+## # a # ##
+## ## ## ##
+## ## ## ##
+## ## ## ##
+################# #################
+""" # [] [] [] # """
+
+ winds = """
+>> <<
+>>>>>>>>>>>>>>>>>^^<<<<<<<<<<<<<<<<<
+>>^ ^<<
+>>^ ^<<
+>>^ > ^^ < ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>> <<
+"""
+
+
+class level19(boarddef.Level):
+ letter = 0
+ fire = 0
+ lightning = 0
+ water = 0
+ top = 0
+
+ a = LNasty
+ b = LMonky
+ c = LOrcy
+ d = LGramy
+
+ walls = """
+####################################
+####################################
+####################################
+####################################
+####################################
+####################################
+####################################
+####################################
+## ##
+## # # ##
+## # # ##
+## # # # # ##
+## # # # # ##
+## # # # # ##
+## # # # # # # ##
+## # # # # # # ##
+## # # # # # # ##
+## # # # # # # ##
+## # # # # # # # # ##
+## # # # # # # # # ##
+## # # # # # # # # ##
+## # # # # # # # # ##
+## # # # # # # # # ##
+## # # # # # # # # ##
+## # # # # # # # # ##
+## # # # # # # # # ##
+## #a #b #c #d #c #b #a # ##
+####################################
+""" # [] [] [] # """
+
+ winds = """
+>>xxxxxxxxx>>>>xxxxxx<<<<xxxxxxxxx<<
+>>^ >>> ^ ^<<
+>>^ ^ <<< ^<<
+>>^ ^<<
+>>^ >> << ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>> <<
+"""
+
+
+class level20(boarddef.Level):
+ letter = 1
+ fire = 0
+ lightning = 0
+ water = 0
+ top = 1
+
+ a = RGhosty
+ b = RNasty
+ c = LSpringy
+ d = LFlappy
+
+ walls = """
+## ## # # # ##
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+## ### # # ## ##
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+## ## # # # ### ##
+## # # ##
+## # a d d d # ##
+## # a # ##
+## # a c # ##
+## # c # ##
+## # b b b c # ##
+## ### # # # ## ##
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+## ## # # ### ##
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+################ # # ###############
+""" # [] [] [] # """
+
+ winds = """
+>>v v< v v v>v v<<
+>>v v<v>vxvv>v v<<
+>>v v<vvvvvv>v v<<
+>>v v<vvvvvv>v v<<
+>>v v<>v>v<v>v v<<
+>>v v<< v x <>>v v<<
+>>v v<vvvvvvvv>v v<<
+>>v v<vvvvvvvv>v v<<
+>>v v<vvvvvvvv>v v<<
+>>v v<v<v<v<v<>v v<<
+>>v v<<v x x v >>v v<<
+>>v v<vvvvvvvvvv>v v<<
+>>v v<vvvvvvvvvv>v v<<
+>>v v<vvvvvvvvvv>v v<<
+>>v v<vvvvvvvvvv>v v<<
+>>v v<vvvvvvvvvv>v v<<
+>>v v<>>v<v<v<<<>v v<<
+>>v v<< v x x v>>v v<<
+>>v v<v>>vvvvv>v v<<
+>>v v<vvvvvvvv>v v<<
+>>v v<vvvvvvvv>v v<<
+>>v v<>v>v<v<<>v v<<
+>>v v<<v x < >>v v<<
+>>v v<vvvvvv>v v<<
+>>v v<vvvvvv>v v<<
+>>v v<vvvvvv>v v<<
+>>v v<>v>v<v>v v<<
+>> v< v v v>v <<
+"""
+
+
+class level21(boarddef.Level):
+ letter = 0
+ fire = 0
+ lightning = 0
+ water = 0
+ top = 0
+
+ s = LSpringy, LSpringy
+ f = LFlappy, LFlappy
+ g = RGhosty, RGhosty
+
+ walls = """
+########### ## ##########
+## ## s ## ##
+## ##f ## ## ##
+## ## ## ## ##
+## ## ## s ## ##
+## # ## ##
+## ## s ## ##
+## ## #### ##
+## ## ## ## ##
+## ## s ## ## ##
+## ## ## ## ##
+## ## ## ## ##
+## ## s ## ## ##
+## ## ## ## ##
+## ## ## ## ##
+## ##s g ## ##
+## ## ## ## ##
+## ## ## ## ##
+## ## ## f ## ##
+## # ## ##
+## ## g ## ##
+## ## #### ##
+## ## ## ## ##
+## ## f ## ## ##
+## ## ## ## ##
+## ## ## ## ##
+## ## g ## ## ##
+########### ## ##########
+""" # [] [] [] # """
+
+
+class level22(level21):
+ water = 1
+ letter = 1
+
+ s = RBlitzy, RBlitzy
+ f = LOrcy, LOrcy
+ g = LGramy, LGramy
+
+
+class level23(boarddef.Level):
+ letter = 1
+ fire = 1
+ lightning = 1
+ water = 1
+ top = 0
+
+ a = LNasty
+ b = RMonky
+ c = LGramy
+ d = ROrcy
+ s = LSpringy
+
+ walls = """
+## ##
+## ### ####### ############## # ##
+## # # a # b # # # ##
+## # ### # ### # ##### # ### # ##
+## #d # # # # # # c # # # ##
+## ### # # # ### # ##### ### # ##
+## # # # # s # # d # # ##
+## ### # # ### #### ####### ### ##
+## #c # # # # a # # ##
+## ### # ### # ########## ### # ##
+## # # # # # # # b # c # # ##
+## # ### # ### # ### ### ### # ##
+## # b # #s # # # ##
+## # ####### # ######## # ##### ##
+## # # a # # # a # d # ##
+## ### ##### ### # ##### ### # ##
+## # d # # # b # # # ##
+## ### # ####### # ##### # ### ##
+## # # # cs # # # # ##
+## ### ### ######## # ### ### # ##
+## # # # b # # #c # # ##
+## # ### # ##### ##### # ### # ##
+## # d # # # # # # ##
+## ### # # # # ########## ### # ##
+## # # # # # a # # # ##
+## # ####### ################ # ##
+## ##
+####################################
+"""
+
+
+class level24(boarddef.Level):
+ letter = 0
+ fire = 0
+ lightning = 0
+ water = 0
+ top = 0
+
+ n = LOrcy
+ a = RGhosty, LFlappy
+
+ walls = """
+####################################
+## ## ## # # # # # # # ### ##
+## ## # # # # # # # ## # # # ##
+## ## ### # #a # n # # # ##
+## ## # # a #a # ## # ### ##
+## ## # a # ### ##
+###### # # #a # ########
+###### n #a # # ######
+##### # # # #######
+####### # n #####
+#### # # #######
+##### #a ####
+##### # # # #######
+##### # # ####
+#### # # #####
+###### # # #####
+#### # # ### ####
+####### # ######
+##### # # # # #####
+##### ## # # ######
+####### # # # # # #######
+####### # # # # ######
+######## # # # # # # ########
+######## ## # # # # #########
+########## # # # # # ## ##########
+## ###### # # # # # ###### ##
+## ##
+####################################
+"""
+
+ winds = """
+>> <<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>^ > xx < ^<<
+>>^ > xx < ^<<
+>>^ > xxx x < ^<<
+>>^ > xxx xxx < ^<<
+>>^ > x x< ^<<
+>>^ >x ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>> <<
+"""
+
+
+class level25(boarddef.Level):
+ letter = 0
+ fire = 0
+ lightning = 0
+ water = 0
+ top = 0
+
+ b = RGhosty
+ a = LGhosty
+
+ walls = """
+####################################
+## ##
+## ##
+## ####################### ##
+## # ##
+## a a a a a a # ##
+## ################## # ##
+## # # # ##
+## # a a a a a a #b # ##
+## # ########## # ## ##
+## # # # # # ##
+## #b #a a a #b # # ##
+## ## # ##### ## # ##
+## # # # # ##
+## # # b b b b #b # ##
+## # ########### ## ##
+## # # # ##
+## #b b b b b b # ##
+## ###### b ###### ##
+## ####### ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+####################################
+""" # [] [] [] # """
+
+
+class level26(boarddef.Level):
+ letter = 0
+ fire = 0
+ lightning = 0
+ water = 0
+ top = 0
+
+ n = LNasty
+ m = RNasty
+ a = LGramy
+ g = LGhosty
+
+ walls = """
+## ####### ####### ##
+## ### ########## ### ##
+## g ## ## g ##
+##n m n m n ########## m n m n m ##
+############### ###############
+## ################ ##
+## #### #### ##
+## ############ ##
+## ###### ## ## ###### ##
+## ### ######### ### ##
+## ### # ## ### ##
+##nmnmnm ### ########## ###mnmnmn ##
+###############nmnmn ###############
+##### ################ #####
+############# #############
+## ## ## ## ## ##
+## ####### ####### ##
+## # ################ # ##
+## ########### ########### ##
+## # # ############ # # ##
+## ####### ## ## ####### ##
+## # m n # ######## # n m # ##
+## ####### # # ####### ##
+## ######## ##
+## # m # ##
+## ######## ##
+## ##
+####################################
+""" # [] [] [] # """
+
+
+class level27(boarddef.Level):
+ letter = 1
+ fire = 1
+ lightning = 1
+ water = 0
+ top = 0
+
+ n = LNasty
+ m = RMonky
+
+ walls = """
+########### ###### # ##
+## # # ##
+## ######### # # n ##
+## # ###########
+## # nnn ##
+## ######### ##
+## ##
+## nnn # ##
+## ####### ## # ##
+## # # ##
+## # # ##
+## #nnn mmmm # # m ##
+## ##### ###### ###########
+## ##
+## ##
+## ####### ##
+## ### # ##
+## # # ##
+## nnn # # n ##
+## ###### ###########
+## ##
+## #mmmmmm ##
+## ######## ##
+## ##
+## ######## ### # ##
+## # # ##
+## nnn # # ##
+########### ###### ###########
+""" # [] [] [] # """
+
+
+class level28(boarddef.Level):
+ letter = 0
+ fire = 0
+ lightning = 0
+ water = 1
+ top = 1
+
+ m = LMonky
+ g = LGramy
+ h = LGhosty
+ f = LFlappy
+ b = LSpringy
+ a = RSpringy
+
+ walls = """
+## # # ##
+## b # #a ##
+## b # #a ##
+## ##### ##### ##
+## # # ##
+## # # ##
+## # # ##
+## # # ##
+## ##
+## ##
+## ##
+## # # ##
+###### ##### # # # # # ##
+## m m m # # ##
+## ######### # # h f h f ##
+## g g g # # ##
+####### ###### # h f ##
+## m m m # # f ##
+## ########### # # h h h ##
+## g g g # # f f ##
+######## ####### # # # # # # # ##
+## ##
+## ##
+## ##
+####### ##### ## ##### #######
+## # ## # ##
+## # # ##
+################# #################
+""" # [] [] [] # """
+
+ winds = """
+>>v v<<
+>>v v<<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>> <<
+"""
+
+class level29(boarddef.Level):
+ letter = 0
+ fire = 0
+ lightning = 0
+ water = 0
+ top = 0
+
+ m = LMonky, RMonky
+ g = LGramy, RGramy
+ o = LOrcy, ROrcy
+ n = LNasty, RNasty
+
+ walls = """
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+################# #################
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## # m g o nn o g m # ##
+## ######################## ##
+## ##
+""" # [] [] [] # """
+
+ winds = """
+vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+>> <<
+>> <<
+>> <<
+>> <<
+>> <<
+>> <<
+>> <<
+>> <<
+>>xxxxxxxxxxxxxxx xxxxxxxxxxxxxxx<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>x>>>>v>>>>v<>v<<<<v<<<<x<<<<<<
+vvvvvvxxxxxxxxxxxxxxxxxxxxxxxxvvvvvv
+vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+"""
+
+class level29(boarddef.Level):
+ letter = 0
+ fire = 0
+ lightning = 0
+ water = 0
+ top = 1
+
+ a = LNasty
+ b = RNasty
+ g = RGhosty
+ r = RGramy
+ m = LMonky
+
+ walls = """
+## ############################
+## ##
+##### ##
+##### ##
+##### ##
+##### ##
+##### # ##
+##### a b a ba ab a ba # ##
+################################ ##
+## ##
+## ##
+## ## g ##
+## ## ##
+## ## ##
+## ## ##
+## ## ##
+## ## br a rb a rb a r a ##
+## #############################
+## ## ##
+## ## ## ## ##
+##### ## mm ##mm ## ##
+############################## ##
+##### ## ## ## ##
+##### ## ## ##
+##### ##
+## ##
+## ##
+## ################################
+""" # [] [] [] # """
+
+ winds = """
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv ^<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv ^<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv ^<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv ^<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv ^<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv ^<<
+>>vv>>>>>>>>>>>>>>>>>>>>>>>>>>>> v<<
+>>vv <<
+>>vv <<
+>>vv vvvvvvvvvvvvvvvvvvvvvv <<
+>>vv vvvvvvvvvvvvvvvvvvvvvv <<
+>>vv vvvvvvvvvvvvvvvvvvvvvv <<
+>>vv vvvvvvvvvvvvvvvvvvvvvv <<
+>>vv vvvvvvvvvvvvvvvvvvvvvv <<
+>>vv vvvvvvvvvvvvvvvvvvvvvv <<
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>> <<
+"""
+
+
+class level30(boarddef.Level):
+ letter = 1
+ fire = 1
+ lightning = 1
+ water = 0
+ top = 1
+
+ a = RNasty
+
+ walls = """
+####################################
+####################################
+## ##### ## ##### ##
+## a ##### a ## a ##### a ##
+####################################
+####################################
+####################################
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+###### ######
+## ##
+## ##
+## ##
+## ##
+####################################
+""" # [] [] [] # """
+
+ winds = """
+>> <<
+>> <<
+>>>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx<<<
+>>>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx<<<
+>>>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx<<<
+>>>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx<<<
+>>> <<<
+>>>>>>>>>>>>>>>>>vv<<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>>vv<<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>>vv<<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>>vv<<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>>vv<<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>>vv<<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>>vv<<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>>vv<<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>>vv<<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>>vv<<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>>vv<<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>>vv<<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>>vv<<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>>vv<<<<<<<<<<<<<<<<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>> <<
+"""
+
+
+class level31(level30):
+ fire = 0
+ lightning = 0
+
+
+class level32(boarddef.Level):
+ n = LNasty
+ m = LMonky
+ o = LOrcy
+ g = LGramy
+ h = LGhosty
+ f = LFlappy
+ s = LSpringy
+ b = LBlitzy
+
+ walls = """
+#################### ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ########
+## ##
+## ##
+## # ##
+## ####### ##
+## ##
+## ##
+## # ##
+## ####### ##
+## ##
+## ##
+## ##
+## # # ##
+## # # # ##
+## # # # n ##
+## # # ######
+## # # # ##
+## # # # n n ##
+## # #########
+## # ##
+## # ##
+#################### ##
+""" # [] [] [] # """
+
+ winds = """
+>>>>>>>>>>>>>>>>xxxx<<vvvvvvvvvvvv>v
+>>^ ^<<vvvvvvvvvv>v
+>>^ ^<<vvvvvvvv>v
+>>^ ^<<vvvvvv>v
+>>^ ^<<vvvv>v
+>>^ ^<<<<<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ vvvvvvvvvvvvvv>v
+>>^ vvvvvvvvvvvvvv>v
+>> vvvvvvvvvvvvvv>v
+"""
+
+
+class level33(boarddef.Level):
+ m = LMonky, RMonky
+ g = LGramy, RGramy
+ o = LOrcy, ROrcy
+ n = LNasty, RNasty
+
+ walls = """
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+################# #################
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ##
+## ## m g o nn o g m ## ##
+## ######################## ##
+## ##
+""" # [] [] [] # """
+
+ winds = """
+v<vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv>v
+v<vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv>v
+v<vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv>v
+v<vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv>v
+>> <<
+>> <<
+>> <<
+>> <<
+>> <<
+>> <<
+>> <<
+>> <<
+>>xxxxxxxxxxxxxxx xxxxxxxxxxxxxxx<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>v>>>>v>>>>v<>v<<<<v<<<<v<<<<<<
+>>>>>>x>>>>v>>>>v<>v<<<<v<<<<x<<<<<<
+v<vvvvxxxxxxxxxxxxxxxxxxxxxxxxvvvv>v
+v<vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv>v
+"""
+
+
+class level34(boarddef.Level):
+ letter = 0
+ fire = 0
+ lightning = 0
+ water = 0
+ top = 1
+
+ a = RBlitzy
+ b = LBlitzy
+
+ walls = """
+## # ## # ## # ## # ##
+## ## # ba # ## ##
+## ### b#### #### ### ##
+## # # # # b # # ##
+## #### # # #### ##
+## #######b # # ####### ##
+## # # #b # ##
+## # # # # ##
+## # # # # ##
+## #b # # # ##
+## # # #b # ##
+## # # ##
+## # # # # ##
+## #b # # # ##
+## # # #b # ##
+## # # # # ##
+## # # # # ##
+## #b # # # ##
+## # # #b # ##
+## # # # # ##
+## # # # # ##
+## #b # # # ##
+## # # #b # ##
+## ####### # # ####### ##
+## #### # # #### ##
+## #### #### #### #### ##
+## #### b #### ##
+## ## # # ## ##
+""" # [] [] [] # """
+
+ winds = """
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>xxxxxvvvvvvvvvvvvvvvvvvvvvvxxxxx<<
+"""
+
+
+class level35(boarddef.Level):
+ s = LNasty
+ o = LNasty, LNasty, RNasty, RNasty
+ a = RBlitzy
+ b = LBlitzy
+
+ walls = """
+####################################
+## ###s ### ##
+##s ## b ######## a ##s ##
+####################################
+## ##
+## ##
+## ##
+## ## ##
+## #### ##
+## ######## ##
+## ############ ##
+## ###### ##
+## ########## ##
+## ################ ##
+## ########## ##
+## ############## ##
+## ################## ##
+## ## ##
+## ## ##
+## #### ##
+## ###### ##
+## ## ## ## ##
+## ## ## ## ##
+## ##
+## ##
+## ##
+## #o o o o o o o o o o o o # ##
+####################################
+""" # [] [] [] # """
+
+ winds = """
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<
+>>>>>>>>>>>>>> <<<<<<<<<<<<<<
+>>>>>>>>>>>>> <<<<<<<<<<<<<
+>>>>>>>>>>>> <<<<<<<<<<<<
+>>>>>>>>>>> <<<<<<<<<<<
+>>>>>>>>>> <<<<<<<<<<
+>>>>>>>>> <<<<<<<<<
+>>>>>>>> <<<<<<<<
+>>>>>>> <<<<<<<
+>>>>>> <<<<<<
+>>>>> <<<<<
+>>>> <<<<
+>>> <<<
+>>vv<<<<<<<<<<<<<<>>>>>>>>>>>>>>vv<<
+>>vv<<<<<<<<<<<<<<>>>>>>>>>>>>>>vv<<
+>>vv<<<<<<<<<<<<<<>>>>>>>>>>>>>>vv<<
+>>vv<<<<<<<<<<<<<<>>>>>>>>>>>>>>vv<<
+>>vv<<<<<<<<<<<<<<>>>>>>>>>>>>>>vv<<
+>>vv<<<<<<<<<<<<<<>>>>>>>>>>>>>>vv<<
+>>vv<<<<<<^^^^^^^^^^^^^^^^>>>>>>vv<<
+>>vv<<<<^^^^^^^^^^^^^^^^^^^^>>>>vv<<
+>>xx<<^^^^^^^^^^^^^^^^^^^^^^^^>>xx<<
+>>xx<<<<<<<<<<<<<<>>>>>>>>>>>>>>xx<<
+"""
+
+
+class level36(boarddef.Level):
+ s = LSpringy
+ b = LBlitzy
+
+ walls = """
+## b b ##
+## s ##
+## b b ##
+## s ##
+## b b ##
+## s ##
+## b b ##
+## s ##
+## b b ##
+## s ##
+## b b ##
+## s ##
+## b b ##
+## s ##
+## b b ##
+## s ##
+## b b ##
+## s ##
+## b b ##
+## s ##
+## b b ##
+## s ##
+## b b ##
+## s ##
+## b b ##
+## s ##
+## b b ##
+## s ##
+""" # [] [] [] # """
+
+ winds = """
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>>>>>>>>>>>>>>>xxxx<<<<<<<<<<<<<<<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>>^ ^<<
+>> <<
+"""
+
+
+class level37(boarddef.Level):
+ n = LNasty
+ m = LMonky
+
+ walls = """
+################# #################
+## m m m m m # ## #m m m m m ##
+## #n n n n n # #n n n n n # ##
+################# #################
+## ####### ####### ##
+## ################ ##
+## ############################ ##
+## # #### #### # ##
+## #### ##### ##### #### ##
+## #### ################ #### ##
+## #### ################ #### ##
+## ######### ######### ##
+## ### ############## ### ##
+## #### # ############ # #### ##
+## #### ############ #### ##
+############ #### ############
+############ ## ############
+## # ## ## # ##
+## ############ ############ ##
+## # ##### ##### # ##
+## ############################ ##
+## ############################ ##
+## ######## ######## ##
+######## ## ## ########
+######## # #### # ########
+## # #### # ##
+## ## ### ### ## ##
+###### ################ ######
+""" # [] [] [] # """
+
+ winds = """
+>>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<<
+>>xx<<<<<<<<<<<<<<>>>>>>>>>>>>>>xx<<
+>>xx^^^^^^^^^^^^^^^^^^^^^^^^^^^^xx<<
+v<vv>>>>vvvvvvvvvvvvvvvvvvvv<<<<vv>v
+v<vv>>>>vvvvvvvvvvvvvvvvvvvv<<<<vv>v
+v<vv>>>>vvvvvvvvvvvvvvvvvvvv<<<<vv>v
+v<vv>>>>vvvvvvvvvvvvvvvvvvvv<<<<vv>v
+v<vv>>>>vvvvvvvvvvvvvvvvvvvv<<<<vv>v
+v<vv>>>>vvvvvvvvvvvvvvvvvvvv<<<<vv>v
+v<vv>>>>vvvvvvvvvvvvvvvvvvvv<<<<vv>v
+v<vv>>>>vvvvvvvvvvvvvvvvvvvv<<<<vv>v
+v<vv>>>>vvvvvvvvvvvvvvvvvvvv<<<<vv>v
+v<vv>>>>vvvvvvvvvvvvvvvvvvvv<<<<vv>v
+v<vvvv<>vvvvvvvvvvvvvvvvvvvv<>vvvv>v
+v<vvvv>>vvvvvvvvvvvvvvvvvvvv<<vvvv>v
+v<vv>vvvvvvvvvvvvvvvvvvvvvvvvvv>vv>v
+v<vv>vvvvvvvvvvvvvvvvvvvvvvvvvv>vv>v
+v>vv<vvvvvvvvvvvvvvvvvvvvvvvvvv>vv<v
+v>vv<vvvvvvvvvvvvvvvvvvvvvvvvvv>vv<v
+v>vv<vvvvvvvvvvvvvvvvvvvvvvvvvv>vv<v
+v>vv<vvvvvvvvvvvvvvvvvvvvvvvvvv>vv<v
+v>vv<vvvvvvvvvvvvvvvvvvvvvvvvvv>vv<v
+v>vv<vvvvvvvvvvvvvvvvvvvvvvvvvv>vv<v
+v>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<v
+v>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<v
+v>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<v
+v>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<v
+v>vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv<v
+"""
+
+class level38(boarddef.Level):
+ g = RGhosty
+
+ walls = """
+####################################
+## # ##
+## g # g ##
+## # ##
+## # g ##
+## # ##
+## ### ##### ## ##
+## ### ######## ## ##
+## #### ### ###### ##
+## ### ### ####### ### ##
+## ## ########## ##
+## # ######## ##
+## # g ##
+## g ########## ##
+## ########### ##
+## ########## ## ##
+## ############ ## ##
+## ### ############ ## ##
+## #### ########## ### ##
+## ##### ######## ## ##
+## #### ###### ##
+## ##### ##
+## ######## ##
+## ##
+## ##
+## ##
+## ##
+####################################
+"""
+
+
+class levelFinal(boarddef.Level):
+
+ walls = """
+################ ################
+## ##
+## ##
+## ### ### ##
+## ##
+## ### ### ##
+## ##
+## ### ### ##
+## ##
+## ### ### ##
+## ##
+##### #####
+## ##
+## ### ### ##
+## ##
+## ### ### ##
+## ##
+## ### ### ##
+## ##
+## ### ### ##
+## ##
+####################################
+## ##
+## ##
+## ##
+## ##
+## ##
+################ ################
+""" # [] [] [] # """
+# nb.: the previous line has no purpose
+# other than helping with wall alignment
+
+ winds = """
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>>>>>>>>>>>>>>>>^^^^<<<<<<<<<<<<<<<<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+>> ^^^^ <<
+"""