Case Study: Building a Multi-Platform Accessible Solitaire Game

Case Study: Building a Multi-Platform Accessible Solitaire Game

A while ago I built a solitaire app for Windows, specifically to explore game-playing experiences involving a variety of ways people interact with their devices. Part of my motivation for doing this was that I’d tried a number of existing solitaire games and found some significant accessibility issues with them, such as not supporting players who use screen readers, or always showing fixed colours and sizes of content.

I shared my learnings in a collection of articles, including The Sa11ytaire Experiment - End of Part 1, discussing input methods such as keyboard, touch, speech, switch, and eye control, and The Sa11ytaire Experiment - End of Part 2, where I started incorporating Azure AI into the mix, first with Language Understanding and later with playing card image recognition.

I was recently asked whether I’d be making that solitaire app available for Android, and this got me wondering about what it would take to build a .NET MAUI version of the app. Hopefully this would make it practical for me to release a version of the app for both Android and iOS.

Here I’ll share some of my experiences as I started out on that journey, having just released a new app, Accessible Solitaire for Android. Some details on how to play the game, and its accessibility-related features, can be found at Accessible Solitaire ReadMe.


An in-progress Accessible Solitaire game with partially built-up target card piles and multiple cards moved between the dealt card piles. A black five card is selected in dealt card pile 3.
Figure 1: An in-progress Accessible Solitaire game with partially built-up target card piles and multiple cards moved between the dealt card piles. A black five card is selected in dealt card pile 3.

Porting the app from UWP to .NET MAUI

Already having a XAML-based, C# UWP Windows app gave me a great starting point for a .NET MAUI app. After all, lots of the XAML and C# will be unchanged in the new app. Rather than trying to port the original Visual Studio Solution over to .NET MAUI, I decided to create a new .NET MAUI app and copy in all the XAML and C# content. It was then just a case of updating the places where it didn’t build, to use equivalent .NET MAUI content. For example, replacing a Page with a ContentPage, and a StackPanel with a StackLayout. Overall, this was pretty straightforward.

One very important area which I chose not to port over at this time related to the keyboard experience. The most exciting aspect of my original Windows solitaire game was exploring a variety of new ways to make playing the game with the keyboard as efficient as possible. I’ll look forward to exploring that again at some point, but initially the new app would not focus on the keyboard experience.

The Initial accessibility of the Accessible Solitaire game

When building a new app, I always use semantic controls that come with the UI framework. By doing so, I’m getting a good head start on serving all the game’s players well, regardless of how those players interact with their devices. For example, players who use screen readers will be informed of the state of toggleable buttons or selectable list items. If instead I was to only convey such information through visuals associated with custom controls, a player using a screen reader might not be made aware of the information required to play the game.

That said, I couldn’t get the Android TalkBack screen reader to announce the selection state of CollectionView items, or the position of those items in their container, regardless of TalkBack’s verbosity settings. So given that that information is so important, I incorporated it into the items’ names. I hope to remove that at some point if I can get TalkBack to announce it automatically.

Providing a usable screen reader experience was made practical thanks to the features described at Build accessible apps with semantic properties. The app made good use of SemanticProperties.Description, SemanticProperties.Hint, SemanticProperties.HeadingLevel, AutomationProperties.IsInAccessibleTree, and very importantly, also used SemanticScreenReader.Default.Announce() to have helpful custom announcements made following specific actions taken in the game.

Note: Careful consideration is required around making custom announcements, as too many of those can render an app very difficult to use.


The Accessible Solitaire app with TalkBack’s highlight around a partially obscured card in a dealt card pile. TalkBack’s caption shows: “10 of Clubs, selected, 3 of 5, In list Pile 3”.
Figure 2: The Accessible Solitaire app with TalkBack’s highlight around a partially obscured card in a dealt card pile. TalkBack’s caption shows: “10 of Clubs, selected, 3 of 5, In list Pile 3”.


The Accessible Solitaire app with TalkBack’s highlight around the 3 of Spades in the Spade target card pile. TalkBack’s caption shows: “Moved 3 of Spades, Revealed Empty card pile in dealt card pile 3”.
Figure 3: The Accessible Solitaire app with TalkBack’s highlight around the 3 of Spades in the Spade target card pile. TalkBack’s caption shows: “Moved 3 of Spades, Revealed Empty card pile in dealt card pile 3”.


The Accessible Solitaire app with TalkBack’s highlight around the “Screen reader announce game state” button. TalkBack’s caption describes the full card layout of the game.
Figure 4: The Accessible Solitaire app with TalkBack’s highlight around the “Screen reader announce game state” button. TalkBack’s caption describes the full card layout of the game.

Given that the playing cards’ suit symbols are so small, and in some cases so similar between suits, it is essential for players to be provided with a means to make everything shown in the game bigger. While Android itself provides helpful magnification, I felt it was important for the solitaire app to provide more options.

