Skip to content

Commit

Permalink
add preview function
Browse files Browse the repository at this point in the history
  • Loading branch information
flick-ai committed Aug 27, 2024
1 parent 4bd7017 commit eca0f19
Show file tree
Hide file tree
Showing 9 changed files with 541 additions and 97 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ A simulator of the Genius Invokation TCG in Genshin impact
- [ ] 丰富和美化网页端的功能
- [ ] 完成了强化学习算法的实习和训练

## 版本更新特色
## 版本更新说明
4.8版本:为所有内容维护了id信息编码。
5.0版本:增加特技效果的维护;优化切换角色的代码实现
5.0版本:增加特技效果的维护;优化切换角色的代码实现;新增了预览功能


## 本地运行
Expand Down
8 changes: 4 additions & 4 deletions genius_invocation/card/action/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ def calculate_dice(self) -> int:
count = self.cost_num
return count

def get_dice(self) -> int:
def calculate_cost(self) -> int:
if self.card_type == ActionCardType.EQUIPMENT_TALENT:
count = sum([i['cost_num'] for i in self.cost])
cost = self.cost
else:
count = self.cost_num
return count
cost = [{'cost_num':self.cost_num, 'cost_type':self.cost_type}]
return cost

def on_played(self, game: 'GeniusGame') -> None:
'''
Expand Down
148 changes: 148 additions & 0 deletions genius_invocation/game/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
'''

from genius_invocation.utils import *
from genius_invocation.user_layout import print_prompt
import genius_invocation.user_input as user_input
from genius_invocation.utils_dict import compare_dict
from loguru import logger

'''
Expand Down Expand Up @@ -112,6 +114,152 @@ def from_dict(action: dict):
(1, 1, list(n))
'''
return Action(action['choice'], action['target'], action['dice'])

@staticmethod
def from_layout(game: 'GeniusGame', layout, jump=True):
action = None
history = []
while action is None:
if game.incoming_state:
true_active_player = game.active_player
true_active_player_index = game.active_player_index
game.active_player = game.incoming_state.active_player
game.active_player_index = game.incoming_state.active_player_index

mask, use_dice = game.active_player.action_mask[:,:,0], game.active_player.action_mask[:,:,1:]
choice_dict = {0:'打出本方第1张手牌',
1:'打出本方第2张手牌',
2:'打出本方第3张手牌',
3:'打出本方第4张手牌',
4:'打出本方第5张手牌',
5:'打出本方第6张手牌',
6:'打出本方第7张手牌',
7:'打出本方第8张手牌',
8:'打出本方第9张手牌',
9:'打出本方第10张手牌',
10:'使用出战角色第1个技能',
11:'使用出战角色第2个技能',
12:'使用出战角色第3个技能',
13:'使用出战角色第4个技能',
14:'切换角色',
15:'结束回合',
16:'选择操作本方骰子',
17:'选择操作本方手牌',
18:'使用特技'}
history.append(f"您是{game.active_player_index}号玩家")
choose_prompt = f"以下是你可以选择的行动,请输入一个数字表示你的行动选择(按确认以提交或清空选择):\n"
choose_list = []
last_choice = -1
mask_sum = mask.sum(axis=1)
for i in range(CHOICE_NUM):
if mask_sum[i] >= 1:
choose_prompt = choose_prompt+str(i)+'.'+choice_dict[i]+'\n'
choose_list.append(i)
last_choice = i

if len(choose_list) == 1:
choice = last_choice
print_prompt(layout, history, choose_prompt+'您目前只能选择如下行动:'+str(last_choice)+'.'+choice_dict[last_choice]+'\n')
if jump and choice == 16:
return Action(16, 13, [])
if jump and choice == 17:
return Action(17, 14, [])
else:
print_prompt(layout, history, choose_prompt)
choice = int(user_input.get_sel('', choose_list))
history.append("您选择的行动为:"+str(choice)+'.'+choice_dict[choice])

target_dict = {0:'选择对方',
1:'选择本方',
2:'选择角色0',
3:'选择角色1',
4:'选择角色2',
5:'选择0号召唤',
6:'选择1号召唤',
7:'选择2号召唤',
8:'选择3号召唤',
9:'选择0号支援',
10:'选择1号支援',
11:'选择2号支援',
12:'选择3号支援',
13:'选择操作本方骰子',
14:'选择操作本方手牌'}
target_prompt = '根据您选择的行动,您可以选择以下目标\n'
target_list = []
last_target = -1
for i in range(TARGET_NUM):
if mask[choice][i] == 1:
target_prompt = target_prompt+str(i)+'.'+target_dict[i]+'\n'
target_list.append(i)
last_target = i

if len(target_list) == 1:
target = last_target
print_prompt(layout, history, target_prompt+'您目前只能选择如下目标:'+str(last_target)+'.'+target_dict[last_target]+'\n')
else:
print_prompt(layout, history, target_prompt)
target = user_input.get_sel('', target_list)
history.append("您选择的目标为:"+str(target)+'.'+target_dict[target])

