暴力解决游戏《崩坏:星穹铁道》中的引航罗盘解密。由于复杂度较低,所以暴力解具有可行性。
图片介绍参数设定:
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 flag
if __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('不存在正确解')