As such, the game’s Settings page provides a zoom level, to magnify everything in the game across two independently scrollable areas. This means that the target card piles can be kept in view while portions of the dealt card piles are scrolled around to bring whatever is of most interest in those dealt card piles into view.


The Accessible Solitaire app with all content magnified to a level of 150%. The upper scrollable area has the two right-most target card piles scrolled out of view, and the lower scrollable area shows portions of five of the seven dealt card piles.
Figure 5: The Accessible Solitaire app with all content magnified to a level of 150%. The upper scrollable area has the two right-most target card piles scrolled out of view, and the lower scrollable area shows portions of five of the seven dealt card piles.

Reacting to player feedback

In order to have the new Accessible Solitaire game published at the Google Play Store, I needed to find at least twenty people who would be prepared to test the app for a while, and to provide feedback. This turned out to be far more helpful to me than I anticipated. The players’ feedback included many great suggestions, some of which related to the general solitaire game-playing experience, and some being specific to the accessibility of the game. I did update the app during the testing period a number of times based on feedback, and I’m tracking the suggestions I’ve yet to get to at Accessible Solitaire feature suggestions.

I am extremely grateful to all the people who devoted their time and effort in order to help me make the game available to everyone.

One of the most important areas of feedback related to the in-app zoom feature. A number of people raised concerns that while the feature technically worked, many players would not enjoy having to perform the significant amount of scrolling required to play the game.

One person suggested perhaps a long-press gesture might be added to zoom in on a card. That really did seem like a great idea, and one that turned out to be quite interesting to explore. While trying out various touch gesture options, I found a pinch gesture on a card quite difficult to perform, and a double-tap gesture introduced a slight delay when selecting a card with a single-tap gesture, so perhaps a long-press gesture really was the best choice. In the end I found I couldn’t get the .NET MAUI binding for a long-press gesture to work reliably once cards had been moved between CollectionViews, so I didn’t end up going with that. Rather I added an option to have a Zoom Card button shown on each card. I realise that that approach has accessibility issues of its own given the size of the button, but at least it’s accessible to the TalkBack screen reader, and all the app’s features must be accessible to TalkBack. I’m sure I’ll be revisiting this Zoom Card feature in the future.


The Accessible Solitaire app with face-up cards in all areas of the game showing a magnifying glass icon at their top right corners. The only face-up card in dealt card pile 4 is the 3 of Spades.
Figure 6: The Accessible Solitaire app with face-up cards in all areas of the game showing a magnifying glass icon at their top right corners. The only face-up card in dealt card pile 4 is the 3 of Spades.


The Accessible Solitaire app showing a popup occupying the full height of the screen, showing the 3 of Spades card and a Close button. In the background is a greyed-out solitaire game in progress.
Figure 7: The Accessible Solitaire app showing a popup occupying the full height of the screen, showing the 3 of Spades card and a Close button. In the background is a greyed-out solitaire game in progress.

Another interesting topic to explore was around the contents shown on a card. Rather than only having one representation for a card’s details, perhaps in addition other representations might be helpful. To get the ball rolling on this discussion, I added an option to not show the traditional collection of small suit symbols, and instead, show one large suit symbol and one large number or letter representing the rank. I’m looking forward to receiving more feedback in the future around other helpful representations of the card.


The Accessible Solitaire app with the centre of all face-up cards showing a large suit symbol and large letter or number, instead of the traditional collection of small suit symbols.
Figure 8: The Accessible Solitaire app with the centre of all face-up cards showing a large suit symbol and large letter or number, instead of the traditional collection of small suit symbols.

While I was adding the above feature, I took the opportunity to have the app support the Android Dark Mode setting. So now if the app’s started while the Android Dark Mode feature is on, it will show light-on-dark versions of the cards rather than dark-on-light.


The Accessible Solitaire app at an in-app zoom level of 150% and cards showing large suit symbols and rank letters, while showing custom Dark Mode colours.
Figure 9: The Accessible Solitaire app at an in-app zoom level of 150% and cards showing large suit symbols and rank letters, while showing custom Dark Mode colours.


The Accessible Solitaire app with all face-up cards showing a magnifying glass icon at their corners, while showing custom Dark Mode colours.
Figure 10: The Accessible Solitaire app with all face-up cards showing a magnifying glass icon at their corners, while showing custom Dark Mode colours.


The Accessible Solitaire app showing a popup occupying the full height of the screen, showing the 10 of Clubs card, while showing custom Dark Mode colours.
Figure 11: The Accessible Solitaire app showing a popup occupying the full height of the screen, showing the 10 of Clubs card, while showing custom Dark Mode colours.

Am I ignoring Google’s reports relating to the accessibility of the app?

