示例#1
0
        public static bool AxisAligned(IList <Hex> hexes, Position direction)
        {
            if (null == hexes || hexes.Count < 2)
            {
                return(true);
            }
            Hex directionHex         = Neighborhood.GetDirectionHex(direction);
            Hex directionOppositeHex = Neighborhood.GetDirectionHex(Neighborhood.GetOpposite(direction));

            return(hexes.Skip(1).All(h =>
                                     AxisAligned(hexes[0], h) &&
                                     (DirectionHex(hexes[0], h) == directionHex || DirectionHex(hexes[0], h) == directionOppositeHex)
                                     ));
        }
示例#2
0
文件: Board.cs 项目: vfridell/Gipf
        public static bool IsCongruent(Board board1, Board board2)
        {
            if (!EqualPiecesInPlay(board1, board2))
            {
                return(false);
            }

            // check reflection congruence
            for (int i = 1; i <= 6; i++)
            {
                bool isCongruent = true;
                foreach (Cell cell in board1._cellMap.Values)
                {
                    if (cell.Piece != board2._cellMap[Neighborhood.MirrorOriginHex(cell.hex, i)].Piece)
                    {
                        isCongruent = false;
                        break;
                    }
                }
                if (isCongruent)
                {
                    return(true);
                }
            }

            // check rotational congruence
            for (int i = 1; i < 6; i++)
            {
                bool isCongruent = true;
                foreach (Cell cell in board1._cellMap.Values)
                {
                    if (cell.Piece != board2._cellMap[Neighborhood.Rotate60DegreesClockwiseHex(cell.hex, i)].Piece)
                    {
                        isCongruent = false;
                        break;
                    }
                }
                if (isCongruent)
                {
                    return(true);
                }
            }
            return(false);
        }
示例#3
0
        public void PostProcessHandler(object sender, EventArgs e)
        {
            _extendedRunsOfFour = new List <CellRun>();
            foreach (CellRun run in RunsOfFourOrMore)
            {
                Cell        end1        = run.First;
                Cell        end2        = run.Last;
                Position    direction2  = Neighborhood.GetDirection(end1.hex, end2.hex);
                Position    direction1  = Neighborhood.GetDirection(end2.hex, end1.hex);
                Cell        currentCell = end1.NeighborhoodCells[direction1];
                List <Cell> cellList    = new List <Cell>(run.Run);
                while (!(currentCell is Wall) && currentCell.Piece.Color != PieceColor.None)
                {
                    cellList.Add(currentCell);
                    currentCell = currentCell.NeighborhoodCells[direction1];
                }
                // now go the other way
                currentCell = end2.NeighborhoodCells[direction2];
                while (!(currentCell is Wall) && currentCell.Piece.Color != PieceColor.None)
                {
                    cellList.Add(currentCell);
                    currentCell = currentCell.NeighborhoodCells[direction2];
                }

                _extendedRunsOfFour.Add(new CellRun(cellList));
            }

            // track intersectons
            HashSet <Hex> hexesInRuns = new HashSet <Hex>();

            _extendedRunsOfFour.All(l => l.Run.All((c) =>
            {
                if (hexesInRuns.Contains(c.hex))
                {
                    _intersections.Add(c);
                }
                else
                {
                    hexesInRuns.Add(c.hex);
                }
                return(true);
            }
                                                   ));
        }
示例#4
0
 public RemoveMovePart(IEnumerable <Hex> removeList)
 {
     _hexesToRemove = removeList.ToList();
     _direction     = Neighborhood.GetDirection(_hexesToRemove.First(), _hexesToRemove.Last());
 }
示例#5
0
文件: Cell.cs 项目: vfridell/Gipf
 public static void LinkCells(Cell from, Cell to, Position pos)
 {
     from.neighborhood[pos] = to;
     to.neighborhood[Neighborhood.GetOpposite(pos)] = from;
 }
示例#6
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);
            }
        }