public Game DiscardPlayerCards(string gameName, string playerId, string cards)
        {
            object gameLock = GetGameLock(gameName);

            lock (gameLock)
            {
                Game game = GetGame(gameName);
                ValidateGame(game, StatusEnum.PLAYING);

                Player player = game.Players.Find(p => p.Id == playerId);
                ValidatePlayer(player, StatusEnum.PLAYING, game.PlayerNameTurn);

                DiscardResult result;
                player.LastDownCard = null;

                if (cards == "down")
                {
                    if (player.InHandCards.Count != 0 || player.OpenCards.Count != 0)
                    {
                        throw new GameException("Player cannot play down card with open or hand cards");
                    }

                    var cardToBePlayed = player.DownCards[0];
                    player.DownCards.RemoveAt(0);

                    result = _shitheadService.EvaluateCardsOnTable(new List <string> {
                        cardToBePlayed
                    }, game.TableCards);

                    if (result == DiscardResult.Refuse)
                    {
                        player.LastDownCard = cardToBePlayed;
                        player.InHandCards.Add(cardToBePlayed);
                        player.InHandCards.AddRange(game.TableCards);
                        game.TableCards.Clear();
                        game.PlayerNameTurn = _shitheadService.NextPlayerFrom(game.Players, playerId, 1);
                    }
                    else if (result == DiscardResult.Ok)
                    {
                        game.TableCards.Add(cardToBePlayed);

                        string cardNumber     = ShitheadService.GetCardNumber(cardToBePlayed);
                        int    stepToNextTurn = cardNumber == "8" ? 2 : 1;

                        game.PlayerNameTurn = _shitheadService.NextPlayerFrom(game.Players, playerId, stepToNextTurn);

                        if (player.DownCards.Count == 0)
                        {
                            player.Status = StatusEnum.OUT;
                            if (game.PlayerNameTurn.Equals(player.Name))
                            {
                                game.PlayerNameTurn = _shitheadService.NextPlayerFrom(game.Players, playerId, 1);
                            }
                        }
                    }
                    else if (result == DiscardResult.OkBurned)
                    {
                        game.LastBurnedCard    = cardToBePlayed;
                        game.BurnedCardsCount += game.TableCards.Count + 1;
                        game.TableCards.Clear();

                        if (player.DownCards.Count == 0)
                        {
                            player.Status       = StatusEnum.OUT;
                            game.PlayerNameTurn = _shitheadService.NextPlayerFrom(game.Players, playerId, 1);
                        }
                    }
                }
                else
                {
                    List <string> cardsToBePlayed = cards.Split(",").ToList();
                    if (cardsToBePlayed.Count > 1 && !cardsToBePlayed.All(c => _shitheadService.SameNumber(c, cardsToBePlayed[0])))
                    {
                        throw new GameException("Player cannot discard multiple cards with different numbers");
                    }

                    if (player.InHandCards.Count > 0 && !cardsToBePlayed.All(c => player.InHandCards.Contains(c)))
                    {
                        throw new GameException("Player hand does not contain the cards to discard");
                    }

                    if (player.InHandCards.Count == 0 && !cardsToBePlayed.All(c => player.OpenCards.Contains(c)))
                    {
                        throw new GameException("Player open cards does not contain the cards to discard");
                    }

                    result = _shitheadService.EvaluateCardsOnTable(cardsToBePlayed, game.TableCards);

                    if (result == DiscardResult.Ok)
                    {
                        game.TableCards.AddRange(cardsToBePlayed);

                        if (player.InHandCards.Count > 0)
                        {
                            player.InHandCards.RemoveAll(c => cardsToBePlayed.Contains(c));
                        }
                        else
                        {
                            player.OpenCards.RemoveAll(c => cardsToBePlayed.Contains(c));
                        }

                        if (player.DownCards.Count == 0 && player.InHandCards.Count == 0 && player.OpenCards.Count == 0)
                        {
                            player.Status       = StatusEnum.OUT;
                            game.PlayerNameTurn = _shitheadService.NextPlayerFrom(game.Players, playerId, 1);
                        }
                        else
                        {
                            string cardNumber = ShitheadService.GetCardNumber(cardsToBePlayed[0]);

                            int stepToNextTurn = cardNumber == "8" ? cardsToBePlayed.Count + 1 : 1;

                            game.PlayerNameTurn = _shitheadService.NextPlayerFrom(game.Players, playerId, stepToNextTurn);
                        }
                    }
                    else if (result == DiscardResult.OkBurned)
                    {
                        game.LastBurnedCard    = cardsToBePlayed[0];
                        game.BurnedCardsCount += game.TableCards.Count + cardsToBePlayed.Count;
                        game.TableCards.Clear();

                        if (player.InHandCards.Count > 0)
                        {
                            player.InHandCards.RemoveAll(c => cardsToBePlayed.Contains(c));
                        }
                        else
                        {
                            player.OpenCards.RemoveAll(c => cardsToBePlayed.Contains(c));
                        }

                        if (player.DownCards.Count == 0 && player.InHandCards.Count == 0 && player.OpenCards.Count == 0)
                        {
                            player.Status       = StatusEnum.OUT;
                            game.PlayerNameTurn = _shitheadService.NextPlayerFrom(game.Players, playerId, 1);
                        }
                    }

                    if (game.CardsInDeck.Count > 0 && player.InHandCards.Count < 3)
                    {
                        int numToBuy = 3 - player.InHandCards.Count;
                        player.InHandCards.AddRange(game.CardsInDeck.Take(numToBuy));
                        game.CardsInDeck.RemoveRange(0, Math.Min(numToBuy, game.CardsInDeck.Count));
                    }
                }

                if (game.Players.Count() - 1 == (game.Players.Count(player => player.Status == StatusEnum.OUT)))
                {
                    game.Status = StatusEnum.OUT;
                }

                SaveGame(game);

                return(game);
            }
        }