Whenever I submit an update of the app to be published, Google helpfully provides me with a report detailing potential accessibility issues with the app. The issues reported by Google fell in the following three areas.

Content labelling

The report suggested that the game’s Menu button and Next Card button might not have labels readable by screen readers, yet I’d specifically given them localisable accessible names, and tested them with the TalkBack screen reader. So, until I learn otherwise from players, I’m going to assume those buttons are satisfactorily labelled.

Touch target size

This issue related to the size of interactable elements, and is a fair point given that some elements do have very small hit targets. Some of those element sizes are the defaults provided by the combination of the .NET MAUI framework and Android, for example, the size of a switch, a picker, and a button on the Settings page. Typically I do not try to override the framework’s default sizing.

Other controls with hit target issues are very much under my control, for example, a partially obscured card in a dealt card pile. One player testing the app raised a very interesting idea of having a tap in any of the face-down cards in a dealt card pile select the nearest face-up card in that pile. This is something I intend to explore further, but for this first release of the app I do acknowledge that hit targets will be problematic for some players.?

Low contrast

Most of the low contrast issues reported related to visuals shown in the main area of the game, once it had become very dark (and low contrast) because the app’s menu flyout had appeared. I’m not planning on making changes to the app in response to this reported issue.

The only other low contrast issue reported related to the empty area where upturned cards will be placed, and now that this has been highlighted for me, I do consider it a bug. I’ve logged this bug at GitHub to help me track fixing that.

So what happens now?

With the help of the people who’ve already tried out the app and provided feedback, I feel I’m now at a point where I can reach out to organisations and individuals who are familiar with various accessibility-related features and invite more feedback on how I should prioritise the improvements that I make to the app. I’m sure many improvements are necessary, but I do hope this first release of the app will demonstrate its potential for providing an accessible and fun solitaire game-playing experience for all.

I’m also intending to explore other interaction experiences, such as controlling the game through speech and a switch device. This first release of the app did not explore those experiences, but I am pleased that having run the app with both the Android Voice Access and Universal Switch Access features turned on, the results seem encouraging.


The Accessible Solitaire app with the Android Voice Access feature showing numbers over all cards and other interactable elements in the game. The Jack of Spades lies over a red Queen in a dealt card pile. The Voice Access feature UI appears at the top of the screen and shows the text: “Tapped Queen of Hearts”.
Figure 12: The Accessible Solitaire app with the Android Voice Access feature showing numbers over all cards and other interactable elements in the game. The Jack of Spades lies over a red Queen in a dealt card pile. The Voice Access feature UI appears at the top of the screen and?shows the text: “Tapped Queen of Hearts”.


An Android phone showing an in-progress Accessible Solitaire game. In the foreground is an Xbox Adaptive Controller with a Bluetooth connection to the phone, and the controller’s A and B buttons being used to play the game via the Android Universal Switch feature. The switch has been used to select a 10 of Diamonds, and then move to a Jack of Spades.
Figure 13: An Android phone showing an in-progress Accessible Solitaire game. In the foreground is an Xbox Adaptive Controller with a Bluetooth connection to the phone, and the controller’s A and B buttons being used to play the game via the Android Universal Switch feature. The switch has been used to select a 10 of Diamonds, and then move to a Jack of Spades.

And of course, very importantly, I’d like to start exploring the possibility of releasing a version of the game for iOS. Out of curiosity, I did build my new app for iOS and found it started up fine, which is another very encouraging development.


The Accessible Solitaire app running on an iPad.
Figure 14: The Accessible Solitaire app running on an iPad.

So if you, or someone you know, might be interested in the potential for the app to provide fun game-playing experiences that aren’t available through other apps, please do try out the app and send feedback my way. I’ll do my best to update the app in whatever ways might be helpful.

And of course – please do spread the word!

The app’s available at Accessible Solitaire for Android.

All the best,

Guy


Guy Barker

Exploring how to make apps more accessible to more people, and sharing all I learn.

3 个月

Thanks for sharing the post @tomreemer. Since I wrote the article, I've been exploring what it would take to get the .NET Maui app running on iOS. Overall it was fairly straightforward, but I couldn't get the same code to work for both the Android and iOS screen readers. So the only platform #if now in the app relates to the screen reader experience. The images here show the iOS version of the app with its in-app zoom, VoiceOver screen reader caption, Voice Control showing element names, and Switch Control scan moving through the cards. For the first time this afternoon I completed a full game using only the iOS Switch Control feature, which really was rewarding. Next week I might look into what it would take to get the iOS version of the app published. The app's perf leaves a bit to be desired at the moment, but I'd like to start getting feedback on the iOS version to help me learn where to focus next.

  • 该图片无替代文字

要查看或添加评论,请登录

Guy Barker的更多文章