private async Task sendCzarChoice() { var response = $"Everyone has chosen! Time for {currentCzar.Mention} to decide:\n"; //int i = 0; response += $"{currentBlackCard.ToString()}:\n"; foreach (var kvp in WhiteCardsAssortment.OrderBy(x => x.Key)) { var str = ""; foreach (var t in kvp.Value.Value) { str += t.ToString() + ", "; } response += $"\n{kvp.Key + 1}. {str}"; //!!! } //a check for long responses if (response.Length >= 2000) { var split = response.Split('\n').ToList(); var splitIndex = split.Count() / 2; var partOne = string.Join("\n", split.GetRange(0, splitIndex)); var partTwo = string.Join("\n", split.GetRange(splitIndex, splitIndex)); await channel.SendMessage(partOne); await channel.SendMessage(partTwo); } else { await channel.Send(response); } }
/// <summary> /// A random index between the limits /// </summary> /// <returns>Random index</returns> private int getRandomIndex() { var random = new Random(); var rand = random.Next(0, Players.Count - 1); while (WhiteCardsAssortment.ContainsKey(rand)) { rand = random.Next(0, Players.Count - 1); } return(rand); }
/// <summary> /// This is what happens when NadekoBot receives messages /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public async void PotentialPlacement(object sender, MessageEventArgs e) { try { #region checks //Getting the messages we want if (e.Channel.IsPrivate) { return; //Because the default message would show up as well } if (e.Server != server) { return; } if (!Players.Keys.Contains(e.User)) { return; //Only track current players } if (e.User == currentCzar && !CzarDecision) { return; } if (CzarDecision && e.User != currentCzar) { return; } #endregion #region CzarDecision //if the Tzar is making the decision if (CzarDecision) { int choice; if (!int.TryParse(e.Message.Text, out choice)) { return; } choice--; //check whether it's out of range if (choice > WhiteCardsAssortment.Count - 1) { return; } var chosen = WhiteCardsAssortment[choice]; var winner = chosen.Key; var message = $"{winner.Name} has won this round with:\n"; var cards = WhiteCardsAssortment[choice].Value; if (currentBlackCard.CardContents.Contains("\\_\\_\\_")) { var str = currentBlackCard.ToString(); var cardsArray = cards.ToArray(); for (int i = 0; i < cards.Count(); i++) { var c = cardsArray[0]; str = str.Replace("\\_\\_\\_", c.CardContents); } message += str; } else { message += currentBlackCard.ToString(); cards.ToList().ForEach(x => message += x.CardContents + "\n"); } //cahCancelSource.Cancel(); CzarDecision = false; Players[winner].Points++; GameActive = false; await channel.SendMessage(message); //Remove chosen card of winner foreach (var card in cards) { Players[winner].Hand.Remove(card); } //Is it a final win? if (Players[winner].Points != WinRequirement) { return; } ShouldStopGame = true; await channel.Send($"We have a winner! Its {winner.Mention}\n{getLeaderboard()}"); //add leaderboard await FlowersHandler.AddFlowersAsync(winner, "Won CAH", 2); return; } #endregion #region regularPlayers var msg = e.Message.Text; var cardSet = new HashSet <CAHWhiteCard>(); CAHStats stat; if (!Players.TryGetValue(e.User, out stat)) { return; } if (currentBlackCard.WhiteCards == 1) { int index; if (!int.TryParse(msg.Trim(), out index)) { return; } index--; //!!! if (index > stat.Hand.Count() - 1) { return; } cardSet.Add(stat.Hand[index]); } else { if (!Regex.IsMatch(msg, @"\d")) { return; } var matches = Regex.Matches(msg, @"\d+"); if (matches.Count < currentBlackCard.WhiteCards) { await channel.SendMessage($"Black card need {currentBlackCard.WhiteCards} cards, seperated from each other."); return; } foreach (Match m in matches) { var s = m.Value; int index; if (!int.TryParse(s, out index)) { return; } index--; //!!! if (index < 0 || index > stat.Hand.Count() - 1) { cardSet.Add(stat.Hand[index]); } } } var newIndex = getRandomIndex(); var kvp = new KeyValuePair <User, HashSet <CAHWhiteCard> >(e.User, cardSet); var containing = false; WhiteCardsAssortment.Values.ForEach(x => { if (x.Key == e.User) { containing = true; var toUpdate = WhiteCardsAssortment.Where(y => y.Value.Equals(x)).First(); WhiteCardsAssortment.TryUpdate(toUpdate.Key, kvp, toUpdate.Value); } }); if (!containing) { WhiteCardsAssortment.TryAdd(newIndex, kvp); } //chosenWhiteCards.Add(e.User, stat.Hand[index]); //catch the outofRangeExceptions var unset = unSetPlayers(); await channel.SendMessage($"Registered chosen card(s) for {e.User.Mention}\n{unset}"); if (unset == String.Empty) //There are no players who haven't chosen yet { allChosen = true; } #endregion } catch (IndexOutOfRangeException) { //This shouldn't happen anymore await channel.SendMessage("Index given was out of range"); } catch (Exception ex) { Console.WriteLine(ex.Message); } }
private async Task StartGame() { var CzarIndex = 0; //Three Phases: //Allow users to join Message msg = null; while (StartUp) { if (msg != null) { await msg.Delete(); } msg = await channel.SendMessage("New Players may join using >cahjoin.\n Use >cahstart to start"); await Task.Delay(10000); } while (!ShouldStopGame) { allowChangePlayers = false; //Set the CzarIndex correctly if (CzarIndex >= Players.Count) { CzarIndex = 0; } //Set the current Czar currentCzar = Players.Keys.ToList()[CzarIndex++]; //Get a new Black card currentBlackCard = CAHBlackCardPool.Instance.GetRandomBlackCard(oldBlackCards); if (currentBlackCard == null) { await channel.SendMessage("No more black cards found"); await End(); return; } oldBlackCards.Add(currentBlackCard); //Start the new round await channel.SendMessage($"**New Round**:\n" + $"Current Card Czar = {currentCzar.Mention}\n" + $"Black Card:\n" + $"{currentBlackCard.ToString()}\n" + $"**SET YOUR CHOICE BY SENDING INDEX OF CARD TO CHAT: a number from 1-{CAHStats.HandSize}**\n" + "If multiple cards are asked, seperate them with commas: `1,2`"); //send the players their cards foreach (var player in Players.Where(x => x.Key != currentCzar)) { await player.Key.SendMessage(filled(player.Key)); } allowChangePlayers = true; //receive messages NadekoBot.Client.MessageReceived += PotentialPlacement; //Allow the players to play GameActive = true; CzarDecision = false; allChosen = false; while (!allChosen) { await Task.Delay(5000); } await sendCzarChoice(); CzarDecision = true; while (CzarDecision) { //check every 5 seconds whether the Czar has chosen await Task.Delay(5000); } GameActive = false; NadekoBot.Client.MessageReceived -= PotentialPlacement; WhiteCardsAssortment.Clear(); await Task.Delay(2000); } await End(); #region Previousway /* * while (!ShouldStopGame) * { * * //reset the cancellation source * cahCancelSource = new CancellationTokenSource(); * var token =cahCancelSource.Token; * //Load black card * currentBlackCard = CAHBlackCardPool.Instance.GetRandomBlackCard(oldBlackCards); * if (currentBlackCard == null) * { * await channel.SendMessage($":exclamation: Failed to load black card"); * await End(); * return; * } * //add current to exclusion list * oldBlackCards.Add(currentBlackCard); * * * currentTzar = Players.ToList()[TzarIndex++].Key; //should I sort the list? * * await channel.SendMessage($"**New Round**:\n"+ * $"Current Card Czar = {currentTzar.Mention}\n"+ * $"Black Card:\n"+ * $"{currentBlackCard.ToString()}\n"+ * //$"You have {RoundDurationMilliseconds/1000} seconds to set your choice.\n" + * $"**SET YOUR CHOICE BY SENDING INDEX OF CARD TO CHAT**"); * * foreach (var player in Players.Where(x=>x.Key != currentTzar)) * { * await player.Key.SendMessage(filled(player.Key)); * } * * //receive messages * NadekoBot.Client.MessageReceived += PotentialPlacement; * * //allow sending number * GameActive = true; * CzarDecision = false; * allChosen = false; * try * { * * while (!allChosen) * { * //check every 5 seconds whether everyone has chosen * await Task.Delay(5000); * } * // await Task.Delay(RoundDurationMilliseconds, token); * // var response = $":clock2: Time's up! time for the Tzar to decide is {DecideDurationMilliseconds/1000} seconds:"; * var response = $"Everyone has chosen! Time for the Tzar to decide:"; * //int i = 0; * response += $"**{currentBlackCard}**:\n"; * foreach (var kvp in WhiteCardsAssortment.OrderBy(x=>x.Key)) * { * var str = ""; * foreach (var t in kvp.Value.Value) * { * str += t.ToString() + ", "; * } * response += $"\n{kvp.Key}. **{str}**"; * } * if (response.Length >= 2000) * { * var split = response.Split('\n').ToList(); * var splitIndex = split.Count() / 2; * var partOne = string.Join("\n", split.GetRange(0, splitIndex)); * var partTwo = string.Join("\n", split.GetRange(splitIndex, splitIndex)); * await channel.SendMessage(partOne); * await channel.SendMessage(partTwo); * } * else * { * await channel.Send(response); * } * * CzarDecision = true; * //await Task.Delay(DecideDurationMilliseconds, token); * while (CzarDecision) * { * //check every 5 seconds whether the Czar has chosen * await Task.Delay(5000); * } * * } catch (TaskCanceledException) * { * //Console.WriteLine("CAH canceled"); * } * * GameActive = false; * if (!cahCancelSource.IsCancellationRequested) * { * string s = $"Time's up! Since Czar couldn't decide, no one gets a point"; * await channel.SendMessage(s); * } * NadekoBot.Client.MessageReceived -= PotentialPlacement; * WhiteCardsAssortment.Clear(); * await Task.Delay(2000); * } * await End(); */ #endregion }