if choice == 16:
list_prompt = f'您需要选择重新投掷的骰子的位置,形式如0 1 2所示,数值应该在{0}-{use_dice[choice][target][0]-1}之间:'
dice = user_input.get_special_rng_mul_sel(list_prompt, min=0, max=use_dice[choice][target][0]-1)
elif choice == 17:
list_prompt = f'您需要选择重新获取的手牌的位置,形式如0 1 2所示,数值应该在{0}-{use_dice[choice][target][0]-1}之间:'
dice = user_input.get_special_rng_mul_sel(list_prompt, min=0, max=use_dice[choice][target][0]-1)
elif use_dice.sum() == 0:
dice = []
else: # what is this?
while True:
try:
dice = []
for i in range(2):
cost_num = use_dice[choice][target][i*2]
if cost_num != 0:
if use_dice[choice][target][i*2+1] < 0:
cost_type = DiceType(-use_dice[choice][target][i*2+1])
list_prompt = f'您需要选择使用的{cost_num}个非{cost_type}骰子的位置,形式如0 1 2所示:'
else:
cost_type = CostType(use_dice[choice][target][i*2+1])
list_prompt = f'您需要选择使用的{cost_num}{cost_type}骰子的位置,形式如0 1 2所示:'

print_prompt(layout, history, list_prompt)
sub_dice = user_input.get_rng_mul_sel(
'', min=0, max=game.active_player.dice_zone.num()-1,
assert_fn=lambda x: game.active_player.dice_zone.check_dice(x, cost_num, use_dice[choice][target][i*2+1]))
# sub_dice = [ int(i) for i in sub_dice.split()]
dice = dice + sub_dice

assert not check_duplicate_dice(dice)
break
except KeyboardInterrupt:
exit()
except:
print(layout, "您选择的骰子包含重复位置,非法,请重新选择")
history.append("您选择的多目标为:"+str(dice))


if game.incoming_state:
game.active_player = true_active_player
game.active_player_index = true_active_player_index
action = Action(choice, target, dice)

if game.game_phase == GamePhase.ACTION_PHASE:
copy_game = game.copy_game()
copy_game.step(action)
old_dict = game.encoder_dict()
new_dict = copy_game.encoder_dict()
diff_zone = compare_dict(old_dict, new_dict)

copy_layout = copy_game.encode_message(base=diff_zone)
print_prompt(copy_layout, history, '预览效果,请按1确认进行行动')

fix_input = input()
fix_input = bool(int(fix_input))
if not fix_input:
action = None
history = ["重新输入行动"]
return action

@staticmethod
def from_input(game: 'GeniusGame', log=None, mode='a', jump=True):
Expand Down
16 changes: 12 additions & 4 deletions genius_invocation/game/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,6 @@ def step(self, action: 'Action'):
'''
回合轮次
'''

if self.root_game == self:
logger.info("in main game")
if self.is_dying:
Expand Down Expand Up @@ -327,6 +326,10 @@ def step(self, action: 'Action'):
self.incoming_action_list_index = 0
self.is_dying = False
self.incoming_state = None
# if self.game_phase == GamePhase.ACTION_PHASE:
# old_message = self.encode_message()
# new_message = game_for_plan.encode_message()
# import ipdb; ipdb.set_trace()
self.prev_action = action
else:
logger.info("in plan game")
Expand Down Expand Up @@ -429,12 +432,17 @@ def end_phase(self):
# 进入下一个回合
self.roll_phase()

def encode_message(self):
def encode_message(self, base=None):
'''
新版: 尝试将Game信息编码成table呈现给使用者
'''
return layout(self)
# return get_dict(self)
return layout(self, base)

def encoder_dict(self):
'''
旧版: 将Game信息编码成dict
'''
return get_dict(self)

def change_active_player(self):
self.active_player_index = 1 - self.active_player_index
Expand Down
2 changes: 1 addition & 1 deletion genius_invocation/game/zone.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def get_sort_map(self):

# 数量多优先
sum_dice = self.space.sum(axis=0)[:-1]
for i in range(DICENUM-1):
for i in range(DICENUM):
sort_map[i] += 10 * sum_dice[i]
return sort_map

Expand Down
35 changes: 23 additions & 12 deletions genius_invocation/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def get_parser():
parser.add_argument('--code', action='store_true', default=False)
parser.add_argument('--save', action='store_true', default=False)
parser.add_argument('--omni', action='store_true', default=False)
parser.add_argument('--jump', action='store_true', default=False)
parser.add_argument('--log', action='store_true', default=False)
parser.add_argument('--seed', type=int, default=2026)
args = parser.parse_args()
return args
Expand Down Expand Up @@ -218,15 +220,24 @@ def code_to_deck(code):
action = Action.from_input(game, log, mode='w', jump=False)
game.step(action)
else:
log = []
while not game.is_end:
if game.incoming_state:
print(game.incoming_state.encode_message())
else:
print(game.encode_message())
action = Action.from_input(game, log, mode='w', jump=False)
game.step(action)
# save log
if args.save:
with open("./action.log", "w") as f:
json.dump(log, f, indent=4)
if args.log:
log = []
while not game.is_end:
if game.incoming_state:
print(game.incoming_state.encode_message())
else:
print(game.encode_message())
action = Action.from_input(game, log, mode='w', jump=args.jump)
game.step(action)
# save log
if args.save:
with open("./action.log", "w") as f:
json.dump(log, f, indent=4)
else:
while not game.is_end:
if game.incoming_state:
layout = game.incoming_state.encode_message()
else:
layout = game.encode_message()
action = Action.from_layout(game, layout, jump=args.jump)
game.step(action)
Loading

0 comments on commit eca0f19

Please sign in to comment.