示例#1
0
        public void PlaceStone(HexCoordinate cord)
        {
            if (Winner != Player.None)
            {
                throw new Exception("The game is already over");
            }

            if (!validPlacements.Contains(cord))
            {
                throw new Exception("Tried to place a stone in an invalid position!");
            }

            // Update the chain collection
            switch (ActivePlayer)
            {
            case Player.Black: BlackChains.Add(cord); break;

            case Player.White: WhiteChains.Add(cord); break;
            }

            // Place stone
            Board.PlaceStone(cord, ActivePlayer);
            lastMoves.Push(cord);

            // Switch active player
            ActivePlayer = ActivePlayer.GetOpponent();

            // Remove the old placement coordinate
            if (IsFirstTurn)
            {
                validPlacements.Clear();
                IsFirstTurn = false;
            }
            else
            {
                validPlacements.Remove(cord);
            }

            // Add new placement coordinates
            var neighbors = Board.GetNeighbors(cord);

            for (var i = 0; i < neighbors.Length; i++)
            {
                var neighbor = neighbors[i];
                // Do not add coordinates where a stone is already placed
                if (Board[neighbor] != Player.None)
                {
                    continue;
                }

                var neighborCount = CountNeighborStones(neighbor);
                if (neighborCount >= 2)
                {
                    validPlacements.Add(neighbor);
                }
            }

            // Check if a player won or if it's a draw
            Winner = GetWinner(cord);
            if (Winner != Player.None || validPlacements.Count == 0)
            {
                IsGameOver = true;
                return;
            }
        }
示例#2
0
        public void UndoLastMove()
        {
            if (lastMoves.Count == 0)
            {
                throw new Exception("Tried to undo the last move, when no last moves are available");
            }

            var lastMove = lastMoves.Pop();

            // Remove the stone
            Board.RemoveStone(lastMove);
            validPlacements.Add(lastMove);

            // Switch the active player
            ActivePlayer = ActivePlayer.GetOpponent();

            // Remove enclosed stones
            if (moveEnclosedStones.ContainsKey(lastMove))
            {
                foreach (var tile in moveEnclosedStones[lastMove])
                {
                    EnclosedStones[ActivePlayer].Remove(tile);
                }
                moveEnclosedStones.Remove(lastMove);
            }

            // Update the chain collection
            switch (ActivePlayer)
            {
            case Player.Black: BlackChains.Remove(lastMove); break;

            case Player.White: WhiteChains.Remove(lastMove); break;
            }

            // Remove now invalid placements
            if (CanUndo)
            {
                var neighbors = Board.GetNeighbors(lastMove);
                for (var i = 0; i < neighbors.Length; i++)
                {
                    var neighbor = neighbors[i];
                    if (Board[neighbor] != Player.None)
                    {
                        continue;
                    }

                    var neighborCount = CountNeighborStones(neighbor);
                    if (neighborCount < 2)
                    {
                        validPlacements.Remove(neighbor);
                    }
                }
            }
            else
            {
                // We are at the beginning of the game
                IsFirstTurn = true;
                validPlacements.Clear();
                foreach (var neighbor in Center.GetNeighborsClockwise())
                {
                    validPlacements.Add(neighbor);
                }
            }

            // Remove the winning player
            Winner     = Player.None;
            IsGameOver = false;
        }