@ -2,8 +2,8 @@ import curses
import sys
import sys
import random
import random
WALL = 1
WALL = ' # '
SPACE = 0
SPACE = ' . '
class Map :
class Map :
def __init__ ( self , width , height ) :
def __init__ ( self , width , height ) :
@ -15,6 +15,13 @@ class Map:
self . hunt_and_kill ( grid )
self . hunt_and_kill ( grid )
self . render_map ( grid )
self . render_map ( grid )
def spawn ( self ) :
while True :
y = random . randrange ( 0 , self . height )
x = random . randrange ( 0 , self . width )
if self . map [ y ] [ x ] == SPACE :
return x , y
def sample_rooms ( self , grid , dead_ends , size , count ) :
def sample_rooms ( self , grid , dead_ends , size , count ) :
grid = self . make_grid ( )
grid = self . make_grid ( )
for x , y in random . sample ( dead_ends , count ) :
for x , y in random . sample ( dead_ends , count ) :
@ -39,7 +46,7 @@ class Map:
for x in range ( 1 , self . width , 2 ) :
for x in range ( 1 , self . width , 2 ) :
if grid [ y ] [ x ] != WALL : continue
if grid [ y ] [ x ] != WALL : continue
found = self . neighborsAB ( grid , x , y )
found = self . neighbors ( grid , x , y )
for found_x , found_y in found :
for found_x , found_y in found :
if grid [ found_y ] [ found_x ] == SPACE :
if grid [ found_y ] [ found_x ] == SPACE :
return [ [ x , y ] , [ found_x , found_y ] ]
return [ [ x , y ] , [ found_x , found_y ] ]
@ -49,7 +56,7 @@ class Map:
def inbounds ( self , x , y ) :
def inbounds ( self , x , y ) :
return x > = 0 and x < self . width and y > = 0 and y < self . height
return x > = 0 and x < self . width and y > = 0 and y < self . height
def neighborsAB ( self , grid , x , y ) :
def neighbors ( self , grid , x , y ) :
points = [ [ x , y - 2 ] ,
points = [ [ x , y - 2 ] ,
[ x , y + 2 ] ,
[ x , y + 2 ] ,
[ x - 2 , y ] ,
[ x - 2 , y ] ,
@ -61,15 +68,11 @@ class Map:
result . append ( [ x , y ] )
result . append ( [ x , y ] )
return result
return result
def neighbors ( self , grid , x , y ) :
def neighbor_walls ( self , grid , x , y ) :
points = [ [ x , y - 2 ] ,
neighbors = self . neighbors ( grid , x , y )
[ x , y + 2 ] ,
[ x - 2 , y ] ,
[ x + 2 , y ] ]
result = [ ]
result = [ ]
for x , y in point s:
for x , y in neighbors :
if self . inbounds ( x , y ) and grid [ y ] [ x ] == WALL :
if grid [ y ] [ x ] == WALL :
result . append ( [ x , y ] )
result . append ( [ x , y ] )
return result
return result
@ -79,7 +82,7 @@ class Map:
dead_ends = [ ]
dead_ends = [ ]
while True :
while True :
n = self . neighbors ( grid , on_x , on_y )
n = self . neighbor_wall s ( grid , on_x , on_y )
if len ( n ) == 0 :
if len ( n ) == 0 :
dead_ends . append ( [ on_x , on_y ] )
dead_ends . append ( [ on_x , on_y ] )
t = self . find_coord ( grid )
t = self . find_coord ( grid )
@ -107,22 +110,19 @@ class Map:
cur_row = " "
cur_row = " "
for x , char in enumerate ( y_line ) :
for x , char in enumerate ( y_line ) :
if char == 0 :
cur_row + = char
cur_row + = ' . '
else :
cur_row + = ' # '
self . map . append ( cur_row )
self . map . append ( cur_row )
def move_player ( self , player , target_y , target_x ) :
def move_player ( self , player , target_x , target_y ) :
if self . map [ target_y - 1 ] [ target_x - 1 ] != ' # ' :
if self . map [ target_y ] [ target_x ] != ' # ' :
player . y = target_y
player . y = target_y
player . x = target_x
player . x = target_x
def draw ( self , win ) :
def draw ( self , win ) :
map_line = 1
map_line = 0
for line in self . map :
for line in self . map :
win . addstr ( map_line , 1 , line )
win . addstr ( map_line , 0 , line )
map_line + = 1
map_line + = 1
class UI :
class UI :
@ -134,7 +134,7 @@ class UI:
win = curses . newwin ( height , width , begin_y , begin_x )
win = curses . newwin ( height , width , begin_y , begin_x )
win . keypad ( True )
win . keypad ( True )
status = win . subwin ( status_height , width - 2 , height - status_height , begin_x + 1 )
status = win . subwin ( status_height , width , height - status_height , begin_x )
# keep these for later by assigning to self
# keep these for later by assigning to self
self . begin_x = 0
self . begin_x = 0
@ -149,23 +149,28 @@ class UI:
def set_map ( self , the_map ) :
def set_map ( self , the_map ) :
self . map = the_map
self . map = the_map
def update ( self , player ) :
def update ( self , actors ) :
assert self . map , " You forgot to call set_map() "
assert self . map , " You forgot to call set_map() "
self . win . clear ( )
self . win . clear ( )
self . win . box ( )
self . status . box ( )
self . status . hline ( 0 , 0 , curses . ACS_HLINE , self . width - 2 )
self . map . draw ( self . win )
self . map . draw ( self . win )
self . draw_status ( )
# this assumes actors[0] is the player
self . draw_player ( player )
self . draw_status ( actors [ 0 ] )
for actor in actors :
self . draw_actor ( actor )
self . win . refresh ( )
self . win . refresh ( )
def draw_status ( self ) :
def draw_status ( self , player ) :
self . status . addstr ( 1 , 1 , " PLAYER STATS " )
self . status . addstr ( 1 , 1 , f " PLAYER AT { player . x } , { player . y } " )
def draw_actor ( self , actor ) :
assert self . map . map [ actor . y ] [ actor . x ] != ' # ' , f " WHAT? actor at { actor . x } , { actor . y } but that ' s a wall! "
def draw_player ( self , player ) :
# actor has to be moved in by 1 for the border
self . win . addstr ( player . y , player . x , ' @ ' , curses . A_BOLD )
self . win . addstr ( actor . y , actor . x , actor . symbol , curses . A_BOLD )
def handle_input ( self , y , x ) :
def handle_input ( self , x , y ) :
ch = self . win . getch ( )
ch = self . win . getch ( )
if ch == ord ( ' q ' ) :
if ch == ord ( ' q ' ) :
@ -179,30 +184,49 @@ class UI:
elif ch == curses . KEY_LEFT :
elif ch == curses . KEY_LEFT :
x = ( x - 1 ) % self . width
x = ( x - 1 ) % self . width
return y , x
return x , y
class Player :
class Player :
def __init__ ( self , x , y ) :
def __init__ ( self , x , y ) :
self . x = x
self . x = x
self . y = y
self . y = y
self . symbol = ' @ '
class Enemy :
def __init__ ( self , x , y , symbol ) :
self . x = x
self . y = y
self . symbol = symbol
class GameEngine :
class GameEngine :
def __init__ ( self , ui ) :
def __init__ ( self , ui ) :
self . ui = ui
self . ui = ui
self . player = Player ( 4 , 4 )
self . map = Map ( ui . width , ui . height - ui . status_height )
self . map = Map ( 77 , 19 )
self . ui = ui
self . ui = ui
ui . set_map ( self . map )
ui . set_map ( self . map )
def spawn_actors ( self ) :
x , y = self . map . spawn ( )
self . player = Player ( x , y )
x , y = self . map . spawn ( )
self . enemy = Enemy ( x , y , ' { ' )
self . actors = [ self . player , self . enemy ]
def run ( self ) :
def run ( self ) :
self . spawn_actors ( )
self . map . move_player ( self . player , self . player . x , self . player . y )
while True :
while True :
self . ui . update ( self . player )
# remember, first one has to be the player
new_y , new_x = self . ui . handle_input ( self . player . y , self . player . x )
self . ui . update ( self . actors )
self . map . move_player ( self . player , new_y , new_x )
new_x , new_y = self . ui . handle_input ( self . player . x , self . player . y )
self . map . move_player ( self . player , new_x , new_y )
def main ( stdscr ) :
def main ( stdscr ) :
width = 80
width = 27
height = 26
height = 1 6
ui = UI ( stdscr , height , width , 5 )
ui = UI ( stdscr , height , width , 5 )
game = GameEngine ( ui )
game = GameEngine ( ui )
game . run ( )
game . run ( )