成语接龙5.0、群空调功能
This commit is contained in:
@ -69,10 +69,11 @@ class TryStopState(Enum):
|
||||
class TryVerifyState(Enum):
|
||||
VERIFIED = 0
|
||||
VERIFIED_AND_REAL = 1
|
||||
NOT_IDIOM = 2
|
||||
WRONG_FIRST_CHAR = 3
|
||||
BUT_NO_NEXT = 4
|
||||
GAME_END = 5
|
||||
ALREADY_USED = 2
|
||||
NOT_IDIOM = 3
|
||||
WRONG_FIRST_CHAR = 4
|
||||
BUT_NO_NEXT = 5
|
||||
GAME_END = 6
|
||||
|
||||
|
||||
class IdiomGame:
|
||||
@ -96,12 +97,14 @@ class IdiomGame:
|
||||
self.all_buff_score = 0
|
||||
self.lock = asynkio.Lock()
|
||||
self.remain_rounds = 0 # 剩余回合数
|
||||
self.already_idioms: dict[str, int] = {} # 已经使用过的成语和使用过的次数
|
||||
self.idiom_history: list[list[str]] = [] # 成语使用历史记录,多个数组以存储不同成语链
|
||||
IdiomGame.INSTANCE_LIST[group_id] = self
|
||||
|
||||
def be_able_to_play(self) -> bool:
|
||||
if self.last_play_date != datetime.date.today():
|
||||
self.last_play_date = datetime.date.today()
|
||||
self.remain_playing_times = 1
|
||||
self.remain_playing_times = 3
|
||||
if self.remain_playing_times > 0:
|
||||
self.remain_playing_times -= 1
|
||||
return True
|
||||
@ -115,6 +118,8 @@ class IdiomGame:
|
||||
self.last_char = self.last_idiom[-1]
|
||||
if not self.is_nextable(self.last_char):
|
||||
self.choose_start_idiom()
|
||||
else:
|
||||
self.add_history_idiom(self.last_idiom, new_chain=True)
|
||||
return self.last_idiom
|
||||
|
||||
@classmethod
|
||||
@ -148,6 +153,9 @@ class IdiomGame:
|
||||
def clear_score_board(self):
|
||||
self.score_board = {}
|
||||
self.last_char = ""
|
||||
self.all_buff_score = 0
|
||||
self.already_idioms = {}
|
||||
self.idiom_history = []
|
||||
|
||||
def get_score_board(self) -> dict:
|
||||
return self.score_board
|
||||
@ -169,6 +177,8 @@ class IdiomGame:
|
||||
self.last_char = self.last_idiom[-1]
|
||||
if not self.is_nextable(self.last_char):
|
||||
self._skip_idiom_async()
|
||||
else:
|
||||
self.add_history_idiom(self.last_idiom, new_chain=True)
|
||||
return self.last_idiom
|
||||
|
||||
async def try_verify_idiom(self, idiom: str, user_id: str) -> TryVerifyState:
|
||||
@ -184,6 +194,29 @@ class IdiomGame:
|
||||
判断是否有成语可以接
|
||||
"""
|
||||
return last_char in IdiomGame.AVALIABLE_IDIOM_FIRST_CHAR
|
||||
|
||||
def add_already_idiom(self, idiom: str):
|
||||
if idiom in self.already_idioms:
|
||||
self.already_idioms[idiom] += 1
|
||||
else:
|
||||
self.already_idioms[idiom] = 1
|
||||
|
||||
def get_already_used_num(self, idiom: str) -> int:
|
||||
if idiom in self.already_idioms:
|
||||
return self.already_idioms[idiom]
|
||||
return 0
|
||||
|
||||
def add_history_idiom(self, idiom: str, new_chain: bool = False):
|
||||
if new_chain or len(self.idiom_history) == 0:
|
||||
self.idiom_history.append([idiom])
|
||||
else:
|
||||
self.idiom_history[-1].append(idiom)
|
||||
|
||||
def display_history(self) -> list[str]:
|
||||
result = []
|
||||
for chain in self.idiom_history:
|
||||
result.append(" -> ".join(chain))
|
||||
return result
|
||||
|
||||
def _verify_idiom(self, idiom: str, user_id: str) -> list[TryVerifyState]:
|
||||
state = []
|
||||
@ -196,13 +229,18 @@ class IdiomGame:
|
||||
state.append(TryVerifyState.NOT_IDIOM)
|
||||
return state
|
||||
# 成语合法,更新状态
|
||||
self.add_history_idiom(idiom)
|
||||
score_k = 0.5 ** self.get_already_used_num(idiom) # 每被使用过一次,得分减半
|
||||
if(score_k != 1):
|
||||
state.append(TryVerifyState.ALREADY_USED)
|
||||
self.add_already_idiom(idiom)
|
||||
state.append(TryVerifyState.VERIFIED)
|
||||
self.last_idiom = idiom
|
||||
self.last_char = idiom[-1]
|
||||
self.add_score(user_id, 1)
|
||||
self.add_score(user_id, 1 * score_k) # 先加 1 分
|
||||
if idiom in IdiomGame.ALL_IDIOMS:
|
||||
state.append(TryVerifyState.VERIFIED_AND_REAL)
|
||||
self.add_score(user_id, 4) # 再加 4 分
|
||||
self.add_score(user_id, 4 * score_k) # 再加 4 分
|
||||
self.remain_rounds -= 1
|
||||
if self.remain_rounds <= 0:
|
||||
self.now_playing = False
|
||||
@ -217,7 +255,7 @@ class IdiomGame:
|
||||
if user_id not in self.score_board:
|
||||
return 0
|
||||
# 避免浮点数精度问题导致过长
|
||||
handled_score = round(self.score_board[user_id]["score"], 1)
|
||||
handled_score = round(self.score_board[user_id]["score"] + self.all_buff_score, 1)
|
||||
return handled_score
|
||||
|
||||
def add_score(self, user_id: str, score: int):
|
||||
@ -401,7 +439,7 @@ async def end_game(event: BaseEvent, group_id: str):
|
||||
result_text = UniMessage().text("游戏结束!\n最终得分榜:\n")
|
||||
score_board = instance.get_score_board()
|
||||
if len(score_board) == 0:
|
||||
result_text += "无人得分!"
|
||||
result_text += "无人得分!\n"
|
||||
else:
|
||||
# 按分数排序,名字用 at 的方式
|
||||
sorted_score = sorted(
|
||||
@ -413,6 +451,13 @@ async def end_game(event: BaseEvent, group_id: str):
|
||||
+ UniMessage().at(user_id)
|
||||
+ f": {round(info['score'] + instance.get_all_buff_score(), 1)} 分\n"
|
||||
)
|
||||
if len(instance.idiom_history) == 0:
|
||||
result_text += "\n本局没有任何接龙记录。"
|
||||
else:
|
||||
result_text += "\n你们的接龙记录是:\n"
|
||||
history_lines = instance.display_history()
|
||||
for line in history_lines:
|
||||
result_text += line + "\n"
|
||||
await evt.send(await result_text.export())
|
||||
instance.clear_score_board()
|
||||
|
||||
@ -499,20 +544,39 @@ async def _(event: BaseEvent, msg: UniMsg, target: DepLongTaskTarget):
|
||||
.export()
|
||||
)
|
||||
return
|
||||
already_used_num = instance.get_already_used_num(user_idiom)
|
||||
if TryVerifyState.VERIFIED_AND_REAL in state:
|
||||
await evt.send(
|
||||
await UniMessage()
|
||||
.at(user_id)
|
||||
.text(f" 接上了,这是个真实成语,喜提 5 分!你有 {instance.get_user_score(user_id)} 分!")
|
||||
.export()
|
||||
)
|
||||
score = 5 * (0.5 ** (already_used_num - 1))
|
||||
if already_used_num > 1:
|
||||
await evt.send(
|
||||
await UniMessage()
|
||||
.at(user_id)
|
||||
.text(f" 接上了,这是个被重复用过的成语,喜提 {score} 分!你有 {instance.get_user_score(user_id)} 分!")
|
||||
.export()
|
||||
)
|
||||
else:
|
||||
await evt.send(
|
||||
await UniMessage()
|
||||
.at(user_id)
|
||||
.text(f" 接上了,这是个真实成语,喜提 5 分!你有 {instance.get_user_score(user_id)} 分!")
|
||||
.export()
|
||||
)
|
||||
elif TryVerifyState.VERIFIED in state:
|
||||
await evt.send(
|
||||
await UniMessage()
|
||||
.at(user_id)
|
||||
.text(f" 接上了,喜提 1 分!你有 {instance.get_user_score(user_id)} 分!")
|
||||
.export()
|
||||
)
|
||||
score = 1 * (0.5 ** (already_used_num - 1))
|
||||
if already_used_num > 1:
|
||||
await evt.send(
|
||||
await UniMessage()
|
||||
.at(user_id)
|
||||
.text(f" 接上了,但重复了,喜提 {score} 分!你有 {instance.get_user_score(user_id)} 分!")
|
||||
.export()
|
||||
)
|
||||
else:
|
||||
await evt.send(
|
||||
await UniMessage()
|
||||
.at(user_id)
|
||||
.text(f" 接上了,喜提 1 分!你有 {instance.get_user_score(user_id)} 分!")
|
||||
.export()
|
||||
)
|
||||
if TryVerifyState.GAME_END in state:
|
||||
await evt.send(await UniMessage().text("全部回合结束!").export())
|
||||
await end_game(event, group_id)
|
||||
|
||||
Reference in New Issue
Block a user