/// <summary> /// Proxy function that sends the pressed card to the Game host /// </summary> /// <param name="cardName"></param> public async Task PostCard(string cardName) { ServerGameSession sGame = MvcApplication.Manager.FindSessionByClientConnectionId(Context.ConnectionId); if (sGame != null) { UnoGame game = sGame.game; //get the player object PlayerObject player = game.Players.FirstOrDefault(n => n.connid == Context.ConnectionId); if (player != null) { //get the card object CardObject card = player.cards.FirstOrDefault(n => n.name == cardName); if (card != null) { //send the game to the host, and let the host process it await sGame.PlayCard(player.id, card); } else { //todo: maybe not end the session, but there is some cheating going on await Clients.Caller.endSession("The card you played was not in your posession."); } } else { await Clients.Caller.endSession("You are not a member of this game"); } } else { await Clients.Caller.endSession("You are not a member of a game"); } }
/// <summary> /// Proxy function that is called after a user picks a color, the function checks if it needs to send cards from the draw four card. /// </summary> /// <param name="game">game object</param> /// <param name="effects">the effects object</param> /// <returns></returns> public async Task HandleSpecialAfterColorPick(UnoGame game, SpecialCardActions effects) { ServerGameSession sGame = MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId); if (effects.sendColorWheel) { if (effects.cardDrawAmount != 0) { //send the NEXT client the amount of cards. game.CurrentPlayer = GetNextPlayerId(game, null); string targetPlayer = new string(game.CurrentPlayer.ToCharArray()); game.CurrentPlayer = GetNextPlayerId(game, null); await PushGame(game); Clients.Caller.drawCardFromSpecial(targetPlayer, effects.cardDrawAmount); } else { game.CurrentPlayer = GetNextPlayerId(game, null); } await PushGame(game); //set the current playing name: await MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId).UpdateCurrentPlayingName(game.Players.FirstOrDefault(n => n.id == game.CurrentPlayer)); } }
/// <summary> /// Function that progresses the game turn depending on the card playing status /// </summary> /// <param name="game"></param> /// <param name="success"></param> public async Task ConfirmCardGame(UnoGame game, bool success) { if (success) { string currentPlayer = game.CurrentPlayer; game.CurrentPlayer = GetNextPlayerId(game, null); int drawCards = CheckUno(game, currentPlayer); await PushGame(game); //set the current playing name: var session = MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId); PlayerObject pObject = game.Players.FirstOrDefault(n => n.id == game.CurrentPlayer); await session.UpdateCurrentPlayingName(pObject); if (drawCards > 0) { await Clients.Caller.drawCardFromSpecial(currentPlayer, drawCards); } else if (drawCards == -69) { await Clients.Caller.gameWon(currentPlayer); } await Clients.Caller.displayMessage($"Player {pObject.name ?? "Unknown (" + pObject.id.Substring(0, 8) + ")"} is up next!"); } else { await PushGame(game); } }
/// <summary> /// Proxy function that requests a card from the Draw Pile at the Game host /// </summary> public async Task DrawCardFromDeck() { string connId = Context.ConnectionId; ServerGameSession session = MvcApplication.Manager.FindSessionByClientConnectionId(Context.ConnectionId); if (session != null) { UnoGame game = session.game; PlayerObject player = game.Players.FirstOrDefault(n => n.connid == connId); await session.DrawCard(player.id); } }
/// <summary> /// Proxy function that is called when an Action card is used in the game, the function decides what the game should do. /// </summary> /// <param name="game">current game object</param> /// <param name="effects">effects object</param> /// <returns></returns> public async Task HandleSpecialCard(UnoGame game, SpecialCardActions effects) { ServerGameSession sGame = MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId); string currentPlayer = game.CurrentPlayer; if (effects.sendColorWheel) { //send the colorwheel update to the current client. //after receiving the color wheel update advance the turn await sGame.ShowColorWheelInClient(effects); } else if (effects.cardDrawAmount != 0) { //send the NEXT client the amount of cards. game.CurrentPlayer = GetNextPlayerId(game, null); string targetPlayer = new string(game.CurrentPlayer.ToCharArray()); game.CurrentPlayer = GetNextPlayerId(game, null); await PushGame(game); await Clients.Caller.drawCardFromSpecial(targetPlayer, effects.cardDrawAmount); } else if (effects.skipNextPerson) { //the skip is handled in code game.CurrentPlayer = GetNextPlayerId(game, effects); } else if (effects.reverseOrder) { game.DirectionClockwise = !game.DirectionClockwise; if (game.Players.Count > 2) { game.CurrentPlayer = GetNextPlayerId(game, null); } } int drawCards = CheckUno(game, currentPlayer); await PushGame(game); //set the current playing name: PlayerObject pObject = game.Players.FirstOrDefault(n => n.id == game.CurrentPlayer); await MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId).UpdateCurrentPlayingName(pObject); if (drawCards > 0) { await Clients.Caller.drawCardFromSpecial(currentPlayer, drawCards); } else if (drawCards == -69) { await Clients.Caller.gameWon(currentPlayer); } }
static void Main(string[] args) { Deck deck = new Deck(new CardRules(9,0,4)); UnoGame unoGame = new UnoGame(deck); StartOfProgram: Console.Clear(); Console.WriteLine(" ____ ___ ________ ________ _______ _______ _______ "); Console.WriteLine(" | | \\____ ____ / _____/_____ _____ ____ \\_____ \\ _ \\ \\ _ \\ \\ _ \\ "); Console.WriteLine(" ______ | | / \\ / _ \\/ \\ ___\\__ \\ / \\_/ __ \\ _(__ </ /_\\ \\/ /_\\ \\/ /_\\ \\ ______ "); Console.WriteLine(" /_____/ | | / | ( <_> ) \\_\\ \\/ __ \\| Y Y \\ ___/ / \\ \\_/ \\ \\_/ \\ \\_/ \\ /_____/ "); Console.WriteLine(" |______/|___| /\\____/ \\______ (____ /__|_| /\\___ > /______ /\\_____ /\\_____ /\\_____ / "); Console.WriteLine(" \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ "); Console.WriteLine(); Console.WriteLine(); Console.WriteLine("Input number of players between 2-6"); int players; if (int.TryParse(Console.ReadLine(), out players)) { if (players >= 2 && players <= 6) Console.WriteLine("You selected to start a game with "+players+" players"); else { Console.WriteLine("You did not select a number between 2 and 6. Press a key to try again"); Console.ReadKey(); goto StartOfProgram; } } else { Console.WriteLine("Incorrect input. Press a key to try again"); Console.ReadKey(); goto StartOfProgram; } for (int i = 0; i < players; i++) { Console.WriteLine("Please input name of player "+(i+1)); unoGame.AddPlayer(new Player(unoGame, Console.ReadLine())); } StartOfGame: unoGame.StartGame(); int selection; Console.WriteLine("\nPress 1 to play again with the same players. Press 2 to select new players. Press any key to exit"); if (int.TryParse(Console.ReadLine(), out selection)) { if (selection == 1) goto StartOfGame; if (selection == 2) goto StartOfProgram; } }
public static Card?Parse(string value, UnoGame game) { bool auto = value.Contains("auto"); value = value.ReplaceMany((" ", ""), ("auto", ""), ("uno", ""), ("draw2", "drawtwo"), ("draw4", "drawfour")); CardColor?color = EnumTraits <CardColor> .Values .FirstOrNull(x => value.StartsOrEndsWith(x.ToString().ToLowerInvariant())); CardType?type = EnumTraits <CardType> .Values.ToList().Reversed() .FirstOrNull(x => value.StartsOrEndsWith(x.ToString().ToLowerInvariant()) || x <= CardType.Nine && value.StartsOrEndsWith(((int)x).ToString())); if (auto) { var cards = game.CurrentPlayer.cards.ToList().Sorted(); if (color == null && type == null) { return(value == "" ? cards.FirstOrNull(game.CanDiscard) : null); } if (color == null) { return(cards.FirstOrNull(x => x.Type == type && game.CanDiscard(x))); } if (type == null) { return(cards.FirstOrNull(x => x.Color == color && game.CanDiscard(x))); } } if (color == null && type.HasValue && IsWild(type.Value)) { color = CardColor.Black; } if (type.HasValue && color.HasValue) { return(new Card(type.Value, color.Value)); } else { return(null); } }
/// <summary> /// Local function that is called after every card action, to determain if the current player has uno. /// </summary> /// <param name="game"></param> /// <param name="playerId"></param> /// <returns></returns> private int CheckUno(UnoGame game, string playerId) { PlayerObject player = game.Players.FirstOrDefault(n => n.id == playerId); if (!player.reportedUno && player.cards.Count > 1) { player.hasUno = false; } if (player.cards.Count == 1) { if (player.reportedUno) { // allow player.reportedUno = false; player.hasUno = true; Clients.Caller.displayMessage($"Player {player.name} has UNO!"); } else { //give player 2 cards player.reportedUno = false; player.hasUno = false; return(2); } } if (player.cards.Count == 0 && player.hasUno) { //player has won return(-69); //:) } if (player.reportedUno && player.cards.Count > 1) { //false uno, draw one card player.reportedUno = false; player.hasUno = false; return(1); } return(0); }
/// <summary> /// Local function that takes the current game and gives you the next player in turn. /// </summary> /// <param name="game">current game object</param> /// <param name="effects">effects object</param> /// <returns></returns> private string GetNextPlayerId(UnoGame game, SpecialCardActions effects) { int currentPlayerIndex = game.Players.FindIndex(n => n.id == game.CurrentPlayer); if (effects == null) { if (game.DirectionClockwise) { int newPlayerId = (game.Players.Count > (currentPlayerIndex + 1)) ? currentPlayerIndex + 1 : 0; return(game.Players[newPlayerId].id); } else { int newPlayerId = ((currentPlayerIndex - 1) >= 0) ? currentPlayerIndex - 1 : game.Players.Count - 1; return(game.Players[newPlayerId].id); } } else if (effects.skipNextPerson) { if (game.DirectionClockwise) { int newPlayerId = currentPlayerIndex + 1; newPlayerId = (game.Players.Count > newPlayerId) ? newPlayerId : 0; newPlayerId++; //adds the skip newPlayerId = (game.Players.Count > newPlayerId) ? newPlayerId : 0; return(game.Players[newPlayerId].id); } else { int newPlayerId = currentPlayerIndex - 1; newPlayerId = (newPlayerId >= 0) ? newPlayerId : game.Players.Count - 1; newPlayerId--; //adds the skip newPlayerId = (newPlayerId >= 0) ? newPlayerId : game.Players.Count - 1; return(game.Players[newPlayerId].id); } } throw new Exception("Passed an effect object without enabling special effects."); }
/// <summary> /// Proxy and local function that syncs the JS and C# backend with eachother. /// </summary> /// <param name="game"></param> /// <returns></returns> public async Task PushGame(UnoGame game) { ServerGameSession sGame = MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId); if (sGame != null) { if (sGame.game.FullDeck.Count == 0 || sGame.game.CurrentPlayer == null) { //new game, select first player from list. sGame.game = game; sGame.game.CurrentPlayer = sGame.game.Players[0].id; } else { sGame.game = game; } await sGame.UpdateAll(); } else { await Clients.Caller.endSession("unkown game id was passed to the server."); } }
public void Setup() { _unoGame = new UnoGame(Substitute.For<IDeck>()); uut = new Player(_unoGame, "Hans"); }
public override void Execute(IMessage messageIn) { if (!(messageIn is SocketMessage)) { DiscordNETWrapper.SendText("This command only works on discord", messageIn.Channel).Wait(); return; } var message = messageIn as SocketMessage; string[] split = message.Content.Split(' '); if (split.Contains("new")) { UnoGame newGame = new UnoGame(message.MentionedUsers.Distinct().Append(message.Author).ToList()); if (newGame.Players.Count < 2) { DiscordNETWrapper.SendText("You need more players to play Uno!", message.Channel).Wait(); return; } if (newGame.Players.Exists(x => x.Item1.IsBot)) { DiscordNETWrapper.SendText("Bots can't play Uno!", message.Channel).Wait(); return; } if (UnoGames.Exists(x => x.Players.Exists(y => y.Item1.Id == message.Author.Id))) { DiscordNETWrapper.SendText("You are already in a uno game!", message.Channel).Wait(); return; } UnoGames.Add(newGame); newGame.Send(message.Channel); foreach (Tuple <SocketUser, List <UnoCard> > player in newGame.Players) { newGame.SendDeck(player); } } else if (split.Contains("print_cards") && message.Author.Id == Program.Master.Id) // Size = {Width = 434 Height = 621} { foreach (UnoCard c in UnoCards) { DiscordNETWrapper.SendBitmap(c.Picture, message.Channel, c.Type.ToString() + " " + c.Color.ToString()).Wait(); } } else if (split.Contains("print")) { UnoGame game = UnoGames.FirstOrDefault(x => x.Players.Exists(y => y.Item1.Id == message.Author.Id)); if (game != null) { game.Send(message.Channel); } else { DiscordNETWrapper.SendText("You are not in a game :thinking:", message.Channel).Wait(); } } else if (split.Length >= 2 && split[1] == "draw") { UnoGame game = UnoGames.FirstOrDefault(x => x.Players.Exists(y => y.Item1.Id == message.Author.Id)); if (game.TurnPlayerID() != message.Author.Id) { DiscordNETWrapper.SendText("It's not your turn :thinking:", message.Channel).Wait(); return; } if (game != null) { game.DrawCards(1, message.Author.Id); } else { DiscordNETWrapper.SendText("You are not in a game :thinking:", message.Channel).Wait(); return; } } else if (split.Length >= 2 && split[1] == "cancel") { UnoGame game = UnoGames.FirstOrDefault(x => x.Players.Exists(y => y.Item1.Id == message.Author.Id)); DiscordNETWrapper.SendText($"`{message.Author.Username}` canceled the match! :cold_sweat: :scream: :dizzy_face: :skull_crossbones: ", message.Channel).Wait(); UnoGames.Remove(game); } else if (split.Length >= 4 && split[1] == "move") { UnoGame game = UnoGames.FirstOrDefault(x => x.Players.Exists(y => y.Item1.Id == message.Author.Id)); if (game == null) { DiscordNETWrapper.SendText("You are not in a game :thinking:", message.Channel).Wait(); return; } UnoCardType t = UnoCardType.one; UnoColor c = UnoColor.none; Enum.TryParse(split[2].ToLower(), out t); Enum.TryParse(split[3].ToLower(), out c); if (split[2].Length > 0 && char.IsDigit(split[2][0])) { t = ToUnoType(Convert.ToInt32(split[2])); } game.PutCardOnTopOfStack(t, c, message.Author.Id, message.Channel); game.Send(message.Channel); Tuple <SocketUser, List <UnoCard> > winner = game.Players.FirstOrDefault(x => x.Item2.Count == 0); if (winner != null) { DiscordNETWrapper.SendText($"`{winner.Item1.Username}` won! :trophy: :tada: ", message.Channel).Wait(); UnoGames.Remove(game); } } else { DiscordNETWrapper.SendEmbed(HelpMenu, message.Channel).Wait(); } return; }