/
lockpick.py
176 lines (157 loc) · 3.77 KB
/
lockpick.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import random, sys
sys.path.append("..")
import consolelib
class Pick(object):
def __init__(self, s):
self.s = s
rows = s.split("\n")
self.width = len(max(rows, key=len))
self.height = len(rows)
picks = [
"""\
====""",
"""\
==
==""",
"""\
=
===""",
"""\
==
==""",
"""\
==
==""",
"""\
=
===""",
"""\
=
==
="""
]
for i, s in enumerate(picks):
picks[i] = Pick(s)
locks = [[
"""\
=
====
==="""
],[
"""\
= =
====
==""",
"""\
==
==
====
==""",
"""\
==
===
====
===""",
],[
"""\
==
====
= ==
===""",
"""\
===
=====
=
====
===""",
]]
for diff, difftab in enumerate(locks):
for i, lock in enumerate(difftab):
difftab[i] = [" "]*25
for y, line in enumerate(lock.split("\n")):
for x, val in enumerate(line):
difftab[i][y*5 + x] = val #(val=="=") and 1 or 0
helptext = """Help :
wasd : Move current pin
q e : Change current pin
space: Weld current pin
enter: Attempt to unlock
z : Start over
ctl-c: Give up
Pins Remaining: \
"""
def main(difficulty, pins):
"""Engages the lockpicking minigame.
returns 0 (player gave up with ctrl-c), False (fail), True (success)
"""
#Draw the lock (left hand side)
lock = random.choice(locks[difficulty-1])
slock = " Lock:\n"
for y in range(-1, 6):
for x in range(-1, 6):
if x == -1 or y == -1 or x == 5 or y == 5:
slock += "#" #borders
else:
slock += lock[y*5 + x] == "=" and "." or "#"
slock += "\n"
tkey = [" "]*25
posx = posy = 0
pick = 0
press = ""
while True:
#Change selected tetronimo
pick += (press == "q" and -1 or (press == "e" and 1) or 0)
if pick < 0: pick = len(picks) - 1
elif pick >= len(picks): pick = 0
#Move the tetromino around
posx += (press == "d" and 1 or (press == "a" and -1))
posy += (press == "s" and 1 or (press == "w" and -1))
while (posx + picks[pick].width) > 5: posx -= 1
while (posy + picks[pick].height) > 5: posy -= 1
if posx < 0: posx = 0
if posy < 0: posy = 0
#Save the current tetronimo + position with `space`
if press == " ":
if pins < 1:
print("You don't have any pins remaining.")
return 0, pins
for y, row in enumerate(picks[pick].s.split("\n")):
for x, char in enumerate(row):
if char == "=": tkey[(posy+y)*5 + (posx+x)] = "="
pins -= 1
#Clear the saved tetrominos with `z`
elif press == "z":
tkey = [" "]*25
#Attempt to solve the lock
elif press == "\r":
result = lock == tkey
if result: print("Your makeshift key manages to open the lock!")
else: print("Your makeshift key isn't tripping all the tumblers; the door remains locked.")
return result, pins
#== DRAWING ==
#=============
current = [" "]*25
#Draw the previous tetrominos
for i, char in enumerate(tkey):
if char != " ": current[i] = char
#Draw the current tetromino
for y, row in enumerate(picks[pick].s.split("\n")):
for x, char in enumerate(row):
if char != " ":
current[(posy+y)*5 + (posx+x)] = consolelib.background(current[(posy+y)*5 + (posx+x)], "RED")
#Convert the current board into a string
skey = " Key:\n" + "#"*7 + "\n"
for i in range(0,25,5): skey += "#" + "".join(current[i:i+5]) + "#\n"
skey += "#"*7
consolelib.clear()
print("""\
Using your Booker, you scan the internal layout of the tumblers, creating
a 3D model. You'll need to bend your flexium pins to the correct shape,
and then flashweld them to create a working key.\n""")
print(consolelib.screenSplit((slock, skey, helptext + str(pins)), width=10) + "\n")
try: press = consolelib.getKey()
except KeyboardInterrupt:
print("You decide to give up on picking the lock for now.")
return 0, pins
if __name__ == "__main__":
print(main(1, 10))