/// <summary>
        ///  get candidate moves - 
        ///  this list is comprehensive - it will contain all empty cells on the board
        ///  and sorted - good moves come first
        ///  the list returned may be longer than the valid cells
        ///  but then will have a null location at the end
        ///  Actual length is (BoardSize ^ 2) - number of moves already played
        /// </summary>
        /// <param name="board">the board to read</param>
        /// <param name="lookaheadDepth">the current depth of lookahead</param>
        /// <returns>the locations</returns>
        public IEnumerable<Location> CandidateMoves(HexBoard board, int lookaheadDepth)
        {
            // No potential good moves? return them all then
            if (this.goodMoves.GetCount(lookaheadDepth) == 0)
            {
                return board.EmptyCells();
            }

            int maxListLength = (board.Size * board.Size) - this.cellsPlayedCount;

            // enough space for all the possible moves
            Location[] result = new Location[maxListLength];
            int resultIndex = 0;

            // mask out the ones that have been used - intialised to false
            bool[,] maskCellSelected = new bool[board.Size, board.Size];

            // good moves are found first
            Location[] myGoodMoves = this.goodMoves.GetGoodMoves(lookaheadDepth);

            // copy in the good moves
            foreach (Location goodMoveLoc in myGoodMoves)
            {
                if (board.GetCellAt(goodMoveLoc).IsEmpty() && (!maskCellSelected[goodMoveLoc.X, goodMoveLoc.Y]))
                {
                    result[resultIndex] = goodMoveLoc;
                    resultIndex++;
                    maskCellSelected[goodMoveLoc.X, goodMoveLoc.Y] = true;
                }
            }

            // copy in all moves where the cell is empty;
            // and not already in by virtue of being a good move
            foreach (Cell testCell in board.GetCells())
            {
                if (testCell.IsEmpty() && (!maskCellSelected[testCell.X, testCell.Y]))
                {
                    result[resultIndex] = testCell.Location;
                    resultIndex++;
                }
            }

            // null marker at the end
            if (resultIndex < maxListLength)
            {
                result[resultIndex] = Location.Null;
            }

            return result;
        }
Exemple #2
0
        public void BoardLayoutTest()
        {
            HexBoard hexBoard = new HexBoard(BoardSize);
            for (int x = 0; x < hexBoard.Size; x++)
            {
                for (int y = 0; y < hexBoard.Size; y++)
                {
                    Cell cell = hexBoard.GetCellAt(x, y);

                    Assert.IsNotNull(cell);
                    Assert.IsTrue(cell.X == x);
                    Assert.IsTrue(cell.Y == y);
                }
            }
        }
Exemple #3
0
        public void CopyStateFrom(HexBoard otherBoard)
        {
            if (otherBoard != null)
            {
                if (otherBoard.Size != this.Size)
                {
                    throw new Exception("Board sizes do not match");
                }

                foreach (Cell cell in this.cells)
                {
                    cell.IsOccupied = otherBoard.GetCellAt(cell.Location).IsOccupied;
                }

                this.movesPlayedCount = otherBoard.MovesPlayedCount;
            }
        }
        /// <summary>
        /// // get the candidate moves
        /// </summary>
        /// <param name="board">the board to get moves from</param>
        /// <param name="lookaheadDepth">the lookahead depth</param>
        /// <returns>the candiate move locations</returns>
        public IEnumerable<Location> CandidateMoves(HexBoard board, int lookaheadDepth)
        {
            int maxListLength = (board.Size * board.Size) - this.cellsPlayedCount;

            // enough space for all the possible moves
            List<Location> result = new List<Location>(maxListLength);

            // mask out the ones that have been used - intialised to false
            bool[,] maskCellSelected = new bool[board.Size, board.Size];

            if (lookaheadDepth < this.goodMoves.Depth)
            {
                // good moves are found first
                Location[] myGoodMoves = this.goodMoves.GetGoodMoves(lookaheadDepth);

                // copy in the good moves
                foreach (Location goodMoveLoc in myGoodMoves)
                {
                    if (board.GetCellAt(goodMoveLoc).IsEmpty() && (!maskCellSelected[goodMoveLoc.X, goodMoveLoc.Y]))
                    {
                        result.Add(goodMoveLoc);
                        maskCellSelected[goodMoveLoc.X, goodMoveLoc.Y] = true;
                    }
                }
            }

            // copy in all moves where the cell is empty,
            // and not already in by virtue of being a good move
            foreach (Cell testCell in board.GetCells())
            {
                if (testCell.IsEmpty() && (!maskCellSelected[testCell.X, testCell.Y]))
                {
                    if (IsIncluded(testCell, board) || HasFilledNeighbour(testCell, board))
                    {
                        result.Add(testCell.Location);
                    }
                }
            }

            return result.ToArray();
        }
