I’m building a “spot the diffrence” multiplayer game.
The specifiactions of the game are :
- There can be up to 10 players in each game.
- A user must not see the same picture twice.
(a picture consists of
four images and the user must “spot the difference” between them ).
I have a collection of thousands and possibly even tens of thousands of
pictures to choose from. The problem I’m facing is an extremely
non-eficient and un-scalable method for finding a picture that none of the
game players have seen yet.
In my database I have a usage table with the following fields :
- picture_id
- user_id
My current solution is as follows :
User enters game, app selects a picture from the database that does not appear in the usage table for that user, and for each user that enters I run the same function only adding values of pictures that other users in the same game have already seen.
I am concerned that once there is a database of tens of thousands of pictures to choose from, and the usage table is already being filled up by previous games, that the function will simply take too long damaging the flow of the game.
This method is not very scalable and I am expecting quite a steady flow of constant traffic meaning lots of games being played.
Does anyone have any suggestions on how to improve this logic or suggestions for a better database structure?
You could simply add a field to the picture table (not the user/picture mapping) that flags whether a picture has been used. You can then set that flag whenever a pictures is used, and index that field for fast identification of unused pictures. This is effectively caching the result to a hasBeenUsed() function.
Some people may object on various ground and that such premature optimisations can lead to a highly cluttered and very tightly coupled structure. Penalising future maintainability.
An alternative is to have every picture in the user/picture mapping table. If a picture is not used, its associated user_id is left as NULL. An index with picture_id first will make identification of un-used pictures very quick.
But most of all, it actually depends on the query you have to make this random selection. Very often (but not always) poorly scalable algorithms can be replaced with much more scalable algorithms without changing the database structure at all. But to know that we need to see your query, as well as the schema and behavioral information about the data (constraints, likely %unused, etc).