// This modifies both decks. Must be called withn the deckLock. private void ShuffleDiscard() { Console.WriteLine($"{DateTime.Now}:Deck empty, reshuffling."); // pull cards out out of the discard in a random order, and insert into the draw pile. while (discardPile.Count != 0) { int index = randGen.Next(0, discardPile.Count - 1); ConceptCard card = discardPile [index]; drawPile.Enqueue(card); discardPile.RemoveAt(index); } }
public static void SendCardGraphicResponse(HttpListenerResponse response, ConceptCard card) { response.AddHeader("Cache-Control", "no-transform, public, max-age=900"); response.AddHeader("Etag", card.GetHashCode().ToString()); Console.WriteLine($"{DateTime.Now}:Sending image of card:{card.id}"); // Pull the image out of the card in memory and send it down. response.ContentLength64 = card.CardImage.Length; System.IO.Stream output = response.OutputStream; output.Write(card.CardImage, 0, card.CardImage.Length); // You must close the output stream. output.Close(); }
public void DiscardCard(int cardId) { if (cardsInUse.Where(p => p.id == cardId).Count() == 0) { Console.WriteLine($"{DateTime.Now}:Attempt to discard card {cardId} which is not in use."); return; } Console.WriteLine($"{DateTime.Now}:Card {cardId} discarded."); lock (deckLock) { ConceptCard chosenCard = cardsInUse.Where(p => p.id == cardId).First(); discardPile.Add(chosenCard); cardsInUse.Remove(chosenCard); } }
public static void TestCardShuffling() { List <ConceptCard> parsedCards = new List <ConceptCard>(); for (int i = 0; i < 100; i++) { parsedCards.Add(CreateTestCard(i)); } ConceptDeck deck = new ConceptDeck(parsedCards, randGen); for (int i = 0; i < 101; i++) { ConceptCard drawn = deck.DrawCard(); deck.DiscardCard(drawn.id); } Console.WriteLine(deck.ToString()); }
private static void ProcessRequest(object contextArg) { HttpListenerContext context = contextArg as HttpListenerContext; HttpListenerRequest request = context.Request; HttpListenerResponse response = context.Response; // read the first part of the query string. If it's the name of a deck, then find the appopriate deck for use. // should be exactly two or three segments in the URI. // Valid items: // / xbox/ // / xbox/ [filename] // / xbox/play?action=draw // / xbox/play?action=discard if ((request.Url.Segments.Length < 2) || (request.Url.Segments.Length > 3)) { // 404 it. ResponseUtils.SendTextResponse(response, "Invalid URL."); return; } // read the deck name segment and trim the forward slash. string deckName = request.Url.Segments[1]; deckName = deckName.Substring(0, deckName.Length - 1); if (!decks.ContainsKey(deckName)) { // 404 it. ResponseUtils.SendTextResponse(response, "Invalid deck name."); return; } // ConceptDeck deck = decks[request.Url.Segments[1]]; ConceptDeck deck = decks[deckName]; string cookieName = $"{deckName}_cardid"; try { NameValueCollection queryParams = ResponseUtils.ParseQueryString(request.Url.Query); // If it doesn't end in a /, it indicates a file. if (queryParams.Count == 0 && !request.Url.LocalPath.EndsWith("/")) { if (customCardMatch.IsMatch(request.Url.LocalPath)) { // the card images are served from memory. Isolate the card number and pass along the card. MatchCollection matches = numberMatch.Matches(request.Url.Segments[2]); ResponseUtils.SendCardGraphicResponse(response, deck.GetCardById(Int32.Parse(matches[0].Value))); } else { // return whatever file is asked for, if it's present. ResponseUtils.SendFileResponse(fileDirectory + request.Url.Segments[2], response); } return; } // If it does end in a /, it's the root of a deck. Perform a default first behavior. if (queryParams.Count == 0 && (request.Url.LocalPath.Equals("") || request.Url.LocalPath.EndsWith("/"))) { int currentCard = 0; ConceptCard card; if (context.Request.Cookies != null && context.Request.Cookies[cookieName] != null && Int32.TryParse(context.Request.Cookies[cookieName].Value, out currentCard)) { // If the user already has a card, and it's not expired, // display to them the one they have. card = deck.GetCardById(currentCard); if (!card.IsExpired()) { card.RefreshExpiry(); ResponseUtils.SendTemplateResponse(response, cookieName, card); return; } } // Otherwise, it's first use--draw a card. card = deck.DrawCard(); ResponseUtils.SendTemplateResponse(response, cookieName, card); return; } // ?action=draw if (request.Url.LocalPath.EndsWith("/play") && queryParams["action"] == "draw") { int currentCard = 0; if (context.Request.Cookies != null && context.Request.Cookies[cookieName] != null && Int32.TryParse(context.Request.Cookies[cookieName].Value, out currentCard)) { deck.DiscardCard(currentCard); } ConceptCard card = deck.DrawCard(); ResponseUtils.SendTemplateResponse(response, cookieName, card); return; } // ?action=discard if (request.Url.LocalPath.EndsWith("/play") && queryParams["action"] == "discard") { int currentCard = 0; if (context.Request.Cookies != null && context.Request.Cookies[cookieName] != null && Int32.TryParse(context.Request.Cookies[cookieName].Value, out currentCard)) { deck.DiscardCard(currentCard); } ResponseUtils.SendTemplateResponse(response, cookieName, "No card present. Select draw to draw a card."); return; } // ?action=refresh if (request.Url.LocalPath.EndsWith("/play") && queryParams["action"] == "refresh") { int currentCard = 0; if (Int32.TryParse(context.Request.Cookies[cookieName].Value, out currentCard)) { ConceptCard card = deck.GetCardById(currentCard); if (!card.IsExpired()) { card.RefreshExpiry(); } } ResponseUtils.SendTextResponse(response, "Refresh"); return; } } catch (Exception e) { Console.WriteLine(e); return; // response.StatusCode = (int) HttpStatusCode.BadRequest; // ResponseUtils.SendTextResponse (response, "Bad Request:" + e.Message); } ResponseUtils.SendTextResponse(response, "No matching handler!"); }
public static void SendTemplateResponse(HttpListenerResponse response, string cookieName, ConceptCard card) { // Looks like we need to write the card info in the template instead, and // provide a way for the later call to get access to it. response.AppendCookie(new Cookie(cookieName, card.id.ToString())); string returnFile = templateFile; if (card != null) { returnFile = SetRefresh(true, returnFile); returnFile = returnFile.Replace("__TEMPLATE_ITEM_1__", $"<IMG SRC = \"CustomCard_{card.id}.jpg\" ID=\"bg\">"); } else { returnFile = SetRefresh(false, returnFile); returnFile = returnFile.Replace("__TEMPLATE_ITEM_1__", "The draw pile is empty. Wait for another player to discard a card!"); } Console.WriteLine($"{DateTime.Now}:Sending template with for card:" + ((card != null) ? card.id.ToString() : "no_card")); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(returnFile); // Get a response stream and write the response to it. response.ContentLength64 = buffer.Length; System.IO.Stream output = response.OutputStream; output.Write(buffer, 0, buffer.Length); // You must close the output stream. output.Close(); }