代码拉取完成,页面将自动刷新
"""
请使用Python3.9及以上版本运行
因为程序中使用了 | 运算符来合并字典
(或者你可以改写这部分代码,位置: CONST_OBJECT.__or__)
"""
import random
import analyse
class CONST_OBJECT:
"""
常量
"""
def __init__(self, v, _type):
if not isinstance(v, dict):
self._value = {_type: v}
else:
self._value = v
@property
def value(self):
return self._value
def __or__(self, other):
return CONST_OBJECT(self.value | other.value, '_')
def __contains__(self, item):
for _key in item.value.keys():
_value = item.value[_key]
if _key in self._value.keys():
if self._value[_key] == _value:
pass # 可以
else:
return False
else:
return False
return True
def __eq__(self, other):
return True if self._value == other.value else False
def __repr__(self):
return str(self.value)
class Length(CONST_OBJECT):
def __init__(self, v):
super().__init__(v, "length")
class Key(CONST_OBJECT):
def __init__(self, v):
super().__init__(v, "key")
class File(CONST_OBJECT):
"""
mode : 使用 osu / malody 铺
"""
def __init__(self, path):
super().__init__(path, "osu/malody")
LEFT = CONST_OBJECT(0, "direction")
RIGHT = CONST_OBJECT(1, "direction")
RANDOM = CONST_OBJECT(2, "direction") # 随机生成方向
BITE = CONST_OBJECT(3, "direction") # 首尾相接
LOUTI = CONST_OBJECT(0, "mode")
JIAOHU = CONST_OBJECT(10, "mode")
ZONGLIAN = CONST_OBJECT(20, "mode")
MESS = CONST_OBJECT(30, "mode") # 随机
MIXED = CONST_OBJECT(40, "mode")
KEY = Key(4)
# ZONGLIANLIMIT = CONST_OBJECT(5, "direction")
def getKeyboardMap():
# 获取键位映射表
if KEY.value["key"] == 4:
return 'dfjk'
elif KEY.value["key"] == 5:
return 'dfhjk'
elif KEY.value["key"] == 6:
return 'dfghjk'
elif KEY.value["key"] == 7:
return 'dfghjkl'
...
def getLouti(code):
"""
获取楼梯对应的beatmap
:param code: 存储了 length / direction/ ...
:return:
"""
length = code.value["length"]
key = code.value["key"]
beatmap = []
rightLouti = list(range(key))
leftLouti = list(reversed(rightLouti))
startKEY = 0
# startKEY = random.randint(0, key-1)
length += startKEY
# direction = direction.value["direction"]
if RIGHT in code:
beatmap += rightLouti * (length // key)
beatmap += rightLouti[:length - key * (length // key)]
if LEFT in code: # LEFT / RIGHT
beatmap += leftLouti * (length // key)
beatmap += leftLouti[:length - key * (length // key)]
elif RANDOM in code:
_lastDirection = random.randint(0, 1)
_direction = _lastDirection
while length >= key:
if _direction == _lastDirection: # 方向相同,楼梯直接叠加
beatmap += (rightLouti if _direction else leftLouti)
length -= key
else:
beatmap.pop()
beatmap += (rightLouti if _direction else leftLouti)
length -= key - 1
_lastDirection = _direction
_direction = random.randint(0, 1)
if length:
_direction = random.randint(0, 1)
if _direction == _lastDirection: # 方向相同,楼梯直接叠加
beatmap += (rightLouti if _direction else leftLouti)[:length - key * (length // key)]
else:
beatmap.pop()
beatmap += (rightLouti if _direction else leftLouti)[:length - key * (length // key) + 1]
else: # BITE
_direction = random.randint(0, 1) # 起始方向
beatmap = [-1]
while length >= key:
beatmap.pop()
beatmap += (rightLouti if _direction else leftLouti)
_direction = 1 - _direction
length -= key - 1
if length:
beatmap.pop()
beatmap += (rightLouti if _direction else leftLouti)[:length - key * (length // key)]
return beatmap[startKEY:]
def getJiaohu(code):
"""
获取交互
:param key:
:param code:
:return:
"""
length = code.value["length"]
key = code.value["key"]
beatmap = []
startKey = random.randint(0, key - 1)
endKey = random.randint(0, key - 1)
while endKey == startKey: # 起始点不能与结束点重合
endKey = random.randint(0, key - 1)
singleJiaohu = [startKey, endKey]
beatmap += singleJiaohu * (length // 2)
beatmap += singleJiaohu[:length - 2 * (length // 2)]
return beatmap
def getZonglian(code):
length = code.value["length"]
key = code.value["key"]
beatmap = []
startKey = random.randint(0, key - 1)
beatmap += [startKey] * length
return beatmap
def getMess(code):
length = code.value["length"]
key = code.value["key"]
beatmap = []
for _ in range(length):
beatmap.append(random.randint(0, key - 1))
return beatmap
def _getBeatmap(code):
"""
获取一种模式下的铺面
:param code: 模式代码
<!> 方向的限制对 JIAOHU / MESS / LOUTI 无效
:return:
"""
mode = code.value["mode"]
length = code.value["length"]
key = code.value["key"]
# print(mode, direction)
if LOUTI in code:
return getLouti(code)
elif JIAOHU in code:
return getJiaohu(code)
elif ZONGLIAN in code:
return getZonglian(code)
elif MESS in code:
return getMess(code)
else:
# 种类数量随机
# 每个种类物量随机
modeNum = random.randint(5, 7)
modeList = [random.choice([LOUTI, JIAOHU, MESS, ZONGLIAN]) for _ in range(modeNum)]
modeLength = [0] * modeNum
beatmap = []
def check(_modeLength, _modeList):
# 校验随机生成的结果是否合法
if 0 in _modeLength:
return False
for i in range(len(_modeList)):
_mode = _modeList[i]
_length = _modeLength[i]
if _mode == LOUTI:
if _length < key:
return False
elif _mode == JIAOHU:
if _length < 2:
return False
# elif _mode == ZONGLIAN:
# if _length > 6:
# return False
return True
while not check(modeLength, modeList):
modePercent = [random.random() for _ in range(modeNum)]
modeLength = [int(percent / sum(modePercent) * length) for percent in modePercent]
minIndex = modeLength.index(min(modeLength))
modeLength[minIndex] += length - sum(modeLength)
index = 0
for mode in modeList:
beatmap += _getBeatmap(mode | RANDOM | Length(modeLength[index]) | KEY)
index += 1
return beatmap
def getBeatmap(codeList):
# osu / malody 模式下,其余模式无效
index = 0
for code in codeList:
if "osu/malody" in code.value:
return analyse.file2map(code.value["osu/malody"])
codeList[index] = code | LENGTH | KEY
index += 1
if len(codeList) > 1:
newMap = _getBeatmap(codeList[0])
for i in range(1, len(codeList)):
newMap = mergeBeatmap(
newMap, _getBeatmap(codeList[i]), codeList[i].value["key"]
)
return newMap
else:
_newMap = _getBeatmap(codeList[0])
newMap = [[0] * KEY.value["key"] for i in range(codeList[0].value['length'])]
for i in range(codeList[0].value['length']):
newMap[i][_newMap[i]] = 1
return newMap
def mergeBeatmap(map1, map2, key):
newMap = []
if isinstance(map1[0], int) and isinstance(map2[0], int): # 两个简单铺面合并
for i in range(len(map1)):
newMap.append([0]*key)
newMap[-1][map1[i]] = 1
if not newMap[-1][map2[i]]: # 目标位置经过map1覆盖后仍为空白
k = random.random()
if k <= ALPHA: # 覆盖率为ALPHA
newMap[-1][map2[i]] = 1
# 不需要else,如果此处不为空白,则再覆盖无意义
return newMap
elif isinstance(map1[0], list) and isinstance(map2[0], list): # 两个复杂铺面合并
for i in range(len(map1)):
newMap.append([0]*key)
for j in range(len(map1[i])):
newMap[-1][j] = map1[i][j]
for j in range(len(map2[i])):
if map2[i][j]:
k = random.random()
if k <= ALPHA: # 覆盖率为ALPHA
newMap[-1][j] = 1
# if map2[i][j]: # 保留原始代码
# newMap[-1][j] = 1
return newMap
else: # 复杂铺面与简单铺面合并
# 本质上是把简单铺面转化成复杂铺面,再调用本方法的复杂铺面与复杂铺面合并功能
# 因此无需编写覆盖率算法
if isinstance(map1[0], list): # map2是简单铺面
# map2 = mergeBeatmap(map2, [0]*len(map2)) # 将map2转化成复杂铺面
_map2 = []
for i in range(len(map2)):
_map2.append([0] * key)
_map2[-1][map2[i]] = 1
return mergeBeatmap(map1, _map2, key)
else: # map1是简单铺面
_map1 = []
for i in range(len(map1)):
_map1.append([0] * key)
_map1[-1][map2[i]] = 1
return mergeBeatmap(_map1, map2, key)
def checkBoot():
# 启动游戏前检查参数合法性
print(f"""checking game parameters...
CODE : {CODE}
REVERSE: {REVERSE}
ALPHA: {ALPHA}""")
if len(CODE) < 1:
return 0
else:
return 1
# def init():
# global CODE, lastTarget, beatmap, combo, accList, effectList, slideList, score, REVERSE, LENGTH, LIMIT, ALPHA
# CODE = [] # 决定了生成的铺面种类
# lastTarget = 0 # 点击目标会使该变量 自减1, 当该变量值小于 LIMIT 时,会调用getBeatmap生成新铺面
# beatmap = [] # 铺面
# combo = 0 # 连击
# accList = [1]
# effectList = []
# slideList = []
# score = 0 # 命中数
# REVERSE = True
# LENGTH = KEY.value["key"] * 10 # 每次生成的铺面长度
# LIMIT = LENGTH - 1
# ALPHA = 0.33 # mergeBeatmap 覆盖率
CODE = [] # 决定了生成的铺面种类
lastTarget = 0 # 点击目标会使该变量 自减1, 当该变量值小于 LIMIT 时,会调用getBeatmap生成新铺面
beatmap = [] # 铺面
combo = 0 # 连击
accList = [1]
effectList = []
slideList = []
score = 0 # 命中数
REVERSE = False
LENGTH = Length(KEY.value["key"] * 10) # 每次生成的铺面长度
LIMIT = KEY.value["key"] * 10
ALPHA = 0.33 # mergeBeatmap 覆盖率
TIMER = True # 启用计时
if __name__ == '__main__':
# test getLouti
print(getBeatmap([File("1.osu")]))
print(getBeatmap([Length(40) | LEFT | KEY | LOUTI]))
print(getBeatmap([Length(40) | LEFT | KEY | JIAOHU]))
print(getBeatmap([Length(40) | LEFT | KEY | ZONGLIAN]))
print(getBeatmap([Length(40) | LEFT | KEY | MESS]))
print(getBeatmap([Length(40) | LEFT | KEY | MIXED]))
# print(getLouti(15, BITE, key_))
#
# # test getJiaohu
# print(getJiaohu(8, key_))
# print(getJiaohu(15, key_))
#
# # test getZonglian
# print(getZonglian(8, key_))
# print(getZonglian(15, key_))
#
# # test getMess
# print(getMess(8, key_))
# print(getMess(15, key_))
#
# # test getBeatmap
# print(getBeatmap(JIAOHU, 8, key_))
# print(getBeatmap(LOUTI | LEFT, 15, key_))
#
# # test mergeBeatmap
# a = getZonglian(8, key_)
# b = getLouti(8, LEFT, key_)
# c = getMess(8, key_)
# d = getJiaohu(8, key_)
# print(a)
# print(b)
# print(c)
# print(d)
# print(mergeBeatmap(a, b, key_))
# print(mergeBeatmap(c, d, key_))
# print(mergeBeatmap(mergeBeatmap(a, b, key_), c, key_))
# print(mergeBeatmap(mergeBeatmap(a, b, key_), mergeBeatmap(c, d, key_), key_))
#
# for idx in range(10000):
# sys.stdout.write("\r process: %d / %d" % (idx+1, 10000))
# if not getBeatmap(MIXED, 40, key_):
# raise ValueError(
# "wrong data"
# )
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。