/// <summary> /// The eat piece if allowed. /// </summary> /// <param name="exeCuteParam"> /// board tile to et /// </param> private void EatPieceIfAllowed(BoardTile exeCuteParam) { if (exeCuteParam.Owner == this.game.CurrentPlayer || exeCuteParam.Owner == null) { return; } exeCuteParam.EatAnimation(); exeCuteParam.Owner = null; exeCuteParam.PlayerData = null; if (this.game.CurrentPlayer == Player.Player1) { this.game.Player2Pieces--; } else { this.game.Player1Pieces--; } // Message eat done this.eventAggregator.GetEvent<GameStateEvent>().Publish(GameStates.EatPieceDone); this.StoreState(); }
/// <summary> /// Initializes a new instance of the <see cref="GameAreaViewModel"/> class. /// </summary> /// <param name="eventAggregator"> /// The event Aggregator. /// </param> public GameAreaViewModel(IEventAggregator eventAggregator) { // Players service to use this.players = this.Container.Resolve<IPlayers>(ServiceNames.PlayersService); this.PlayersList = this.players.PlayersList; this.eventAggregator = eventAggregator; // Messaging this.eventAggregator.GetEvent<GameStateEvent>().Subscribe(this.GameStateChange); this.eventAggregator.GetEvent<GameActionEvent>().Subscribe(this.GameActionEvent); // Game service to use this.game = this.Container.Resolve<IGame>(ServiceNames.GameService); // Undo redo stack to use as undo redo turns this.undoRedo = this.Container.Resolve<IUndoRedoStack>(ServiceNames.UndoRedoStackService); // this.BoardTiles = new ObservableCollection<BoardTile>(); this.AddBoardTiles(); // this.StoreState(); // Mousedown means that tile is clicked. This handles what to do // Different game states make it work differently this.MouseDownDelegateCommand = new DelegateCommand<BoardTile>( exeCuteParam => { var piece = this.selectedPiece; if (piece != null) piece.IsSelected = false; this.selectedPiece = null; if (exeCuteParam == null) { return; } if ((this.game.GameState != GameStates.MovePiece && this.game.GameState != GameStates.SpecialState) || this.game.CurrentPlayer != exeCuteParam.Owner) return; this.HighLightPossibleMoves(exeCuteParam); foreach (var boardTile in this.BoardTiles.Where(boardTile => boardTile.DropAllowed)) { this.selectedPiece = exeCuteParam; this.selectedPiece.IsSelected = true; } }); // Mouse button is up. If eat state do eat. this.MouseUpDelegateCommand = new DelegateCommand<BoardTile>( exeCuteParam => { if (exeCuteParam == null) { return; } if (this.game.GameState == GameStates.EatPiece) { this.EatPieceIfAllowed(exeCuteParam); } foreach (var tile in this.BoardTiles) { // Remove allowed moves tile.Thickness = 0; tile.DropAllowed = false; } }); this.BoardTileClickDelegateCommand = new DelegateCommand<BoardTile>(this.MakeMove); }
/// <summary> /// The check row. /// </summary> /// <param name="newPiece"> /// The new piece. /// </param> /// <returns> /// The <see cref="bool"/>. /// </returns> private bool CheckRow(BoardTile newPiece) { if (this.CheckEastWestRow(newPiece)) { return true; } if (this.CheckNorthSouthRow(newPiece)) { return true; } return this.CheckNorthEastSouthWestRow(newPiece) || this.CheckSouthEastNorthWestRow(newPiece); }
/// <summary> /// The check south east north west row for mylly. /// if 3 pieces row /// </summary> /// <param name="newPiece"> /// The new piece. /// </param> /// <returns> /// The <see cref="bool"/>. /// </returns> private bool CheckSouthEastNorthWestRow(BoardTile newPiece) { // Start SouthEastNorthWest Check var piecesInRow = 1; if (newPiece.SouthEastSiblings) { var newTile = this.GetTileEndpointTile( newPiece.ColumnIndex + 1, newPiece.RowIndex + 1, Directions.SouthEast); if (newTile?.Owner == this.game.CurrentPlayer) { piecesInRow++; if (newTile.SouthEastSiblings) { newTile = this.GetTileEndpointTile( newTile.ColumnIndex + 1, newTile.RowIndex + 1, Directions.SouthEast); if (newTile?.Owner == this.game.CurrentPlayer) { piecesInRow++; if (piecesInRow >= 3) { return true; } } } } } if (!newPiece.NorthWestSiblings) { return false; } { var newTile = this.GetTileEndpointTile( newPiece.ColumnIndex - 1, newPiece.RowIndex - 1, Directions.NorthWest); if (newTile?.Owner != this.game.CurrentPlayer) { return false; } piecesInRow++; if (piecesInRow >= 3) { return true; } if (!newTile.NorthWestSiblings) { return false; } newTile = this.GetTileEndpointTile(newTile.ColumnIndex - 1, newTile.RowIndex - 1, Directions.NorthWest); if (newTile?.Owner != this.game.CurrentPlayer) { return false; } piecesInRow++; if (piecesInRow >= 3) { return true; } } // End SouthEastNorthWest Check return false; }
/// <summary> /// The add board tiles to game. /// Also adds interfaces to work with /// </summary> private void AddBoardTiles() { BoardSettings.NewTiles(); this.BoardTiles = BoardSettings.BoardSettingsCollection; foreach (var tile in this.BoardTiles) { tile.DroppedInterface = this; tile.DraggedInterface = this; } // Not used this.tesTile = this.BoardTiles.First(); }
/// <summary> /// The add player piece to board. /// </summary> /// <param name="newPiece"> /// The new piece. /// </param> private void AddPlayerPiece(BoardTile newPiece) { // Initial state allows pieces to add on board if (this.game.InitialPieces != 0) { newPiece.Owner = this.game.CurrentPlayer; newPiece.PlayerData = this.PlayersList[(int)this.game.CurrentPlayer]; this.game.InitialPieces = this.game.InitialPieces - 1; var rowFound = this.CheckRow(newPiece); // Send message when move done or nead eat this.eventAggregator.GetEvent<GameStateEvent>() .Publish(!rowFound ? GameStates.MoveDone : GameStates.NeedEat); this.StoreState(); } else { // Send messagethat set game phase here is done this.eventAggregator.GetEvent<GameStateEvent>().Publish(GameStates.SetGameDone); } }
/// <summary> /// The drop execute. When something is dropped on tile /// </summary> /// <param name="source"> /// Dropped object /// </param> /// <param name="target"> /// Target of drop /// </param> public void DropExecute(object source, object target) { var selected = source as BoardTile; var canvasControl = target as MyllyCanvasControl; if (selected == null || canvasControl == null) return; this.selectedPiece.IsSelected = false; this.selectedPiece = selected; this.selectedPiece.IsSelected = true; var targetTile = canvasControl.DataContext as BoardTile; if (targetTile != null) { // Move dropped object to place on board this.MakeMove(targetTile); } // Clean var boardTile = this.selectedPiece; if (boardTile != null) boardTile.IsSelected = false; this.selectedPiece = null; }
/// <summary> /// Is direction here valid /// This checks from element if it has siblings in direction. /// </summary> /// <param name="element"> /// Board tile /// </param> /// <param name="direction"> /// The direction. /// </param> /// <returns> /// The <see cref="bool"/>. /// true if allowed /// </returns> private static bool CheckDirectionValid(BoardTile element, Directions direction) { switch (direction) { case Directions.North: return element.NorthSiblings; case Directions.NorthEast: return element.NorthEastSiblings; case Directions.East: return element.EastSiblings; case Directions.SouthEast: return element.SouthEastSiblings; case Directions.South: return element.SouthSiblings; case Directions.SouthWest: return element.SouthWestSiblings; case Directions.West: return element.WestSiblings; case Directions.NorthWest: return element.NorthWestSiblings; default: return false; } }
/// <summary> /// The mark all free spots. for special state /// </summary> /// <param name="startinTile"> /// The startin tile. /// </param> private void MarkAllFreeSpots(BoardTile startinTile) { var rIndex = startinTile.RowIndex; var cIndex = startinTile.ColumnIndex; foreach (var tile in this.BoardTiles) { if (tile.RowIndex == rIndex && tile.ColumnIndex == cIndex) { continue; } if (!tile.IsEndPoint) continue; if (tile.PlayerData != null) continue; tile.Thickness = 6; tile.DropAllowed = true; } }
/// <summary> /// Make move to wanted tile if it is allowed /// </summary> /// <param name="targetTile"> /// The target tile. /// </param> private void MakeMove(BoardTile targetTile) { if (targetTile == null) { return; } if (this.game.GameState == GameStates.SpecialState && this.selectedPiece != null && targetTile.IsEndPoint && targetTile.Owner == null) { targetTile.Owner = this.selectedPiece.Owner; targetTile.PlayerData = this.selectedPiece.PlayerData; this.selectedPiece.Owner = null; this.selectedPiece.PlayerData = null; this.selectedPiece.IsSelected = false; this.selectedPiece = null; this.eventAggregator.GetEvent<GameStateEvent>() .Publish(!this.CheckRow(targetTile) ? GameStates.MoveDone : GameStates.NeedEat); this.StoreState(); } if (this.selectedPiece != null && targetTile.IsEndPoint && targetTile.Owner == null) { if (this.IsMoveAllowed( targetTile, this.selectedPiece.RowIndex, this.selectedPiece.ColumnIndex, true, null)) { targetTile.Owner = this.selectedPiece.Owner; targetTile.PlayerData = this.selectedPiece.PlayerData; this.selectedPiece.Owner = null; this.selectedPiece.PlayerData = null; this.selectedPiece.IsSelected = false; this.selectedPiece = null; this.eventAggregator.GetEvent<GameStateEvent>() .Publish(!this.CheckRow(targetTile) ? GameStates.MoveDone : GameStates.NeedEat); this.StoreState(); } } if (this.game.GameState == GameStates.SetGame && targetTile.Owner == null && targetTile.IsEndPoint) { this.AddPlayerPiece(targetTile); } }
/// <summary> /// Is wanted move allowed recursive call /// Crawls from starting point to wanted point and checks if it is allowed to do. /// </summary> /// <param name="wantedPosition"> /// The wanted position. /// </param> /// <param name="rowIndex"> /// The row index. /// </param> /// <param name="columnIndex"> /// The column index. /// </param> /// <param name="isStartingPoint"> /// The is starting point. /// </param> /// <param name="calledFrom"> /// The called from. /// </param> /// <returns> /// The <see cref="bool"/>. /// </returns> private bool IsMoveAllowed( BoardTile wantedPosition, int rowIndex, int columnIndex, bool isStartingPoint, Directions? calledFrom) { while (true) { BoardTile currentTile = null; var rIndex = rowIndex; var cIndex = columnIndex; foreach ( var tile in this.BoardTiles.Where(tile => tile.RowIndex == rIndex && tile.ColumnIndex == cIndex)) { currentTile = tile; } if (currentTile == null) { return false; } if (!isStartingPoint) { if (currentTile.IsEndPoint) { if (currentTile.PlayerData != null) { return false; } return currentTile == wantedPosition; } } if (currentTile == wantedPosition) { return false; } if (currentTile.NorthSiblings && calledFrom != Directions.North) { if (this.IsMoveAllowed( wantedPosition, currentTile.RowIndex - 1, currentTile.ColumnIndex, false, Directions.South)) { return true; } } if (currentTile.NorthEastSiblings && calledFrom != Directions.NorthEast) { if (this.IsMoveAllowed( wantedPosition, currentTile.RowIndex - 1, currentTile.ColumnIndex + 1, false, Directions.SouthWest)) { return true; } } if (currentTile.NorthWestSiblings && calledFrom != Directions.NorthWest) { if (this.IsMoveAllowed( wantedPosition, currentTile.RowIndex - 1, currentTile.ColumnIndex - 1, false, Directions.SouthEast)) { return true; } } if (currentTile.EastSiblings && calledFrom != Directions.East) { if (this.IsMoveAllowed( wantedPosition, currentTile.RowIndex, currentTile.ColumnIndex + 1, false, Directions.West)) { return true; } } if (currentTile.SouthSiblings && calledFrom != Directions.South) { if (this.IsMoveAllowed( wantedPosition, currentTile.RowIndex + 1, currentTile.ColumnIndex, false, Directions.North)) { return true; } } if (currentTile.SouthEastSiblings && calledFrom != Directions.SouthEast) { if (this.IsMoveAllowed( wantedPosition, currentTile.RowIndex + 1, currentTile.ColumnIndex + 1, false, Directions.NorthWest)) { return true; } } if (currentTile.SouthWestSiblings && calledFrom != Directions.SouthWest) { if (this.IsMoveAllowed( wantedPosition, currentTile.RowIndex + 1, currentTile.ColumnIndex - 1, false, Directions.NorthEast)) { return true; } } if (!currentTile.WestSiblings || calledFrom == Directions.West) { return false; } rowIndex = currentTile.RowIndex; columnIndex = currentTile.ColumnIndex - 1; isStartingPoint = false; calledFrom = Directions.East; } }
/// <summary> /// The high light possible moves. /// </summary> /// <param name="currentTile"> /// The current tile. /// </param> private void HighLightPossibleMoves(BoardTile currentTile) { if (this.game.GameState != GameStates.SpecialState) { this.FindSpots(currentTile.RowIndex, currentTile.ColumnIndex, true, null); } else { // Special state this.MarkAllFreeSpots(currentTile); } }
/// <summary> /// The high light possible add. /// </summary> /// <param name="exeCuteParam"> /// The exe cute param. /// </param> private void HighLightPossibleAdd(BoardTile exeCuteParam) { foreach (var boardTile in this.BoardTiles.Where(boardTile => boardTile != null && boardTile.Owner == null) .Where(boardTile => boardTile.IsEndPoint)) { boardTile.Thickness = 6; boardTile.DropAllowed = true; } }