/// <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] }, }; }
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; }
/// <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(); } }