aboutsummaryrefslogtreecommitdiff
path: root/fifteen.py
diff options
context:
space:
mode:
Diffstat (limited to 'fifteen.py')
-rw-r--r--fifteen.py170
1 files changed, 170 insertions, 0 deletions
diff --git a/fifteen.py b/fifteen.py
new file mode 100644
index 0000000..070494d
--- /dev/null
+++ b/fifteen.py
@@ -0,0 +1,170 @@
+import curses
+from curses import wrapper
+import random
+
+board = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
+winning_board = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
+moves = ['u', 'd', 'l', 'r']
+
+def init_board(rand_moves):
+ # make a number of random moves
+ for i in range(0,rand_moves):
+ r = random.choice(moves)
+ if r is 'u':
+ do_up()
+ elif r is 'd':
+ do_down()
+ elif r is 'l':
+ do_left()
+ elif r is 'r':
+ do_right()
+
+# True if we've won, False if not
+def has_won():
+ if board == winning_board:
+ return True
+ return False
+
+# returns the index of the blank tile
+def blank():
+ return board.index(16)
+
+# Move validity
+def can_down():
+ return blank() // 4 != 0
+def can_up():
+ return blank() // 4 != 3
+def can_right():
+ return blank() % 4 != 0
+def can_left():
+ return blank() % 4 != 3
+
+# perform a move
+def move(offset):
+ oc = blank()
+ ov = board[oc]
+ tc = blank() + offset
+ tv = board[tc]
+ board[oc] = tv
+ board[tc] = ov
+def do_right():
+ if can_right():
+ move(-1)
+ return True
+ return False
+def do_left():
+ if can_left():
+ move(1)
+ return True
+ return False
+def do_down():
+ if can_down():
+ move(-4)
+ return True
+ return False
+def do_up():
+ if can_up():
+ move(4)
+ return True
+ return False
+
+# main method
+def main(stdscr):
+
+ # set up a board with 400 random moves
+ init_board(400)
+ mvs = 0
+ print_board(stdscr, mvs)
+
+ # loop until someone presses "q"
+ while 1:
+
+ # move based on input
+ c = stdscr.getch()
+ if c == curses.KEY_LEFT:
+ if do_left():
+ mvs = mvs + 1
+ elif c == curses.KEY_RIGHT:
+ if do_right():
+ mvs = mvs + 1
+ elif c == curses.KEY_UP:
+ if do_up():
+ mvs = mvs + 1
+ elif c == curses.KEY_DOWN:
+ if do_down():
+ mvs = mvs + 1
+ elif c == ord('q'):
+ break
+
+ # print the new board
+ print_board(stdscr, mvs)
+
+# print an empty board
+def print_empty_board(stdscr, y, x):
+ # print the first line of dashes
+ stdscr.addstr(y,x*5,"{:-^21}".format(""), curses.A_BOLD)
+
+ # empty squares
+ for i in range(1,5):
+ for j in range(0,5):
+ stdscr.addstr((i+y), (j+x)*5, "|", curses.A_BOLD)
+
+ # print the last line of dashes
+ stdscr.addstr((5+y), x*5,"{:-^21}".format(""), curses.A_BOLD)
+
+# print the tiles of a board
+def print_board_tiles(stdscr, b, y, x):
+
+ # create the color pairs
+ curses.init_pair(1, curses.COLOR_RED, curses.COLOR_WHITE)
+ curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_RED)
+
+ # put in numbers
+ ocnt = y+1
+ icnt = (x*5)+1
+ for i,v in enumerate(b):
+ # odds get one color, evens the other
+ if v % 2 == 1:
+ stdscr.addstr(ocnt,icnt,"{:^4}".format(v), curses.color_pair(1))
+ elif v == 16:
+ # blank tile gets no coloring
+ stdscr.addstr(ocnt,icnt,"{:^4}".format(""))
+ else:
+ stdscr.addstr(ocnt,icnt,"{:^4}".format(v), curses.color_pair(2))
+
+ # update counts
+ if (i+1) % 4 == 0:
+ ocnt = ocnt + 1
+ icnt = (x*5) + 1
+ else:
+ icnt = icnt + 5
+
+
+def print_board(stdscr, mvs):
+ # clear screen
+ stdscr.clear()
+
+ # headers
+ stdscr.addstr(0, 0, "{:~^56}".format("Fifteen Puzzle"), curses.A_BOLD)
+ stdscr.addstr(2, 0, "{:^21}".format("Play"))
+ stdscr.addstr(2, 35, "{:^21}".format("Target"))
+
+ # print play board
+ print_empty_board(stdscr, 3, 0)
+ print_board_tiles(stdscr, board, 3, 0)
+
+ # print target board
+ print_empty_board(stdscr, 3, 7)
+ print_board_tiles(stdscr, winning_board, 3, 7)
+
+ # print the moves
+ stdscr.addstr(9, 0, "{} moves".format(str(mvs)))
+
+ # print if we won
+ stdscr.addstr(9, 35, "Have we won? {}".format(str(has_won())))
+
+ # refresh the screen
+ stdscr.refresh()
+
+# wrap the main method in the curses wrapper
+wrapper(main)