shlomif / PySolFC

A comprehensive, feature-rich, open source, and portable, collection of Solitaire games.
http://pysolfc.sourceforge.net/
GNU General Public License v3.0
445 stars 97 forks source link

Archway: Cannot take desired suit from arch #332

Closed SimonN closed 8 months ago

SimonN commented 10 months ago

PySolFC 2.21.0

Archway is David Parlett's derivative of Lady of the Manor.

From David Parlett's Archway web page: "The exposed card of each column and all the cards in the arch are available for building on suites." This implies that buried cards in the arch are available, and I should be able to play any of the buried cards to a foundation where it fits. I accept that it's not 100 % clear in his text. But since he explicitly mentions that only the exposed cards in the column are available, then re-quantorizes his statement for the arch ("and all the cards in the arch are available"), it's likely that he allows pulling out buried cards from the arch. Thus:

Expected: In the arch, all cards should be available, even buried ones.

Observed: In each pile in the arch, only the top card is available. To take a buried card of a desired suit, you must first play all covering cards in the same pile, which is often strategically wrong or impossible.

PySolFC implements Lady of the Manor first, and inherits Archway from it. Since Lady of the Manor allows building foundations regardless of suit, all cards in each arch pile are equivalent because they're the same rank. It doesn't matter that Lady of the Manor offers only the top card. But Archway requires building in suit.


Here are some ideas for the UI to get to buried cards in the arch. The most common use-case is to play several same-suited cards of adjacent ranks from adjacent arch piles.

  1. An annoying idea is to left-click an arch pile to rotate it. We'd often have to click a pile several times to get to the desired suit, and we'll then to click several piles several times.

  2. Fan the cards in each arch pile and allow clicks on buried cards. It's hard to fit 13 fans on the screen instead of the 13 arch piles. Even if we enlarge the space to fit 13 fans, it's still not obvious that you can click on buried cards to pull them out.

  3. Offer four buttons, one per suit. Such a button rotates, within each of the 13 arch piles, all cards of the desired ranks to the top. If a pile doesn't contain a suit, it's okay if the pile shows a different suit afterwards. The benefit of this idea is that you can see at a glance which arch piles still have, e.g., spades. You don't see if a pile contains one or both jacks of spades. Maybe fan the piles, too?

  4. Left-click a foundation to pull its next-required card from the arch. This is unusual UI for solitaire, but feels okay for Archway. After all, every move in Archway is a play to a foundation.

I run PySolFC from its Arch Linux package, with Python 3.11.3.

(Unrelated to this bug: The information on David Parlett's Archway page has a mistake at the top: Archway doesn't use 52 cards; it uses 104 cards. Its win rate is not 90 %; most deals are unwinnable.)

joeraz commented 10 months ago

I confirmed the way you describe it is correct, although there a few other solitaire collections that use the rules PySol currently uses. But yes, the challenge is the UI.

Option 1 is similar to what Pretty Good Solitaire uses, and is probably the most practical, but yes, annoying. Option 2 would require a bit of a redesign of the UI, especially because usually you can't pull cards from the middle of a fan. Option 3 is very difficult to pull off in the PySol engine, as there isn't really solid support for using a command button in game outside of redealing. Option 4 is doable, but not a very intuitive UI.

I'd like to propose a fifth option, which is what SolSuite does. If you click one of the arch piles, it deals out all of the cards in it below the layout (and if any cards are currently there, it deals them back to the arch pile). Then, the cards from there can be moved freely.

SimonN commented 10 months ago

Thanks for the quick reply!

I agree that options 2 (click on buried card in fan) and 4 (foundation pulls card by itself) are unintuitive. To make option 2 (fan all piles) intuitive, we'd likely have to show the card in full on mouseover, and I don't think I've seen such mouseover action in PySolFC before.

