private bool RemovalValid(Hex hex) { return(ExtendedRunsOfFour.Any(run => run.Run.Count(c => c.hex == hex) > 0)); }
/* * 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); } }