本文詳實的記錄的我的思考過程,類似流水賬....
目前已經爛尾,我對付不了133關后面的關卡
這個手機游戲挺不錯的,就是有點難,所以要寫程序,暴力的通關。
游戲名字:Calculator:The Game
編程語言:python
圖標長這個樣子
游戲界面這個樣子
灰色按鈕表示對數字的操作
游戲很簡單,在步數限制內,將數字變成“目標數字”
目前看上去,很容易,for循環+eval函數就可以解決問題
就算后來出現了乘除 eval函數 也能應付
s = [ "+2" ,"+3"] begin = 0 end = 8 for i_0 in s: for i_1 in s: for i_2 in s: num = begin num =eval( str(num) +i_0 ) num =eval( str(num) +i_1 ) num =eval( str(num) +i_2 ) if num == end: print(i_0,end = ",") print(i_1,end = ",") print(i_2)
后來果然出現了乘除
而且步數限制變成了4,也就是加個for循環的事
后來解鎖了一個新的鍵 它可以刪掉數字的最后一位,例如 4321-->432-->43-->4
其實,它並不算新運算,它就是“//10”
>>> s = ["+8","*5","//10"] >>> begin = 0 >>> end = 4 >>> game_3(s,begin,end) +8,*5,//10
ps:我已經悄悄的包裝成函數啦
后來限制步數變成了5 我不想再添for了
現在開始思考
>>> s = ["+2","+3"] >>> con = s #定義變量con表示所有可能的解法 #當步數為1時,con就等於s >>> con = [ (x,y) for x in con for y in s] >>> con [('+2', '+2'), ('+2', '+3'), ('+3', '+2'), ('+3', '+3')] #當步數為2時,兩層遍歷就可以啦 #但是,再遍歷一次可不是步數為3的情況 >>> con_3 = [ (x,y) for x in con for y in s] >>> con_3 [(('+2', '+2'), '+2'), (('+2', '+2'), '+3'), (('+2', '+3'), '+2'), (('+2', '+3'), '+3'), (('+3', '+2'), '+2'), (('+3', '+2'), '+3'), (('+3', '+3'), '+2'), (('+3', '+3'), '+3')] #仔細觀察(('+2', '+2'), '+2')可不是想要的格式 #('+2', '+2', '+2')才是 #所以遍歷的時候,需要對x解構 >>> con = [ (*x,y) for x in con for y in s] >>> con [('+2', '+2', '+2'), ('+2', '+2', '+3'), ('+2', '+3', '+2'), ('+2', '+3', '+3'), ('+3', '+2', '+2'), ('+3', '+2', '+3'), ('+3', '+3', '+2'), ('+3', '+3', '+3')] #這才是正確的做法
完整的代碼
s = tuple(s) con = s con = ( (x,y) for x in con for y in s) for i in range(step-2): con = ( (*x,y) for x in con for y in s) #列表生成式 改成 生成器 #為了避免的不必要的麻煩,list改成tuple
PS:因為這個游戲的特性,步數不可能是1,2(那樣就太簡單了)
然后對con遍歷,尋找正確的解
然后整體加上必要的input(),實際使用中發現,輸入按鈕類型時,輸入大量的引號,對此做點優化
def game(): begin = int(input("初始數字:")) end = int(input("目標數字:")) step = int(input("限制步數:")) s = [] n = int(input("按鈕數量:")) for i in range(n): s.append(input("第%d個:"%(i+1))) s = tuple(s) con = s con = ( (x,y) for x in con for y in s) for i in range(step-2): con = ( (*x,y) for x in con for y in s) for i in con : num = begin for j in i: num = eval(str(num) + j) if num == end: print(i)
實際的使用情況
>>> game() 初始數字:0 目標數字:404 限制步數:5 按鈕數量:3 第1個:+8 第2個:*10 第3個:/2 ('+8', '*10', '*10', '+8', '/2') >>> game() 初始數字:171 目標數字:23 限制步數:4 按鈕數量:3 第1個:*2 第2個:-9 第3個://10 ('-9', '*2', '//10', '-9') ('-9', '//10', '*2', '-9')
出現里新按鈕 它可以在數字最后面加一個數字
那也沒問題這個按鈕可以理解為“*10+1” 當然,直接一個1也是可以的
>>> a = 23 >>> b = eval(str(a)+'5') >>> b 235
初始數字:0 目標數字:56 限制步數:3 按鈕數量:2 第1個:1 第2個:+5 Traceback (most recent call last): File "F:\py\測試IDEL\5-3.py", line 48, in <module> game() File "F:\py\測試IDEL\5-3.py", line 44, in game num = eval(str(num) + j) File "<string>", line 1 01 ^ SyntaxError: invalid token
遭遇了一個錯誤↑↑↑
還是老老實實的寫成*10+1吧
26級左右出現了新按鈕,其實也沒啥, *100+10 就可以啦
我本以為,我可以靠這點代碼打通關的,結果我錯了
好吧對代碼進行微調
for i in con : num = begin for j in i: if "-/" not in j: num = eval(str(num) + j) else: num = int(str(num).replace( j[0], j[3])) if num == end: print(i)
使用情況
初始數字:0 目標數字:93 限制步數:4 按鈕數量:3 第1個:+6 第2個:*7 第3個:6-/9 ('+6', '6-/9', '*7', '6-/9')
完美 φ(>ω<*)
32關遭遇bug
初始數字:11 目標數字:29 限制步數:5 按鈕數量:4 第1個:/2 第2個:+3 第3個:1-/2 第4個:2-/9 Traceback (most recent call last): File "F:\py\測試IDEL\5-3.py", line 52, in games game() File "F:\py\測試IDEL\5-3.py", line 47, in game num = int(str(num).replace( j[0], j[3])) ValueError: invalid literal for int() with base 10: '0.6875'
解決方法 : int改為float
當初偷得懶,遲早要還的 T^T
for i in con : num = begin for j in i: if "-/" not in j: num = eval(str(num) + j) else: k = j.split('-/') num = float(str(num).replace( *k )) if num == end: print(i)
后來出現了負數....-1 *10+5 = -5 對負數而言 應該是*10-5才對
好吧,再改改
for i in con : num = begin for j in i: if "-/" in j: k = j.split('-/') num = float(str(num).replace( *k )) elif "++" in j: k =int( j.split('++')[-1] ) num = num*10 + k if num >=0 else num*10 - k else: num = eval(str(num) + j) if num == end: print(i)
Q:k =int( j.split('++')[-1] )中的[-1]是什么意思
A:split產生的是列表,而且++前面的空白也被切出來了..所以不是[0]
>>> '++5'.split('++') ['', '5']
使用情況
初始數字:0 目標數字:-85 限制步數:4 按鈕數量:3 第1個:+6 第2個:++5 第3個:-7 ('+6', '-7', '-7', '++5') ('-7', '+6', '-7', '++5') ('-7', '-7', '+6', '++5')
PS:再也不用打*10+5啦,格式改成++5
39左右出現新按鈕
for j in i: if "-/" in j: k = j.split('-/') num = float(str(num).replace( *k )) elif "++" in j: k =int( j.split('++')[-1] ) num = num*10 + k if num >=0 else num*10 - k elif "+-" in j : num = -num else: num = eval(str(num) + j) if num == end: print(i)
使用情況
>>>game() 初始數字:0 目標數字:-13 限制步數:4 按鈕數量:3 第1個:+3 第2個:-7 第3個:+- ('+3', '+3', '+-', '-7')
看來得加入新東西啦
if "-/" in j: k = j.split('-/') num = float(str(num).replace( *k )) elif "++" in j: k =int( j.split('++')[-1] ) num = num*10 + k if num >=0 else num*10 - k elif "+-" in j : num = -num elif "00" in j: num = int(str(num)[::-1]) else: num = eval(str(num) + j)
另外,大量使用中發現,基礎的數據需要手動錄入那沒有辦法,那只能減少其它不必要的按鍵
#原來的 begin = int(input("初始數字:")) end = int(input("目標數字:")) step = int(input("限制步數:")) s = [] n = int(input("按鈕數量:")) for i in range(n): s.append(input("第%d個:"%(i+1))) #改后 begin ,end, step = map(int,input("始-終-步:").split(" ")) s = input("按鈕們:").split(" ")
使用效果
遭遇bug
>>>game() 始-終-步:0 58 4 按鈕們:+4 *4 -3 00 ('+4', '*4', '00', '-3') Traceback (most recent call last): File "F:\py\測試IDEL\5-3.py", line 65, in games game() File "F:\py\測試IDEL\5-3.py", line 57, in game num = int(str(num)[::-1]) ValueError: invalid literal for int() with base 10: '2-'
負數的問題..
微調下(游戲里面應該不會有“翻轉”負數的情況)
elif "00" in j: if num >= 0: num = int(str(num)[::-1]) else: break
第2個bug
>>>game() 始-終-步:6 4 3 按鈕們:++1 /4 00 Traceback (most recent call last): File "F:\py\測試IDEL\5-3.py", line 68, in games game() File "F:\py\測試IDEL\5-3.py", line 58, in game num = int(str(num)[::-1]) ValueError: invalid literal for int() with base 10: '52.51'
看來小數也不行
elif "00" in j: if num >= 0 and num%1 == 0 : num = int(str(num)[::-1]) else: break
又一個bug
>>>game() 始-終-步:6 4 3 按鈕們:++1 /4 00 ('++1', '00', '/4') ('/4', '++1', '/4') Traceback (most recent call last): File "F:\py\測試IDEL\5-3.py", line 68, in games game() File "F:\py\測試IDEL\5-3.py", line 58, in game num = int(str(num)[::-1]) ValueError: invalid literal for int() with base 10: '0.61'
浮點數也不行...
elif "00" in j: if num >= 0 : num = int(str(int(num))[::-1]) else: break
這下應該沒問題啦
62級處,出現無解的情況..
>>>game() 始-終-步:0 102 4 按鈕們:++10 *4 +5 00
原因也找到了,原有的代碼,為了兼容負數,結果兼容不了“添加兩個數字”啦
#原有的 elif "++" in j: k =int( j.split('++')[-1] ) num = num*10 + k if num >=0 else num*10 - k #更改后 elif "++" in j: k = j.split('++')[-1] num = int(str(num)+k)
PS,必須用int 不能用eval,下面感受下它們的不同
>>> a = int("010") >>> a 10 >>> b = eval("010") Traceback (most recent call last): File "<pyshell#7>", line 1, in <module> b = eval("010") File "<string>", line 1 010 ^ SyntaxError: invalid token
OK bug修復
>>>game() 始-終-步:0 102 4 按鈕們:++10 *4 +5 00 ('+5', '*4', '++10', '00')
打臉了,
>>>game() 始-終-步:0 7 4 按鈕們:++2 +1 /3 00 Traceback (most recent call last): File "F:\py\測試IDEL\5-3.py", line 71, in games game() File "F:\py\測試IDEL\5-3.py", line 53, in game num = int(str(num)+k) ValueError: invalid literal for int() with base 10: '7.3333333333333332'
補個int吧
elif "++" in j: k = j.split('++')[-1] num = int(str(int(num))+k)
解決了
>>>game() 始-終-步:0 7 4 按鈕們:++2 +1 /3 00 ('++2', '++2', '/3', '00') ('+1', '++2', '00', '/3')
按第一個解法,結果...
我發現這個游戲里顯示不了小數..
按第一個解法
('++2', '++2', '/3', '00')
0 --> 2 --> 22 --> 7.1 --> 7
else: num = eval(str(num) + j) if num%1 != 0: break if num == end: print(i)
加上些代碼,由於監測num是否變成小數,一旦變了,直接終止
第71級 無解bug
>>>game() 始-終-步:0 -43 5 按鈕們:-5 +7 -9 00
最終原因,游戲里面實驗了下,負數可以翻轉...-18翻轉成-81..
而我的代碼否定了負數的翻轉...
#之前的 elif "00" in j: if num >= 0 : num = int(str(int(num))[::-1]) else: break #改正后 elif "00" in j: if num >= 0 : num = int(str(num)[::-1]) else: num = int(str(num)[1:][::-1])*-1
PS,由於,num不可能是小數,內層的int就去掉了
>>>game() 始-終-步:0 -43 5 按鈕們:-5 +7 -9 00 ('-5', '-9', '00', '+7', '-9') ('-5', '-9', '00', '+7', '00') ('-5', '-9', '00', '-9', '+7') ('-9', '-5', '00', '+7', '-9') ('-9', '-5', '00', '+7', '00') ('-9', '-5', '00', '-9', '+7')
......不知道該說些什么...
>>>game() 始-終-步:88 41 4 按鈕們:/4 -4 00 Traceback (most recent call last): File "F:\py\測試IDEL\5-3.py", line 73, in games game() File "F:\py\測試IDEL\5-3.py", line 61, in game num = int(str(num)[::-1]) ValueError: invalid literal for int() with base 10: '0.41'
#之前 if num%1 != 0: break if num == end: print(i) #之后 if num%1 != 0: break else: num = int(num) if num == end: print(i)
bug:算出的解,游戲里面沒法用
>>>game() 始-終-步:50 101 5 按鈕們:1-/10 +50 00 5-/1 ... ('5-/1', '5-/1', '00', '+50', '+50')
游戲: 如果沒法轉換,按了按鈕,也不算步數...
我的代碼: 如果沒法轉換,按了按鈕,算步數...
結果出現了一些偏差.......
for j in i: if "-/" in j: k = j.split('-/') num = float(str(num).replace( *k )) #改為 for j in i: if "-/" in j: num_0 = num k = j.split('-/') num = float(str(num).replace( *k )) if num_0 == num: break
89級處出現新按鈕
使用+*+表示吧,PS:盡量使用小鍵盤
elif "+*+" in j: num = sum(map(int,str(num)))
103級
>>>game() 始-終-步:9 30 4 按鈕們:-5 *-6 +- +*+ Traceback (most recent call last): File "F:\py\測試IDEL\5-3.py", line 80, in games game() File "F:\py\測試IDEL\5-3.py", line 68, in game num = sum(map(int,str(num))) ValueError: invalid literal for int() with base 10: '-'
經驗證 sum可以對負數求和 -54 --> -9 就是去掉符號再求和
elif "+*+" in j: if num>=0: num = sum(map(int,str(num))) else: num = -num num = sum(map(int,str(num))) num = -num else:
舉個例子1234-->2341-->3412-->4123(這是向左的,還會有向右的)
elif "/**" in j : num = str(num) num = int(num[1:]+num[0]) elif "**/" in j: num = str(num) num = int(num[-1]+num[:-1])
/* 向左, */ 向右
示例
>>>game() 始-終-步:101 121 3 按鈕們:/** **/ +2 ('*/', '+2', '/*')
>>>game() 始-終-步:120 210 5 按鈕們:+1 /** +- Traceback (most recent call last): File "F:\py\測試IDEL\5-3.py", line 91, in games game() File "F:\py\測試IDEL\5-3.py", line 76, in game num = int(num[1:]+num[0]) ValueError: invalid literal for int() with base 10: '123-'
負數..負數是去掉符號再移動
elif "/*" in j : fh = 1 if num>=0 else -1 num = str(abs(num)) num = int(num[1:]+num[0]) num = num*fh elif "*/" in j: fh = 1 if num>=0 else -1 num = str(abs(num)) num = int(num[-1]+num[:-1]) num = num*fh
新按鈕,作用 23---> 2332
elif "---" in j: num = str(num) num = int(num+num[::-1])
使用
>>>game() 始-終-步:91 19 6 按鈕們:+5 --- +*+ ('+5', '+5', '+5', '---', '+5', '+*+') ('+5', '+5', '+5', '---', '+*+', '+5') ...........
經驗證,游戲里面對負數也可以鏡像,老套路,忽略符號....
elif "---" in j: fh = 1 if num>=0 else -1 num = str(abs(num)) num = int(num+num[::-1]) num = num*fh
發現新特性,游戲中不能6位以上的數字
if num%1 != 0 : break else: num = int(num) #改為 if num%1 != 0 or num >=10**6 : break else: num = int(num)
最終代碼
def game(): begin ,end, step = map(int,input("始-終-步:").split(" ")) s = input("按鈕們:").split(" ") s = tuple(s) con = s con = ( (x,y) for x in con for y in s) for i in range(step-2): con = ( (*x,y) for x in con for y in s) for i in con : num = begin for j in i: if "-/" in j: num_0 = num k = j.split('-/') num = float(str(num).replace( *k )) if num_0 == num: break elif "++" in j: k = j.split('++')[-1] num = int(str(num)+k) elif "+-" in j : num = -num elif "00" in j: if num >= 0 : num = int(str(num)[::-1]) else: num = int(str(num)[1:][::-1])*-1 elif "+*+" in j: if num>=0: num = sum(map(int,str(num))) else: num = -num num = sum(map(int,str(num))) num = -num elif "/**" in j : fh = 1 if num>=0 else -1 num = str(abs(num)) num = int(num[1:]+num[0]) num = num*fh elif "**/" in j: fh = 1 if num>=0 else -1 num = str(abs(num)) num = int(num[-1]+num[:-1]) num = num*fh elif "---" in j: fh = 1 if num>=0 else -1 num = str(abs(num)) num = int(num+num[::-1]) num = num*fh else: num = eval(str(num) + j) if num%1 != 0 or num >=10**6 : break else: num = int(num) if num == end: print(i)
爛尾啦
133級遇到了新按鈕,我短時間內找不到解決方法
#