commit da08927a85bbaf51133c1a1781733e88b22e6ccc
Author: Antoine Amarilli <ant.amarilli@free.fr>
Date: Sat, 19 Dec 2009 04:08:25 +0100
Added files.
Diffstat:
level | | | 27 | +++++++++++++++++++++++++++ |
level2 | | | 134 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
level2.best | | | 10 | ++++++++++ |
levelb | | | 30 | ++++++++++++++++++++++++++++++ |
levelc | | | 26 | ++++++++++++++++++++++++++ |
leveld | | | 42 | ++++++++++++++++++++++++++++++++++++++++++ |
levele | | | 26 | ++++++++++++++++++++++++++ |
main.py | | | 423 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
8 files changed, 718 insertions(+), 0 deletions(-)
diff --git a/level b/level
@@ -0,0 +1,27 @@
+2
+2
+0
+1
+5
+5
+##### Level syntax tips
+#@ # First line is number of block lines
+###% Second line is number of block cols
+#* % Third line is line position of empty block
+##### Fourth line is col position of empty block
+ Fifth line is width of blocks
+ Sixth line is height of blocks
+ Following lines are description of blocks one after the other
+ Blocks will be assigned left to right and then top to bottom
+ (ie. give the blocks for the first line, then second line, etc.)
+##### If there are too many characters on a line, they get ignored
+# %% You can use this to write comments (like these)
+ % # The following sprites are allowed:
+ %# # - ' ' is empty space (player falls thru, can walk thru)
+##### - '#' is a wall (player can walk over, can't pass thru)
+##### - '%' is a ladder (player can walk over, can climb over)
+ ^# - '*' is a key (collect all to open the exit
+#%### - '^' is an exit (reach any with all keys to win)
+#% *# - '@' is the player's start position (only one allowed, will be empty space when player leaves it)
+##### PS: you must give a block description for the empty block, it
+ will be ignored
diff --git a/level2 b/level2
@@ -0,0 +1,134 @@
+4
+4
+3
+3
+8
+8
+ ##
+ ##
+ @ ## ^
+ # ## #
+ ##
+ ##
+ ##
+ ## end
+ ##
+ #
+ #####
+
+
+
+
+ ## end
+
+
+
+
+### ###
+### ###
+
+ end
+ ##
+ ##
+ ##
+ ##
+ ## ##
+ ## ##
+ ##
+ ## End
+ ##
+ ##
+ *##
+ ###
+ ## #
+ ##
+ ##
+ ## end
+
+
+
+ %%%%##
+#
+#
+
+ end
+
+
+
+ ##%%%%
+ #
+ #
+
+ end
+ ##
+ ##
+ ##
+ ##
+########
+########
+
+ End
+
+
+ % %
+ # # ##
+
+
+
+ end
+ ##
+
+###
+ #
+ ######
+ ######
+
+ end
+
+
+ % %
+ # # ##
+
+
+
+ end
+ ##
+ ##
+ ##
+ ##
+## ##
+## ##
+ ##
+ ## End
+
+
+
+
+######
+######
+
+ end
+ ##
+ ##
+ ##
+ ##
+ ## ##
+ ## ##
+ ##
+ ## end
+
+ *
+ %##%
+ %####%
+ ######
+
+
+ END
+ BLANK
+ BLANK
+ BLANK
+ BLANK
+ BLANK
+ BLANK
+ BLANK
+ BLANK
diff --git a/level2.best b/level2.best
@@ -0,0 +1,10 @@
+ Your score was:
+ Moves: 14
+ Dist: 62
+ Swaps: 55
+
+
+Your score was:
+ Moves: 20
+ Dist: 52
+ Swaps: 79
diff --git a/levelb b/levelb
@@ -0,0 +1,30 @@
+2
+2
+0
+1
+6
+6
+######
+# @
+######
+#
+# ^
+######
+
+
+
+
+
+
+######
+
+######
+ ###
+
+######
+######
+ ##
+# ## #
+# ## #
+ ##
+######
diff --git a/levelc b/levelc
@@ -0,0 +1,26 @@
+2
+2
+1
+1
+5
+5
+#####
+# @#
+# ##
+# #
+### #
+### #
+# #
+# ###
+# #
+# # #
+# # #
+# ^ #
+ ####
+#
+#####
+
+
+
+
+
diff --git a/leveld b/leveld
@@ -0,0 +1,42 @@
+2
+3
+1
+2
+6
+8
+## #####
+## @ #
+##### #
+##### #
+## #
+## #####
+### # ##
+ # # ##
+### # ##
+ # #
+ #### #
+## ## #
+## #####
+##
+########
+ #
+ #
+### # ##
+## ## #
+## #
+###### #
+## #
+## ^ #
+## #####
+########
+ ####
+### ####
+ #
+ #
+## #####
+
+
+
+
+
+
diff --git a/levele b/levele
@@ -0,0 +1,26 @@
+2
+2
+1
+0
+5
+10
+
+
+
+
+ #
+
+
+ ^
+@
+#
+
+
+
+
+
+#
+
+
+
+
diff --git a/main.py b/main.py
@@ -0,0 +1,423 @@
+#/usr/bin/python
+
+
+import sys
+import curses
+
+
+class Square:
+ wall, ladder, empty, exit, player, blank, key = range(7)
+ asciiMap = {wall: '#', ladder:'%', empty:' ', exit:'^', player:'@', blank:'!', key:'*'}
+
+ def __init__(self, parent, type, pos):
+ self.parent = parent
+ self.type = type
+ self.pos = pos
+
+ def getNeighbour(self, dir):
+ return self.parent.getSquare((self.pos[0] + dir[0], self.pos[1] + dir[1]))
+
+ def getType(self):
+ return self.type
+
+ def setType(self, type):
+ self.type = type
+
+ def render(self, pad, x, y):
+ if (self.parent.parent.getPlayer().getPos() == self):
+ self.parent.parent.getPlayer().setGraphPos((x + self.pos[0],y + self.pos[1]))
+ c = '@'
+ mode = curses.A_BOLD + curses.A_BLINK + curses.color_pair(1)
+ else:
+ if (self.parent.parent.getPlayer().getPos().getParent() == self.parent):
+ mode = curses.A_BOLD
+ else:
+ mode = 0
+ c = Square.asciiMap[self.type]
+ if (c == '^'):
+ if (self.parent.parent.keysLeft() == True):
+ mode = curses.A_BOLD + curses.color_pair(8)
+ else:
+ mode = curses.A_BOLD + curses.color_pair(2)
+ if (c == '%'): mode = curses.color_pair(3)
+ if (c == '#'): mode = curses.color_pair(4)
+ if (c == '!'):
+ mode = curses.color_pair(5)
+ pad.addch( x + self.pos[0],y + self.pos[1], c, mode)
+ c = ' '
+ if (c == '*'): mode = curses.A_BOLD + curses.color_pair(2)
+ try:
+ pad.addch( x + self.pos[0],y + self.pos[1], c, mode)
+ except curses.error:
+ pass
+
+ def getParent(self):
+ return self.parent
+
+
+class Block:
+ left, right, top, bottom = range(4)
+ def __init__(self, parent, h, w, pos):
+ self.parent = parent
+ self.h = h
+ self.w = w
+ self.pos = pos
+ self.map = []
+ for i in range(0, h):
+ self.map.append([])
+ for j in range(0, w):
+ self.map[i].append(Square(self, 0, (0, 0)))
+
+ def getBorder(self, t):
+ a = []
+ if (t == Block.left):
+ for i in range(0, self.h):
+ a.append(self.getSquare((i,0)).getType())
+ if (t == Block.right):
+ for i in range(0, self.h):
+ a.append(self.getSquare((i, self.w-1)).getType())
+ if (t == Block.top):
+ for i in range(0, self.w):
+ a.append(self.getSquare((0, i)).getType())
+ if (t == Block.bottom):
+ for i in range(0, self.w):
+ a.append(self.getSquare((self.h-1, i)).getType())
+ return a
+
+ def getNeighbour(self, dir):
+ return self.parent.getBlock((self.pos[0] + dir[0], self.pos[1] + dir[1]))
+
+ def setSquare(self, x, y, s):
+ self.map[x][y] = s
+
+ def getSquare(self, p):
+ x = p[0]
+ y = p[1]
+ if (x < 0):
+ a = self.getNeighbour((-1, 0))
+ if (self.getBorder(Block.top) != a.getBorder(Block.bottom)):
+ return BlockSentry(self.parent, 0, 0, (0, 0)).getSquare((0,0))
+ return a.getSquare((a.getH() + p[0], p[1]))
+ elif (y < 0):
+ a = self.getNeighbour((0, -1))
+ if (self.getBorder(Block.left) != a.getBorder(Block.right)):
+ return BlockSentry(self.parent, 0, 0, (0, 0)).getSquare((0,0))
+ return a.getSquare((p[0], a.getW() + p[1]))
+ elif (x >= self.getH()):
+ a = self.getNeighbour((1, 0))
+ if (self.getBorder(Block.bottom) != a.getBorder(Block.top)):
+ return BlockSentry(self.parent, 0, 0, (0, 0)).getSquare((0,0))
+ return a.getSquare((p[0] - self.getH(), p[1]))
+ elif (y >= self.getW()):
+ a = self.getNeighbour((0, 1))
+ if (self.getBorder(Block.right) != a.getBorder(Block.left)):
+ return BlockSentry(self.parent, 0, 0, (0, 0)).getSquare((0,0))
+ return a.getSquare((p[0], p[1] - self.getW()))
+ else:
+ return self.map[x][y]
+
+ def getW(self):
+ return self.w
+
+ def getH(self):
+ return self.h
+
+ def render(self, pad, x, y):
+ for i in self.map:
+ for j in i:
+ j.render(pad, x, y)
+
+ def loadFromFile(self, f):
+ for i in range(0, self.getH()):
+ l = f.readline()
+ for j in range(0, self.getW()):
+ x = l[j]
+ c = {v:k for k, v in Square.asciiMap.items()}[x]
+ if (x == '*'):
+ self.parent.addKey()
+ if (x == '@'):
+ c = Square.empty
+ self.map[i][j] = Square(self, c, (i, j))
+ if (x == '@'):
+ self.parent.getPlayer().setPos(self.map[i][j])
+
+
+ def move(self, p):
+ self.pos = (self.pos[0] + p[0], self.pos[1] + p[1])
+
+
+
+class BlockSentry(Block):
+ def getSquare(self, p):
+ return Square(self, Square.blank, (0,0))
+
+ def render(self, pad, x, y):
+ for i in range(0, self.h):
+ for j in range(0, self.w):
+ (Square(self, Square.blank, (i,j))).render(pad, x, y)
+
+class Player:
+ keyMap = {(0, -1): 'h', (1, 0):'j', (-1, 0):'k', (0, 1): 'l'}
+
+ def __init__(self, parent, square):
+ self.parent = parent
+ self.pos = square
+ self.graphPos = (0,0)
+
+ def render(self, pad):
+ pad.move(self.graphPos[0], self.graphPos[1])
+
+ def setGraphPos(self, p):
+ self.graphPos = p
+
+ def move(self, direction, volont):
+ a = self.pos.getNeighbour(direction)
+ if (a.getType() != Square.wall and a.getType() != Square.blank):
+ self.pos = a
+ self.parent.addDist()
+ if (volont == True): self.parent.addMoves()
+ if (self.pos.getType() == Square.key):
+ self.parent.removeKey()
+ self.pos.setType(Square.empty)
+ if (self.pos.getType() == Square.exit and not self.parent.keysLeft()):
+ return True
+ else:
+ return self.fall()
+
+ def getPos(self):
+ return self.pos
+
+ def setPos(self, pos):
+ self.pos = pos
+
+ def fall(self):
+ a = self.pos.getType()
+ b = self.pos.getNeighbour((1,0)).getType()
+ while (self.pos.getType() != Square.ladder and (self.pos.getNeighbour((1,0)).getType() == Square.empty or self.pos.getNeighbour((1,0)).getType() == Square.key or self.pos.getNeighbour((1,0)).getType() == Square.exit)):
+ if self.move((1, 0), 0):
+ return True
+ return False
+
+
+class Level:
+ codeMap = {104: 'h', 106:'j', 107:'k', 108: 'l', 113: 'q', 72: 'H', 74:'J', 75: 'K', 76:'L'}
+ def __init__(self, h, w, x, y):
+ self.h = h
+ self.w = w
+ self.holeX = x
+ self.holeY = y
+ self.map = []
+ self.keys = 0
+ self.cswap = 0
+ self.cmove = 0
+ self.cdist = 0
+ for i in range(0, h):
+ self.map.append([])
+ for j in range(0, w):
+ self.map[i].append(Block(0, 0, 0, 0))
+ self.player = Player(self, Square(0, 0, (0,0)))
+
+ def loadFromFile(self, f):
+ bh = int(f.readline())
+ bw = int(f.readline())
+ for i in range(0, self.h):
+ for j in range(0, self.w):
+ if ((i, j) != (self.holeX, self.holeY)):
+ self.map[i][j] = Block(self, bh, bw, (i, j))
+ else:
+ self.map[i][j] = BlockSentry(self, bh, bw, (i, j))
+ self.map[i][j].loadFromFile(f)
+
+ def addKey(self):
+ self.keys+=1
+
+ def addDist(self):
+ self.cdist += 1
+
+ def addMoves(self):
+ self.cmove += 1
+
+ def addSwap(self):
+ self.cswap += 1
+
+ def removeKey(self):
+ self.keys-=1
+
+ def keysLeft(self):
+ return self.keys != 0
+
+ def getPlayer(self):
+ return self.player
+
+ def render(self, pad):
+ m = 0
+ for i in range(0, self.w):
+ m = m + self.map[0][i].getW() + 1
+ for i in range(0, m+1):
+ pad.addch( 0 ,i, '\'', curses.color_pair(5))
+ pad.addch( 0 ,i, ' ', curses.color_pair(5))
+ x = 0
+ for j in range(0, self.h):
+ y = 0
+ for i in range(0, self.map[0][j].getH()+1):
+ pad.addch( j*(self.map[0][j].getH()+1)+1 +i ,0, ' ', curses.color_pair(5))
+ for i in range(0, self.w):
+ a = self.map[j][i]
+ a.render(pad, j*a.getH()+1+j, i*a.getW()+1+i)
+ l = a.getBorder(Block.bottom)
+ l2 = a.getNeighbour((1, 0)).getBorder(Block.top)
+ if (l != l2):
+ for k in range(0, a.getW()+1):
+ if (l2 != [] and l != [] and l[k-1] != l2[k-1]):
+ pad.addch( x+self.map[0][j].getH() +1,y+k, '?', curses.color_pair(5))
+ else:
+ pad.addch( x+self.map[0][j].getH() +1,y+k, '\'', curses.color_pair(5))
+ pad.addch( x+self.map[0][j].getH() +1,y+k, ' ', curses.color_pair(5))
+ else:
+ for k in range(0, a.getW()):
+ if (l[k] == Square.wall):
+ pad.addch( x+self.map[0][j].getH()+1,y+k+1, '|', curses.color_pair(6))
+ else:
+ pad.addch( x+self.map[0][j].getH()+1,y+k+1, '\'', curses.color_pair(7))
+ pad.addch( x+self.map[0][j].getH()+1,y+k+1, ' ', curses.color_pair(7))
+ y = y + a.getW() + 1
+ l = a.getBorder(Block.right)
+ l2 = a.getNeighbour((0, 1)).getBorder(Block.left)
+ if (l != l2):
+ for k in range(0, a.getH()+1):
+ if (l2 != [] and l != [] and l[k-1] != l2[k-1]):
+ pad.addch( x+k ,y, '?', curses.color_pair(5))
+ else:
+ pad.addch( x+k ,y, '\'', curses.color_pair(5))
+ pad.addch( x+k ,y, ' ', curses.color_pair(5))
+ else:
+ for k in range(0, a.getH()):
+ if (l[k] == Square.wall):
+ pad.addch( x+k+1 ,y, '-', curses.color_pair(6))
+ else:
+ pad.addch( x+k+1 ,y, '\'', curses.color_pair(7))
+ pad.addch( x+k+1 ,y, ' ', curses.color_pair(7))
+ for k in range(0, a.getH()+1):
+ pad.addch( x+k ,y, '\'', curses.color_pair(5))
+ pad.addch( x+k ,y, ' ', curses.color_pair(5))
+ x = x + self.map[0][j].getH() + 1
+ m = 0
+ for i in range(0, self.h):
+ m = m + self.map[i][0].getH() + 1
+ for i in range(0, y+1):
+ pad.addch( m ,i, '\'', curses.color_pair(5))
+ pad.addch( m ,i, ' ', curses.color_pair(5))
+ x = 0
+ for j in range(0, self.h+1):
+ y = 0
+ for i in range(0, self.w+1):
+ pad.addch(x, y, '+', curses.color_pair(9))
+ y += self.getBlock((min(j, self.h-1), i)).getW() + 1;
+ x += self.getBlock((j, self.w-1)).getH() + 1;
+
+
+ pad.addstr( self.scoreRep())
+ self.player.render(pad)
+ pad.refresh()
+
+ def scoreRep(self):
+ return "Moves: %3d\nDist: %4d\nSwaps: %3d" %(self.cmove, self.cdist, self.cswap )
+
+ def getH(self):
+ return self.h
+
+ def getW(self):
+ return self.w
+
+ def getBlock(self, p):
+ x = p[0]
+ y = p[1]
+ if (x < 0 or y < 0 or x >= self.getH() or y >= self.getW()):
+ return BlockSentry(self, 0, 0, (0,0))
+ else:
+ return self.map[x][y]
+
+ def move(self, p):
+ p2 = (-p[0], -p[1])
+ tx = p2[0]+self.holeX
+ ty = p2[1]+self.holeY
+ t = self.getBlock((tx, ty))
+ if (type(t) != BlockSentry):
+ self.map[tx][ty] = self.map[self.holeX][self.holeY]
+ self.map[self.holeX][self.holeY] = t
+ t.move(p)
+ self.map[tx][ty].move(p2)
+ self.holeX = tx
+ self.holeY = ty
+ self.addSwap()
+ return self.player.fall()
+
+
+
+
+
+
+
+
+
+
+
+stdscr = curses.initscr()
+curses.noecho()
+curses.cbreak()
+stdscr.keypad(1)
+
+
+f = open(sys.argv[1])
+h = int(f.readline())
+w = int(f.readline())
+x = int(f.readline())
+y = int(f.readline())
+l = Level(h, w, x, y)
+l.loadFromFile(f)
+
+pad = curses.newwin(h*(l.getBlock((0,0)).getH()+1)+4, w*(l.getBlock((0,0)).getW()+1)+1)
+
+curses.start_color()
+curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK)
+curses.init_pair(2, curses.COLOR_RED, curses.COLOR_YELLOW)
+curses.init_pair(3, curses.COLOR_GREEN, curses.COLOR_BLACK)
+curses.init_pair(4, curses.COLOR_BLUE, curses.COLOR_BLUE)
+curses.init_pair(5, curses.COLOR_BLACK, curses.COLOR_RED)
+curses.init_pair(6, curses.COLOR_RED, curses.COLOR_BLUE)
+curses.init_pair(7, curses.COLOR_WHITE, curses.COLOR_BLACK)
+curses.init_pair(8, curses.COLOR_YELLOW, curses.COLOR_BLACK)
+curses.init_pair(9, curses.COLOR_MAGENTA, curses.COLOR_MAGENTA)
+
+exit = False
+won = False
+
+stdscr.addstr ("Continuity\nGame\n\nNameless\ncurses\nclone\n\nPress\nany\nkey\n")
+
+while (not exit):
+ l.render(pad)
+ try: input = Level.codeMap[stdscr.getch()]
+ except KeyError:
+ input = ''
+ pass
+ if (input == 'q'):
+ exit = True
+ elif (input == input.upper()):
+ try: won = l.move({v:k for k, v in Player.keyMap.items()}[input.lower()])
+ except KeyError: pass
+ else:
+ try: won = l.getPlayer().move({v:k for k, v in Player.keyMap.items()}[input], 1)
+ except KeyError: pass
+ exit = exit or won
+
+curses.endwin()
+
+curses.nocbreak(); stdscr.keypad(0); curses.echo()
+
+
+if (won):
+ print ("Congratulations, you won!\n")
+ print ("Your score was:")
+ print (l.scoreRep())
+else: print ("Bye.\n")
+