crobertsbmw / deckofcards

An API to simulate a deck of cards
MIT License
1.34k stars 335 forks source link

Draw same card on subsequent draws #80

Closed farcitoast closed 2 years ago

farcitoast commented 4 years ago

Hi @crobertsbmw, first of all thanks for sharing this cool project!

I'm trying to develop a demo app for a card game and your API seemed perfect to fit my needs. My problem is that subsequent draw requests (that occur within milliseconds) sometimes cause the same card to be drawn twice! In the response the 'remaining' field doesn't decrease.

I'll describe my setup below, maybe I didn't understand something in the docs correctly.

I create a new deck with this URL: https://deckofcardsapi.com/api/deck/new/shuffle/?cards=AS,2S,3S,4S,5S,6S,7S,JS,QS,KS,AD,2D,3D,4D,5D,6D,7D,JD,QD,KD,AC,2C,3C,4C,5C,6C,7C,JC,QC,KC,AH,2H,3H,4H,5H,6H,7H,JH,QH,KH I use this long URL because I need a 40 card deck without 8,9,10 and jokers. Is this the right approach? The response I get is this (everything seems fine): { success: true, deck_id: 'yjc38jz2qev7', remaining: 40, shuffled: true }

Then i try to draw some cards from this deck in a short period of time (one card at a time) with this URL: https://deckofcardsapi.com/api/deck/yjc38jz2qev7/draw/?count=1

These are four responses I got by performing four GET requests on the URL above.

{
  success: true,
  deck_id: 'yjc38jz2qev7',
  cards: [
    {
      code: '5C',
      image: 'https://deckofcardsapi.com/static/img/5C.png',
      images: {
        svg: 'https://deckofcardsapi.com/static/img/5C.svg',
        png: 'https://deckofcardsapi.com/static/img/5C.png'
      },
      value: '5',
      suit: 'CLUBS'
    }
  ],
  remaining: 39
}

{
  success: true,
  deck_id: 'yjc38jz2qev7',
  cards: [
    {
      code: 'AD',
      image: 'https://deckofcardsapi.com/static/img/aceDiamonds.png',
      images: {
        svg: 'https://deckofcardsapi.com/static/img/aceDiamonds.svg',
        png: 'https://deckofcardsapi.com/static/img/aceDiamonds.png'
      },
      value: 'ACE',
      suit: 'DIAMONDS'
    }
  ],
  remaining: 38
}

{
  success: true,
  deck_id: 'yjc38jz2qev7',
  cards: [
    {
      code: '4S',
      image: 'https://deckofcardsapi.com/static/img/4S.png',
      images: {
        svg: 'https://deckofcardsapi.com/static/img/4S.svg',
        png: 'https://deckofcardsapi.com/static/img/4S.png'
      },
      value: '4',
      suit: 'SPADES'
    }
  ],
  remaining: 37
}

{
  success: true,
  deck_id: 'yjc38jz2qev7',
  cards: [
    {
      code: '4S',
      image: 'https://deckofcardsapi.com/static/img/4S.png',
      images: {
        svg: 'https://deckofcardsapi.com/static/img/4S.svg',
        png: 'https://deckofcardsapi.com/static/img/4S.png'
      },
      value: '4',
      suit: 'SPADES'
    }
  ],
  remaining: 37
}

As you can see the last two cards drawn are the same and the remaining counter doesn't decrease. I would say that almost always at least two cards are the same, could you help me on this?

Thanks again for your work!

crobertsbmw commented 4 years ago

Oh man. That's a tricky one. Is there any reason each card needs to be drawn with a separate request? Why not just draw 10 cards or however many you need with one request?

On Sat, May 2, 2020 at 3:58 AM farcitoast notifications@github.com wrote:

Hi @crobertsbmw https://github.com/crobertsbmw, first of all thanks for sharing this cool project!

I'm trying to develop a demo app for a card game and your API seemed perfect to fit my needs. My problem is that subsequent draw requests (that occur within milliseconds) sometimes cause the same card to be drawn twice! In the response the 'remaining' field doesn't decrease.

I'll describe my setup below, maybe I didn't understand something in the docs correctly.

I create a new deck with this URL:

https://deckofcardsapi.com/api/deck/new/shuffle/?cards=AS,2S,3S,4S,5S,6S,7S,JS,QS,KS,AD,2D,3D,4D,5D,6D,7D,JD,QD,KD,AC,2C,3C,4C,5C,6C,7C,JC,QC,KC,AH,2H,3H,4H,5H,6H,7H,JH,QH,KH I use this long URL because I need a 40 card deck without 8,9,10 and jokers. Is this the right approach? The response I get is this (everything seems fine): { success: true, deck_id: 'yjc38jz2qev7', remaining: 40, shuffled: true }

Then i try to draw some cards from this deck in a short period of time (one card at a time) with this URL: https://deckofcardsapi.com/api/deck/yjc38jz2qev7/draw/?count=1

