@ -7,6 +7,8 @@ import contextlib
import termios
import termios
import timeout_decorator
import timeout_decorator
import os
import os
import argparse
import json
from blessings import Terminal
from blessings import Terminal
@ -20,26 +22,26 @@ class RanIntoSomethingError(QuitGameError):
def draw_worm ( ) :
def draw_worm ( ) :
for location in worm_locations :
for location in worm_locations :
print ( term . move ( * reversed ( location ) ) + term . bright_blue ( ' o ' ) , end = ' ' )
print ( do_ move( * reversed ( location ) ) + term . bright_blue ( ' o ' ) , end = ' ' )
print ( term . move ( * reversed ( worm_head ) ) + ' @ ' + term . move ( * reversed ( worm_head ) ) , end = ' ' )
print ( do_ move( * reversed ( worm_head ) ) + ' @ ' + do_ move( * reversed ( worm_head ) ) , end = ' ' )
def draw_frame ( ) :
def draw_frame ( ) :
print ( term . clear , end = ' ' )
print ( term . clear , end = ' ' )
print ( term . move ( 0 , 0 ) + term . on_red ( ' worm ' ) + term . bright_cyan_on_red ( ' .py ' ) + ' Press ' + term . bold_green ( ' I ' ) + ' for info, ' + term . bold_red ( ' Ctrl-C ' ) + ' to quit ' , end = ' ' )
print ( do_ move( 0 , 0 ) + term . on_red ( ' worm ' ) + term . bright_cyan_on_red ( ' .py ' ) + ' Press ' + term . bold_green ( ' I ' ) + ' for info, ' + term . bold_red ( ' Ctrl-C ' ) + ' to quit ' , end = ' ' )
if score > - 1 :
if score > - 1 :
print ( term . move ( 0 , width - 12 ) + f ' Score: { " " * ( 4 - len ( str ( score ) ) ) } { term . bright_green ( str ( score ) ) } ' , end = ' ' )
print ( do_ move( 0 , width - 12 ) + f ' Score: { " " * ( 4 - len ( str ( score ) ) ) } { term . bright_green ( str ( score ) ) } ' , end = ' ' )
print ( term . move ( 1 , 0 ) + term . white_on_red ( ' ┌ ' + ( ' ─ ' * ( width - 3 ) ) + ' ┐ ' ) , end = ' ' )
print ( do_ move( 1 , 0 ) + term . white_on_red ( ' ┌ ' + ( ' ─ ' * ( width - 3 ) ) + ' ┐ ' ) , end = ' ' )
for y in range ( 2 , height - 1 ) :
for y in range ( 2 , height - 1 ) :
print ( term . move ( y , 0 ) + term . white_on_red ( ' │ ' + term . move ( y , width - 2 ) + ' │ ' ) , end = ' ' )
print ( do_ move( y , 0 ) + term . white_on_red ( ' │ ' + do_ move( y , width - 2 ) + ' │ ' ) , end = ' ' )
print (
print (
term . move ( height - 1 , 0 )
do_ move( height - 1 , 0 )
+ term . white_on_red ( ' └ ' )
+ term . white_on_red ( ' └ ' )
+ term . white_on_red ( ' ─ ' * ( width - 3 ) )
+ term . white_on_red ( ' ─ ' * ( width - 3 ) )
+ term . white_on_red ( ' ┘ ' )
+ term . white_on_red ( ' ┘ ' )
, end = ' ' )
, end = ' ' )
print ( term . move ( * reversed ( bonus_location ) ) + term . black_on_green ( term . on_bright_green ( str ( bonus_points ) ) ) , end = ' ' )
print ( do_ move( * reversed ( bonus_location ) ) + term . black_on_green ( term . on_bright_green ( str ( bonus_points ) ) ) , end = ' ' )
draw_worm ( )
draw_worm ( )
sys . stdout . flush ( )
sys . stdout . flush ( )
@ -115,6 +117,7 @@ def run(*_):
do_automove = False
do_automove = False
return
return
elif k in ' ' :
elif k in ' ' :
save_game ( )
sys . exit ( 0 )
sys . exit ( 0 )
elif k in ' iI ' :
elif k in ' iI ' :
do_help = True
do_help = True
@ -139,12 +142,42 @@ def new_bonus():
]
]
def do_move ( y , x ) :
y + = ( term . height - height ) / / 2
x + = ( term . width - width ) / / 2
return term . move ( y , x )
term = Terminal ( )
term = Terminal ( )
gamesave_path = os . path . join ( os . getenv ( ' HOME ' ) , ' .worm.py-gamesave ' )
height = term . height
parser = argparse . ArgumentParser ( )
width = term . width
parser . add_argument ( " --length " , ' -l ' , help = " initial worm length (default 7) " , default = 7 , type = int )
parser . add_argument ( " --save " , ' -s ' , help = " enable game saving (sets screen size to 80x24) " , action = ' store_true ' )
parser . add_argument ( " --delete-save " , help = " delete saved game and exit " , action = ' store_true ' )
args = parser . parse_args ( )
size = args . length
if args . delete_save :
try :
os . unlink ( gamesave_path )
print ( " Saved game deleted. " )
except FileNotFoundError :
print ( " No saved game found. " )
except Exception as e :
print ( " An error occurred. " )
print ( str ( type ( e ) ) . split ( " ' " ) [ 1 ] + ' : ' + str ( e ) )
sys . exit ( 1 )
sys . exit ( 0 )
if args . save :
height = 24
width = 80
else :
height = term . height
width = term . width
info_1 = term . clear ( ) + term . move ( 0 , 0 ) + term . on_red ( ' worm ' ) \
info_1 = term . clear ( ) + do_ move( 0 , 0 ) + term . on_red ( ' worm ' ) \
+ term . bright_cyan_on_red ( ' .py ' ) + f ''' v1.0: bsdgames worm, ported \
+ term . bright_cyan_on_red ( ' .py ' ) + f ''' v1.0: bsdgames worm, ported \
to Python and improved
to Python and improved
@ -171,12 +204,12 @@ after `{term.bright_red('worm')}{term.bright_cyan('.py')}`, as in \
{ term . bright_red ( ' worm ' ) } { term . bright_cyan ( ' .py ' ) } is released under the MIT \
{ term . bright_red ( ' worm ' ) } { term . bright_cyan ( ' .py ' ) } is released under the MIT \
license . ''' \
license . ''' \
+ ' {} Press {} to continue, {} to exit the game... ' . format (
+ ' {} Press {} to continue, {} to exit the game... ' . format (
term . move ( height - 1 , 0 ) ,
do_ move( height - 1 , 0 ) ,
term . bold_green ( ' C ' ) ,
term . bold_green ( ' C ' ) ,
term . bold_red ( ' Ctrl-C ' )
term . bold_red ( ' Ctrl-C ' )
)
)
info_2 = term . clear ( ) + term . move ( 0 , 0 ) + term . on_red ( ' worm ' ) \
info_2 = term . clear ( ) + do_ move( 0 , 0 ) + term . on_red ( ' worm ' ) \
+ term . bright_cyan_on_red ( ' .py ' ) + f ''' Copyright and License Info
+ term . bright_cyan_on_red ( ' .py ' ) + f ''' Copyright and License Info
Copyright ( c ) 2021 Samuel L . Sloniker
Copyright ( c ) 2021 Samuel L . Sloniker
@ -200,34 +233,37 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE . ''' ) \
SOFTWARE . ''' ) \
+ ' {} Press {} to return to the game, {} to exit... ' . format (
+ ' {} Press {} to return to the game, {} to exit... ' . format (
term . move ( height - 1 , 0 ) ,
do_ move( height - 1 , 0 ) ,
term . bold_green ( ' C ' ) ,
term . bold_green ( ' C ' ) ,
term . bold_red ( ' Ctrl-C ' )
term . bold_red ( ' Ctrl-C ' )
)
)
last_dir = ' x '
if len ( sys . argv ) == 2 :
try :
size = int ( sys . argv [ 1 ] )
if size < = 0 or size > = width - 13 :
size = 7
except ValueError :
size = 7
else :
size = 7
score = 0
worm_y = height / / 2
worm_y = height / / 2
worm_locations = [ [ i + 10 , worm_y ] for i in range ( size ) ]
def save_game ( ) :
worm_head = [ size + 10 , worm_y ]
if args . save :
with open ( gamesave_path , ' w+ ' ) as f :
json . dump ( [ worm_locations , worm_head , last_dir , score , size , bonus_location , bonus_points , do_automove , do_help ] , f )
try :
if not args . save :
raise FileNotFoundError ( ) #TODO: this is not pythonic
with open ( gamesave_path ) as f :
save = json . load ( f )
worm_locations , worm_head , last_dir , score , size , bonus_location , bonus_points , do_automove , do_help = save
except FileNotFoundError :
worm_locations = [ [ i + 10 , worm_y ] for i in range ( size ) ]
worm_head = [ size + 10 , worm_y ]
last_dir = ' x '
score = 0
do_automove = True
do_help = False
new_bonus ( )
new_bonus ( )
do_automove = True
do_help = False
try :
try :
with term . fullscreen ( ) :
with term . fullscreen ( ) :
@ -243,6 +279,7 @@ try:
k = await_keys ( ' cC ' )
k = await_keys ( ' cC ' )
if k in ' ' :
if k in ' ' :
save_game ( )
sys . exit ( 0 )
sys . exit ( 0 )
do_help = False
do_help = False
@ -252,8 +289,14 @@ try:
except timeout_decorator . timeout_decorator . TimeoutError :
except timeout_decorator . timeout_decorator . TimeoutError :
pass
pass
except KeyboardInterrupt :
except KeyboardInterrupt :
save_game ( )
sys . exit ( 0 )
sys . exit ( 0 )
except RanIntoSomethingError :
except RanIntoSomethingError :
try :
if args . save :
os . unlink ( gamesave_path )
except FileNotFoundError :
pass
os . system ( ' stty -raw echo ' )
os . system ( ' stty -raw echo ' )
print ( ' ' , end = ' \r \n ' )
print ( ' ' , end = ' \r \n ' )
if size + 1 > = ( height - 3 ) * ( width - 1 ) :
if size + 1 > = ( height - 3 ) * ( width - 1 ) :