Also shifts logic of starting game length timer into function
`start_timer_if_necessary`, so it can be called from original
mouse event handler and new `auto_move_eligible_cards_to_stacks`
When we don't have a matching card for the lead card rather than
always preferring to play hearts we should try to get rid of our
high value cards first if no other player has hearts cards higher
than what we have.
When we're the third player in a trick and we don't have a lower value
card we would previously pick a slightly higher value card. Instead
we should pick the highest value card unless there are points in the
current trick or the lead card is spades and the higher value card
we would've picked is higher than the queen and another player still
has the queen.
The rationale is that we have to take the trick anyway so we might as
well get rid of our highest value card. If the trailing player has a
lower value card of the same type we take the trick but don't gain
any points. If they don't have a card of the same type it doesn't
matter whether we play a high value or low value card.
Previously the AI would prefer playing a lead card for which no other
player had a card with a higher value even though it also had a card
for which a higher value card was still in play.
Currently, the player loses 100 points each time the waste stack is
recycled. In three-card draw mode, it's standard to only lose 20 points
after the third recycle event.
This invocation will exit immediately. There's also no reason to invoke
stop_game_over_animation here because that's the first thing that will
happen in the call to setup.
When an animation is stopped the cards should be moved to their final
position anyway. Otherwise they might end up getting stuck in the
middle of the animation.
This changes the game so that more than one hand can be played. Once
one player has 100 or more points the game ends. A score card is shown
between each hand.
Fixes#7374.
Instead of picking the card with the lowest value we should pick the
card with the highest value for which we know no lower value card is
in play anymore and that someone else still has an even higher value
card.
Problem:
- `static` variables consume memory and sometimes are less
optimizable.
- `static const` variables can be `constexpr`, usually.
- `static` function-local variables require an initialization check
every time the function is run.
Solution:
- If a global `static` variable is only used in a single function then
move it into the function and make it non-`static` and `constexpr`.
- Make all global `static` variables `constexpr` instead of `const`.
- Change function-local `static const[expr]` variables to be just
`constexpr`.
Currently, it is possible for the player to drag an entire stack
of cards to the foundation stack, provided the top card of the stack
(i.e the "root" card) can be dropped onto the foundation stack.
This causes an invalid state where, e.g, red cards end up in a
black foundation stack, or vice versa.
- Make the ball chill out a bit by reducing its x velocity by 1.
- Make the AI dumber. It now relaxes until the ball is coming towards it
and is in its half of the court.
Just because you're the player, doesn't mean you can cheat ;)
- Limit paddle speed when following mouse cursor.
- Unhide pointer -- can't grab it, can't see when it's about to leave
the window otherwise.
- Add last pointer y position indication for the player paddle.
- Prevent the paddle from following the mouse when Up or Down is being
held (avoid controls fighting).
Begin and end triggers for AI paddle to start moving prevent it from
continually jerking around the ball's position. It still moves in steps
of paddle.speed though, but overall experience is smoother.
Player 1's score used to be score's width offset to the right. Now it's
score_margin away from the divider line, same as player 2's.
Also factored out score margin and increased it from 2px to 5px just
to make it look a little nicer.