fixed linebreaks

master
panki27 7 years ago
parent d0fe415df5
commit 2f4b7374a2

@ -1,337 +1,337 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
#TODO: show controls, restartable, command line flags like "easy, hard" #TODO: show controls, restartable, command line flags like "easy, hard"
import random, io, sys, time, os import random, io, sys, time, os
import curses import curses
from curses import wrapper from curses import wrapper
NOTHING = 0 NOTHING = 0
MINE = -1 MINE = -1
FLAG = -2 FLAG = -2
UNKNOWN = -3 UNKNOWN = -3
FLAG_MINE = -4 FLAG_MINE = -4
score_x, score_y = 0, 0 score_x, score_y = 0, 0
OFFSET = 11 OFFSET = 11
STARTTIME = 0 STARTTIME = 0
SCREEN = 0 SCREEN = 0
firstmove = False firstmove = False
FIELD_GENERATED = False FIELD_GENERATED = False
CURSOR_POSITION=[0,0] CURSOR_POSITION=[0,0]
FIELDS_CLEARED = 0 FIELDS_CLEARED = 0
width, height = 9, 9 width, height = 9, 9
MINECOUNT = 10 MINECOUNT = 10
FLAGCOUNT = 0 FLAGCOUNT = 0
difficulty = 'medium' difficulty = 'medium'
param_error = 'minebash: Invalid parameters. See \'minebash.py ?\' for help ' param_error = 'minebash: Invalid parameters. See \'minebash.py ?\' for help '
helpstr = '''Usage: minebash.py [easy|medium|hard] [width height minecount] helpstr = '''Usage: minebash.py [easy|medium|hard] [width height minecount]
Difficulty presets: Difficulty presets:
easy: 5x5 4 mines easy: 5x5 4 mines
medium: 9x9 15 mines medium: 9x9 15 mines
hard: 12x12 35 mines hard: 12x12 35 mines
Specify your own: Specify your own:
4 4 4 4x4 4 mines 4 4 4 4x4 4 mines
8 8 10 8x8 10 mines 8 8 10 8x8 10 mines
Controls: Controls:
Arrow Keys: Move Cursor Arrow Keys: Move Cursor
Spacebar: Try field Spacebar: Try field
F: Place flag F: Place flag
''' '''
if len(sys.argv) > 1: if len(sys.argv) > 1:
if len(sys.argv) == 2: #param is string like easy, hard if len(sys.argv) == 2: #param is string like easy, hard
if sys.argv[1] == '?': if sys.argv[1] == '?':
print(helpstr) print(helpstr)
sys.exit(0) sys.exit(0)
if sys.argv[1] == 'easy': if sys.argv[1] == 'easy':
width = 5 width = 5
height = 5 height = 5
MINECOUNT = 4 MINECOUNT = 4
elif sys.argv[1] == 'medium': elif sys.argv[1] == 'medium':
width = 9 width = 9
height = 9 height = 9
MINECOUNT = 15 MINECOUNT = 15
elif sys.argv[1] == 'hard': elif sys.argv[1] == 'hard':
width = 12 width = 12
height = 12 height = 12
MINECOUNT = 35 MINECOUNT = 35
else: else:
print(param_error) print(param_error)
sys.exit(0) sys.exit(0)
difficulty = sys.argv[1] difficulty = sys.argv[1]
elif len(sys.argv) == 4: #this means the user has specified width, height and minecount elif len(sys.argv) == 4: #this means the user has specified width, height and minecount
width = int(sys.argv[1]) width = int(sys.argv[1])
height = int(sys.argv[2]) height = int(sys.argv[2])
if int(sys.argv[3]) < width*height: if int(sys.argv[3]) < width*height:
MINECOUNT = int(sys.argv[3]) MINECOUNT = int(sys.argv[3])
difficulty = 'custom' difficulty = 'custom'
else: else:
print('Minecount muss be less than width x height.') print('Minecount muss be less than width x height.')
system.exit(0) system.exit(0)
else: else:
print(param_error) print(param_error)
sys.exit(0) sys.exit(0)
playfield = [[UNKNOWN for x in range(width)] for y in range(height)] playfield = [[UNKNOWN for x in range(width)] for y in range(height)]
#stdscr = curses.initscr() #stdscr = curses.initscr()
#curses.noecho() #curses.noecho()
#curses.cbreak() #curses.cbreak()
headline = '.' headline = '.'
midline = '|' midline = '|'
tailline = '\'' tailline = '\''
def setup_strings(colcount): def setup_strings(colcount):
#setup lines to print #setup lines to print
for i in range(colcount): for i in range(colcount):
global headline, midline, tailline global headline, midline, tailline
headline += '---.' headline += '---.'
midline += '---|' midline += '---|'
tailline += '---\'' tailline += '---\''
def endgame(msg=''): def endgame(msg=''):
# curses.nocbreak() # curses.nocbreak()
# stdscr.keypad(False) # stdscr.keypad(False)
# curses.echo() # curses.echo()
#curses.endwin() #curses.endwin()
if msg != '': if msg != '':
print(msg) print(msg)
sys.exit(0) sys.exit(0)
def calculate_hint(col, row): def calculate_hint(col, row):
hint = 0 hint = 0
if playfield[row][col] != MINE: if playfield[row][col] != MINE:
for x in range(col-1, col+2): for x in range(col-1, col+2):
if x >= 0 and x < len(playfield): if x >= 0 and x < len(playfield):
for y in range(row-1, row+2): for y in range(row-1, row+2):
if y >= 0 and y < len(playfield[0]): if y >= 0 and y < len(playfield[0]):
if playfield[y][x] == MINE or playfield[y][x] == FLAG_MINE: if playfield[y][x] == MINE or playfield[y][x] == FLAG_MINE:
hint+=1 hint+=1
else: else:
hint = MINE hint = MINE
return hint return hint
def setup_playfield(w, h, x, y): def setup_playfield(w, h, x, y):
#do this only once [AFTER THE FIRST GUESS] -> Done #do this only once [AFTER THE FIRST GUESS] -> Done
#randomly distribute mines across the field #randomly distribute mines across the field
global playfield, FIELD_GENERATED, STARTTIME global playfield, FIELD_GENERATED, STARTTIME
minesleft = MINECOUNT minesleft = MINECOUNT
while minesleft > 0: while minesleft > 0:
randx = random.randint(0, width-1) randx = random.randint(0, width-1)
randy = random.randint(1, height-1) randy = random.randint(1, height-1)
if playfield[randy][randx] != MINE and randx != x and randy != y: if playfield[randy][randx] != MINE and randx != x and randy != y:
playfield[randy][randx] = MINE playfield[randy][randx] = MINE
minesleft -= 1 minesleft -= 1
FIELD_GENERATED = True FIELD_GENERATED = True
STARTTIME = time.time() STARTTIME = time.time()
def gameover(win): def gameover(win):
SCREEN.clear() SCREEN.clear()
if not win: if not win:
SCREEN.addstr(0, 0, ' ________________') SCREEN.addstr(0, 0, ' ________________')
SCREEN.addstr(1, 0, ' ____/ ( ( ) ) \___') SCREEN.addstr(1, 0, ' ____/ ( ( ) ) \___')
SCREEN.addstr(2, 0, ' /( ( ( ) _ )) ) )\ ') SCREEN.addstr(2, 0, ' /( ( ( ) _ )) ) )\ ')
SCREEN.addstr(3, 0, ' (( ( )( ) ) ( ) )') SCREEN.addstr(3, 0, ' (( ( )( ) ) ( ) )')
SCREEN.addstr(4, 0, ' ((/ ( _( ) ( _) ) ( () ) )') SCREEN.addstr(4, 0, ' ((/ ( _( ) ( _) ) ( () ) )')
SCREEN.addstr(5, 0, ' ( ( ( (_) (( ( ) .((_ ) . )_') SCREEN.addstr(5, 0, ' ( ( ( (_) (( ( ) .((_ ) . )_')
SCREEN.addstr(6, 0, ' ( ( ) ( ( ) ) ) . ) ( )') SCREEN.addstr(6, 0, ' ( ( ) ( ( ) ) ) . ) ( )')
SCREEN.addstr(7, 0, ' ( ( ( ( ) ( _ ( _) ). ) . ) ) ( )') SCREEN.addstr(7, 0, ' ( ( ( ( ) ( _ ( _) ). ) . ) ) ( )')
SCREEN.addstr(8, 0, ' ( ( ( ) ( ) ( )) ) _)( ) ) )') SCREEN.addstr(8, 0, ' ( ( ( ) ( ) ( )) ) _)( ) ) )')
SCREEN.addstr(9, 0, ' ( ( ( \ ) ( (_ ( ) ( ) ) ) ) )) ( )') SCREEN.addstr(9, 0, ' ( ( ( \ ) ( (_ ( ) ( ) ) ) ) )) ( )')
SCREEN.addstr(10, 0, ' ( ( ( ( (_ ( ) ( _ ) ) ( ) ) )') SCREEN.addstr(10, 0, ' ( ( ( ( (_ ( ) ( _ ) ) ( ) ) )')
SCREEN.addstr(11, 0, ' ( ( ( ( ( ) (_ ) ) ) _) ) _( ( )') SCREEN.addstr(11, 0, ' ( ( ( ( ( ) (_ ) ) ) _) ) _( ( )')
SCREEN.addstr(12, 0, ' (( ( )( ( _ ) _) _(_ ( (_ )') SCREEN.addstr(12, 0, ' (( ( )( ( _ ) _) _(_ ( (_ )')
SCREEN.addstr(13, 0, ' (_((__(_(__(( ( ( | ) ) ) )_))__))_)___)') SCREEN.addstr(13, 0, ' (_((__(_(__(( ( ( | ) ) ) )_))__))_)___)')
SCREEN.addstr(14, 0, ' ((__) \\||lll|l||/// \_))') SCREEN.addstr(14, 0, ' ((__) \\||lll|l||/// \_))')
SCREEN.addstr(15, 0, ' ( /(/ ( ) ) )\ )') SCREEN.addstr(15, 0, ' ( /(/ ( ) ) )\ )')
SCREEN.addstr(16, 0, ' ( ( ( ( | | ) ) )\ )') SCREEN.addstr(16, 0, ' ( ( ( ( | | ) ) )\ )')
SCREEN.addstr(17, 0, ' ( /(| / ( )) ) ) )) )') SCREEN.addstr(17, 0, ' ( /(| / ( )) ) ) )) )')
SCREEN.addstr(18, 0, ' ( ( ((((_(|)_))))) )') SCREEN.addstr(18, 0, ' ( ( ((((_(|)_))))) )')
SCREEN.addstr(19, 0, ' ( ||\(|(|)|/|| )') SCREEN.addstr(19, 0, ' ( ||\(|(|)|/|| )')
SCREEN.addstr(20, 0, ' ( |(||(||)|||| )') SCREEN.addstr(20, 0, ' ( |(||(||)|||| )')
SCREEN.addstr(21, 0, ' ( //|/l|||)|\\ \ )') SCREEN.addstr(21, 0, ' ( //|/l|||)|\\ \ )')
SCREEN.addstr(22, 0, ' (/ / // /|//||||\\ \ \ \ _)') SCREEN.addstr(22, 0, ' (/ / // /|//||||\\ \ \ \ _)')
SCREEN.addstr(23, 0, ' You lose! Press q to quit.') SCREEN.addstr(23, 0, ' You lose! Press q to quit.')
else: else:
now = time.time() now = time.time()
elapsed = now - STARTTIME elapsed = now - STARTTIME
mins = elapsed / 60 mins = elapsed / 60
secs = elapsed % 60 secs = elapsed % 60
winstr = 'You win! It took you {}:{} to bash the field!'.format(int(mins), str(round(secs, 2)).zfill(5)) winstr = 'You win! It took you {}:{} to bash the field!'.format(int(mins), str(round(secs, 2)).zfill(5))
SCREEN.addstr(0, 0, ' /$$ /$$ /$$ /$$ /$$$$$$$ /$$') SCREEN.addstr(0, 0, ' /$$ /$$ /$$ /$$ /$$$$$$$ /$$')
SCREEN.addstr(1, 0, '| $$ /$ | $$ | $$| $$ | $$__ $$ | $$') SCREEN.addstr(1, 0, '| $$ /$ | $$ | $$| $$ | $$__ $$ | $$')
SCREEN.addstr(2, 0, '| $$ /$$$| $$ /$$$$$$ | $$| $$ | $$ \ $$ /$$$$$$ /$$$$$$$ /$$$$$$ | $$') SCREEN.addstr(2, 0, '| $$ /$$$| $$ /$$$$$$ | $$| $$ | $$ \ $$ /$$$$$$ /$$$$$$$ /$$$$$$ | $$')
SCREEN.addstr(3, 0, '| $$/$$ $$ $$ /$$__ $$| $$| $$ | $$ | $$ /$$__ $$| $$__ $$ /$$__ $$| $$') SCREEN.addstr(3, 0, '| $$/$$ $$ $$ /$$__ $$| $$| $$ | $$ | $$ /$$__ $$| $$__ $$ /$$__ $$| $$')
SCREEN.addstr(4, 0, '| $$$$_ $$$$| $$$$$$$$| $$| $$ | $$ | $$| $$ \ $$| $$ \ $$| $$$$$$$$|__/') SCREEN.addstr(4, 0, '| $$$$_ $$$$| $$$$$$$$| $$| $$ | $$ | $$| $$ \ $$| $$ \ $$| $$$$$$$$|__/')
SCREEN.addstr(5, 0, '| $$$/ \ $$$| $$_____/| $$| $$ | $$ | $$| $$ | $$| $$ | $$| $$_____/ ') SCREEN.addstr(5, 0, '| $$$/ \ $$$| $$_____/| $$| $$ | $$ | $$| $$ | $$| $$ | $$| $$_____/ ')
SCREEN.addstr(6, 0, '| $$/ \ $$| $$$$$$$| $$| $$ | $$$$$$$/| $$$$$$/| $$ | $$| $$$$$$$ /$$') SCREEN.addstr(6, 0, '| $$/ \ $$| $$$$$$$| $$| $$ | $$$$$$$/| $$$$$$/| $$ | $$| $$$$$$$ /$$')
SCREEN.addstr(7, 0, '|__/ \__/ \_______/|__/|__/ |_______/ \______/ |__/ |__/ \_______/|__/') SCREEN.addstr(7, 0, '|__/ \__/ \_______/|__/|__/ |_______/ \______/ |__/ |__/ \_______/|__/')
SCREEN.addstr(10, 0, winstr) SCREEN.addstr(10, 0, winstr)
SCREEN.addstr(11,0, 'Press q to quit!') SCREEN.addstr(11,0, 'Press q to quit!')
while True: while True:
key = SCREEN.getch() key = SCREEN.getch()
if key == ord('q'): if key == ord('q'):
endgame() endgame()
#if key == ord('r'): #if key == ord('r'):
# os.execl(sys.executable, sys.executable, *sys.argv) # os.execl(sys.executable, sys.executable, *sys.argv)
def print_playfield(playfield, screen): def print_playfield(playfield, screen):
global score_x, score_y global score_x, score_y
currentline = 0 currentline = 0
screen.addstr(currentline, 10, headline, curses.color_pair(1)) screen.addstr(currentline, 10, headline, curses.color_pair(1))
currentline +=1 currentline +=1
#print headline #print headline
for rowindex, row in enumerate(playfield): for rowindex, row in enumerate(playfield):
screen.addstr(currentline, 10, '|') screen.addstr(currentline, 10, '|')
pos = OFFSET pos = OFFSET
for colindex, cell in enumerate(row): for colindex, cell in enumerate(row):
# is the cell selected? # is the cell selected?
selected = False selected = False
if [colindex, rowindex] == CURSOR_POSITION: if [colindex, rowindex] == CURSOR_POSITION:
screen.addstr(currentline, pos, '[') screen.addstr(currentline, pos, '[')
selected = True selected = True
else: else:
screen.addstr(currentline, pos, ' ') screen.addstr(currentline, pos, ' ')
pos += 1 pos += 1
# did we find a hint? # did we find a hint?
if cell > 0: if cell > 0:
if cell == 1: color = curses.color_pair(3) #cyan if cell == 1: color = curses.color_pair(3) #cyan
elif cell == 2: color = curses.color_pair(4) #blue elif cell == 2: color = curses.color_pair(4) #blue
else: color = curses.color_pair(5) #yellow else: color = curses.color_pair(5) #yellow
screen.addstr(currentline, pos, str(cell), color) screen.addstr(currentline, pos, str(cell), color)
elif cell == 0: elif cell == 0:
screen.addstr(currentline, pos, ' ') screen.addstr(currentline, pos, ' ')
elif cell == UNKNOWN or cell == MINE: elif cell == UNKNOWN or cell == MINE:
screen.addstr(currentline, pos, '#', curses.color_pair(7)) #rowstring+= '#' screen.addstr(currentline, pos, '#', curses.color_pair(7)) #rowstring+= '#'
elif cell == FLAG_MINE or cell == FLAG: elif cell == FLAG_MINE or cell == FLAG:
screen.addstr(currentline, pos, 'P', curses.color_pair(2)) #rowstring += 'P' screen.addstr(currentline, pos, 'P', curses.color_pair(2)) #rowstring += 'P'
#elif cell == MINE: #elif cell == MINE:
# rowstring += 'X' # rowstring += 'X'
pos += 1 pos += 1
if selected: if selected:
screen.addstr(currentline, pos, ']|') screen.addstr(currentline, pos, ']|')
else: else:
screen.addstr(currentline, pos, ' |') screen.addstr(currentline, pos, ' |')
pos += 2 pos += 2
currentline +=1 currentline +=1
if(rowindex < len(row)-1): if(rowindex < len(row)-1):
screen.addstr(currentline, 10, midline) screen.addstr(currentline, 10, midline)
currentline +=1 currentline +=1
screen.addstr(currentline, 10, tailline) screen.addstr(currentline, 10, tailline)
currentline +=1 currentline +=1
score_y = currentline score_y = currentline
score_x = int(pos/2) score_x = int(pos/2)
#print tailline #print tailline
def hit(x, y, recursive_call=False): def hit(x, y, recursive_call=False):
global playfield, FIELDS_CLEARED global playfield, FIELDS_CLEARED
if playfield[y][x] == UNKNOWN: if playfield[y][x] == UNKNOWN:
hint = calculate_hint(x, y) hint = calculate_hint(x, y)
playfield[y][x] = hint playfield[y][x] = hint
FIELDS_CLEARED += 1 FIELDS_CLEARED += 1
if not recursive_call and hint == NOTHING: if not recursive_call and hint == NOTHING:
for i in range(x-1, x+2): for i in range(x-1, x+2):
for j in range(y-1, y+2): for j in range(y-1, y+2):
if i >= 0 and i < width: if i >= 0 and i < width:
if j >= 0 and j< height: if j >= 0 and j< height:
if playfield[j][i] == UNKNOWN: if playfield[j][i] == UNKNOWN:
hint = calculate_hint(i, j) hint = calculate_hint(i, j)
if hint > 0 and hint<3: if hint > 0 and hint<3:
hit(i,j, True) hit(i,j, True)
if hint == 0: if hint == 0:
hit(i,j) hit(i,j)
elif playfield[y][x] == MINE: elif playfield[y][x] == MINE:
gameover(False) gameover(False)
def check_score(): def check_score():
if FIELDS_CLEARED == (width*height)-MINECOUNT: if FIELDS_CLEARED == (width*height)-MINECOUNT:
gameover(True) gameover(True)
def place_flag(x, y): def place_flag(x, y):
global playfield, FLAGCOUNT global playfield, FLAGCOUNT
#playfield[y][x] = playfield[y][x] #playfield[y][x] = playfield[y][x]
if playfield[y][x] == MINE: if playfield[y][x] == MINE:
playfield[y][x] = FLAG_MINE playfield[y][x] = FLAG_MINE
FLAGCOUNT += 1 FLAGCOUNT += 1
elif playfield[y][x] == UNKNOWN: elif playfield[y][x] == UNKNOWN:
playfield[y][x] = FLAG playfield[y][x] = FLAG
FLAGCOUNT += 1 FLAGCOUNT += 1
elif playfield[y][x] == FLAG_MINE: elif playfield[y][x] == FLAG_MINE:
playfield[y][x] = MINE playfield[y][x] = MINE
FLAGCOUNT -= 1 FLAGCOUNT -= 1
elif playfield[y][x] == FLAG: elif playfield[y][x] == FLAG:
playfield[y][x] = UNKNOWN playfield[y][x] = UNKNOWN
FLAGCOUNT -=1 FLAGCOUNT -=1
def handle_input(k): def handle_input(k):
global CURSOR_POSITION, firstmove global CURSOR_POSITION, firstmove
if k == curses.KEY_LEFT: if k == curses.KEY_LEFT:
if CURSOR_POSITION[0] > 0: if CURSOR_POSITION[0] > 0:
CURSOR_POSITION[0] -=1 CURSOR_POSITION[0] -=1
elif k == curses.KEY_RIGHT: elif k == curses.KEY_RIGHT:
if CURSOR_POSITION[0] < width-1: if CURSOR_POSITION[0] < width-1:
CURSOR_POSITION[0] +=1 CURSOR_POSITION[0] +=1
elif k == curses.KEY_UP: elif k == curses.KEY_UP:
if CURSOR_POSITION[1] > 0: if CURSOR_POSITION[1] > 0:
CURSOR_POSITION[1] -=1 CURSOR_POSITION[1] -=1
elif k == curses.KEY_DOWN: elif k == curses.KEY_DOWN:
if CURSOR_POSITION[1] < height-1: if CURSOR_POSITION[1] < height-1:
CURSOR_POSITION[1] +=1 CURSOR_POSITION[1] +=1
elif k == ord('f'): elif k == ord('f'):
if FIELD_GENERATED: if FIELD_GENERATED:
place_flag(CURSOR_POSITION[0], CURSOR_POSITION[1]) place_flag(CURSOR_POSITION[0], CURSOR_POSITION[1])
elif k == ord(' '): elif k == ord(' '):
if not firstmove: if not firstmove:
firstmove = True firstmove = True
else: else:
hit(CURSOR_POSITION[0], CURSOR_POSITION[1]) hit(CURSOR_POSITION[0], CURSOR_POSITION[1])
def print_score(screen): def print_score(screen):
scorestr = 'Mines: {} Flags: {} Difficulty: {}'.format(MINECOUNT, FLAGCOUNT, difficulty) scorestr = 'Mines: {} Flags: {} Difficulty: {}'.format(MINECOUNT, FLAGCOUNT, difficulty)
xpos = int((score_x) - (len(scorestr)/2)) + int(OFFSET/2) xpos = int((score_x) - (len(scorestr)/2)) + int(OFFSET/2)
screen.addstr(score_y, xpos, scorestr) screen.addstr(score_y, xpos, scorestr)
def setup_colors(): def setup_colors():
curses.start_color() curses.start_color()
curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK) curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK)
curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK) curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
curses.init_pair(3, curses.COLOR_CYAN, curses.COLOR_BLACK) curses.init_pair(3, curses.COLOR_CYAN, curses.COLOR_BLACK)
curses.init_pair(4, curses.COLOR_BLUE, curses.COLOR_BLACK) curses.init_pair(4, curses.COLOR_BLUE, curses.COLOR_BLACK)
curses.init_pair(5, curses.COLOR_YELLOW, curses.COLOR_BLACK) curses.init_pair(5, curses.COLOR_YELLOW, curses.COLOR_BLACK)
curses.init_pair(7, curses.COLOR_WHITE, curses.COLOR_WHITE) curses.init_pair(7, curses.COLOR_WHITE, curses.COLOR_WHITE)
def main(stdscr): def main(stdscr):
global SCREEN global SCREEN
SCREEN = stdscr SCREEN = stdscr
stdscr.clear() stdscr.clear()
setup_strings(width) setup_strings(width)
setup_colors() setup_colors()
#generate mines: #generate mines:
#TODO: user input #TODO: user input
while(True): while(True):
print_playfield(playfield, stdscr) print_playfield(playfield, stdscr)
key = stdscr.getch() key = stdscr.getch()
handle_input(key) handle_input(key)
if (firstmove) and not (FIELD_GENERATED): if (firstmove) and not (FIELD_GENERATED):
setup_playfield(width, height, CURSOR_POSITION[0], CURSOR_POSITION[1]) setup_playfield(width, height, CURSOR_POSITION[0], CURSOR_POSITION[1])
handle_input(key) handle_input(key)
STARTTIME = time.time() STARTTIME = time.time()
check_score() check_score()
print_score(stdscr) print_score(stdscr)
stdscr.refresh() stdscr.refresh()
#stdscr.getkey() #stdscr.getkey()
if __name__ == "__main__": if __name__ == "__main__":
wrapper(main) wrapper(main)

