Speed up animations and reduce CPU turn delays
- Reduce move animation durations by 40% for snappier card movement - Widen and slow down turn indicator shake for better visibility - Cut CPU turn delays significantly: - Pre-turn pause: 0.6s → 0.25s - Initial look: 0.6-0.9s → 0.3-0.5s - Post-draw settle: 0.9s → 0.5s - Post-draw consider: 0.6-0.9s → 0.3-0.6s - Post-action pause: 0.6-0.9s → 0.3-0.5s Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
bc1b1b7725
commit
df422907b0
@ -190,7 +190,7 @@ class CardAnimations {
|
|||||||
targets: animCard,
|
targets: animCard,
|
||||||
translateY: -15,
|
translateY: -15,
|
||||||
rotate: [-2, 0],
|
rotate: [-2, 0],
|
||||||
duration: 105,
|
duration: 63,
|
||||||
easing: this.getEasing('lift')
|
easing: this.getEasing('lift')
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -200,7 +200,7 @@ class CardAnimations {
|
|||||||
left: holdingRect.left,
|
left: holdingRect.left,
|
||||||
top: holdingRect.top,
|
top: holdingRect.top,
|
||||||
translateY: 0,
|
translateY: 0,
|
||||||
duration: 175,
|
duration: 105,
|
||||||
easing: this.getEasing('move')
|
easing: this.getEasing('move')
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -276,7 +276,7 @@ class CardAnimations {
|
|||||||
targets: animCard,
|
targets: animCard,
|
||||||
translateY: -12,
|
translateY: -12,
|
||||||
scale: 1.05,
|
scale: 1.05,
|
||||||
duration: 42
|
duration: 25
|
||||||
});
|
});
|
||||||
|
|
||||||
// Direct move to holding
|
// Direct move to holding
|
||||||
@ -286,7 +286,7 @@ class CardAnimations {
|
|||||||
top: holdingRect.top,
|
top: holdingRect.top,
|
||||||
translateY: 0,
|
translateY: 0,
|
||||||
scale: 1,
|
scale: 1,
|
||||||
duration: 126
|
duration: 76
|
||||||
});
|
});
|
||||||
|
|
||||||
// Minimal pause
|
// Minimal pause
|
||||||
@ -675,8 +675,8 @@ class CardAnimations {
|
|||||||
|
|
||||||
anime({
|
anime({
|
||||||
targets: element,
|
targets: element,
|
||||||
translateX: [0, -4, 4, -3, 2, 0],
|
translateX: [0, -8, 8, -6, 4, 0],
|
||||||
duration: 200,
|
duration: 400,
|
||||||
easing: 'easeInOutQuad'
|
easing: 'easeInOutQuad'
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
50
server/ai.py
50
server/ai.py
@ -41,29 +41,29 @@ def ai_log(message: str):
|
|||||||
|
|
||||||
CPU_TIMING = {
|
CPU_TIMING = {
|
||||||
# Delay before CPU "looks at" the discard pile
|
# Delay before CPU "looks at" the discard pile
|
||||||
"initial_look": (0.5, 0.7),
|
"initial_look": (0.3, 0.5),
|
||||||
# Brief pause after draw broadcast
|
# Brief pause after draw broadcast - let draw animation complete
|
||||||
"post_draw_settle": 0.05,
|
"post_draw_settle": 0.5,
|
||||||
# Consideration time after drawing (before swap/discard decision)
|
# Consideration time after drawing (before swap/discard decision)
|
||||||
"post_draw_consider": (0.2, 0.4),
|
"post_draw_consider": (0.3, 0.6),
|
||||||
# Variance multiplier range for chaotic personality players
|
# Variance multiplier range for chaotic personality players
|
||||||
"thinking_multiplier_chaotic": (0.6, 1.4),
|
"thinking_multiplier_chaotic": (0.6, 1.4),
|
||||||
# Pause after swap/discard to let animation complete and show result
|
# Pause after swap/discard to let animation complete and show result
|
||||||
"post_action_pause": (0.5, 0.7),
|
"post_action_pause": (0.3, 0.5),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Thinking time ranges by card difficulty (seconds)
|
# Thinking time ranges by card difficulty (seconds)
|
||||||
THINKING_TIME = {
|
THINKING_TIME = {
|
||||||
# Obviously good cards (Jokers, Kings, 2s, Aces) - easy take
|
# Obviously good cards (Jokers, Kings, 2s, Aces) - easy take
|
||||||
"easy_good": (0.2, 0.4),
|
"easy_good": (0.15, 0.3),
|
||||||
# Obviously bad cards (10s, Jacks, Queens) - easy pass
|
# Obviously bad cards (10s, Jacks, Queens) - easy pass
|
||||||
"easy_bad": (0.2, 0.4),
|
"easy_bad": (0.15, 0.3),
|
||||||
# Medium difficulty (3, 4, 8, 9)
|
# Medium difficulty (3, 4, 8, 9)
|
||||||
"medium": (0.2, 0.4),
|
"medium": (0.15, 0.3),
|
||||||
# Hardest decisions (5, 6, 7 - middle of range)
|
# Hardest decisions (5, 6, 7 - middle of range)
|
||||||
"hard": (0.2, 0.4),
|
"hard": (0.15, 0.3),
|
||||||
# No discard available - quick decision
|
# No discard available - quick decision
|
||||||
"no_card": (0.2, 0.4),
|
"no_card": (0.15, 0.3),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1056,20 +1056,28 @@ class GolfAI:
|
|||||||
# Pair hunters might hold medium cards hoping for matches
|
# Pair hunters might hold medium cards hoping for matches
|
||||||
if best_pos is not None and not player.cards[best_pos].face_up:
|
if best_pos is not None and not player.cards[best_pos].face_up:
|
||||||
if drawn_value >= 5: # Only hold out for medium/high cards
|
if drawn_value >= 5: # Only hold out for medium/high cards
|
||||||
pair_viability = get_pair_viability(drawn_card.rank, game)
|
# DON'T hold if placing at best_pos would actually CREATE a pair right now!
|
||||||
phase = get_game_phase(game)
|
partner_pos = get_column_partner_position(best_pos)
|
||||||
pressure = get_end_game_pressure(player, game)
|
partner_card = player.cards[partner_pos]
|
||||||
|
would_make_pair = partner_card.face_up and partner_card.rank == drawn_card.rank
|
||||||
|
|
||||||
effective_hope = profile.pair_hope * pair_viability
|
if would_make_pair:
|
||||||
if phase == 'late' or pressure > 0.5:
|
ai_log(f" Skip hold-for-pair: placing at {best_pos} creates pair with {partner_card.rank.value}")
|
||||||
effective_hope *= 0.3
|
else:
|
||||||
|
pair_viability = get_pair_viability(drawn_card.rank, game)
|
||||||
|
phase = get_game_phase(game)
|
||||||
|
pressure = get_end_game_pressure(player, game)
|
||||||
|
|
||||||
ai_log(f" Hold-for-pair check: value={drawn_value}, viability={pair_viability:.2f}, "
|
effective_hope = profile.pair_hope * pair_viability
|
||||||
f"phase={phase}, effective_hope={effective_hope:.2f}")
|
if phase == 'late' or pressure > 0.5:
|
||||||
|
effective_hope *= 0.3
|
||||||
|
|
||||||
if effective_hope > 0.5 and random.random() < effective_hope:
|
ai_log(f" Hold-for-pair check: value={drawn_value}, viability={pair_viability:.2f}, "
|
||||||
ai_log(f" >> HOLDING: discarding {drawn_card.rank.value} hoping for future pair")
|
f"phase={phase}, effective_hope={effective_hope:.2f}")
|
||||||
return None # Discard and hope for pair later
|
|
||||||
|
if effective_hope > 0.5 and random.random() < effective_hope:
|
||||||
|
ai_log(f" >> HOLDING: discarding {drawn_card.rank.value} hoping for future pair")
|
||||||
|
return None # Discard and hope for pair later
|
||||||
|
|
||||||
# Log final decision
|
# Log final decision
|
||||||
if best_pos is not None:
|
if best_pos is not None:
|
||||||
|
|||||||
@ -1144,8 +1144,8 @@ async def check_and_run_cpu_turn(room: Room):
|
|||||||
if not room_player or not room_player.is_cpu:
|
if not room_player or not room_player.is_cpu:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Pause before CPU starts - let client animations settle and show current state
|
# Brief pause before CPU starts - animations are faster now
|
||||||
await asyncio.sleep(0.6)
|
await asyncio.sleep(0.25)
|
||||||
|
|
||||||
# Run CPU turn
|
# Run CPU turn
|
||||||
async def broadcast_cb():
|
async def broadcast_cb():
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user