Ejemplo n.º 1
0
        /// <summary>
        /// Constructor.
        /// </summary>
        public Game()
        {
            _players = new PlayerState[]
            {
                new PlayerState(1)
                {
                    Name = "Player 1"
                },
                new PlayerState(2)
                {
                    Name = "Player 2"
                }
            };
            _phase = GamePhase.WaitingForPlayers;

            Board = new BoardField[8, 11];
            for (ushort y = 0; y < 11; ++y)
            {
                for (ushort x = 0; x < 8; ++x)
                {
                    Board[x, y] = new BoardField(x, y);
                }
            }

            PlayerOnlineCards = new OnlineCard[2, 8];
            for (int p = 0; p < 2; ++p)
            {
                for (int c = 0; c < 8; ++c)
                {
                    PlayerOnlineCards[p, c] = new OnlineCard {
                        Owner = _players[p]
                    }
                }
            }
            ;

            PlayerFirewallCards = new FirewallCard[2]
            {
                new FirewallCard {
                    Owner = _players[0]
                },
                new FirewallCard {
                    Owner = _players[1]
                },
            };
        }
Ejemplo n.º 2
0
        public void Update(Sync sync, PlayerState[] players)
        {
            // Do not check the coordinates! They might require transformation for player 2!
            Card card;

            if (sync.Card.IsFirewall)
            {
                card = new FirewallCard
                {
                    Owner = sync.Card.Owner == 1 ? players[0] : players[1]
                };
            }
            else
            {
                card = new OnlineCard
                {
                    HasBoost = sync.Card.HasBoost,
                    IsFaceUp = sync.Card.IsFaceUp,
                    Owner    = sync.Card.Owner == 1 ? players[0] : players[1],
                    Type     = sync.Card.Type
                };
            }
            Card = card;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Command      Syntax             Example
        /// -------------------------------------------
        /// Deply        dp VVVVLLLL
        /// Move         mv x1,y1,x2,y2     mv 1,1,2,1
        /// Boost        bs x1,y1,e         bs 1,1,1
        /// Firewall     fw x1,y1,e         fw 1,1,1
        /// Virus Check  vc x1,y1           vc 1,1
        /// Error 404    er x1,y1,x2,y2,s   er 1,1,2,2,1
        ///
        /// All coordinates start at 1, not 0. Letters a-h are allowed for x.
        ///
        /// </summary>
        /// <param name="command">Command to play.</param>
        /// <param name="player">Player number.</param>
        /// <returns></returns>
        public virtual async Task <bool> ExecuteCommand(string command, int player)
        {
            await _executeLock.WaitAsync();

            try
            {
                command = ReplaceAltSyntax(command);

                if (player != 1 && player != 2)
                {
                    return(false);
                }
                if (Phase == GamePhase.Player1Turn && player != 1)
                {
                    return(false);
                }
                if (Phase == GamePhase.Player2Turn && player != 2)
                {
                    return(false);
                }
                if (string.IsNullOrEmpty(command))
                {
                    return(false);
                }

                var cmd = command.Trim();

                #region Deploy Command "dp"
                // Deployment command is a command that contains 4 'L' and 4 'V' characters.
                // It corresponds to the 8 cards that will be deployed. The card positions are
                // counted from left to right on the deployment line.
                // The command is "dp". Example:
                // "dp LLVLVVVL"
                if (cmd.StartsWith("dp ", StringComparison.InvariantCultureIgnoreCase))
                {
                    if (Phase != GamePhase.Deployment)
                    {
                        return(false);
                    }
                    if (cmd.Length < 11)
                    {
                        return(false);
                    }
                    cmd = cmd.Substring(3).Trim();
                    if (cmd.Length != 8)
                    {
                        return(false);
                    }
                    // Verify string
                    int linkCount  = 0;
                    int virusCount = 0;
                    var layout     = new OnlineCardType[8];
                    for (int i = 0; i < 8; ++i)
                    {
                        if (cmd[i] == 'L' || cmd[i] == 'l')
                        {
                            ++linkCount;
                            layout[i] = OnlineCardType.Link;
                        }
                        else if (cmd[i] == 'V' || cmd[i] == 'v')
                        {
                            ++virusCount;
                            layout[i] = OnlineCardType.Virus;
                        }
                    }
                    if (linkCount != 4 || virusCount != 4)
                    {
                        return(false);
                    }
                    linkCount  = 0;
                    virusCount = 0;
                    --player; // Working with index !!!
                    var y1 = player == 0 ? 0 : 7;
                    var y2 = player == 0 ? 1 : 6;
                    for (int x = 0; x < 8; ++x)
                    {
                        // Clear stack.
                        //Board[x, 8 + player].Card = null; stack not used for depl. anymore
                        // Place card
                        int y      = (x == 3 || x == 4) ? y2 : y1;
                        int offset = layout[x] == OnlineCardType.Link ? linkCount++ : (4 + virusCount++);
                        var xx     = player == 0 ? x : 7 - x;
                        Board[xx, y].Card = PlayerOnlineCards[player, offset];
                    }
                    _hasDeployed[player] = true;
                    if (_hasDeployed[0] && _hasDeployed[1])
                    {
                        BeginTurns();
                    }
                    return(true);
                }
                #endregion

                #region Move command "mv"
                if (cmd.StartsWith("mv ", StringComparison.InvariantCultureIgnoreCase) && command.Length > 3)
                {
                    command = command.Substring(3).Trim();
                    var split = command.Split(new[] { ',' });
                    if (split.Length != 4)
                    {
                        return(false);
                    }
                    ReplaceLettersWithNumbers(ref split);
                    uint x1, x2, y1, y2;
                    if (!uint.TryParse(split[0], out x1) ||
                        !uint.TryParse(split[1], out y1) ||
                        !uint.TryParse(split[2], out x2) ||
                        !uint.TryParse(split[3], out y2))
                    {
                        return(false);
                    }

                    // Convert to zero based index:
                    --x1; --x2; --y1; --y2;

                    if (x1 > 7 || x2 > 7 || (y1 > 7 && y1 != 10) || (y2 > 7 && y2 != 10))
                    {
                        return(false);
                    }

                    var field1 = Board[x1, y1];
                    var field2 = Board[x2, y2];
                    var card1  = field1.Card as OnlineCard;
                    if (card1?.Owner?.PlayerNumber != player)
                    {
                        return(false);
                    }

                    if (!GetMoveTargetFields(this, field1).Contains(field2))
                    {
                        return(false);
                    }

                    // Check if card is claimed
                    if (field2.Card != null)
                    {
                        var card2 = field2.Card as OnlineCard;
                        if (card2 == null || card2.Owner?.PlayerNumber == player)
                        {
                            return(false);
                        }
                        card2.IsFaceUp = true;
                        PlaceCardOnStack(field2, player);
                        if (field2.Card != null)
                        {
                            // Could not move card, error!
                            Phase = GamePhase.Aborted;
                            return(true);
                        }
                        if (card2.HasBoost)
                        {
                            card2.HasBoost = false;
                        }
                    }
                    if (field2.IsServerArea)
                    {
                        PlaceCardOnStack(field1, player);
                        if (field1.Card != null)
                        {
                            // Could not move card, error!
                            Phase = GamePhase.Aborted;
                            return(true);
                        }
                        if (card1.HasBoost)
                        {
                            card1.HasBoost = false;
                        }
                    }
                    field2.Card = field1.Card;
                    field1.Card = null;
                    SwitchPlayerTurnPhase();
                    return(true);
                }
                #endregion

                #region Boost command "bs"
                if (command.StartsWith("bs ", StringComparison.InvariantCultureIgnoreCase) && command.Length > 3)
                {
                    command = command.Substring(3).Trim();
                    var split = command.Split(new[] { ',' });
                    if (split.Length != 3)
                    {
                        return(false);
                    }

                    ReplaceLettersWithNumbers(ref split);

                    uint x1, y1, enabled;
                    if (!uint.TryParse(split[0], out x1) ||
                        !uint.TryParse(split[1], out y1) ||
                        !uint.TryParse(split[2], out enabled))
                    {
                        return(false);
                    }

                    // Convert to zero based index:
                    --x1; --y1;

                    if (x1 > 7 || y1 > 7 || enabled > 1)
                    {
                        return(false);
                    }

                    var field1 = Board[x1, y1];
                    var card1  = field1.Card as OnlineCard;
                    if (card1?.Owner?.PlayerNumber != player)
                    {
                        return(false);
                    }

                    OnlineCard boostedCard = null;
                    for (int i = 0; i < 8; ++i)
                    {
                        var card = PlayerOnlineCards[player - 1, i];
                        if (card.HasBoost)
                        {
                            boostedCard = card;
                            break;
                        }
                    }

                    if (enabled == 1)
                    {
                        if (boostedCard != null)
                        {
                            return(false); // Boost already placed
                        }
                        card1.HasBoost = true;
                        SwitchPlayerTurnPhase();
                        return(true);
                    }

                    // enabled == 0
                    if (boostedCard != card1)
                    {
                        return(false); // wrong card selected
                    }
                    card1.HasBoost = false;
                    SwitchPlayerTurnPhase();
                    return(true);
                }
                #endregion

                #region Firewall command "fw"
                if (cmd.StartsWith("fw ", StringComparison.InvariantCulture) && command.Length > 3)
                {
                    command = command.Substring(3).Trim();
                    var split = command.Split(new[] { ',' });
                    if (split.Length != 3)
                    {
                        return(false);
                    }

                    ReplaceLettersWithNumbers(ref split);

                    uint x1, y1, enabled;
                    if (!uint.TryParse(split[0], out x1) ||
                        !uint.TryParse(split[1], out y1) ||
                        !uint.TryParse(split[2], out enabled))
                    {
                        return(false);
                    }

                    // Convert to zero based index:
                    --x1; --y1;

                    if (x1 > 7 || y1 > 7 || enabled > 1)
                    {
                        return(false);
                    }

                    var field1 = Board[x1, y1];
                    var card1  = field1.Card;

                    if (enabled == 1)
                    {
                        if (card1 != null)
                        {
                            return(false);               // Can only place on empty field
                        }
                        // Make sure firewall card wasn't already placed
                        for (int x = 0; x < 8; ++x)
                        {
                            for (int y = 0; y < 8; ++y)
                            {
                                var card = Board[x, y].Card;
                                if (card?.Owner.PlayerNumber != player)
                                {
                                    continue;
                                }
                                if (card is FirewallCard)
                                {
                                    return(false);                      // card already placed
                                }
                            }
                        }

                        field1.Card = PlayerFirewallCards[player - 1];
                        SwitchPlayerTurnPhase();
                        return(true);
                    }

                    // enabled == 0
                    if (!(card1 is FirewallCard) || card1.Owner?.PlayerNumber != player)
                    {
                        return(false);
                    }
                    field1.Card = null;
                    SwitchPlayerTurnPhase();
                    return(true);
                }
                #endregion

                #region Virus Check command "vc"

                if (command.StartsWith("vc ", StringComparison.InvariantCultureIgnoreCase) && command.Length > 3)
                {
                    command = command.Substring(3).Trim();
                    var split = command.Split(new[] { ',' });
                    if (split.Length != 2)
                    {
                        return(false);
                    }

                    ReplaceLettersWithNumbers(ref split);

                    uint x1, y1;
                    if (!uint.TryParse(split[0], out x1) ||
                        !uint.TryParse(split[1], out y1))
                    {
                        return(false);
                    }

                    if (Players[player - 1].DidVirusCheck)
                    {
                        return(false);
                    }

                    // Convert to zero based index:
                    --x1; --y1;

                    if (x1 > 7 || y1 > 7)
                    {
                        return(false);
                    }

                    var field1 = Board[x1, y1];
                    var card1  = field1.Card as OnlineCard;

                    if (card1 == null || card1.Owner?.PlayerNumber == player || card1.IsFaceUp)
                    {
                        return(false);
                    }

                    card1.IsFaceUp = true;
                    Players[player - 1].DidVirusCheck = true;
                    SwitchPlayerTurnPhase();
                    return(true);
                }

                #endregion

                #region Error 404 command "er"

                if (command.StartsWith("er ", StringComparison.InvariantCultureIgnoreCase) && command.Length > 3)
                {
                    command = command.Substring(3).Trim();
                    var split = command.Split(new[] { ',' });
                    if (split.Length != 5)
                    {
                        return(false);
                    }

                    ReplaceLettersWithNumbers(ref split);

                    uint x1, y1, x2, y2, switchCards;
                    if (!uint.TryParse(split[0], out x1) ||
                        !uint.TryParse(split[1], out y1) ||
                        !uint.TryParse(split[2], out x2) ||
                        !uint.TryParse(split[3], out y2) ||
                        !uint.TryParse(split[4], out switchCards))
                    {
                        return(false);
                    }

                    if (Players[player - 1].Did404NotFound)
                    {
                        return(false);
                    }

                    // Convert to zero based index:
                    --x1; --x2; --y1; --y2;

                    if (x1 > 7 || y1 > 7 || x2 > 7 || y2 > 7 || switchCards > 1)
                    {
                        return(false);
                    }

                    var field1 = Board[x1, y1];
                    var field2 = Board[x2, y2];
                    var card1  = field1.Card as OnlineCard;
                    var card2  = field2.Card as OnlineCard;

                    if (card1?.Owner?.PlayerNumber != player || card2?.Owner?.PlayerNumber != player)
                    {
                        return(false);
                    }

                    card1.IsFaceUp = false;
                    card2.IsFaceUp = false;

                    if (switchCards == 1)
                    {
                        field1.Card = card2;
                        field2.Card = card1;
                        if (card2.HasBoost)
                        {
                            card1.HasBoost = true;
                            card2.HasBoost = false;
                        }
                        else if (card1.HasBoost)
                        {
                            card1.HasBoost = false;
                            card2.HasBoost = true;
                        }
                    }

                    Players[player - 1].Did404NotFound = true;
                    SwitchPlayerTurnPhase();
                    return(true);
                }

                #endregion

                return(false);
            }
            finally
            {
                _executeLock.Release();
            }
        }