forked from asweigart/the-big-book-of-small-python-projects
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslidingtilepuzzle.py
138 lines (108 loc) · 3.95 KB
/
slidingtilepuzzle.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
"""Sliding Tile Puzzle, by Al Sweigart [email protected]
Slide the numbered tiles into the correct order.
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: large, game, puzzle"""
import random, sys
BLANK = ' ' # Note: This string is two spaces, not one.
def main():
print('''Sliding Tile Puzzle, by Al Sweigart [email protected]
Use the WASD keys to move the tiles
back into their original order:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 ''')
input('Press Enter to begin...')
gameBoard = getNewPuzzle()
while True:
displayBoard(gameBoard)
playerMove = askForPlayerMove(gameBoard)
makeMove(gameBoard, playerMove)
if gameBoard == getNewBoard():
print('You won!')
sys.exit()
def getNewBoard():
"""Return a list of lists that represents a new tile puzzle."""
return [['1 ', '5 ', '9 ', '13'], ['2 ', '6 ', '10', '14'],
['3 ', '7 ', '11', '15'], ['4 ', '8 ', '12', BLANK]]
def displayBoard(board):
"""Display the given board on the screen."""
labels = [board[0][0], board[1][0], board[2][0], board[3][0],
board[0][1], board[1][1], board[2][1], board[3][1],
board[0][2], board[1][2], board[2][2], board[3][2],
board[0][3], board[1][3], board[2][3], board[3][3]]
boardToDraw = """
+------+------+------+------+
| | | | |
| {} | {} | {} | {} |
| | | | |
+------+------+------+------+
| | | | |
| {} | {} | {} | {} |
| | | | |
+------+------+------+------+
| | | | |
| {} | {} | {} | {} |
| | | | |
+------+------+------+------+
| | | | |
| {} | {} | {} | {} |
| | | | |
+------+------+------+------+
""".format(*labels)
print(boardToDraw)
def findBlankSpace(board):
"""Return an (x, y) tuple of the blank space's location."""
for x in range(4):
for y in range(4):
if board[x][y] == ' ':
return (x, y)
def askForPlayerMove(board):
"""Let the player select a tile to slide."""
blankx, blanky = findBlankSpace(board)
w = 'W' if blanky != 3 else ' '
a = 'A' if blankx != 3 else ' '
s = 'S' if blanky != 0 else ' '
d = 'D' if blankx != 0 else ' '
while True:
print(' ({})'.format(w))
print('Enter WASD (or QUIT): ({}) ({}) ({})'.format(a, s, d))
response = input('> ').upper()
if response == 'QUIT':
sys.exit()
if response in (w + a + s + d).replace(' ', ''):
return response
def makeMove(board, move):
"""Carry out the given move on the given board."""
# Note: This function assumes that the move is valid.
bx, by = findBlankSpace(board)
if move == 'W':
board[bx][by], board[bx][by+1] = board[bx][by+1], board[bx][by]
elif move == 'A':
board[bx][by], board[bx+1][by] = board[bx+1][by], board[bx][by]
elif move == 'S':
board[bx][by], board[bx][by-1] = board[bx][by-1], board[bx][by]
elif move == 'D':
board[bx][by], board[bx-1][by] = board[bx-1][by], board[bx][by]
def makeRandomMove(board):
"""Perform a slide in a random direction."""
blankx, blanky = findBlankSpace(board)
validMoves = []
if blanky != 3:
validMoves.append('W')
if blankx != 3:
validMoves.append('A')
if blanky != 0:
validMoves.append('S')
if blankx != 0:
validMoves.append('D')
makeMove(board, random.choice(validMoves))
def getNewPuzzle(moves=200):
"""Get a new puzzle by making random slides from a solved state."""
board = getNewBoard()
for i in range(moves):
makeRandomMove(board)
return board
# If this program was run (instead of imported), run the game:
if __name__ == '__main__':
main()