コード例 #1
0
ファイル: Board.cs プロジェクト: vfridell/Gipf
 private bool RemovalValid(Hex hex)
 {
     return(ExtendedRunsOfFour.Any(run => run.Run.Count(c => c.hex == hex) > 0));
 }
コード例 #2
0
ファイル: Board.cs プロジェクト: vfridell/Gipf
/*
 *        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);
            }
        }