@ -0,0 +1,337 @@
#!/usr/bin/env python3
#TODO: show controls, restartable, command line flags like "easy, hard"
import random, io, sys, time, os
import curses
from curses import wrapper
NOTHING = 0
MINE = -1
FLAG = -2
UNKNOWN = -3
FLAG_MINE = -4
score_x, score_y = 0, 0
OFFSET = 11
STARTTIME = 0
SCREEN = 0
firstmove = False
FIELD_GENERATED = False
CURSOR_POSITION=[0,0]
FIELDS_CLEARED = 0
width, height = 9, 9
MINECOUNT = 10
FLAGCOUNT = 0
difficulty = 'medium'
param_error = 'minebash: Invalid parameters. See \'minebash ?\' for help '
helpstr = '''Usage: minebash [easy|medium|hard] [width height minecount]
Difficulty presets:
easy: 5x5 4 mines
medium: 9x9 15 mines
hard: 12x12 35 mines
Specify your own:
4 4 4 4x4 4 mines
8 8 10 8x8 10 mines
Controls:
Arrow Keys: Move Cursor
Spacebar: Try field
F: Place flag
'''
if len(sys.argv) > 1:
if len(sys.argv) == 2: #param is string like easy, hard
if sys.argv[1] == '?':
print(helpstr)
sys.exit(0)
if sys.argv[1] == 'easy':
width = 5
height = 5
MINECOUNT = 4
elif sys.argv[1] == 'medium':
width = 9
height = 9
MINECOUNT = 15
elif sys.argv[1] == 'hard':
width = 12
height = 12
MINECOUNT = 35
else:
print(param_error)
sys.exit(0)
difficulty = sys.argv[1]
elif len(sys.argv) == 4: #this means the user has specified width, height and minecount
width = int(sys.argv[1])
height = int(sys.argv[2])
if int(sys.argv[3]) < width*height:
MINECOUNT = int(sys.argv[3])
difficulty = 'custom'
else:
print('Minecount muss be less than width x height.')
system.exit(0)
else:
print(param_error)
sys.exit(0)
playfield = [[UNKNOWN for x in range(width)] for y in range(height)]
#stdscr = curses.initscr()
#curses.noecho()
#curses.cbreak()
headline = '.'
midline = '|'
tailline = '\''
def setup_strings(colcount):
#setup lines to print
for i in range(colcount):
global headline, midline, tailline
headline += '---.'
midline += '---|'
tailline += '---\''
def endgame(msg=''):
# curses.nocbreak()
# stdscr.keypad(False)
# curses.echo()
#curses.endwin()
if msg != '':
print(msg)
sys.exit(0)
def calculate_hint(col, row):
hint = 0
if playfield[row][col] != MINE:
for x in range(col-1, col+2):
if x >= 0 and x < len(playfield):
for y in range(row-1, row+2):
if y >= 0 and y < len(playfield[0]):
if playfield[y][x] == MINE or playfield[y][x] == FLAG_MINE:
hint+=1
else:
hint = MINE
return hint
def setup_playfield(w, h, x, y):
#do this only once [AFTER THE FIRST GUESS] -> Done
#randomly distribute mines across the field
global playfield, FIELD_GENERATED, STARTTIME
minesleft = MINECOUNT
while minesleft > 0:
randx = random.randint(0, width-1)
randy = random.randint(1, height-1)
if playfield[randy][randx] != MINE and randx != x and randy != y:
playfield[randy][randx] = MINE
minesleft -= 1
FIELD_GENERATED = True
STARTTIME = time.time()
def gameover(win):
SCREEN.clear()
if not win:
SCREEN.addstr(0, 0, ' ________________')
SCREEN.addstr(1, 0, ' ____/ ( ( ) ) \___')
SCREEN.addstr(2, 0, ' /( ( ( ) _ )) ) )\ ')
SCREEN.addstr(3, 0, ' (( ( )( ) ) ( ) )')
SCREEN.addstr(4, 0, ' ((/ ( _( ) ( _) ) ( () ) )')
SCREEN.addstr(5, 0, ' ( ( ( (_) (( ( ) .((_ ) . )_')
SCREEN.addstr(6, 0, ' ( ( ) ( ( ) ) ) . ) ( )')
SCREEN.addstr(7, 0, ' ( ( ( ( ) ( _ ( _) ). ) . ) ) ( )')
SCREEN.addstr(8, 0, ' ( ( ( ) ( ) ( )) ) _)( ) ) )')
SCREEN.addstr(9, 0, ' ( ( ( \ ) ( (_ ( ) ( ) ) ) ) )) ( )')
SCREEN.addstr(10, 0, ' ( ( ( ( (_ ( ) ( _ ) ) ( ) ) )')
SCREEN.addstr(11, 0, ' ( ( ( ( ( ) (_ ) ) ) _) ) _( ( )')
SCREEN.addstr(12, 0, ' (( ( )( ( _ ) _) _(_ ( (_ )')
SCREEN.addstr(13, 0, ' (_((__(_(__(( ( ( | ) ) ) )_))__))_)___)')
SCREEN.addstr(14, 0, ' ((__) \\||lll|l||/// \_))')
SCREEN.addstr(15, 0, ' ( /(/ ( ) ) )\ )')
SCREEN.addstr(16, 0, ' ( ( ( ( | | ) ) )\ )')
SCREEN.addstr(17, 0, ' ( /(| / ( )) ) ) )) )')
SCREEN.addstr(18, 0, ' ( ( ((((_(|)_))))) )')
SCREEN.addstr(19, 0, ' ( ||\(|(|)|/|| )')
SCREEN.addstr(20, 0, ' ( |(||(||)|||| )')
SCREEN.addstr(21, 0, ' ( //|/l|||)|\\ \ )')
SCREEN.addstr(22, 0, ' (/ / // /|//||||\\ \ \ \ _)')
SCREEN.addstr(23, 0, ' You lose! Press q to quit.')
else:
now = time.time()
elapsed = now - STARTTIME
mins = elapsed / 60
secs = elapsed % 60
winstr = 'You win! It took you {}:{} to bash the field!'.format(int(mins), str(round(secs, 2)).zfill(5))
SCREEN.addstr(0, 0, ' /$$ /$$ /$$ /$$ /$$$$$$$ /$$')
SCREEN.addstr(1, 0, '| $$ /$ | $$ | $$| $$ | $$__ $$ | $$')
SCREEN.addstr(2, 0, '| $$ /$$$| $$ /$$$$$$ | $$| $$ | $$ \ $$ /$$$$$$ /$$$$$$$ /$$$$$$ | $$')
SCREEN.addstr(3, 0, '| $$/$$ $$ $$ /$$__ $$| $$| $$ | $$ | $$ /$$__ $$| $$__ $$ /$$__ $$| $$')
SCREEN.addstr(4, 0, '| $$$$_ $$$$| $$$$$$$$| $$| $$ | $$ | $$| $$ \ $$| $$ \ $$| $$$$$$$$|__/')
SCREEN.addstr(5, 0, '| $$$/ \ $$$| $$_____/| $$| $$ | $$ | $$| $$ | $$| $$ | $$| $$_____/ ')
SCREEN.addstr(6, 0, '| $$/ \ $$| $$$$$$$| $$| $$ | $$$$$$$/| $$$$$$/| $$ | $$| $$$$$$$ /$$')
SCREEN.addstr(7, 0, '|__/ \__/ \_______/|__/|__/ |_______/ \______/ |__/ |__/ \_______/|__/')
SCREEN.addstr(10, 0, winstr)
SCREEN.addstr(11,0, 'Press q to quit!')
while True:
key = SCREEN.getch()
if key == ord('q'):
endgame()
#if key == ord('r'):
# os.execl(sys.executable, sys.executable, *sys.argv)
def print_playfield(playfield, screen):
global score_x, score_y
currentline = 0
screen.addstr(currentline, 10, headline, curses.color_pair(1))
currentline +=1
#print headline
for rowindex, row in enumerate(playfield):
screen.addstr(currentline, 10, '|')
pos = OFFSET
for colindex, cell in enumerate(row):
# is the cell selected?
selected = False
if [colindex, rowindex] == CURSOR_POSITION:
screen.addstr(currentline, pos, '[')
selected = True
else:
screen.addstr(currentline, pos, ' ')
pos += 1
# did we find a hint?
if cell > 0:
if cell == 1: color = curses.color_pair(3) #cyan
elif cell == 2: color = curses.color_pair(4) #blue
else: color = curses.color_pair(5) #yellow
screen.addstr(currentline, pos, str(cell), color)
elif cell == 0:
screen.addstr(currentline, pos, ' ')
elif cell == UNKNOWN or cell == MINE:
screen.addstr(currentline, pos, '#', curses.color_pair(7)) #rowstring+= '#'
elif cell == FLAG_MINE or cell == FLAG:
screen.addstr(currentline, pos, 'P', curses.color_pair(2)) #rowstring += 'P'
#elif cell == MINE:
# rowstring += 'X'
pos += 1
if selected:
screen.addstr(currentline, pos, ']|')
else:
screen.addstr(currentline, pos, ' |')
pos += 2
currentline +=1
if(rowindex < len(row)-1):
screen.addstr(currentline, 10, midline)
currentline +=1
screen.addstr(currentline, 10, tailline)
currentline +=1
score_y = currentline
score_x = int(pos/2)
#print tailline
def hit(x, y, recursive_call=False):
global playfield, FIELDS_CLEARED
if playfield[y][x] == UNKNOWN:
hint = calculate_hint(x, y)
playfield[y][x] = hint
FIELDS_CLEARED += 1
if not recursive_call and hint == NOTHING:
for i in range(x-1, x+2):
for j in range(y-1, y+2):
if i >= 0 and i < width:
if j >= 0 and j< height:
if playfield[j][i] == UNKNOWN:
hint = calculate_hint(i, j)
if hint > 0 and hint<3:
hit(i,j, True)
if hint == 0:
hit(i,j)
elif playfield[y][x] == MINE:
gameover(False)
def check_score():
if FIELDS_CLEARED == (width*height)-MINECOUNT:
gameover(True)
def place_flag(x, y):
global playfield, FLAGCOUNT
#playfield[y][x] = playfield[y][x]
if playfield[y][x] == MINE:
playfield[y][x] = FLAG_MINE
FLAGCOUNT += 1
elif playfield[y][x] == UNKNOWN:
playfield[y][x] = FLAG
FLAGCOUNT += 1
elif playfield[y][x] == FLAG_MINE:
playfield[y][x] = MINE
FLAGCOUNT -= 1
elif playfield[y][x] == FLAG:
playfield[y][x] = UNKNOWN
FLAGCOUNT -=1
def handle_input(k):
global CURSOR_POSITION, firstmove
if k == curses.KEY_LEFT:
if CURSOR_POSITION[0] > 0:
CURSOR_POSITION[0] -=1
elif k == curses.KEY_RIGHT:
if CURSOR_POSITION[0] < width-1:
CURSOR_POSITION[0] +=1
elif k == curses.KEY_UP:
if CURSOR_POSITION[1] > 0:
CURSOR_POSITION[1] -=1
elif k == curses.KEY_DOWN:
if CURSOR_POSITION[1] < height-1:
CURSOR_POSITION[1] +=1
elif k == ord('f'):
if FIELD_GENERATED:
place_flag(CURSOR_POSITION[0], CURSOR_POSITION[1])
elif k == ord(' '):
if not firstmove:
firstmove = True
else:
hit(CURSOR_POSITION[0], CURSOR_POSITION[1])
def print_score(screen):
scorestr = 'Mines: {} Flags: {} Difficulty: {}'.format(MINECOUNT, FLAGCOUNT, difficulty)
xpos = int((score_x) - (len(scorestr)/2)) + int(OFFSET/2)
screen.addstr(score_y, xpos, scorestr)
def setup_colors():
curses.start_color()
curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK)
curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
curses.init_pair(3, curses.COLOR_CYAN, curses.COLOR_BLACK)
curses.init_pair(4, curses.COLOR_BLUE, curses.COLOR_BLACK)
curses.init_pair(5, curses.COLOR_YELLOW, curses.COLOR_BLACK)
curses.init_pair(7, curses.COLOR_WHITE, curses.COLOR_WHITE)
def main(stdscr):
global SCREEN
SCREEN = stdscr
stdscr.clear()
setup_strings(width)
setup_colors()
#generate mines:
#TODO: user input
while(True):
print_playfield(playfield, stdscr)
key = stdscr.getch()
handle_input(key)
if (firstmove) and not (FIELD_GENERATED):
setup_playfield(width, height, CURSOR_POSITION[0], CURSOR_POSITION[1])
handle_input(key)
STARTTIME = time.time()
check_score()
print_score(stdscr)
stdscr.refresh()
#stdscr.getkey()
if __name__ == "__main__":
wrapper(main)
Loading…
Cancel
Save