/// <summary> /// Queues a piecemove as a animation /// </summary> /// <param name="move">Piecemove to animate</param> /// <param name="team">Team of move</param> /// <param name="time">Elapsed time for animation</param> public void QueueAnimation(PieceMove move, sbyte team, float time) { if (move.IsTakingOutMarble) { Vector2 start = Vector2.Zero; if (!currentPlayer.IsHuman) { for (int j = starts[team].Length - 1; j >= 0; j--) { if (starts[team][j].HasMarble) { start = new Vector2(starts[team][j].Rect.X, starts[team][j].Rect.Y); starts[team][j].HasMarble = false; break; } } } Square homeSquare = new Square(team, 0); Vector2?homeSquareTarget = GetVector(homeSquare); Vector2?target = GetVector(move.To); if (homeSquareTarget.HasValue && target.HasValue) { MarbleView takeOut = new MarbleView(this, move.From, team, start); if (homeSquare.Equals(move.To)) { animations.Enqueue(new MarbleView[1] { takeOut }); takeOut.MoveTo(homeSquareTarget.Value, time); } else { MarbleView moveAnim = new MarbleView(this, move.From, team, homeSquareTarget.Value); animations.Enqueue(new MarbleView[2] { takeOut, moveAnim }); takeOut.MoveTo(homeSquareTarget.Value, time / 2); moveAnim.MoveTo(target.Value, time / 2); } } } else { Vector2?start = GetVector(move.From); Vector2?target = GetVector(move.To); if (start.HasValue && target.HasValue) { MarbleView anim = new MarbleView(this, move.From, team, start.Value); animations.Enqueue(new MarbleView[1] { anim }); anim.MoveTo(target.Value, time); } } }
/// <summary> /// Evaluates whether this move is the same as another move /// </summary> /// <param name="square">Move to evaluate</param> public bool Equals(PieceMove move) { if (From == null) { return(move.From == null && To.Equals(move.To)); } return(From.Equals(move.From) && To.Equals(move.To)); }
/// <summary> /// Updates the drag logic /// </summary> /// <param name="mState">Current Mouse State</param> private void UpdateDrag(MouseState mState) { if (currentPlayer.IsHuman && currentRoll != null) { //Update drag if not null if (currentDrag != null) { currentDrag.DragTo(new Vector2(mState.X, mState.Y)); } //Check if drag is done if (mState.LeftButton == ButtonState.Released) { if (currentDrag != null) { Square target = currentDrag.StopDrag(); if (target != null) { PieceMove move = new PieceMove(currentDrag.From, target); if (board.IsPossibleTreeMove(currentRoll, move, currentPlayer.Team)) { currentMove.Add(move); if (PlayMarbleSounds) { PlayRandomPlaceSound(); } if (move.IsTakingOutMarble) { currentDrag.FromView.HasMarble = false; } } else { if (currentDrag.FromView != null) { currentDrag.FromView.HasMarble = true; } } } else { if (currentDrag.FromView != null) { currentDrag.FromView.HasMarble = true; } } currentDrag = null; } } } }
/// <summary> /// Performs a piece move on the board /// </summary> /// <param name="position">The position to change</param> /// <param name="pieceMove">Piece move</param> /// <param name="team">Team of the piece move</param> public void PerformMove(Position position, PieceMove pieceMove, sbyte team) { if (pieceMove.IsTakingOutMarble) { position.Set(pieceMove.To, team); } else { position.Set(pieceMove.From, -1); position.Set(pieceMove.To, team); } }
/// <summary> /// Performs a piece move on the board /// </summary> /// <param name="pieceMove">Piece move</param> /// <param name="team">Team of the piece move</param> public void PerformMove(PieceMove pieceMove, sbyte team) { if (pieceMove.IsTakingOutMarble) { //Since the move is really two moves, "taking out", then moving //remove any marble on the home square Square homeSquare = new Square(team, 0); Set(homeSquare, -1); Set(pieceMove.To, team); } else { Set(pieceMove.From, -1); Set(pieceMove.To, team); } }
/// <summary> /// Checks if the piece move is part of a valid move /// </summary> /// <param name="roll">Current roll</param> /// <param name="move">Move to check</param> /// <param name="team">Team</param> public bool IsPossibleTreeMove(DiceRoll roll, PieceMove move, sbyte team) { MoveCollection collection = GetMoves(roll, team); for (int j = 0; j < collection.Count; j++) { PieceMove[] moves = collection[j].PieceMoves; for (int i = 0; i < moves.Length; i++) { if (moves[i].Equals(move)) { return(true); } } } return(false); }
/// <summary> /// Performs the move's internals to the board /// </summary> /// <param name="move">Move</param> /// <param name="team">Team</param> public void DoMoveInternals(PieceMove move, sbyte team) { int targetMarble = board.Get(move.To); if (targetMarble != -1) { PutBackMarble(targetMarble); } Square homeSquare = new Square(team, 0); if (move.IsTakingOutMarble && !move.To.Equals(homeSquare)) { int homeSquareMarble = board.Get(homeSquare); if (homeSquareMarble != -1) { PutBackMarble(homeSquareMarble); } } board.PerformMove(move, team); }
/// <summary> /// Validates a piece move /// </summary> /// <param name="pieceMove">Piece move</param> /// <param name="team">Team of the piece</param> public bool IsValid(Position position, Move move, PieceMove pieceMove, sbyte team) { if (pieceMove != null) { if (pieceMove.ValidSyntax) { Square[] path = pieceMove.GetPath(team); for (int i = 0; i < path.Length; i++) { if (position.Get(path[i]) == team) { //Check if marble is going to move bool ignoreIntersection = false; for (int m = 0; m < move.Pieces; m++) { if (!move[m].IsTakingOutMarble) { if (move[m].From.Equals(path[i]) && move[m].To.GetBoardIndex(team) > pieceMove.To.GetBoardIndex(team)) { ignoreIntersection = true; break; } } } if (!ignoreIntersection) { return(false); } } } return(true); } } return(false); }
/// <summary> /// Create a move /// </summary> /// <param name="move">Piece move</param> public Move(PieceMove move, sbyte team) { PieceMoves = new PieceMove[] { move }; Team = team; }
/// <summary> /// Gets all the possible moves for a team given a dice roll /// </summary> /// <param name="roll">Dice roll</param> /// <param name="team">Marble team</param> public MoveCollection GetMoves(Position position, DiceRoll roll, sbyte team) { if (team < 0 || team > TEAM_COUNT) { return(null); } sbyte winner = -1; if (position.IsWon(out winner)) { return(null); } MoveCollection moves = new MoveCollection(this, position); Square[] marbleSquares = GetMarbles(position, team); bool hasMarbleOnSpawn = position.Get(new Square(team, 0)) == team; int activePieces = GetActivePiecesCount(marbleSquares); //Loop until a marble in our base is found for (int i = 0; i < marbleSquares.Length; i++) { //If marble is at start square if (marbleSquares[i] == null) { //If no team marble is on spawn square if (!hasMarbleOnSpawn) { int[] takeOut = roll.CanTakeOutWith(); if (takeOut.Length > 0) { for (int j = 0; j < takeOut.Length; j++) { Square target = new Square(team, takeOut[j]); if (position.Get(target) != team) { moves.Add(new Move(new PieceMove(null, target), team)); } } } } //Add a special case for taking out a piece and using the other die value on another marble if (activePieces > 0) { int[] combinations = roll.GetDoublesTakeOutCombinations(); PieceMove takeOutCombo = new PieceMove(null, new Square(team, 0)); for (int p = 0; p < activePieces; p++) { for (int pc = 0; pc < combinations.Length; pc++) { PieceMove correspondant = new PieceMove(marbleSquares[p], marbleSquares[p].Add(combinations[pc], team)); if (hasMarbleOnSpawn && !correspondant.From.Equals(takeOutCombo.To)) { continue; } moves.Add(new Move(new PieceMove[] { correspondant, takeOutCombo }, team)); } } } break; } } List <int[]> pieceCombinations = GetPieceCombinations(activePieces); for (int c = 0; c < pieceCombinations.Count; c++) { int pieces = pieceCombinations[c].Length; int[][] pieceValues = roll.GetValues(pieces); for (int k = 0; k < pieceValues.Length; k++) { PieceMove[] pieceMoves = new PieceMove[pieces]; for (int j = 0; j < pieces; j++) { Square marblePiece = marbleSquares[pieceCombinations[c][j]]; pieceMoves[j] = new PieceMove(marblePiece, marblePiece.Add(pieceValues[k][j], team)); if (j > 0) { if (pieceMoves[j].From.Equals(pieceMoves[j - 1].To)) { //Swap the move order PieceMove current = pieceMoves[j]; pieceMoves[j] = pieceMoves[j - 1]; pieceMoves[j - 1] = current; } } } Move move = new Move(pieceMoves, team); moves.Add(move); } } return(moves); }
/// <summary> /// Draws the marbles on the board /// </summary> /// <param name="batch">SpriteBatch</param> /// <param name="textures">Texture Library</param> public void DrawMarbles(SpriteBatch batch, TextureLib textures) { bool artificiallyDrawMarble = false; bool isPartOfMove = false; PieceMove partOfMove = null; for (int i = 0; i < 13; i++) { for (int j = 0; j < 13; j++) { if (layout[i][j] != null) { Square current = new Square(layout[i][j]); if (currentAnimation != null) { if (current.Equals(currentAnimation.From)) { continue; } } if (currentDrag != null) { if (current.Equals(currentDrag.From)) { continue; } } artificiallyDrawMarble = false; isPartOfMove = false; for (int k = 0; k < currentMove.Count; k++) { if (currentMove[k].From != null) { if (currentMove[k].From.Equals(current)) { partOfMove = currentMove[k]; artificiallyDrawMarble = false; isPartOfMove = true; } } if (currentMove[k].To.Equals(current)) { partOfMove = currentMove[k]; artificiallyDrawMarble = true; isPartOfMove = true; break; } } if (isPartOfMove) { if (artificiallyDrawMarble) { string asset = GetMarbleAsset(currentPlayer.Team); batch.Draw(textures[asset], squares[i][j].Rect, (squares[i][j].Selected) ? Color.LightBlue : Color.White); } } else { int marble = board.Get(layout[i][j]); if (marble != -1) { string asset = GetMarbleAsset(marble); batch.Draw(textures[asset], squares[i][j].Rect, (squares[i][j].Selected) ? Color.LightBlue : Color.White); } } } } } }