<commit_before>﻿using CatSkald.Roguelike.DungeonGenerator.Directions;
using CatSkald.Roguelike.DungeonGenerator.Maps;
using CatSkald.Tools;

namespace CatSkald.Roguelike.DungeonGenerator.Commands
{
    public sealed class CorridorBuilderCommand : IMapBuilderCommand
    {
        private DirectionPicker _directionsPicker;

        public CorridorBuilderCommand(int twistFactor)
        {
            Throw.IfNotInRange(0, 100, twistFactor, nameof(twistFactor));

            _directionsPicker = new DirectionPicker(twistFactor);
        }

        public void Execute(IMap map)
        {
            Throw.IfNull(map, nameof(map));

            BuildCorridors(map);
        }

        private void BuildCorridors(IMap map)
        {
            Cell nextCell;
            var direction = Dir.Zero;

            var currentCell = map.PickRandomCell();
            map.Visit(currentCell);
            bool success;
            do
            {
                _directionsPicker.LastDirection = direction;
                _directionsPicker.ResetDirections();
                success = TryPickRandomUnvisitedAdjacentCell(
                    map, currentCell, out nextCell, out direction);
                if (success)
                {
                    map.CreateCorridor(currentCell, nextCell, direction);
                    map.Visit(nextCell);
                    currentCell = nextCell;
                    nextCell = null;
                }
                else
                {
                    currentCell = map.PickNextRandomVisitedCell(currentCell);
                }<commit_msg>Added validation for visited cells.<commit_after>﻿using System;
using System.Linq;
using CatSkald.Roguelike.DungeonGenerator.Directions;
using CatSkald.Roguelike.DungeonGenerator.Maps;
using CatSkald.Tools;

namespace CatSkald.Roguelike.DungeonGenerator.Commands
{
    public sealed class CorridorBuilderCommand : IMapBuilderCommand
    {
        private DirectionPicker _directionsPicker;

        public CorridorBuilderCommand(int twistFactor)
        {
            Throw.IfNotInRange(0, 100, twistFactor, nameof(twistFactor));

            _directionsPicker = new DirectionPicker(twistFactor);
        }

        public void Execute(IMap map)
        {
            Throw.IfNull(map, nameof(map));

            BuildCorridors(map);
        }

        private void BuildCorridors(IMap map)
        {
            if (map.Any(c => c.IsVisited))
            {
                throw new InvalidOperationException(
                    "Map should not contain visited cells.");
            }

            Cell nextCell;
            var direction = Dir.Zero;

            var currentCell = map.PickRandomCell();
            map.Visit(currentCell);
            bool success;
            do
            {
                _directionsPicker.LastDirection = direction;
                _directionsPicker.ResetDirections();
                success = TryPickRandomUnvisitedAdjacentCell(
                    map, currentCell, out nextCell, out direction);
                if (success)
                {
                    map.CreateCorridor(currentCell, nextCell, direction);
                    map.Visit(nextCell);
                    currentCell = nextCell;
                    nextCell = null;
                }
                else
                {
                    currentCell = map.PickNextRandomVisitedCell(currentCell);
                }
{'fraction_non_alphanumeric': 0.06938775510204082, 'fraction_numerical': 0.0023323615160349854, 'mean_word_length': 1.651468315301391, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3837454', 'n_tokens_mistral': 910, 'n_tokens_neox': 840, 'n_words': 166}