Closed oscar-h64 closed 4 years ago
So I've done quite a bit on this, I propose firstly someone review it because I'm sure there's bits of this that can be neatened up, then merge it, as I believe I have a single game system that works (apart from the fact it relies on some library functions that don't yet exist). It will eventually support multiple games by switching from IORef
to a database backend, but I think it's best to merge this so people can work on clients, as the API is designed so that it could support multiple games if the backend allowed.
I'll write up the endpoints as a comment on #8 in a second
Currently it only supports 1 game, I planned to merge this version then open a new branch for supporting multiple (I was going to use a database, but I'll look into using stm
). I designed the endpoints so that they'd support multiple games so if people wanted to start writing clients they wouldn't have to update them at a later date when support for multiple games was added
I did think about not sending the whole game, I wasn't sure which details the user needed. I would guess just their Player
object and all the cards on the board (maybe this should be added as a field to Board
?). I'll create a new GameStateResponse
type with those fields and we can easily add more if necessary
This PR is looking great so far.
As I understand it, the client will be responsible for hiding the "private" information from the user for the time being? That's a reasonable first implementation, but obviously this is prone to cheating. A "hidden information masking" function is a desirable feature to add once we have the basics working solidly. Such a thing shouldn't be too difficult to implement; A function maskHiddenInformation :: Player -> State -> State
, which replaces cards in decks and the opponent's hand with blank "hidden" cards, should be all it takes?
@oscar-h64 : In order to avoid issues with instancing, perhaps the getState request should handle the If-Modified-Since
header, sending the full state if that header is absent?
As I understand it, the client will be responsible for hiding the "private" information from the user for the time being? That's a reasonable first implementation, but obviously this is prone to cheating. A "hidden information masking" function is a desirable feature to add once we have the basics working solidly. Such a thing shouldn't be too difficult to implement; A function
maskHiddenInformation :: Player -> State -> State
, which replaces cards in decks and the opponent's hand with blank "hidden" cards, should be all it takes?
That's a good point, that would probably be easier than trying to define a separate type that just doesn't have the sensitive data
@oscar-h64 : In order to avoid issues with instancing, perhaps the getState request should handle the
If-Modified-Since
header, sending the full state if that header is absent?
I really should have checked if something like that existed, that will cleanup a lot of horrible code I wanted to get rid of
I think I'm actually going to change it to a tuple, I think that makes more sense in the context of what its storing
EDIT: Hmm, no the (Maybe Deck, Maybe Deck)
just looks messy, pattern matching on the list looks a lot better
Adds an API server for use by clients (see #8)