private void RemoveOrCapturePieces(IReadOnlyList <Hex> hexes) { if (hexes == null) { return; } foreach (Hex hex in hexes) { GipfPiece pieceToRemove = _cellMap[hex].Piece; if (pieceToRemove.NumPieces == 0) { throw new Exception($"Trying to remove from an empty cell: {hex.column}, {hex.row}"); } if (!RemovalValid(hex)) { throw new Exception($"Piece at Hex not part of an extended run of four: {hex.column}, {hex.row}"); } if (pieceToRemove.Color == ColorToPlay) { AddToReserve(pieceToRemove.Color, pieceToRemove.NumPieces); } else { AddToCaptured(pieceToRemove.Color, pieceToRemove.NumPieces); } _cellMap[hex].SetPiece(Pieces.NoPiece); } _runsDirty = true; }
public void PreProcessHandler(object sender, EventArgs e) { _currentRun = null; _runs?.Clear(); _extendedRunsOfFour?.Clear(); _lastPiece = new GipfPiece(-1, PieceColor.None); }
public void Push(Position position, GipfPiece incomingPiece) { if (!CanPush(position)) { throw new Exception("Can't push here"); } neighborhood[position].PushRecursive(position, incomingPiece); }
protected virtual void PushRecursive(Position position, GipfPiece incomingPiece) { GipfPiece oldPiece = Piece; Piece = incomingPiece; if (oldPiece.Color != PieceColor.None) { neighborhood[position].PushRecursive(position, oldPiece); } }
public bool TryGetPieceAtHex(Hex hex, out GipfPiece piece) { if (!_cellMap.ContainsKey(hex)) { piece = Pieces.NoPiece; return(false); } else { piece = _cellMap[hex].Piece; return(true); } }
public void VisitCellHandler(object sender, VisitCellEventArgs e) { if (e.cell.Piece.Color != _lastPiece.Color || e.newLine) { if (null == _currentRun) { _currentRun = new List <Cell>(); _currentRun.Add(e.cell); } else { _runs.Add(new CellRun(_currentRun)); _currentRun.Clear(); _currentRun.Add(e.cell); } } else { _currentRun.Add(e.cell); } _lastPiece = e.cell.Piece; }
public virtual void SetPiece(GipfPiece piece) { Piece = piece; }
internal Cell(Board board, Hex hex, GipfPiece piece) { _board = board; _hex = hex; Piece = piece; }
/* * private void AddPossibleMoves(List<Hex> removeBeforeList, Board prePushRemovedBoard, Hex wallHex, Position pos, bool isGipf) * { * Board pushBoard = prePushRemovedBoard.Clone(); * Wall pWall = (Wall)pushBoard.Cells[wallHex]; * * pWall.Push(pos, new GipfPiece(isGipf ? 2 : 1, colorToPlay)); * pushBoard.FindRuns(); * pushBoard.CalculateAllPossibleRemoveLists(); * * foreach (IReadOnlyList<Hex> removeAfterList in pushBoard.AllPossibleRemoveLists) * { * Move move = new Move(pWall.hex, pWall.NeighborhoodCells[pos].hex, removeBeforeList.ToList(), removeAfterList.ToList(), isGipf); * move.SimplifyMove(prePushRemovedBoard); * _moves.Add(move); * } * } */ /// <summary> /// Make a move. Validates the move or fails. /// </summary> /// <param name="move"></param> public bool TryMakeMove(Move move) { try { if (_gameResult != GameResult.Incomplete) { throw new Exception("This game is over"); } if (false == _canPlayGipf[(int)ColorToPlay] && move.isGipf) { throw new Exception("Cannot play a Gipf piece at this time"); } GipfPiece piece = Pieces.GetPiece(this, move); Position direction = Neighborhood.GetDirection(move.from, move.to); if (move.isPlacement) { if (_cellMap[move.to].Piece.Color != PieceColor.None) { throw new Exception($"Trying to place on top of an existing piece: {move.to.column}, {move.to.row}"); } } else { if (!(_cellMap[move.from] is Wall)) { throw new Exception($"Trying to push from a non-wall: {move.from.column}, {move.from.row} => {direction}"); } if (!_cellMap[move.from].CanPush(direction)) { throw new Exception($"Cannot push here: {move.from.column}, {move.from.row} => {direction}"); } } RemoveOrCapturePieces(move.removeBefore); // TODO if the run of four is all gipf, do not throw an exception if (ExtendedRunsOfFour.Count != 0) { throw new Exception("Pre-push removal did not clear all extended runs of four"); } if (move.isPlacement) { _cellMap[move.to].SetPiece(piece); } else { _cellMap[move.from].Push(direction, piece); } _runsDirty = true; RemoveFromReserve(piece.Color, piece.NumPieces); RemoveOrCapturePieces(move.removeAfter); if (ExtendedRunsOfFour.Count(r => r.Color == ColorToPlay) != 0) { throw new Exception($"Post-push removal did not clear all extended runs of four of current player's color ({ColorToPlay})"); } if (!move.isGipf) { _canPlayGipf[(int)ColorToPlay] = false; } _movesDirty = true; IncrementTurn(); return(true); } catch (Exception ex) { _lastError = ex.Message; return(false); } }
protected override void PushRecursive(Position position, GipfPiece incomingPiece) { throw new Exception("Can't push into a Wall"); }