Option 5 (SolSuite's solution: click pile to spread it) sounds interesting. Each pile acts like a menu, and the spread will clearly show if the jack pile holds 0, 1, or 2 jacks of spades, that's good. A problem is that it will produce a zig-zagging mouse movement: Spread twos, play two of spades, click threes, play three of spades, click fours, ..., finally play the five of spades from the column, which has been the goal all along. This leaves an aftertaste of a UI workaround.

Assuming that it's reasonably easy to tie arbitrary logic to clicking piles, here's yet another idea, a mixture of options 3 and 5:

Option 6: When you left-click one of the 13 arch piles, it rotates to show a different suit and the other 12 arch piles immediately rotate that suit to the top. To play a card from the arch pile, right-click it, or drag it (with left-click-and-hold) to the foundation. To inspect a pile for the duplicate of the top card (the 1-or-2-jacks-of-spades problem), allow that dragging to reveal the card beneath; if the duplicate is in the pile, it will always be the second card from the top. Problem: This is a roundabout way to inspect for duplicates.

Neither option 5 or 6 sounds perfect yet, but I think we're already going in the right direction.


Some UI findings from playing a few deals with offline playing cards, with 8 or 9 cards (instead of 12 cards) per column to make it easier.

It's relevant to know if 1 or 2 jacks of spades are in the arch. If 2, both of them should be played as soon as each fits on a foundation. If only one jack of spades is in the arch, it requires the usual careful planning.

I've begun to turn unplayed cards sideways to earmark them for the up-building or the down-building foundation.

The arch is really a bouquet. I think it's only grouped by rank to preserve the nice arch formation. Sometimes, it's helpful to see the arch grouped by rank (to see duplicates); other times, it's easier to see it grouped by suit. I conjecture that it's usually better to group the arch by suit, I'll try and see. Maybe it's best as an 11-by-4 matrix (twos through queens) if offline table space permits.

Because aces and kings are prefounded, aces and kings in the arch can be ignored because they're always available and block nothing. Aces and kings in the central columns are nasty blocks.

joeraz commented 10 months ago

The action you describe of peeking at a partially concealed card in full currently does exist in PySol, on a middle click - most people just don't know about it. The find card feature could also help with this. The main problem with building fans is that the current code doesn't easily support pulling a card from the middle. The only game that lets you play a card from the back of a pile without getting the full sequence is Labyrinth, which is unfinished, buggy, and commented out in the code.

It is pretty easy to get something different to trigger on a click, just make a custom stack type and override the clickHandler. This is done in games like Poker Square or Crossword. But usually, when the click is overridden, you're not also trying to move from the same stack as well, and the click and drag actions could interfere with each other.

SimonN commented 10 months ago

Middle click: Indeed, I didn't know. I've known about the find-card feature and have often used it in other patiences. It's straightforward and handy.

Pulling cards from fan's middle is difficult even if we make it look intuitive: I see, thanks for clarifying.

Custom click handler interferes with drag-to-peek: Right, I'd consider that a roadblock for option 6 (click pile to rotate all piles to new suit). In theory, we could salvage the information by flat-out writing "1x" or "2x" next to each arch card. But that is again strange UI for the mere sake of option 6, which isn't necessarily the best in the first place.

Option 7: Implement a single redeal button to rotate all arch piles (or arch fans) to the next suit. PySolFC has such a button in Crescent: In Crescent, that button rotates each bottom card to the top, preserving the order among the remaining pile. In Archway, that button would keep track of the current suit (game-global state) and, on click, go to the next suit and rotate all cards (not only 1 card) of that suit to the top. The Crescent button even reacts to the [D] hotkey, which is excellent.

All options, in particular option 5 (SolSuite's spread) and option 7 (Crescent button), hinge on how fast the spreading/rotation takes. This will be a common action during every deal of Archway.

Given how much screen estate some other patiences in PySolFC take, I'm beginning to think that all arch piles should always be fanned, regardless of which UI we have to access buried cards.

joeraz commented 10 months ago

I'm honestly not sure how much the drag and click interfere with each other - there may be a game that uses both that I'm just not thinking of at the moment. But I know best case scenario, it would be very easy to accidentally click when you meant to drag, or vice versa.

Any dealing animations can be sped up, or outright disabled, by changing the frames parameter in the game code, so that should not be a concern.

Crescent just uses the standard redeal logic, with some dealing logic, and invisible stacks to help arrange the cards correctly. Since Archway doesn't have its own redeal, that could absolutely work. For spreading out an individual stack, as per option 5, Lara's Game has some logic that might help with that.

Fanning out the cards would mostly be adjusting the layout, which is more fiddly than difficult.

SimonN commented 10 months ago

I've played a few rounds of Lara's Game. The hand-dealing (collect old hand into a pile, then spread the new pile into the hand) takes about 1 second, which is fine in Lara's Game because we'll inspect each hand.

For such a hand in Archway, I'd expect a faster deal: The whole exchange should be done in 0.3 seconds, or be instant. Reason: We know exactly what we want to play from each hand in advance. In the mind of the human solver, it's a single task to play several cards from consecutive hands. Unnecessary delay here will disturb the thinking.

If we solve the one-or-two-jacks-of-spades problem by always fanning all arch piles, that's very good, and it takes an important worry out of designing the UI for getting to buried cards.

I think the hand spread and the Crescent button are both good UI. Assuming we always fan each arch pile, I believe I'd slightly prefer an instant Crescent button, because that omits the zig-zagging mouse motion when we play successive arch cards.

joeraz commented 10 months ago

The Crescent redeal approach is probably the easier one to build from a code perspective. Let me see what I can mock up.

joeraz commented 8 months ago

Sorry for the delay - it's been a crazy month.

So it turns out to get the piles to fan (at least without having the fans overlap each other), I'd need to completely rewrite the layout logic for Archway. But I was able to get the Crescent style redeal button working, and in the latest code.

SimonN commented 8 months ago

Thanks! I've played about 20 deals -- no wins, but enough to test it from a UI perspective. The redeal is playable and snappy. I think you can include this without problems in the next full release.

I'll leave the bug open for the bells and whistles: Fanning arch cards, and making the redeal put the same suit on top of every pile instead of Crescent-shifting exactly one card per pile. Or should we file a separate bug for such bells and whistles?

joeraz commented 8 months ago

My vote would be to make it a separate issue - that will make it easier for anyone browsing the issue list to identify what still needs to be done.

SimonN commented 8 months ago

All right, I'll file a separate issue for the bells and whistles. Thanks for implementing the redeal as quickly as you did!