暴力解决游戏《崩坏:星穹铁道》中的引航罗盘解密。由于复杂度较低,所以暴力解具有可行性。
图片介绍参数设定:
import sys# 获取自然数余数def get_nature_remain(dividends: int, divisors: int): remain = dividends % divisors while remain < 0: remain += divisors return remain# 计算符号位,返回至3*3符号矩阵def get_sign(method, directions: tuple): if (len(directions) != 1 and method < 3) or (len(directions) != 2 and method > 2): print('输入格式不正确') sys.exit(-2) if method == 0: # 外圈 return [(0, 0, directions[0]), ] elif method == 1: # 中圈 return [(1, 0, directions[0]), ] elif method == 2: # 内圈 return [(2, 0, directions[0]), ] elif method == 3: # 外中 return [(0, 1, directions[0]), (1, 1, directions[1])] elif method == 4: # 外内 return [(0, 2, directions[0]), (2, 1, directions[1])] else: # 中内 return [(1, 2, directions[0]), (2, 2, directions[1])]# 打印结果def result_print(index, rotate): if index == 0: print('最外圈转', rotate) elif index == 1: print('中间圈转', rotate) elif index == 2: print('最内圈转', rotate) elif index == 3: print('外中联动圈转', rotate) elif index == 4: print('外内联动圈转', rotate) else: print('中内联动圈转', rotate)# 解法为暴力解def star_rail_LuoPan(points: tuple, rotates: tuple, methods: tuple): # 判断输入是否正确 if min(points) < 0 or min(rotates) < 0 or min(methods[0]) < 0 or max(points) > 5 or max(rotates) > 6 or max(methods[0]) > 6 or len(points) != 3 or len(rotates) != 3 or len(methods[0]) != 3 or len(set(methods[0])) != 3: print('输入格式不正确') sys.exit(-1) # 常量参数初始化 p1, p2, p3 = points r1, r2, r3 = rotates # 变量参数矩阵 f = [0 for _ in range(6)] x = methods[0][0] - 1 y = methods[0][1] - 1 z = methods[0][2] - 1 # 公式正负号,顺逆转 sign = [[1, 1, 1], [1, 1, 1], [1, 1, 1]] for i in range(3): for row, col, t_sign in get_sign(method=methods[0][i] - 1, directions=methods[1][i]): sign[row][col] *= t_sign flag = False # 是否存在解,默认不存在解 # 6为一轮,超过6相当于从0开始(数论) for i in range(6): f[x] = i for j in range(6): f[y] = j for k in range(6): f[z] = k # 计算公式 a1 = get_nature_remain(dividends=p1 + (sign[0][0]*f[0] + sign[0][1]*f[3] + sign[0][2]*f[4]) * r1, divisors=6) a2 = get_nature_remain(dividends=p2 + (sign[1][0]*f[1] + sign[1][1]*f[3] + sign[1][2]*f[5]) * r2, divisors=6) a3 = get_nature_remain(dividends=p3 + (sign[2][0]*f[2] + sign[2][1]*f[4] + sign[2][2]*f[5]) * r3, divisors=6) # 当前参数是否满足正确解 if a1 + a2 + a3 == 0: print('*' * 60) result_print(x, i) result_print(y, j) result_print(z, k) flag = True # 存在解 return flagif __name__ == '__main__': # 程序设计有很多参数设定,都是程序猿,相信你能看懂[doge] # 注意,假设取最终汇聚方向处为0°点。下面为一个例子: p = (4, 4, 2) # 设置三个圈点的初始值 < 6,例子的解释为最外圈起始点240°(4*60°,以下同理),中圈240°,内圈120° r = (4, 4, 4) # 设置一次转动的角度 <= 6,例子的解释为最外圈一次转240°,中圈240°,内圈240° # m[0],1为外圈单转,2为中圈单转,3为内圈单转,4为外中圈联动同转,5为外内圈联动同转,6为中外圈联动同转 # m[1],转动方向顺逆,单转要求tuple大小为1,联动转要求tuple大小为2,与m[0]一一对应,1为顺时针,-1为逆时针 m = ((2, 3, 5), ((1,), (-1,), (-1, -1)),) if not star_rail_LuoPan(points=p, rotates=r, methods=m): print('不存在正确解')