Exemple #5
0
        /// <summary>
        /// are two boards the same, ie same state in all cells
        /// </summary>
        /// <param name="otherBoard">the other board</param>
        /// <returns>the equality boolean</returns>
        public bool Equals(HexBoard otherBoard)
        {
            if (otherBoard == null)
            {
                return(false);
            }

            if (otherBoard.Size != this.Size)
            {
                return(false);
            }

            foreach (Cell cell in this.cells)
            {
                if (cell.IsOccupied != otherBoard.GetCellAt(cell.Location).IsOccupied)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #6
0
        /// <summary>
        /// are two boards the same, ie same state in all cells
        /// </summary>
        /// <param name="otherBoard">the other board</param>
        /// <returns>the equality boolean</returns>
        public bool Equals(HexBoard otherBoard)
        {
            if (otherBoard == null)
            {
                return false;
            }

            if (otherBoard.Size != this.Size)
            {
                return false;
            }

            foreach (Cell cell in this.cells)
            {
                if (cell.IsOccupied != otherBoard.GetCellAt(cell.Location).IsOccupied)
                {
                    return false;
                }
            }

            return true;
        }
Exemple #7
0
        /// <summary>
        /// set self equal to the other board 
        /// </summary>
        /// <param name="otherBoard">the board to copy</param>
        public void CopyStateFrom(HexBoard otherBoard)
        {
            if (otherBoard != null)
            {
                if (otherBoard.Size != this.Size)
                {
                    throw new Exception("Board sizes do not match");
                }

                foreach (Cell cell in this.cells)
                {
                    cell.IsOccupied = otherBoard.GetCellAt(cell.Location).IsOccupied;
                }

                this.movesPlayedCount = otherBoard.MovesPlayedCount;
            }
        }
Exemple #8
0
        public void TestCalculateMove2SituationScoreMiddle()
        {
            HexBoard board = new HexBoard(3);
            PlayTwoMoves(board);

            // playing middle gets adavantage
            board.PlayMove(1, 1, true);

            PathLengthLoop pathLength = new PathLengthLoop(board);
            int moveScore = pathLength.SituationScore();
            Assert.AreEqual(1, moveScore);

            board.GetCellAt(1, 1).IsOccupied = Occupied.PlayerY;
            moveScore = pathLength.SituationScore();
            Assert.AreEqual(-1, moveScore);

            board.GetCellAt(1, 1).IsOccupied = Occupied.Empty;
        }
Exemple #9
0
        public void MoveSetsCellOccupied()
        {
            HexBoard hexBoard = new HexBoard(BoardSize);
            Assert.AreEqual(Occupied.Empty, hexBoard.GetCellOccupiedAt(1, 1));

            hexBoard.PlayMove(1, 1, true);
            Assert.AreEqual(Occupied.PlayerX, hexBoard.GetCellAt(1, 1).IsOccupied);
            Assert.AreEqual(Occupied.PlayerX, hexBoard.GetCellOccupiedAt(1, 1));
        }
Exemple #10
0
        public void GetCellAtArrayTwoTest()
        {
            const int SmallBoardSize = 4;
            HexBoard source = new HexBoard(SmallBoardSize);

            Location[] locs = new Location[2];
            locs[0] = new Location(1, 1);
            locs[1] = new Location(2, 2);

            Cell[] result = source.GetCellAt(locs);

            Assert.AreEqual(2, result.Length);
            Assert.AreEqual(1, result[0].Location.X);
            Assert.AreEqual(1, result[0].Location.Y);
            Assert.AreEqual(2, result[1].Location.X);
            Assert.AreEqual(2, result[1].Location.Y);
        }
Exemple #11
0
        public void GetCellAtTest()
        {
            const int SmallBoardSize = 4;
            HexBoard source = new HexBoard(SmallBoardSize);

            for (int x = 0; x < SmallBoardSize; x++)
            {
                for (int y = 0; y < SmallBoardSize; y++)
                {
                    Cell cell = source.GetCellAt(x, y);

                    Assert.AreEqual(x, cell.X);
                    Assert.AreEqual(y, cell.Y);
                }
            }
        }
Exemple #12
0
        public void GetCellAtArrayNullTest()
        {
            const int SmallBoardSize = 4;
            HexBoard source = new HexBoard(SmallBoardSize);

            Location[] locs = null;

            Cell[] result = source.GetCellAt(locs);

            Assert.AreEqual(0, result.Length);
        }
        public void BoardNeighbours2Test()
        {
            HexBoard hexBoard = new HexBoard(BoardSize);

            for (int x = 0; x < hexBoard.Size; x++)
            {
                for (int y = 0; y < hexBoard.Size; y++)
                {
                    Cell cell = hexBoard.GetCellAt(x, y);

                    var neigbours2 = hexBoard.Neighbours2(cell);

                    Assert.IsNotNull(neigbours2);

                    /* all cells have at least 1 neighbours, and at most 6 */
                    Assert.Greater(neigbours2.GetLength(0), 0);
                    Assert.Less(neigbours2.GetLength(0), 7);

                    foreach (Cell[] triplet in neigbours2)
                    {
                        TestNeighbour2Triplet(cell, triplet);
                    }
                }
            }
        }
        public void TestGetEmptyNeighbours2Edge()
        {
            HexBoard hexBoard = new HexBoard(BoardSize);

            // get the neighbours2 with nothing in between
            Cell focus = hexBoard.GetCellAt(3, 0);
            Cell[][] neighbours2EmptyBoard = hexBoard.EmptyNeighbours2(focus);

            Assert.AreEqual(3, neighbours2EmptyBoard.Length);
        }
        public void TestGetEmptyNeighbours2()
        {
            HexBoard hexBoard = new HexBoard(BoardSize);

            // get the neighbours2 with nothing inbetween
            Cell focus = hexBoard.GetCellAt(3, 3);
            Cell[][] neighbours2EmptyBoard = hexBoard.EmptyNeighbours2(focus);

            // should be six sets
            Assert.AreEqual(6, neighbours2EmptyBoard.Length);

            // playing an ajoining cell removes 2 sets
            hexBoard.PlayMove(3, 4, false);
            Cell[][] neighbours2PlayedCell = hexBoard.EmptyNeighbours2(focus);

            Assert.AreEqual(4, neighbours2PlayedCell.Length);
        }
        public void BoardNeighboursTest()
        {
            HexBoard hexBoard = new HexBoard(BoardSize);

            for (int x = 0; x < hexBoard.Size; x++)
            {
                for (int y = 0; y < hexBoard.Size; y++)
                {
                    Cell cell = hexBoard.GetCellAt(x, y);

                    var neigbours = hexBoard.Neighbours(cell);

                    Assert.IsNotNull(neigbours);

                    /* all cells have at least 2 neighbours, and at most 6 */
                    Assert.GreaterOrEqual(neigbours.Length, 2);
                    Assert.LessOrEqual(neigbours.Length, 6);

                    /* cells not on the edge will have 6 neighbours */
                    if ((x > 0) && (y > 0) && (x < (hexBoard.Size - 1)) && (y < (hexBoard.Size - 1)))
                    {
                        Assert.AreEqual(neigbours.Length, 6);
                    }

                    NoNullsInCellArray(neigbours);

                    foreach (Cell neibCell in neigbours)
                    {
                        DoTestNeighbour(cell, neibCell, hexBoard);
                    }
                }
            }
        }