Пример #1
0
 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;
 }
Пример #2
0
 public void PreProcessHandler(object sender, EventArgs e)
 {
     _currentRun = null;
     _runs?.Clear();
     _extendedRunsOfFour?.Clear();
     _lastPiece = new GipfPiece(-1, PieceColor.None);
 }
Пример #3
0
 public void Push(Position position, GipfPiece incomingPiece)
 {
     if (!CanPush(position))
     {
         throw new Exception("Can't push here");
     }
     neighborhood[position].PushRecursive(position, incomingPiece);
 }
Пример #4
0
        protected virtual void PushRecursive(Position position, GipfPiece incomingPiece)
        {
            GipfPiece oldPiece = Piece;

            Piece = incomingPiece;
            if (oldPiece.Color != PieceColor.None)
            {
                neighborhood[position].PushRecursive(position, oldPiece);
            }
        }
Пример #5
0
 public bool TryGetPieceAtHex(Hex hex, out GipfPiece piece)
 {
     if (!_cellMap.ContainsKey(hex))
     {
         piece = Pieces.NoPiece;
         return(false);
     }
     else
     {
         piece = _cellMap[hex].Piece;
         return(true);
     }
 }
Пример #6
0
 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;
 }
Пример #7
0
 public virtual void SetPiece(GipfPiece piece)
 {
     Piece = piece;
 }
Пример #8
0
 internal Cell(Board board, Hex hex, GipfPiece piece)
 {
     _board = board; _hex = hex; Piece = piece;
 }
Пример #9
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);
            }
        }
Пример #10
0
 protected override void PushRecursive(Position position, GipfPiece incomingPiece)
 {
     throw new Exception("Can't push into a Wall");
 }