These are four responses I got by performing four GET requests on the URL above. { success: true, deck_id: 'yjc38jz2qev7', cards: [ { code: '5C', image: ' https://deckofcardsapi.com/static/img/5C.png', images: { svg: ' https://deckofcardsapi.com/static/img/5C.svg', png: ' https://deckofcardsapi.com/static/img/5C.png' }, value: '5', suit: 'CLUBS' } ], remaining: 39 } { success: true, deck_id: 'yjc38jz2qev7', cards: [ { code: 'AD', image: ' https://deckofcardsapi.com/static/img/aceDiamonds.png', images: { svg: ' https://deckofcardsapi.com/static/img/aceDiamonds.svg', png: ' https://deckofcardsapi.com/static/img/aceDiamonds.png' }, value: 'ACE', suit: 'DIAMONDS' } ], remaining: 38 } { success: true, deck_id: 'yjc38jz2qev7', cards: [ { code: '4S', image: ' https://deckofcardsapi.com/static/img/4S.png', images: { svg: ' https://deckofcardsapi.com/static/img/4S.svg', png: ' https://deckofcardsapi.com/static/img/4S.png' }, value: '4', suit: 'SPADES' } ], remaining: 37 } { success: true, deck_id: 'yjc38jz2qev7', cards: [ { code: '4S', image: ' https://deckofcardsapi.com/static/img/4S.png', images: { svg: ' https://deckofcardsapi.com/static/img/4S.svg', png: ' https://deckofcardsapi.com/static/img/4S.png' }, value: '4', suit: 'SPADES' } ], remaining: 37 }

As you can see the last two cards drawn are the same and the remaining counter doesn't decrease. I would say that almost always at least two cards are the same, could you help me on this?

Thanks again for your work!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/crobertsbmw/deckofcards/issues/80, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABMQLHUUI6YYMSLCOOL3YITRPPVC3ANCNFSM4MXTUPXQ .

farcitoast commented 4 years ago

Thanks for the answer, I'll try to explain. Every client happens to contact the server at almost the same time, and the server for each request draws a card by interacting with your API. I already thought about drawing many cards in one request from the server and then distributing those to the clients. I could do that but it wasn't enough "clean". Anyway I solved by making my own implementation of the API (I only needed a very small set of features), I just wanted to let you know so you could maybe improve this cool API. Have a good day!

psibal commented 4 years ago

I am also running into the same issue.

krishna0512 commented 3 years ago

Hi @crobertsbmw, This is a cool API you got there. According to my understanding, the above issue can be resolved just by adding the "transaction.atomic" decorator to the draw function in the views.py You can refer to the related Django docs here: https://docs.djangoproject.com/en/2.1/topics/db/transactions/#django.db.transaction.atomic

crobertsbmw commented 3 years ago

@krishna0512 Thanks for the lead! I made the change to the draw method. Are there other methods that should also be wrapped in atomic blocks?

krishna0512 commented 3 years ago

@krishna0512 Thanks for the lead! I made the change to the draw method. Are there other methods that should also be wrapped in atomic blocks?

Generally, All the view methods where there is a possibility of a race condition in DB access should be wrapped in atomic transaction block. If you are not sure for which requests to decorate I would recommend to set ATOMIC_REQUESTS to True in settings.py that will ensure that all the requests are atomic transactions by default. https://docs.djangoproject.com/en/2.2/topics/db/transactions/#tying-transactions-to-http-requests

MathyTechy commented 2 years ago

I am trying to use this API in my classroom teaching coding to students using code.org App Lab. I use the startWebRequest command and pass the url. I am also getting the same response from subsequent draw requests. Not sure how to start getting help, but If you could reply and I'll get you the info needed to try and solve. It's likely my lack of expertise.

crobertsbmw commented 2 years ago

Sounds like a caching issue. try adding a random variable onto the end of each request ie

https://deckofcardsapi.com/api/deck/<>/draw/?count=2&rand=qwerty23456

On Wed, Oct 27, 2021 at 9:10 AM MathyTechy @.***> wrote:

I am trying to use this API in my classroom teaching coding to students using code.org App Lab. I use the startWebRequest command and pass the url. I am also getting the same response from subsequent draw requests. Not sure how to start getting help, but If you could reply and I'll get you the info needed to try and solve. It's likely my lack of expertise.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/crobertsbmw/deckofcards/issues/80#issuecomment-953027025, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABMQLHWAM6MKNPXFXDADZDLUJAI77ANCNFSM4MXTUPXQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

MathyTechy commented 2 years ago

Thanks for the speedy reply. I just added the random variable at the end exactly as shown but same issue.

MathyTechy commented 2 years ago

When is simply enter the same url into Chrome, it never seems to return the same response. It's in my AppLab request code.

crobertsbmw commented 2 years ago

Are you changing the random variable each time? Also, instead of a GET request, you might also try a POST request.

On Wed, Oct 27, 2021 at 9:17 AM MathyTechy @.***> wrote:

When is simply enter the same url into Chrome, it never seems to return the same response. It's in my AppLab request code.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/crobertsbmw/deckofcards/issues/80#issuecomment-953033280, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABMQLHRFLJ6N4PIXQB7DHBTUJAJXTANCNFSM4MXTUPXQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

MathyTechy commented 2 years ago

Changing the random number each time seems to have solved it! Thank you very much.