private void ApplyMove(GameState game) { int dR, dC; if (Direction == MoveDirection.Left) { dR = 0; dC = -1; } else if (Direction == MoveDirection.Right) { dR = 0; dC = 1; } else if (Direction == MoveDirection.Up) { dR = 1; dC = 0; } else { dR = -1; dC = 0; } PieceStack stack = game.Board[Row, Column].Grab(NumMoved); for (int i = 0; i < Drops.Count; i++) { int row = Row + dR * (i + 1); int col = Column + dC * (i + 1); PieceStack dst = game.Board[row, col]; stack.Drop(dst, Drops[i]); } }
/// <summary> /// Deep copy constructor /// </summary> /// <param name="src"></param> public TakBoard(TakBoard src) { Size = src.Size; Board = new PieceStack[Size, Size]; for (int i = 0; i < Size; i++) { for (int j = 0; j < Size; j++) { Board[i, j] = new PieceStack(src.Board[i, j]); } } }
public TakBoard(int n) { Size = n; Board = new PieceStack[n, n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { Board[i, j] = new PieceStack(); } } }
/// <summary> /// Deep copy constructor /// </summary> /// <param name="src"></param> public PieceStack(PieceStack src) : this() { foreach (TakPiece piece in src.Pieces) { if (piece.IsCapstone) { Pieces.Add(new Capstone(piece as Capstone)); } else { Pieces.Add(new TakPiece(piece)); } } }
/// <summary> /// Grab the top n pieces from the stack, but don't actually modify the stack; just make a copy /// /// This is used when checking for legal moves, since we don't want to disrupt the board state /// </summary> /// <param name="n"></param> /// <returns></returns> internal PieceStack NonDestructiveGrab(int n) { if (n > Size) { throw new ArgumentOutOfRangeException(string.Format("Cannot grab {0} pieces from a stack of size {1}", n, Size)); } PieceStack s = new PieceStack(); for (int i = 0; i < n; i++) { s.Pieces.Insert(0, Pieces[Size - 1 - i]); } return(s); }
/// <summary> /// Grab the top n pieces from this stack and return them as a new stack /// </summary> /// <param name="n"></param> /// <returns></returns> public PieceStack Grab(int n) { if (n > Size) { throw new ArgumentOutOfRangeException(string.Format("Cannot grab {0} pieces from a stack of size {1}", n, Size)); } PieceStack s = new PieceStack(); for (int i = 0; i < n; i++) { s.Pieces.Insert(0, Pieces.Last()); Pieces.RemoveAt(Size - 1); } return(s); }
/// <summary> /// Verify if we can drop n pieces on this stack onto the target space /// </summary> /// <param name="target"></param> /// <param name="n"></param> /// <returns></returns> public bool CanDrop(PieceStack target, int n) { // if the target space is empty or contains flats we're fine if (target.Size == 0 || (!target.Top.IsWall && !target.Top.IsCapstone)) { return(true); } // otherwise check if we're placing a capstone on any non-capstone we're fine else if (Pieces[0].IsCapstone && !target.Top.IsCapstone) { return(true); } // otherwise this is an illegal move return(false); }
/// <summary> /// Drop n pieces off the bottom of the stack onto the target stack /// /// This is used when moving the stack /// </summary> /// <param name="target"></param> /// <param name="n"></param> public void Drop(PieceStack target, int n = 1) { if (n > Size) { throw new ArgumentOutOfRangeException(string.Format("Cannot drop {0} pieces from a stack of size {1}", n, Size)); } // flatten the top piece if it was a wall // NOTE: we're assuming the move is legal, so there is no check if (target.Pieces.Count > 0) { target.Top.IsWall = false; } for (int i = 0; i < n; i++) { target.Pieces.Add(Pieces[0]); Pieces.RemoveAt(0); } }
/// <summary> /// Generate the list of all moves that the stack located at the given coordinate can make /// </summary> /// <param name="gameState"></param> /// <param name="row"></param> /// <param name="column"></param> /// <returns></returns> private static List <TakMove> GenerateStackMoves(TakPiece.PieceColor player, GameState gameState, int row, int column) { TakMove m; List <TakMove> moves = new List <TakMove>(); PieceStack stack = gameState.Board[row, column]; List <List <int> > allDrops = new List <List <int> >(); for (int n = 1; n <= Math.Min(stack.Size, gameState.Board.Size); n++) // for 1 to the carry limit of the board { allDrops.Clear(); MakeDrops(n, allDrops, new List <int>()); foreach (List <int> drops in allDrops) { m = new TakMove(player, row, column, TakMove.MoveDirection.Left, drops); if (m.IsLegal(gameState)) { moves.Add(m); } m = new TakMove(player, row, column, TakMove.MoveDirection.Right, drops); if (m.IsLegal(gameState)) { moves.Add(m); } m = new TakMove(player, row, column, TakMove.MoveDirection.Up, drops); if (m.IsLegal(gameState)) { moves.Add(m); } m = new TakMove(player, row, column, TakMove.MoveDirection.Down, drops); if (m.IsLegal(gameState)) { moves.Add(m); } } } return(moves); }
private bool IsLegalMove(GameState game, out string reason) { TakBoard boardState = game.Board; // if we're moving more pices than are in the stack if (boardState[Row, Column].Size < NumMoved || boardState[Row, Column].Size == 0) { reason = "Not enough pieces in stack"; return(false); } // we actually own the stack being moved if (boardState[Row, Column].Top.Color != PieceColor) { reason = "Stack belongs to another player"; return(false); } // if we're moving more pieces than the carry limit if (boardState.Size < NumMoved) { reason = "Carry limit exceeded"; return(false); } // if we're moving so far that we'd fall off the edge of the board if ((Direction == MoveDirection.Up && Row + Drops.Count >= boardState.Size) || (Direction == MoveDirection.Down && Row - Drops.Count < 0) || (Direction == MoveDirection.Right && Column + Drops.Count >= boardState.Size) || (Direction == MoveDirection.Left && Column - Drops.Count < 0)) { reason = "Not enough room to move in that direction"; return(false); } // if we're placing non-capstones on walls, or any piece on a capstone int dR, dC; if (Direction == MoveDirection.Left) { dR = 0; dC = -1; } else if (Direction == MoveDirection.Right) { dR = 0; dC = 1; } else if (Direction == MoveDirection.Up) { dR = 1; dC = 0; } else { dR = -1; dC = 0; } PieceStack src = boardState[Row, Column].NonDestructiveGrab(NumMoved); for (int i = 0; i < Drops.Count; i++) { int row = Row + dR * (i + 1); int col = Column + dC * (i + 1); PieceStack dst = boardState[row, col]; if (!src.CanDrop(dst, Drops[i])) { reason = string.Format("Cannot drop piece on {0}{1}", (char)(col + 'a'), row + 1); return(false); } src.Drop(Drops[i]); } // if we reach here then the move is legal reason = ""; return(true); }