/// <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] }, }; }
/// <summary> /// Gets all fields of the given board that the card on the given board field can be moved to. /// </summary> /// <param name="game"></param> /// <param name="field"></param> /// <returns></returns> /// <remarks>AiBase classes can call this on themselves since they implement IBoardGame.</remarks> public static List <BoardField> GetMoveTargetFields(IBoardGame game, BoardField field) { var fields = new List <BoardField>(); var card = field?.Card as OnlineCard; // Firewall card cannot be moved directly to another field if (card == null || card.Owner == null) { return(fields); } // No move possible if it is the turn of the other player if (card.Owner.PlayerNumber == 1 && game.Phase == GamePhase.Player2Turn || card.Owner.PlayerNumber == 2 && game.Phase == GamePhase.Player1Turn) { return(fields); } var x = field.X; var y = field.Y; // Code was written for single player mode. // In online play, the board is flipped for player 2 // We cannot transform the coordinates here or everything will be screwed up // Therefore we just invert the player number var currentPlayer = game.Phase == GamePhase.Player1Turn ? 1 : 2; int opponent = game.Phase == GamePhase.Player1Turn ? 2 : 1; #region Deployment // THIS CODE IS NOT NEEDED ANYMORE. JUST HERE FOR REFERENCE //if (game.Phase == GamePhase.Deployment) //{ // // In this phase you can only move cards between stack and deployment fields. // var owner = card.Owner.PlayerNumber; // var depFields = new BoardField[16]; // var y1 = owner == 1 ? 0 : 7; // var y2 = owner == 1 ? 1 : 6; // var y3 = owner == 1 ? 8 : 9; // for (int ix = 0; ix<=7; ++ix) // { // // Set deployment fields // if (ix == 3 || ix == 4) // depFields[ix] = game.Board[ix, y2]; // else // depFields[ix] = game.Board[ix, y1]; // // Set stack fields // depFields[ix+8] = game.Board[ix, y3]; // } // // Select all fields that have no card // fields.AddRange(depFields.Where(o => o.Card == null)); //} #endregion if (game.Phase == GamePhase.Player1Turn || game.Phase == GamePhase.Player2Turn) { // without boost there are 4 possible locations var fs = new BoardField[4]; if (y > 0 && y <= 7) // Down { fs[0] = game.Board[x, y - 1]; } else { // Special case for exit fields: if (y == 0 && field.IsExit && currentPlayer == 2) { fs[0] = game.Board[4, 10]; } } if (y >= 0 && y < 7) // Up { fs[1] = game.Board[x, y + 1]; } else { // Special case for exit fields: if (y == 7 && field.IsExit && currentPlayer == 1) { fs[1] = game.Board[5, 10]; } } if (x > 0 && x <= 7 && y <= 7) // Left; Mask out stack fields { fs[2] = game.Board[x - 1, y]; } if (x >= 0 && x < 7 && y <= 7) // Right { fs[3] = game.Board[x + 1, y]; } // Moves on opponents cards are allowed, move on own card not for (int i = 0; i < 4; ++i) { if (fs[i] == null) { continue; } if (fs[i].Card != null && fs[i].Card.Owner.PlayerNumber == currentPlayer) { continue; } if (fs[i].Card != null && !(fs[i].Card is OnlineCard)) { continue; // Can only jump on online cards <- This ignores the firewall card } if (fs[i].IsStack) { continue; } if (fs[i].IsExit) { // Exit field is allowed, but only your opponents if (currentPlayer == 1 && fs[i].Y == 0) { continue; } if (currentPlayer == 2 && fs[i].Y == 7) { continue; } } fields.Add(fs[i]); } // Boost can add additional fields if (card.HasBoost) { // The same checks as above apply for all fields var additionalfields = new List <BoardField>(); foreach (var f in fields) { // Ignore field if it has an opponents card if (f.Card != null) { continue; } fs = new BoardField[4]; x = f.X; y = f.Y; if (y > 0 && y <= 7) { fs[0] = game.Board[x, y - 1]; } else { // Special case for exit fields: if (y == 0 && f.IsExit && currentPlayer == 2) { fs[0] = game.Board[4, 10]; } } if (y >= 0 && y < 7) { fs[1] = game.Board[x, y + 1]; } else { // Special case for exit fields: if (y == 7 && f.IsExit && currentPlayer == 1) { fs[1] = game.Board[5, 10]; } } if (x > 0 && x <= 7 && y <= 7) // No Stack fields! { fs[2] = game.Board[x - 1, y]; } if (x >= 0 && x < 7 && y <= 7) // No Stack fields! { fs[3] = game.Board[x + 1, y]; } for (int i = 0; i < 4; ++i) { if (fs[i] == null) { continue; } if (fs[i].Card != null && fs[i].Card.Owner.PlayerNumber == currentPlayer) { continue; } if (fs[i].Card != null && !(fs[i].Card is OnlineCard)) { continue; // Can only jump on online cards <- This ignores the firewall card } if (fs[i].IsStack) { continue; } if (fs[i].IsExit) { // Exit field is allowed, but only your opponents if (currentPlayer == 1 && fs[i].Y == 0) { continue; } if (currentPlayer == 2 && fs[i].Y == 7) { continue; } } additionalfields.Add(fs[i]); } } foreach (var f in additionalfields) { if (!fields.Contains(f)) { fields.Add(f); } } } } return(fields); }
void PlaceCardOnStack(BoardField field, int player) { var card = field?.Card as OnlineCard; if (card == null) { return; } // First 4 fields are reserved for link cards, others for viruses // If a card is not revealed it is treated as a link card int y = player == 1 ? 8 : 9; int stackpos = -1; if (card.IsFaceUp && card.Type == OnlineCardType.Virus) { for (int x = 4; x < 8; ++x) { if (Board[x, y].Card != null) { continue; } stackpos = x; break; } } if (stackpos == -1) { for (int x = 0; x < 4; ++x) { if (Board[x, y].Card != null) { continue; } stackpos = x; break; } if (stackpos == -1) // Happens when card.IsFaceUp and card is virus and link stack is full { for (int x = 4; x < 8; ++x) { if (Board[x, y].Card != null) { continue; } stackpos = x; break; } } } // stackpos must have a value by now or stack is full. // Stack can never be full. If more than 6 cards are on the stack, the game is over if (stackpos == -1) { Log.WriteLine(LogPriority.Error, "Game Error! Card cannot be put on stack because it is full"); Phase = GamePhase.Aborted; return; } Board[stackpos, y].Card = card; field.Card = null; // Check if player won or lost int linkCount = 0; int virusCount = 0; for (int x = 0; x < 8; ++x) { var c = Board[x, y].Card as OnlineCard; if (c == null) { continue; } if (c.Type == OnlineCardType.Link) { ++linkCount; } if (c.Type == OnlineCardType.Virus) { ++virusCount; } } if (virusCount >= 4) { Phase = player == 1 ? GamePhase.Player2Win : GamePhase.Player1Win; } if (linkCount >= 4) { Phase = player == 1 ? GamePhase.Player1Win : GamePhase.Player2Win; } }