public void Render(ICanvas canvas, int width, int height, IPixelMapper pixelMapper)
        {
            var tunnelRoofColour = BuildModeAwareColour(Colors.LightGray);
            var firstMountain    = new Terrain()
            {
                Height = Terrain.FirstMountainHeight
            };
            var tunnelBaseColour    = BuildModeAwareColour(TerrainMapRenderer.GetTerrainColour(firstMountain));
            var entranceColourArray = new[] { tunnelBaseColour, tunnelRoofColour, tunnelBaseColour };

            Dictionary <(int column, int row), Tunnel> entrances = new();

            foreach (Track track in _trackLayout)
            {
                var terrain = _terrainMap.Get(track.Column, track.Row);
                if (!terrain.IsMountain)
                {
                    continue;
                }

                (int x, int y, _) = pixelMapper.CoordsToViewPortPixels(track.Column, track.Row);

                // Paint over the tracks with the colour of the terrain. Would be awesome to remove this in future somehow
                var terrainColour = BuildModeAwareColour(TerrainMapRenderer.GetTerrainColour(terrain));
                canvas.DrawRect(x, y, pixelMapper.CellSize, pixelMapper.CellSize,
                                new PaintBrush
                {
                    Style = PaintStyle.Fill,
                    Color = terrainColour,
                });

                TrackNeighbors trackNeighbours = track.GetConnectedNeighbors();

                BuildEntrances(trackNeighbours.Up, Tunnel.Bottom, entrances);
                BuildEntrances(trackNeighbours.Right, Tunnel.Left, entrances);
                BuildEntrances(trackNeighbours.Down, Tunnel.Top, entrances);
                BuildEntrances(trackNeighbours.Left, Tunnel.Right, entrances);

                var currentCellTunnels = (IsEntrance(trackNeighbours.Up) ? Tunnel.Top : Tunnel.NoTunnels) |
                                         (IsEntrance(trackNeighbours.Right) ? Tunnel.Right : Tunnel.NoTunnels) |
                                         (IsEntrance(trackNeighbours.Down) ? Tunnel.Bottom : Tunnel.NoTunnels) |
                                         (IsEntrance(trackNeighbours.Left) ? Tunnel.Left : Tunnel.NoTunnels);

                DrawTunnel(canvas, pixelMapper, tunnelRoofColour, tunnelBaseColour, x, y, currentCellTunnels);
            }

            foreach (var(col, row, tunnels) in entrances)
            {
                DrawEntrance(canvas, pixelMapper, entranceColourArray, col, row, tunnels);
            }
        }
        public bool TryCreateEntity(int column, int row, bool isPartOfDrag, [NotNullWhen(true)] out Track?entity)
        {
            var neighbours = TrackNeighbors.GetConnectedNeighbours(_layout.ToLayout(), column, row, emptyIsConsideredConnected: true);

            // if they click and its the perfect spot for a cross track, just do it
            if (!isPartOfDrag && neighbours.Count == 4)
            {
                entity = new CrossTrack();
                return(true);
            }

            if (isPartOfDrag)
            {
                if (neighbours.Count == 4)
                {
                    entity = new CrossTrack();
                    return(true);
                }

                // if they're dragging, we're looking for them to complete an intersection
                neighbours = TrackNeighbors.GetConnectedNeighbours(_layout.ToLayout(), column - 1, row);
                if (neighbours.Count == 3 && neighbours.Right is null)
                {
                    entity = new Track()
                    {
                        Direction = TrackDirection.Horizontal
                    };
                    _layout.Set(column - 1, row, new CrossTrack());
                    return(true);
                }

                neighbours = TrackNeighbors.GetConnectedNeighbours(_layout.ToLayout(), column, row - 1);
                if (neighbours.Count == 3 && neighbours.Down is null)
                {
                    entity = new Track()
                    {
                        Direction = TrackDirection.Vertical
                    };
                    _layout.Set(column, row - 1, new CrossTrack());
                    return(true);
                }

                neighbours = TrackNeighbors.GetConnectedNeighbours(_layout.ToLayout(), column + 1, row);
                if (neighbours.Count == 3 && neighbours.Left is null)
                {
                    entity = new Track()
                    {
                        Direction = TrackDirection.Horizontal
                    };
                    _layout.Set(column + 1, row, new CrossTrack());
                    return(true);
                }

                neighbours = TrackNeighbors.GetConnectedNeighbours(_layout.ToLayout(), column, row + 1);
                if (neighbours.Count == 3 && neighbours.Up is null)
                {
                    entity = new Track()
                    {
                        Direction = TrackDirection.Vertical
                    };
                    _layout.Set(column, row + 1, new CrossTrack());
                    return(true);
                }
            }

            entity = null;
            return(false);
        }