void Awake() { startGameState = new StartGameState(this); startTurnState = new StartTurnState(this); playerTurnState = new PlayerTurnState(this); dealerTurnState = new DealerTurnState(this); endHandState = new EndHandState(this); endGameState = new EndGameState(this); }
public TurnStateManager(TurnManager owner) : base(owner) { firstState = new FirstState(this); playerStartState = new PlayerStartState(this); playerTurnState = new PlayerTurnState(this); playerEndState = new PlayerEndState(this); enemyStartState = new EnemyStartState(this); enemyEndState = new EnemyEndState(this); resultState = new ResultState(this); current = firstState; }
/// <summary> /// Creates a new game instance. /// </summary> public GameManager() { _gameSettings = new GameSettings(); _gameState = GameStates.NotStarted; _playerTurnState = PlayerTurnState.None; _gameBoard = new GameBoard(); _players = new List<Player>(); _developmentCardDeck = new CardDeck<DevelopmentCards>(); _dice = new Dice(); _tradeHelper = new TradeHelper(); _playersCardsToLose = new Dictionary<Player, int>(); _playersToStealFrom = new List<Player>(); }
public static void Initialize() { endTurnState = new EndTurnState(playerTurnState); playerLandedState = new PlayerLandedState(endTurnState); playerMoveState = new PlayerMoveState(playerLandedState); playerRollState = new PlayerRollState(playerMoveState); playerTurnState = new PlayerTurnState(playerRollState); initialState = new InitialState(playerTurnState); endTurnState.NextState = playerTurnState; States.Add("InitialState", initialState); States.Add("PlayerTurnState", playerTurnState); States.Add("PlayerRollState", playerRollState); States.Add("PlayerMoveState", playerMoveState); States.Add("PlayerLandedState", playerLandedState); States.Add("EndTurnState", endTurnState); }
/// <summary> /// next active actor choosing /// </summary> void ChooseNextActive() { if (IsBattleOver())//check battle is not over { return; } if (active == playerBattle) //check player is active character { if (enemyBattle.stun == true) //check enemy is stunned { if (enemyBattle.tmpStun >= 0) //check temporary stun is bigger than 0 { enemyBattle.tmpStun--; //decrease temprorary stun value state = PlayerTurnState.Waiting; //change to waiting for action if (enemyBattle.tmpStun == 0) //check tmp stun is equal to zero { enemyBattle.stun = false; //change value of stun return; //leave function } SetActive(playerBattle); //activate player } } else//if enemy is not stunned { state = PlayerTurnState.Busy;//change action to busy mode enemyBattle.Attack(playerBattle, () => //attack player { Battle.Instance.SetPlayerHealth(playerBattle.healthSystem.GetHealth()); //update player health ChooseNextActive(); //activate next }); SetActive(enemyBattle); //activate enemy } } else // if enemy is active { state = PlayerTurnState.Waiting;//change mode to waiting SetActive(playerBattle);//set player active } }
/// <summary> /// choice of player /// call when player presses button /// </summary> /// <param name="victim"></param> public void PlayerChoice(GameObject victim) { if (GameManager.Instance.onGamePaused == false) //is not paused { victim = enemyBattle.gameObject; //set victim to enemy if (state == PlayerTurnState.Waiting) //check is it players turn { switch (gameState) { case BattleState.Attack: //attack state = PlayerTurnState.Busy; //set player is doing action playerBattle.Attack(enemyBattle, () => //call attack function { Battle.Instance.SetEnemyHealth(enemyBattle.healthSystem.GetHealth()); //update enemy`s health ChooseNextActive(); //activate next character }); break; case BattleState.Stun: //stun enemy state = PlayerTurnState.Busy; //set player is doing action playerBattle.Stun(enemyBattle, () => //call stun function { ChooseNextActive(); //activate next }); break; case BattleState.Regen: //regeneration state = PlayerTurnState.Busy; //change to busy mode playerBattle.Heal(); //call heal function to add health Battle.Instance.SetPlayerHealth(playerBattle.healthSystem.GetHealth()); //update player health ChooseNextActive(); //activate next break; } } } }
private void Awake() { //Awake handles one time instatiation of the state machine and state components //Super States do not need to be instatiated StateMachine = new PlayerStateMachine(); IdleState = new PlayerIdleState(this, StateMachine, playerData, "idle"); MoveState = new PlayerMoveState(this, StateMachine, playerData, "move"); TurnState = new PlayerTurnState(this, StateMachine, playerData, "turn"); JumpSquatState = new PlayerJumpSquatState(this, StateMachine, playerData, "jumpSquat"); JumpState = new PlayerJumpState(this, StateMachine, playerData, "jump"); InAirState = new PlayerInAirState(this, StateMachine, playerData, "inAir"); LandState = new PlayerLandState(this, StateMachine, playerData, "land"); DiveState = new PlayerDiveState(this, StateMachine, playerData, "dive"); DoubleJumpState = new PlayerDoubleJumpState(this, StateMachine, playerData, "doubleJump"); EndFallState = new PlayerEndFallState(this, StateMachine, playerData, "endFall"); StartFallState = new PlayerStartFallState(this, StateMachine, playerData, "startFall"); AbilityOneState = new PlayerAbilityOneState(this, StateMachine, playerData, "abilityOne"); CrouchState = new PlayerCrouchState(this, StateMachine, playerData, "crouch"); AbilityCrouchOneState = new PlayerAbilityCrouchOneState(this, StateMachine, playerData, "abilityCrouchOne"); AbilityJumpOneState = new PlayerAbilityJumpOneState(this, StateMachine, playerData, "abilityJumpOne"); DodgeState = new PlayerDodgeState(this, StateMachine, playerData, "dodge"); AbilityTwoState = new PlayerAbilityTwoState(this, StateMachine, playerData, "abilityTwo"); }
/// <summary> /// Plays a development card for a player and performs any actions due to the card. /// </summary> public ActionResult PlayerPlayDevelopmentCard(int playerId, DevelopmentCards cardToPlay) { var validation = ValidatePlayerAction(PlayerTurnState.TakeAction, playerId); if (validation.Failed) return validation; var pr = GetPlayerFromId(playerId); if (pr.Failed) return pr; var player = pr.Data; var dr = player.PlayDevelopmentCard(cardToPlay); if (dr.Failed) return dr; if (cardToPlay == DevelopmentCards.Knight) { // Check if the player now has the largest army. var newArmySize = player.ArmySize; // Must be at least 3 knights to have the largest army. if (newArmySize >= 3 && newArmySize > _largestArmy.Item2) _largestArmy = Tuple.Create(playerId, newArmySize); // Now let the player place the robber. _playerTurnState = _gameSettings.RobberMode == RobberMode.None ? PlayerTurnState.TakeAction : PlayerTurnState.PlacingRobber; } else if (cardToPlay == DevelopmentCards.Library || cardToPlay == DevelopmentCards.Chapel || cardToPlay == DevelopmentCards.Market || cardToPlay == DevelopmentCards.University || cardToPlay == DevelopmentCards.GreatHall) { // VP card. Do nothing. } else if (cardToPlay == DevelopmentCards.Monopoly) { _playerTurnState = PlayerTurnState.MonopolySelectingResource; } else if (cardToPlay == DevelopmentCards.YearOfPlenty) { _playerTurnState = PlayerTurnState.YearOfPlentySelectingResources; } else if (cardToPlay == DevelopmentCards.RoadBuilding) { _roadBuildingRoadsRemaining = 2; _playerTurnState = PlayerTurnState.RoadBuildingSelectingRoads; } return ActionResult.CreateSuccess(); }
/// <summary> /// Places a road for the given player at the given location. /// If it's the initial placement phase of the game, the road is free. /// Otherwise, resources will be removed from the player. /// </summary> public ActionResult PlayerPlaceRoad(int playerId, HexEdge location) { var validation = ValidatePlayerAction(PlayerTurnState.PlacingRoad, playerId); if (validation.Failed) return validation; var pr = GetPlayerFromId(playerId); if (pr.Failed) return pr; var player = pr.Data; bool startOfGame = (_gameState == GameStates.InitialPlacement); // Make sure the player doesn't place too many roads in the intial placement phase if (startOfGame) { var buildingCount = _gameBoard.GetBuildingCountForPlayer(playerId); var roadCount = _gameBoard.GetRoadCountForPlayer(playerId); var maxRoads = buildingCount; if (roadCount >= maxRoads) return ActionResult.CreateFailed("Cannot place more than 1 road per settlement during the initial placement phase."); } var placementValidation = _gameBoard.ValidateRoadPlacement(playerId, location, startOfGame); if (placementValidation.Failed) return placementValidation; var purchaseResult = player.Purchase(PurchasableItems.Road, startOfGame); if (purchaseResult.Failed) return purchaseResult; // We'll assume this succeeds because we already validated it. var placement = _gameBoard.PlaceRoad(player.Id, location, startOfGame); System.Diagnostics.Debug.Assert(placement.Succeeded); // When we place a road, do a check to see if we deserve the longest road. CheckForLongestRoad(playerId); // Update game and player states. if (_gameState == GameStates.InitialPlacement) { var buildingCount = _gameBoard.GetBuildingCountForPlayer(playerId); if (LastPlayerIsActive && buildingCount == 1) { // The "last" player gets to place twice. _playerTurnState = PlayerTurnState.PlacingBuilding; } else { // Go to the next players turn. AdvanceToNextPlayerTurn(); } } else if (_gameState == GameStates.GameInProgress) { _playerTurnState = PlayerTurnState.TakeAction; } return ActionResult.CreateSuccess(); }
/// <summary> /// Places a road for the given player at the given location after the RoadBuilding card has been played. /// Can only be called by the active player. /// </summary> public ActionResult PlayerPlaceRoadForRoadBuilding(int playerId, HexEdge location) { var validation = ValidatePlayerAction(PlayerTurnState.RoadBuildingSelectingRoads, playerId); if (validation.Failed) return validation; var pr = GetPlayerFromId(playerId); if (pr.Failed) return pr; var player = pr.Data; // Make sure the player doesn't place too many roads if (_roadBuildingRoadsRemaining <= 0) return ActionResult.CreateFailed("Cannot place more than 2 roads with the RoadBuilding card."); var placementValidation = _gameBoard.ValidateRoadPlacement(playerId, location, false); if (placementValidation.Failed) return placementValidation; var purchaseResult = player.Purchase(PurchasableItems.Road, true); if (purchaseResult.Failed) { // If this failed, it means that the player has no more roads available. This turn state has to end. _roadBuildingRoadsRemaining = 0; _playerTurnState = PlayerTurnState.TakeAction; return purchaseResult; } var rr = _gameBoard.PlaceRoad(player.Id, location, false); if (rr.Failed) return rr; // When we place a road, do a check to see if we deserve the longest road. CheckForLongestRoad(playerId); _roadBuildingRoadsRemaining--; if (_roadBuildingRoadsRemaining <= 0) { _playerTurnState = PlayerTurnState.TakeAction; } return ActionResult.CreateSuccess(); }
/// <summary> /// Places a building for the given player at the given location. /// If it's the start of the game, the building is free. /// Otherwise, resources will be removed from the player. /// </summary> public ActionResult PlayerPlaceBuilding(int playerId, BuildingTypes type, HexPoint location) { var validation = ValidatePlayerAction(PlayerTurnState.PlacingBuilding, playerId); if (validation.Failed) return validation; var pr = GetPlayerFromId(playerId); if (pr.Failed) return pr; var player = pr.Data; bool startOfGame = (_gameState == GameStates.InitialPlacement); // Make sure the player doesn't place too many buildings in the intial placement phase if (startOfGame) { if (type != BuildingTypes.Settlement) return ActionResult.CreateFailed("Can only place settlements during the initial placement phase."); var buildingCount = _gameBoard.GetBuildingCountForPlayer(playerId); var maxBuildingCount = (LastPlayerHasPlaced) ? 2 : 1; if (buildingCount >= maxBuildingCount) return ActionResult.CreateFailed("Cannot place any more settlements during the initial placement phase."); } var placementValidation = _gameBoard.ValidateBuildingPlacement(playerId, type, location, startOfGame); if (placementValidation.Failed) return placementValidation; PurchasableItems itemToBuy = (type == BuildingTypes.City) ? PurchasableItems.City : PurchasableItems.Settlement; var purchaseResult = player.Purchase(itemToBuy, startOfGame); if (purchaseResult.Failed) return purchaseResult; // We'll assume this succeeds because we already validated it. var placement = _gameBoard.PlaceBuilding(player.Id, type, location, startOfGame); System.Diagnostics.Debug.Assert(placement.Succeeded); // Update game and player states. if (_gameState == GameStates.InitialPlacement) { var buildingCount = _gameBoard.GetBuildingCountForPlayer(playerId); if (buildingCount == 2) { // We've played the second building during the setup phase. Collect resources. var resources = _gameBoard.GetResourcesForBuilding(location, BuildingTypes.Settlement); player.ResourceCards.Add(resources); } _playerTurnState = PlayerTurnState.PlacingRoad; } else if (_gameState == GameStates.GameInProgress) { _playerTurnState = PlayerTurnState.TakeAction; } return ActionResult.CreateSuccess(); }
private void Events_Tick(object sender, TickEventArgs e) { if (isDrawing || stopDraw) { return; } isDrawing = true; if (game.State != null) { if (game.State is LandGrantState) { buffer.Fill(Color.White); drawMap(); drawMapHeaderText("LAND GRANT"); drawMapFooterText("PRESS YOUR BUTTON TO SELECT A PLOT"); } else if (game.State is TransportState) { buffer.Fill(Color.White); drawMap(); TransportState state = (TransportState)game.State; if (state.State == TransportState.LocalState.Lifting || state.State == TransportState.LocalState.Leaving || state.ShipRectangle.X < 0) { drawMapFooterText( "THE SHIP WILL BE BACK IN " + game.NumRounds.ToString() + " MONTHS." ); } else { drawMapHeaderText("TRANSPORT SHIP"); drawMapFooterText("YOU'RE LANDING ON THE PLANET IRATA."); } } else if (game.State is SummaryState) { buffer.Fill(Color.Black); drawSummary(); } else if (game.State is PlayerTurnState) { buffer.Fill(Color.White); PlayerTurnState state = (PlayerTurnState)game.State; drawMapHeaderText("DEVELOPMENT #" + game.Round.ToString()); if (state.State == PlayerTurnState.LocalState.WaitForButton) { drawMap(); if (state.State == PlayerTurnState.LocalState.WaitForButton) { drawMapFooterText("PRESS YOUR STICK BUTTON TO START"); } } else if (state.State == PlayerTurnState.LocalState.ZoomInStore || state.State == PlayerTurnState.LocalState.ZoomOutStore) { Surface scaledStore = storebg.CreateScaledSurface(state.StoreScale); buffer.Blit( scaledStore, new Point( buffer.Width / 2 - scaledStore.Width / 2, buffer.Height / 2 - scaledStore.Height / 2 )); destroySurface(scaledStore); drawTicker(state.Ticker.Value); } else if (state.State == PlayerTurnState.LocalState.InStore || state.State == PlayerTurnState.LocalState.Pub) { drawStore( state.PlayerNum, state.PlayerSprite, state.MuleSprite, state.HasMule); drawTicker(state.Ticker.Value); } else if (state.State == PlayerTurnState.LocalState.Outside) { drawMap(); drawTicker(state.Ticker.Value); } } } Surface scaledBuffer = buffer.CreateScaledSurface(bufferScale, antiAlias); screen.Blit( scaledBuffer, new Point( screen.Width / 2 - scaledBuffer.Width / 2, screen.Height / 2 - scaledBuffer.Height / 2 )); destroySurface(scaledBuffer); screen.Update(); isDrawing = false; }
/// <summary> /// Moves the robber to a new location. Can only be called by the active player. /// </summary> public ActionResult PlayerMoveRobber(int playerId, Hexagon newLocation) { var validation = ValidatePlayerAction(PlayerTurnState.PlacingRobber, playerId); if (validation.Failed) return validation; var apr = GetPlayerFromId(playerId); if (apr.Failed) return apr; var activePlayer = apr.Data; var moveResult = _gameBoard.MoveRobber(playerId, newLocation); if (moveResult.Failed) return moveResult; // Success. Check for nearby players which can be robbed. var touchingPlayers = moveResult.Data; if (touchingPlayers != null && touchingPlayers.Any()) { var playersWithCards = FilterOutPlayersWithNoCards(touchingPlayers.Where(pid => pid != playerId)); if (playersWithCards.Any()) { _playersToStealFrom.Clear(); _playersToStealFrom.AddRange(playersWithCards); _playerTurnState = PlayerTurnState.SelectingPlayerToStealFrom; } else { // No one to steal from. _playerTurnState = PlayerTurnState.TakeAction; } } else { _playerTurnState = PlayerTurnState.TakeAction; } return ActionResult.CreateSuccess(); }
/// <summary> /// Offer a player-to-player trade with anyone. This can be immediately accepted or /// players can send counter-offers. Can only be called by the active player. /// </summary> public ActionResult PlayerOfferTrade(int playerId, TradeOffer tradeOffer) { var validation = ValidatePlayerAction(PlayerTurnState.TakeAction, playerId); if (validation.Failed) return validation; if (tradeOffer == null || !tradeOffer.IsValid) { return ActionResult.CreateFailed("Invalid trade offer."); } if (!ActivePlayer.HasAtLeast(tradeOffer.ToGive)) { return ActionResult.CreateFailed("Cannot afford to create this trade offer."); } _tradeHelper.ClearAllOffers(); tradeOffer.CreatorPlayerId = playerId; // Set the playerId manually just in case. _tradeHelper.ActivePlayerTradeOffer = tradeOffer; _playerTurnState = PlayerTurnState.RequestingPlayerTrade; return ActionResult.CreateSuccess(); }
private ActionResult ValidatePlayerAction(PlayerTurnState requiredState, int activePlayerId) { if (ActivePlayer == null || ActivePlayer.Id != activePlayerId) return ActionResult.CreateFailed("Not allowed to play out of turn."); return ValidatePlayerAction(requiredState); }
private void drawMap() { mapBuffer.Blit(map); for (int y = 0; y < numTilesHigh; y++) { for (int x = 0; x < numTilesWide; x++) { if (game.Map.Plots[x, y].Player > -1) { mapBuffer.Blit( plots, new Point( x * PLOTSIZE, y * PLOTSIZE ), new Rectangle( (int)game.Map.Plots[x, y].Resource * PLOTSIZE, ( game.Players[game.Map.Plots[x, y].Player].Highlight ? 0 : (int)game.Players[game.Map.Plots[x, y].Player].Color * PLOTSIZE ), PLOTSIZE, PLOTSIZE )); } } } if (game.State is TransportState) { TransportState state = (TransportState)game.State; drawShip( ShipType.Mothership, state.ShipRectangle.X, state.ShipRectangle.Y, state.ShipRectangle.Width, state.ShipRectangle.Height ); } else if (game.State is LandGrantState) { LandGrantState state = (LandGrantState)game.State; if (state.State == LandGrantState.LocalState.Normal || state.State == LandGrantState.LocalState.GainedPlot) { mapBuffer.Blit( cursor, new Point( state.CursorPos.X * PLOTSIZE, state.CursorPos.Y * PLOTSIZE ), new Rectangle( 0, ( state.State == LandGrantState.LocalState.Normal ? 0 : (int)game.Players[ game.Map.Plots[state.CursorPos.X, state.CursorPos.Y].Player ].Color * PLOTSIZE ), PLOTSIZE, PLOTSIZE )); } } else if (game.State is PlayerTurnState) { PlayerTurnState state = (PlayerTurnState)game.State; if (state.HasMule) { drawMule( mapBuffer, state.PlayerNum, state.MuleSprite.Outfitted, state.MuleSprite.Frame, state.MuleSprite.X, state.MuleSprite.Y, state.MuleSprite.Small ); } drawPlayer( mapBuffer, state.PlayerNum, state.PlayerSprite.Frame, state.PlayerSprite.X, state.PlayerSprite.Y, state.PlayerSprite.Small ); } Surface scaledMap = mapBuffer.CreateScaledSurface(mapScale, antiAlias); buffer.Blit( scaledMap, new Point( buffer.Width / 2 - scaledMap.Width / 2, buffer.Height / 2 - scaledMap.Height / 2 )); destroySurface(scaledMap); }
/// <summary> /// Selects the two resources after the YearOfPlenty card is played. Can only be called by the active player. /// </summary> public ActionResult PlayerSelectResourcesForYearOfPlenty(int playerId, ResourceTypes res1, ResourceTypes res2) { var validation = ValidatePlayerAction(PlayerTurnState.YearOfPlentySelectingResources, playerId); if (validation.Failed) return validation; var pr = GetPlayerFromId(playerId); if (pr.Failed) return pr; var activePlayer = pr.Data; activePlayer.ResourceCards[res1]++; activePlayer.ResourceCards[res2]++; _playerTurnState = PlayerTurnState.TakeAction; return ActionResult.CreateSuccess(); }
/// <summary> /// Starts a brand new game with the current players. /// </summary> public void StartNewGame() { _playerTurnIndex = 0; // The first person in the list goes first. _longestRoad = Tuple.Create(-1, -1); _largestArmy = Tuple.Create(-1, -1); SetupDevelopmentCards(); _gameBoard.Setup(); _gameBoard.RobberMode = _gameSettings.RobberMode; _roadBuildingRoadsRemaining = 0; _dice.ClearLog(); _playersCardsToLose.Clear(); _playersToStealFrom.Clear(); _tradeHelper.ClearAllOffers(); _gameState = GameStates.InitialPlacement; _playerTurnState = PlayerTurnState.PlacingBuilding; // TODO: Possibly wait for something to trigger the game start. }
/// <summary> /// Rolls the dice and handles resources/robber logic. Can only be called by the active player. /// </summary> public ActionResult<int> PlayerRollDice(int playerId) { var validation = ValidatePlayerAction(PlayerTurnState.NeedToRoll, playerId); if (validation.Failed) return validation.ToGeneric<int>(); var diceRoll = _dice.Roll(); // If the roll is a 7, then we do special logic to make players // lose cards and we let the active player place the robber. if (diceRoll == 7) { // Possibly make players lose cards ComputePlayersCardsToLose(); if (_playersCardsToLose.Any()) { // Some players need to lose cards. Change player state. // We will stay in this state until the unlucky players have selected cards to lose. _playerTurnState = PlayerTurnState.AnyPlayerSelectingCardsToLose; } else { // No players need to lose any cards. Immediately let the player move the robber. _playerTurnState = _gameSettings.RobberMode == RobberMode.None ? PlayerTurnState.TakeAction : PlayerTurnState.PlacingRobber; } } else { // Give resources var allResources = _gameBoard.GetResourcesForDiceRoll(diceRoll); foreach (var resources in allResources) { var playerResult = GetPlayerFromId(resources.Key); if (playerResult.Succeeded && playerResult.Data != null) { var player = playerResult.Data; var newResourcesForPlayer = resources.Value; player.AddResources(newResourcesForPlayer); } } // Nothing special to do, just advance to next turn state. _playerTurnState = PlayerTurnState.TakeAction; } return ActionResult<int>.CreateSuccess(diceRoll); }
private void MakeBestMove() { var possibleMoves = GameBoard.GetPossibleMoves(TileState.Black); var move = AlphaBetaSearch(new Board(GameBoard), (int)GameDifficulty*D); GameBoard.MovePiece(move.startTile, GameBoard.GetTileInDirection(move.startTile, move.direction)); if (move.CapturedTiles.Keys.Any()) { GameBoard.MakeMove(move, move.CapturedTiles.Keys.First()); } CurrentPlayer = Player.Human; CurrentPlayerTurnState = PlayerTurnState.NoMove; }
private void InitializeGameStateVars() { CurrentState = GameState.Playing; CurrentPlayer = Player.Human; CurrentPlayerTurnState = PlayerTurnState.NoMove; CanGoToNextTurn = false; CurrentMoveChain = new HashSet<Direction>(); }
private void HandlePieceClick(int x, int y) { var tile = ClickedOnTile(x, y); switch (CurrentPlayerTurnState) { case PlayerTurnState.NoMove: Console.WriteLine("NoMove"); if (tile != null && tile.State != TileState.Empty) // Player clicked on a piece { tile.State = TileState.Selected; CurrentPlayerTurnState = PlayerTurnState.PieceSelected; SelectedPiece = tile; } break; case PlayerTurnState.PieceSelected: Console.WriteLine("PieceSelected"); if (tile != null && tile.State == TileState.Empty) // Player clicked on empty spot { bool legal = MakePlayerMove(SelectedPiece, tile); if (!legal) { // TODO: Display error message Console.WriteLine("Illegal move"); return; } CurrentPlayerTurnState = PlayerTurnState.Moved; } break; case PlayerTurnState.SelectCapture: Console.WriteLine("SelectCapture"); if (possibleMove != null) { } break; case PlayerTurnState.Moved: if(tile != null){} break; } }
private void EndTurn() { CurrentPlayerTurnState = PlayerTurnState.NoMove; SelectedPiece = null; CurrentPlayer = Player.Computer; possibleMove = null; }
/// <summary> /// Selects the resource type after the Monopoly card is played. Can only be called by the active player. /// </summary> public ActionResult PlayerSelectResourceForMonopoly(int playerId, ResourceTypes resource) { var validation = ValidatePlayerAction(PlayerTurnState.MonopolySelectingResource, playerId); if (validation.Failed) return validation; var pr = GetPlayerFromId(playerId); if (pr.Failed) return pr; var activePlayer = pr.Data; // Remove all the resources of the specified type from // the other players and give them to the active player. var otherPlayers = Players.Where(p => p.Id != playerId); var resCount = 0; foreach (var otherPlayer in otherPlayers) { resCount += otherPlayer.RemoveAllResources(resource); } activePlayer.ResourceCards[resource] += resCount; _playerTurnState = PlayerTurnState.TakeAction; return ActionResult.CreateSuccess(); }
/// <summary> /// Accept the active player's current trade. This can only be called by a non-active player. /// </summary> public ActionResult AcceptTradeFromActivePlayer(int playerId) { var validation = ValidatePlayerAction(PlayerTurnState.RequestingPlayerTrade); if (validation.Failed) return validation; var pr = GetPlayerFromId(playerId); if (pr.Failed) return pr; if (!_tradeHelper.HasActivePlayerTradeOffer) { return ActionResult.CreateFailed("There is no active trade offer to accept."); } // Check if the non-active player can afford to do the trade. var nonActivePlayer = pr.Data; var activeOffer = _tradeHelper.ActivePlayerTradeOffer; var result = nonActivePlayer.AcceptTradeOffer(ActivePlayer, activeOffer); if (result.Failed) return result; // Go back to TakeAction player state _tradeHelper.ClearAllOffers(); _playerTurnState = PlayerTurnState.TakeAction; return ActionResult.CreateSuccess(); }
/// <summary> /// Steals a random resource card from a player. Initiated by moving the robber. /// Can only be called by the main player. On success, returns the stolen card. /// </summary> public ActionResult<ResourceTypes> PlayerStealResourceCard(int playerId, int robbedPlayerId) { var validation = ValidatePlayerAction(PlayerTurnState.SelectingPlayerToStealFrom, playerId); if (validation.Failed) return validation.ToGeneric<ResourceTypes>(); var apr = GetPlayerFromId(playerId); if (apr.Failed) return apr.ToGeneric<ResourceTypes>(); var activePlayer = apr.Data; var pr = GetPlayerFromId(robbedPlayerId); if (pr.Failed) return pr.ToGeneric<ResourceTypes>(); var robbedPlayer = pr.Data; if (_playersToStealFrom.All(p => p.Id != robbedPlayerId)) return ActionResult.CreateFailed("This player cannot be robbed.").ToGeneric<ResourceTypes>(); if (robbedPlayer.NumberOfResourceCards == 0) return ActionResult.CreateFailed("This player has no resource cards to steal.").ToGeneric<ResourceTypes>(); var removeResult = robbedPlayer.ResourceCards.RemoveRandom(); if (removeResult.Failed) return removeResult; // Success var typeStolen = removeResult.Data; activePlayer.ResourceCards[typeStolen]++; // Change player state _playerTurnState = PlayerTurnState.TakeAction; _playersToStealFrom.Clear(); return new ActionResult<ResourceTypes>(typeStolen, true); }
/// <summary> /// Accepts a specific counter trade offer. Can only be called by the active player. /// </summary> public ActionResult PlayerAcceptCounterTradeOffer(int playerId, int counterOfferPlayerId) { var validation = ValidatePlayerAction(PlayerTurnState.RequestingPlayerTrade, playerId); if (validation.Failed) return validation; var apr = GetPlayerFromId(playerId); if (apr.Failed) return apr; var activePlayer = apr.Data; var pr = GetPlayerFromId(counterOfferPlayerId); if (pr.Failed) return pr; var counterOfferPlayer = pr.Data; var offer = _tradeHelper.GetCounterOfferByPlayerId(counterOfferPlayerId); if (offer == null) { return ActionResult.CreateFailed("The trade offer does not exist."); } var tradeResult = activePlayer.AcceptTradeOffer(counterOfferPlayer, offer); if (tradeResult.Failed) return tradeResult; // Go back to TakeAction player state _tradeHelper.ClearAllOffers(); _playerTurnState = PlayerTurnState.TakeAction; return ActionResult.CreateSuccess(); }
private void AdvanceToNextPlayerTurn() { // Advances to the next player's turn. if (_gameState == GameStates.GameInProgress) { _playerTurnIndex++; _playerTurnIndex %= _players.Count; _playerTurnState = PlayerTurnState.NeedToRoll; } else if (_gameState == GameStates.InitialPlacement) { // During the initial placement phase, the turn index increases until the last player // makes his placements. Then, the turn index counts down to the first player. if (!LastPlayerHasPlaced) { // The last player has not placed yet. Count up. _playerTurnIndex++; _playerTurnState = PlayerTurnState.PlacingBuilding; } else { // The last player has gone. Count down. _playerTurnIndex--; // If everyone has placed, start the game. if (_playerTurnIndex < 0) { _playerTurnIndex = 0; _gameState = GameStates.GameInProgress; _playerTurnState = PlayerTurnState.NeedToRoll; } else { _playerTurnState = PlayerTurnState.PlacingBuilding; } } } }
/// <summary> /// Cancels a player's current trade offer. /// If called by the active player, cancels all trade offers and changes the turn state. /// If called by a non-active player, cancels a specific counter-offer. /// </summary> public ActionResult PlayerCancelTradeOffer(int playerId) { var validation = ValidatePlayerAction(PlayerTurnState.RequestingPlayerTrade); if (validation.Failed) return validation; if (ActivePlayer.Id == playerId) { // Go back to TakeAction player state _tradeHelper.ClearAllOffers(); _playerTurnState = PlayerTurnState.TakeAction; } else { _tradeHelper.CancelCounterOffer(playerId); } return ActionResult.CreateSuccess(); }
private ActionResult ValidatePlayerAction(PlayerTurnState requiredState) { // Validates that the game and player are in the correct states to take the action. if (requiredState != _playerTurnState) return ActionResult.CreateFailed("Not allowed to take this action at this time."); bool validAction = true; switch (requiredState) { // The following actions can be taken during the initial placement phase or during the normal phase. case PlayerTurnState.PlacingRoad: case PlayerTurnState.PlacingBuilding: validAction = (_gameState == GameStates.GameInProgress || _gameState == GameStates.InitialPlacement); break; // The following actions require the normal game phase to be in progress. case PlayerTurnState.NeedToRoll: case PlayerTurnState.PlacingRobber: case PlayerTurnState.RequestingPlayerTrade: case PlayerTurnState.AnyPlayerSelectingCardsToLose: case PlayerTurnState.SelectingPlayerToStealFrom: case PlayerTurnState.TakeAction: case PlayerTurnState.MonopolySelectingResource: case PlayerTurnState.RoadBuildingSelectingRoads: case PlayerTurnState.YearOfPlentySelectingResources: validAction = (_gameState == GameStates.GameInProgress); break; } return validAction ? ActionResult.CreateSuccess() : ActionResult.CreateFailed("Not allowed to take this action at this time."); }
/// <summary> /// Makes a certain player discard resources. Used when a 7 is rolled /// and the player has too many cards. Can be called by any player. /// </summary> public ActionResult PlayerDiscardResources(int playerId, ResourceCollection toDiscard) { var validation = ValidatePlayerAction(PlayerTurnState.AnyPlayerSelectingCardsToLose); if (validation.Failed) return validation; var apr = GetPlayerFromId(playerId); if (apr.Failed) return apr; var player = apr.Data; if (!_playersCardsToLose.ContainsKey(player)) return ActionResult.CreateFailed("Discarding resources is not required."); var toDiscardCount = toDiscard.GetResourceCount(); var requiredCount = _playersCardsToLose[player]; if (toDiscardCount != requiredCount) return ActionResult.CreateFailed(string.Format("Incorrect number of cards to discard. Selected: {0}. Required: {1}.", toDiscardCount, requiredCount)); if(!player.RemoveResources(toDiscard)) return ActionResult.CreateFailed("Player does not have the cards selected to discard."); // Success. Remove player from pending discard list. _playersCardsToLose.Remove(player); // If the player-discard list is empty now, let the active player place the robber. if (_playersCardsToLose.Count == 0) { _playerTurnState = _gameSettings.RobberMode == RobberMode.None ? PlayerTurnState.TakeAction : PlayerTurnState.PlacingRobber; } return ActionResult.CreateSuccess(); }