bool visible(coordpair pair)
 {
     Vec2 vec = box2dToCamera( getTileCoords(pair.x, pair.y));
     return (vec.X > 2*ox *5) && (vec.X < 100 - 2*ox *5) && (vec.Y > 2*oy *5) && (vec.Y < 100 - 2*oy *5) ;
 }
        List<coordpair> getVisibleTiles()
        {
            //maybe optimize?
            List<coordpair> tiles = new List<coordpair>();
            coordpair farLeft= getTileCoords(cameraToBox2d(new Vec2((float)ox / 2, (float)oy / 2))),
                      farRight= getTileCoords(cameraToBox2d(new Vec2(100f - (float)ox / 2, (float)oy / 2))),
                      nearRight= getTileCoords(cameraToBox2d(new Vec2(100f - (float)ox / 2, 100-(float)oy / 2))),
                      nearLeft = getTileCoords(cameraToBox2d(new Vec2((float)ox / 2, 100f - (float)oy / 2)));
            //наркоманский способ это сделать - идти, например, слева направо по столбцам: найти вершину столбца, после чего опускаться, пока не вышел из камеры, после чего - следующий столбик.
            int leftMost = System.Math.Min(System.Math.Min(farLeft.x, farRight.x), System.Math.Min(nearLeft.x, nearRight.x)),
                rightMost = System.Math.Max(System.Math.Max(farLeft.x, farRight.x), System.Math.Max(nearLeft.x, nearRight.x)),
                downMost = System.Math.Max(System.Math.Max(farLeft.y, farRight.y), System.Math.Max(nearLeft.y, nearRight.y)),
                upMost = System.Math.Min(System.Math.Min(farLeft.y, farRight.y), System.Math.Min(nearLeft.y, nearRight.y));

            for ( int i = leftMost; i<= rightMost; i++)
            {
                for (int j = upMost; j <= downMost; j++)
                {
                    coordpair pair = new coordpair{x = i, y = j};
                    if (visible(pair))
                    {
                        tiles.Add(pair);
                        if (!photos.ContainsKey(pair))
                            photos[pair] =getTileImage(new Bitmap(pplast.cameraView), pair.x, pair.y);
                    }
                }
            }

            return tiles;
        }
        void feedSample(Bitmap tile,coordpair coords, double measuredcost)
        {
            measuredcost = System.Math.Round(measuredcost, 1);
            dynamic sample = wrapper.sampleFromBitmap(tile);
            enc.encode(sample,measuredcost,system);
            //if (!costs.Contains(measuredcost))//used in sam
            //    costs.Add(measuredcost);
            if (samples.ContainsKey(coords))
            {
                samples[coords] = sample;
                images[coords].Name = measuredcost.ToString();

            }
            else
            {
                dataWnd.ListSamples.LargeImageList.Images.Add(tile);
                System.Windows.Forms.ListViewItem listViewItem = new System.Windows.Forms.ListViewItem(measuredcost.ToString(),dataWnd.ListSamples.LargeImageList.Images.Count-1);
                samples[coords] = sample;
                images[coords] = listViewItem;
                dataWnd.ListSamples.Items.AddRange(new System.Windows.Forms.ListViewItem[] { listViewItem });
            }
        }
        public override void intelligentSystemCalculateWeights(PerceptParams pp, float t)
        {
            //ФАЗА СОЗДАНИЯ ПРИМЕРОВ
            foreach ( KeyValuePair<state,double> measure in measures)
            {
                coordpair tile = new coordpair{ x = measure.Key.x, y = measure.Key.y};
                measureHistory[measure.Key] = measure.Value;
                if (photos.ContainsKey(tile))
                {
                    feedSample(photos[tile],tile, measure.Value);
                }
            }
            measures = new Dictionary<state, double>();//да-да, они обнуляются
            if (pythonerLaunched)
            {
                if (!pythoner.IsAlive)
                {
                    tree = system.tree;
                    //работает прямо очень часто. Мб приоритет понизить?
                    dataWnd.treeVisualisationLabel.Text = ((string)tree.visualise(enc)).Replace("takeValue","").Replace("takeConstant","");
                    dataWnd.encbox.Text = enc.visualise();
                    launchComposeThread();
                }
            }
            //конец фазы создания примеров

            //именно здесь происходит обновление весов силами ССИУ
            if (t - tlast > dt)
                tlast = t;
            else return;
            pplast = pp;
            DateTime atStart = DateTime.Now;
            Random picker = new Random();

            for (int itr = 0; itr < classificationsPerCall;itr++ )
            {
                if (tiles.Count == 0)
                {
                    tiles = getVisibleTiles();
                    continue;//in case there are none
                }

                int ind = picker.Next(tiles.Count);
                coordpair tile = tiles[ind];

                tiles.RemoveAt(ind);

                double dist = (getTileCoords(tile.x, tile.y) - new Vec2(pos.xc, pos.yc)).Length();
                if ((dist < 3) || !visible(tile) || measureHistory.ContainsKey(pr.states[orientation.down][tile.x, tile.y])) continue;

                {
                    Bitmap bmp = photos[tile];

                    dynamic sample = wrapper.sampleFromBitmap(bmp);
                    dynamic rsltlist = tree.classify(sample);
                    try
                    {
                        dynamic cost = enc.decode(rsltlist);
                        pr.setCost(tile.x, tile.y, cost);
                        if (cost == double.PositiveInfinity)
                            obsts[pr.states[orientation.down][tile.x, tile.y]] = System.Drawing.Color.Crimson;
                        else if (cost > 2)
                            obsts[pr.states[orientation.down][tile.x, tile.y]] = System.Drawing.Color.DarkGray;
                        else
                        {
                            if (obsts.ContainsKey(pr.states[orientation.down][tile.x, tile.y]))
                                obsts.Remove(pr.states[orientation.down][tile.x, tile.y]);
                            if (infs.Contains(pr.states[orientation.down][tile.x, tile.y]))
                                infs.Remove(pr.states[orientation.down][tile.x, tile.y]);

                        }
                    }
                    catch (Exception e)
                    { };

                }
            }
        }
 double distanceFromRobot(coordpair tile)
 {
     return System.Math.Sqrt((tile.x - x) * (tile.x - x) + (tile.y - y) * (tile.y - y));
 }
        public override void intelligentSystemCalculateWeights(PerceptParams pp, float t)
        {
            //ФАЗА СОЗДАНИЯ ПРИМЕРОВ
            foreach ( KeyValuePair<state,double> measure in measures)
            {
                coordpair tile = new coordpair{ x = measure.Key.x, y = measure.Key.y};
                measureHistory[measure.Key] = measure.Value;
                if (photos.ContainsKey(tile))
                {
                    feedSample(photos[tile],tile, measure.Value);
                }
            }
            measures = new Dictionary<state, double>();//да-да, они обнуляются
            if (pythonerLaunched)//flag for the first single round
            {
                if (!pythoner.IsAlive)
                {
                    dataWnd.treeVisualisationLabel.Text = system.logWriter.readString();
                    dataWnd.encbox.Text = enc.visualise();
                    launchComposeThread();
                }
            }
            //конец фазы создания примеров

            //именно здесь происходит обновление весов силами ССИУ
            if (t - tlast > dt)
                tlast = t;
            else return;
            pplast = pp;
            Random picker = new Random();

            for (int itr = 0; itr < classificationsPerCall; itr++)
            {
                if (tiles.Count == 0)
                {
                    tiles = getActualTiles();
                    continue;//in case there are none
                }

                int ind = picker.Next(tiles.Count);
                coordpair tile = tiles[ind];

                tiles.RemoveAt(ind);

                double dist = distanceFromRobot(tile);
                //don't classify too close,    too far                  , or directly measured
                if ((dist < blindZone) || (dist > classificationRange && !visible(tile)) || measureHistory.ContainsKey(pr.states[orientation.down][tile.x, tile.y])) continue;

                {
                    Bitmap bmp = photos[tile];

                    dynamic sample = wrapper.sampleFromBitmap(bmp);
                    try
                    {//why try: there was chance that some trees got polled while being composed or pruned. If you wanna adjust the learning routine so as it won't cause this error, you may try.
                        dynamic rslt = system.classify(sample, 1, 10);
            #warning adjust
                        double cost = enc.decodeResult(rslt);

                        pr.setCost(tile.x, tile.y, cost);
                        if (cost == double.PositiveInfinity)
                            obsts[pr.states[orientation.down][tile.x, tile.y]] = System.Drawing.Color.Crimson;
                        else if (cost > 2)
                            obsts[pr.states[orientation.down][tile.x, tile.y]] = System.Drawing.Color.DarkGray;
                        else
                        {
                            if (obsts.ContainsKey(pr.states[orientation.down][tile.x, tile.y]))
                                obsts.Remove(pr.states[orientation.down][tile.x, tile.y]);
                            if (infs.Contains(pr.states[orientation.down][tile.x, tile.y]))
                                infs.Remove(pr.states[orientation.down][tile.x, tile.y]);

                        }
                    }
                    catch (Exception e) { }
                    //{ System.Windows.Forms.MessageBox.Show(e.Message); };

                }
            }
        }