Polishing stage. Homemade loops with a parameter in a multi-link “manipulator” for working with data (map generation)

Thanks to the author of the publication. I hope that the reshaping of all human languages ​​of civilization is definitely not too tough for that hater (that I encountered on another forum), but before the establishment of someone’s personal justice and even before the collapse of the universe.

I am not opposed to the Bresenham algorithm, but I understand that it has a completely different task, although it has common facets. Even if my technical specification seems stupid to someone, it doesn’t bother me much, I’m sure that moving using maps is convenient and practical.

First, a short digression on the explanations, under the spoiler.

Hidden text

From an explanation of why assembler is still interesting: when the final representation of the code is still not visible entirely and clearly (all this is within the framework of the project described in the previous publication, purely for myself I will call it “Eye”, if it’s something about computer vision).

Hello. There is a desire to share my experience of organizing cycles (I chose the previews from those generated that were more educational, because in the end I figured out something for myself that I didn’t know before, and I like the previews – this is exactly how I started writing the engine – the robot seems to have only one arm, he raised the other and with his whole appearance expresses complete bewilderment, because according to the description of the picture, his technical specification is to juggle balls capsules, and by the look of him, instead of fulfilling the technical requirements, the result is one question – “HOW?!?!?” :), when he doesn’t even know what juggling is, but despite the fact that the robot in the picture is one-armed and one-sided, he fulfills the specifications by doing much fewer operations than popular algorithms that are similar in terms of specifications, but nevertheless have a different specification). Don’t expect this to be just such a lecture from a specialist, this is just something interesting that I could share at this stage within the project. From the previous publication, using the links, you can go to the code, which is not shiny, but there was a “matte” shade of the assembler there for the following reasons:

to polish the generator algorithm, it was necessary to have an accurate representation of the formulas, but I didn’t have them, and the calculation formulas were literally debugged in the debugger – errors were looked for after the automatic tester found them, and the formulas for debugging the map generator engine were also shuffled around code, to reduce the number of their use, or their parts – this also happened. Why didn’t I use case can also be explained quite simply: in the end, the use of assembler took place – familiarize yourself with the required functionality as much as possible, develop the skill and then apply it. Of course, this is not God knows what an achievement, but nevertheless, the “working chamber” of the map generator engine has changed from this appearance, but this is part of the plan, or rather a small part of its implementation, which may seem to some to be of little significance, but nevertheless:

 {%REGION 'Engine'}
            asm
                     JMP     p
            end;
            p1:
              StringGrid1.Cells[px^, py^] :=
                IntToStr(pTracerX^) + ',' + IntToStr(pTracerY^) + ',' + '1';
//            запись правого столбца
            p := @p3;
            goto p4;
            p2:
            x1:=x+1;
            y1:=y+1;
              StringGrid1.Cells[px^, py^] := IntToStr(px1^) + ',' + IntToStr(py1^) + ',' + '0';
  //          автоматическое забивание координат в местах скоса трассы
            p := @p3;
            goto p4;
            p3:
              x1:=x+1;
              y1:=y;
              StringGrid1.Cells[px^, py^] := IntToStr(px1^) + ',' + IntToStr(py1^) + ',' + '0';
  //          автоматическое забивание координат трассы на прямых участках
            p4:
              x:=x+xInc;
            {%ENDREGION}                       

before this

{%REGION 'Engine'}
            asm
                     JMP     p
            end;
            p1:
            StringGrid1.Cells[px^, py^] := IntToStr(pTracerX^) + ',' + IntToStr(pTracerY^) + ',' + '1';
            //запись правого столбца
            p := @p3;
            goto p4;
            p2:
            y1:=y+1;
            //автоматическое забивание координат в местах скоса трассы
            p := @p3;
            goto p5;
            p3:
              y1:=y;
              p5:
              x1:=x-xInc;
             StringGrid1.Cells[px^, py^] := IntToStr(px1^) + ',' + IntToStr(py1^) + ',' + '0';
            //автоматическое забивание координат трассы на прямых участках
            p4:
              x:=x+xInc;
            {%ENDREGION}               

. It’s not a huge achievement in modifying the structure, but it’s still satisfying and an experience. The replacement in line 18 of line 19 is due to the fact that further the counting direction changes from the input parameter, and only that is, this is a standard replacement of the code during the change of stages of work, and not an improvement.

So the algorithm works based on the calculations of segments on a horizontal line that have already been made, and during the execution of filling the map, it makes one calculation in every first pixel of each line, according to the formula I derived, and at the beginning of each described segment of the last line of the map (it calculates where from the trace you can get to the current pixel after the break of the previous line, that is, the map is an alternation of parallel traces (lines)), but using a more complex formula that replaces a block of code for checking conditions (I decided not to bother and describe everything with mathematical conditions, this is better than a list of contradictory conditions , mating according to rules that would also have to be described).

Closer to the topic:

Again, a digression with explanatory material.

Hidden text

The task of the map generator was disclosed in my previous publication, as well as the project as a whole. The point is how the generator generates a trace for the algorithm that reads the trace map. And it generates it in a completely different way – the generator itself can follow a completely different path than it describes on the map. This occurs where a straight line is beveled. The trace map itself is a description of following the cells of the map, and always indicates the end of the line, so that the algorithm reading the map always knows that it is already following a new line. Thus, a trace map is a set of parallel traces that fill the entire map. Reading of the map ends by counting the traversed pixels, information about the required number of which is attached to the map description, as well as about the coordinates of the entrance to the map, for the algorithm reading the map.

The generator itself always follows only straight horizontal lines as indicated on the fourth animation layer above the number 4

only the reference direction in the code is from right to left, I just lost a lot of time doing household chores between business trips, and did not do a separate render.

only the reference direction in the code is from right to left, I just lost a lot of time doing household chores between business trips, and did not do a separate render.

but in the case when the angle of parallel lines is greater 90 degrees, the direction of the generator counters will change, this is not implemented now, but it will be completed 180 degrees will mean that the generator algorithm is finished, since all the lines that are from 180 before 360 degrees, parallel to the lines that from 0 before 180 degrees. That is, the generator at the place of the bevel simply writes that it came to the given coordinates, from the same where it was, but with the coordinate Y higher. This is his main trick – you don’t necessarily need to follow the paths you describe, you just need to know them for sure. The bevel is described only backwards in order to avoid checking the condition of not going beyond the map, because with a decent size map this would be a big addition to the amount of work produced by the generator.

The very method of processing visual information – replacing convolutional neural networks – was described by me online at the beginning of 22 (in March), and only then here, since I generally work on construction sites, and I have limited access to a computer until retirement.

The publication was not one-day, while editing it I also reworked the code, and all this for about an hour a day. The design has changed several times, positionally, in general it is difficult to review, the algorithm itself is the result of working with its own approach, and of course such work entails many conclusions, maybe bold, maybe modest, maybe someone will be against it, and someone on the contrary – for. And this is not the point, the point is in the material and in some review – conclusion, from a unique point of view, with which everyone is free to agree or not.

So a manipulator, following a horizontal line, cuts different segments in places where the route is beveled. According to the assignment, it turns out that there are frequent steps – several standard and identical in size, which after a certain number will give one rare one – changed to 1 pixel How this is calculated could be written down, but I think that almost anyone can cope with this task. I will describe the most interesting, in my opinion, calculations.

So we have a frequent step (standard) – stepFrequentand rare – stepRare.

Hidden text

Everything in the calculations is quite interesting, starting from the very beginning, namely the calculations. According to the technical specifications, our lines are straight, and therefore, in the case of a bevel, the bevel along the Y axis will always occur after a certain number of pixels, with a small difference that there will always be a fractional part remaining, which, when summed up, will give a one-time change in the step length before the bevel by 1 pixel But this is calculated once, and the calculations are not quite complicated, if anyone is familiar with Pascal Lazarus and its Math module, you can estimate how much I am a fan of sophisticated logic, the possibilities of which are provided by mathematics coupled with programming

     stepFrequent := round(CaTanDeg);
      StringDiv := frac(CaTanDeg);
      StringDiv1 := 1 - StringDiv;
      znak := sign(0.5 - StringDiv) * sign(StringDiv);
      if StringDiv > 0.5 then  stepsBig := round(1 / StringDiv1)
      else
        stepsBig := round(1 / StringDiv);//+1
      if StringDiv = 0 then  stepsBig := 1;
      if CaTanDeg = 1 then
      begin
        znak := 0;
      end;
      stepRare := stepFrequent + znak;
      bigStep := stepsBig * stepFrequent;
      if bigStep = 0 then
      begin
        bigStep := stepRare;
        stepRare := 0;
      end;
      SummSteps:= stepsBig+1; 

, I won’t hide it – I dream of a programming language that would provide all the possibilities for implementing ideas with fewer restrictions and less memory consumption. To be honest, I don’t want to describe the logic of this banal calculation – you can skip it, there’s more interesting stuff ahead.

They now form a set of steps – stepsSetapInLineand plus, perhaps, depending on the angle, there will be a remainder of frequent steps remainderstepsFrequent and also the final, smallest remainder remainder

But what’s most interesting is that for ease of calculation of all these quantities, initially everything should be a remainder remainder – first line of code. Having discovered this for myself, I decided to call it a rule “alpha-omega”or rule “everything is a remainder” .

Under the spoiler I will put a general image, along with an image of the map

Hidden text
C appeared so that the code could work in the same type of loops without unnecessary assembler:

C appeared so that the code could work in the same type of loops without unnecessary assembler:

The calculations under the spoiler further appeared later, when I reorganized the loops and removed the assembler.

Hidden text

The main idea when organizing loops when removing assembler was that, in this calculation system, initially everything is a remainder. That is, everything can at least be calculated in one pass with one remainder, namely a line along the axis size X, in coordinate Y, which may contain only one segment (remainder or one frequent step), and also there may not be a remainder – everything can turn out to be either a set of entire frequent steps, with a whole rare step, or also with a remainder of entire rare steps, and the very there may not be a remainder as such.

     remainder:=RazmerX;
      remainderCicles:=0;///////////////////////////////////////////////////////////////
      stepsSetapInLine:=0;
      remainderstepsFrequent:=0;
      remainderstepsFrequentCicles:=0;////////////////////////////////////////////////////////////////////
      if remainder>bigStep+stepRare then  begin
      stepsSetapInLine:=trunc(RazmerX div (bigStep+stepRare));
      remainder:=RazmerX - stepsSetapInLine*(bigStep+stepRare);
      end;

          if remainder>stepFrequent then begin
      remainderstepsFrequent:=round(remainder div stepFrequent);
      remainder:=remainder-remainderstepsFrequent*stepFrequent;
     end;
      remainderstepsFrequentCicles:=sign(remainderstepsFrequent)*2;//+sign(stepsSetapInLine);
      if remainderstepsFrequentCicles=0 then remainderstepsFrequentCicles:=remainderstepsFrequentCicles+sign(stepsSetapInLine);
      remainderCicles:=1+sign(remainder);//sign(remainder)+sign(remainderstepsFrequentCicles);
      alternation:=2*sign(stepsSetapInLine);
      if stepsSetapInLine = 0 then begin
      alternation:=1;
      end;
      steps1:=sign(remainder)+stepsSetapInLine*(SummSteps)+remainderstepsFrequent;          

That is, the final task of the map generator is to create an array (map) with the coordinates of pixel-by-pixel movement to each next position, with the beginning designated by each conditional parallel line on the map (I chose to designate each beginning of a new line).

Hidden text
Hidden text

To do this, in the Engine code block, the generator following the horizontal lines of the axis X (along a line for each coordinate Y, or just line by line),

for BFCount :=Biger- 1 downto 0 do begin
  
            {%REGION 'Engine'}
            asm
                     JMP     p
            end;
            p1:
            StringGrid1.Cells[px^, py^] := IntToStr(pTracerX^) + ',' + IntToStr(pTracerY^) + ',' + '1';
            //обозначение начала линии записью единицы в третье поле 
            p := @p3;
            goto p4;
            p2:
            y1:=y+1;
            //автоматическое забивание координат в местах скоса трассы: изменение координаты Y
            p := @p3;
            goto p5;
            p3:
              y1:=y;
              p5:
              x1:=x-xInc;// координата X меняется всегда
             StringGrid1.Cells[px^, py^] := IntToStr(px1^) + ',' + IntToStr(py1^) + ',' + '0';
            //автоматическое забивание координат трассы на прямых участках
            p4:
              x:=x+xInc;
            {%ENDREGION}

          end; 

The following functions are provided (described in the comments in the code)

1) designation of the beginning of the line by writing one in the third field,

2)automatically entering coordinates in places where the route is beveled: changing the Y coordinate,

3) automatic recording of route coordinates on straight sections.

And the cycle alternation scheme looks something like this.

To describe the scheme, let us assume that initially there is everything – a set of steps from several frequent and one rare, the remainder of short steps, and the remainder.

It is worth noting in fairness that in the Lazarus environment, in addition to the assembler, there is everything to implement even homemade loops quite simply. I wrote them my own, why so – under the spoiler. This is a completely previous, almost, generation algorithm, but in which there are already fewer uncertainties, unnecessary assembler, and everything is known in advance from preliminary calculations, and therefore it is rational to use a loop with a parameter.

Hidden text

Here, under the spoiler, I will give a fragment of the program code so that you can immediately designate lines and variables, and this is also step-by-step, first only the organization of loops (it’s not easy to delve even into this part, for this you need to delve into the technical specifications, study the diagrams), this fragment the code fills the map to the last line, for which there is a complex formula for “cutting”, but more on that later. And now I’ll immediately say that modern programming paradigms and processor architectures do not suit me, so my loops are homemade, focused on the Zero flag (zero is the origin of reference in any mathematical system, and for all programming languages ​​and any paradigms the actual definition of a loop with a parameter is that a loop with a parameter is a loop whose number of repetitions is known in advance).

//2
if Not (count1 = 0) Then begin 
          marking1:
          Inc(y);
          p := @p1;
          x := xRazmerX;
                  TracerY := y - steps1;
        formula1:= stepFrequent * y + znak *trunc(y / (SummSteps));
        if TracerY < 0 then
        begin
          TracerX := RazmerX - formula1;
          if TracerX < 0 then TracerX := 0;
          TracerY := 0;
        end else TracerX := 0;
//3
                  BremainderstepsFrequentCicles:=remainderstepsFrequentCicles;//3
                  BstepsSetapInLine:=stepsSetapInLine;
                  Balternation:=alternation;
                  BstepsFrequentCicles:=stepsBig;
                  BstepFrequent:=stepFrequent;
//4
                  count2:=remainderCicles;
                   if Not (count2 = 0) Then begin
                   marking2:
//5
                            count3:=BremainderstepsFrequentCicles;
                            if Not (count3 = 0) Then begin
                            marking3:
//6
                                     count4:=BstepsSetapInLine;
                                     if Not (count4 = 0) Then begin
                                     marking4:
//7
                                     Bstep:=BstepFrequent;
//8
                                             count5:=Balternation;
                                             if Not (count5 = 0) Then begin
                                             marking5:
//9                                  
                                                     count6:=BstepsFrequentCicles;
                                                     if Not (count6 = 0) Then
                                                     begin
                                                     marking6:
//10
                                                             count7:=Bstep;
                                                             //count7
                                                             if Not (count7 = 0) Then begin
                                                             marking7:
            {%REGION 'Engine'}
            asm
                     JMP     p
            end;
            p1:
            StringGrid1.Cells[px^, py^] := IntToStr(pTracerX^) + ',' + IntToStr(pTracerY^) + ',' + '1';
            //запись правого столбца
            p := @p3;
            goto p4;
            p2:
            y1:=y+1;
            //автоматическое забивание координат в местах скоса трассы
            p := @p3;
            goto p5;
            p3:
              y1:=y;
              p5:
              x1:=x-xInc;
             StringGrid1.Cells[px^, py^] := IntToStr(px1^) + ',' + IntToStr(py1^) + ',' + '0';
            //автоматическое забивание координат трассы на прямых участках
            p4:
              x:=x+xInc;
            {%ENDREGION}
                                                             dec(count7);
                                                             if Not (count7 = 0) then goto marking7;
                                                             end;
                                                             p := @p2;
///10
//11
                                                     dec(count6);
                                                     if Not (count6 = 0) then goto marking6;
                                                     end;
//12
                                             Bstep:=stepRare;
                                             BstepsFrequentCicles:=1;
//13
                                             dec(count5);
                                             if Not (count5 = 0) then goto marking5;
                                             end;
//14
                                     BstepFrequent:=stepFrequent;
                                     BstepsFrequentCicles:=stepsBig;
//15
                                     dec(count4);
                                     if Not (count4 = 0) then goto marking4;
                                     end;
//16
                                     BremainderstepsFrequentCicles:=1;
                                     BstepsSetapInLine:=1;
                                     Balternation:=1;
                                     BstepsFrequentCicles:=remainderstepsFrequent;
  //17
                            dec(count3);
                            if Not (count3 = 0) then goto marking3;
                            end;
 //18
                            if  BremainderstepsFrequentCicles = 0 then  begin
                                     BstepsSetapInLine:=1;
                                     Balternation:=1;
                            end;
                            BstepFrequent:=remainder;
                            BremainderstepsFrequentCicles:=1;
                            BstepsFrequentCicles:=1;
  //19
                   dec(count2);
                   if Not (count2 = 0) then goto marking2;
                   end;

  //20
          dec(count1);
          if Not (count1 = 0) then goto marking1;
          end;                          

Maybe someday I’ll make something myself, like a compiler.

Black straight down arrows indicate the beginning of the cycles to their end. Blue curved arrows mean data coming from outside. Green arrows – return to the original data before the start of the cycle in which they are returned. Red and brown arrows indicate changes in the source data after executing any cycles. In the code under the spoiler, each block of the circuit is indicated by a number in the comment. Anyone who wants to understand this will understand it. In general, we get the prospect of a good node system for organizing cycles.

Conclusion. Of course this is a personal point of view:

And if this whole scheme is clear, then you can understand what I will say next: it becomes obvious to have, at least as an option, a second option for compiling a loop with a parameter. Namely, the start and exit from the loop must be oriented to the processor flag Zero, which is checked by the processor hardware, and in the specified compilation version, designed to stop the loop at a counter value equal to zero (If zero, then the loop should not start, and if it has already started, it should break off at the end without returning to the beginning). The flag should be checked at the start of the loop, and if it does not indicate that the counter is equal to zero, then start the loop, and the action on the counter can be done at the end or at the beginning, but check the flag while the loop is running Zero it is better at the end, so as not to return to the beginning again, since manipulations with loops can turn out to be very complex, not even depending on the code, but on the data processed in them. That is, then the processor hardware is used to check the condition, this is, in my concept, a loop with a parameter.

In pseudocode it goes something like this:

count:=myVariable;
if Not (count = 0) Then begin
label1:
...;
...;
...;
dec(count);//or inc (count) 
if Not (count = 0) then goto label1;
end;
Hidden text

Now this is compiled with a check for the Zero flag, but it does not give an increase in speed, and this is generally a consequence of beliefs built into the processor (that’s what current firmware and processors are called). It would be wrong to blame for this, but the prospect of creating your own processor remains. Don’t let anyone scold me too much for my impudence, because I create my own algorithms, I see them as quite natural, and the development of any architecture moves towards naturalness. As in an earlier publication they said in the comments that I am writing for myself – I don’t quite agree, I am writing free from technological beliefs hardware (because these beliefs are essentially unnecessary imposed controls and restrictions, which are more beneficial for fraudsters and people who expropriated other people’s rights than for the safety of society and information security as well), whose time will come. You can consider this at least a private point of view, or even a religion, I consider it a rational choice, it is in this tone that one can conduct an unbiased dialogue in society, because other versions are more about religion and society, propaganda, but I am closer to rationality and scientific agnosticism, and in in society it is rational to mean public – right, because faith is personal. This is both ethics and a rational approach, although style, whatever you like, I consider a rational approach.

Yes, according to many, this is not correct, but under the spoiler I described my attitude to this point of view. Why else would I like to create my own compiler, because with zero orientation I also replace blocks of condition checks using the Math module and its mathematical functions. In my opinion, this looks more natural and clearer from the outside than entire listings of condition checks.

A small epithet under the spoiler.

Hidden text

In general, the trend is that computers are becoming more and more suitable for simulating processes, and therefore programming languages ​​will steadily approach the languages ​​of phenomena, be it physics, society, or life, computer architecture will tend in one direction – closer to the natural. Therefore, in the future, it seems to me that languages ​​will become more beautiful and more perfect (most likely the altruists of OOP set precisely this goal, but for example, I prefer a lower level at which everything can be described without language restrictions), and people are characterized by their actions, this is not programmed .

After output, generation of the last line of the map.

As for generating the last line of the map, I just added some loops and a little code, under the spoiler

Hidden text
 p := @p6;
 x := xRazmerX;
         TracerY := y - steps1;
formula1:= stepFrequent * y + znak *trunc(y / (SummSteps));
if TracerY < 0 then
begin
 TracerX := RazmerX - formula1;
 if TracerX < 0 then TracerX := 0;
 TracerY := 0;
end else TracerX := 0;
         BremainderstepsFrequentCicles:=remainderstepsFrequentCicles;//3
         BstepsSetapInLine:=stepsSetapInLine;
         Balternation:=alternation;
         BstepsFrequentCicles:=stepsBig;
         BstepFrequent:=stepFrequent;///3
         count2:=remainderCicles;//4
         steps := stepsBig;
          if Not (count2 = 0) Then begin
          marking8:

                   count3:=BremainderstepsFrequentCicles;//5
                   if Not (count3 = 0) Then begin
                   marking9:

                            count4:=BstepsSetapInLine;//6
                            if Not (count4 = 0) Then begin
                            marking10:
                            Bstep:=BstepFrequent;//7///7
                                    count5:=Balternation;//8
                                    if Not (count5 = 0) Then begin
                                    marking11:
                                            count6:=BstepsFrequentCicles;//9
                                            if Not (count6 = 0) Then
                                            begin
                                            marking12:

                                                    count7:=Bstep;//10
                                                    //count7
                                                    if Not (count7 = 0) Then begin
                                                    marking13:
   {%REGION 'Engine'}
   asm
            JMP     p
   end;
   p6:
   StringGrid1.Cells[px^, py^] := IntToStr(pTracerX^) + ',' + IntToStr(pTracerY^) + ',' + '1';
   //запись правого столбца
   p := @p8;
   goto p9;
   p7:
   y1:=y+1;
   //автоматическое забивание координат в местах скоса трассы
   p := @p8;
   goto p10;
   p8:
     y1:=y;
     p10:
     x1:=x-xInc;
    StringGrid1.Cells[px^, py^] := IntToStr(px1^) + ',' + IntToStr(py1^) + ',' + '0';
   //автоматическое забивание координат трассы на прямых участках
   p9:
     x:=x+xInc;
   {%ENDREGION}
                                                    dec(count7);
                                                    if Not (count7 = 0) then goto marking13;
                                                    end;///10
            //трассировку начальной ячейки каждого шага последней обрабатываемой строки кроме правого столбца
                      if steps = 0 then  steps := SummSteps;
            if RazmerX > RazmerY then begin
                    Dec(steps1);
            TracerX := x - ( znak*sign(trunc((1+sign(y-trunc(y/(stepsBig+1))*(stepsBig+1)-steps)/2))) +  formula1)+1;
                                         if TracerX<1 then begin
                                         TracerY := y - steps1;
                                         TracerX := 0;
                                         if TracerY < 0 then TracerY := 0;
                                         end;
           end else begin
             Dec(steps1);
              TracerY := y - steps1;
              TracerX := 0;
            end;
            p := @p6;
            Dec(steps);////////

                                            dec(count6);
                                            if Not (count6 = 0) then goto marking12;
                                            end;//11
                                    Bstep:=stepRare;//12
                                    BstepsFrequentCicles:=1;
                                    dec(count5);
                                    if Not (count5 = 0) then goto marking11;
                                    end;//13
                            BstepFrequent:=stepFrequent;//14
                            BstepsFrequentCicles:=stepsBig;
                            dec(count4);
                            if Not (count4 = 0) then goto marking10;
                            end;//15
                            BremainderstepsFrequentCicles:=1;//16
                            BstepsSetapInLine:=1;
                            Balternation:=1;
                            BstepsFrequentCicles:=remainderstepsFrequent;///16
                   dec(count3);
                   if Not (count3 = 0) then goto marking9;
                   end;//17
                   if  BremainderstepsFrequentCicles = 0 then  begin
                            BstepsSetapInLine:=1;
                            Balternation:=1;
                   end;
                   BstepFrequent:=remainder;//18
                   BremainderstepsFrequentCicles:=1;
                   BstepsFrequentCicles:=1;

          dec(count2);
          if Not (count2 = 0) then goto marking8;
          end;//19                                                     

I spent a considerable part of the weekend struggling with line 68, but I still couldn’t whitewash it, no matter how hard I tried. Still, language restrictions make themselves felt.

And I’ll mention line 71, which replaces the condition checking block with this part of it znak*sign(trunc((1+sign(y-trunc(y/(stepsBig+1))(stepsBig+1)-steps)/2))), I tried to create a “footcloth” from a list of conditions, but I always stumbled on something, I couldn’t stand it and simply described the conditions with mathematical functions. In short, it checks the condition of fitting one interval into another, and the sizes of both can change from case to case, and I didn’t have enough ability to describe it in just words. But I think that my organization of loops, in principle, makes it clear what I am striving for in my code. This is not about Pascal, and probably not at all suitable for current optimizations. As for the last mathematical expression given, in principle, any result of calculations automatically falls under setting the Zero flag to zero or one, and of course it’s a pity that the module Math does not do this with something enclosed in parentheses, but it would be exactly as it seems natural to me (because zero is the starting point, and the parameter is obviously known).

That’s all for now, I spent a lot of time with the rework, it’s a shame about line 68 from the last listing here, but nothing can be done. Generator project for Lazarustested on OS Ubuntu https://github.com/Andrei-Y/A-trace-map-generator/blob/main/generator_remake_public.zip

This is simply a stage of correcting the organization of loops due to the removal of unnecessary assembler, which helped me, at a minimum, in debugging mathematical expressions, at least what replaced the block of condition checks. That is, the angle from 0 before 90is entered into the first TEdit at the top, and the two below are the axis dimensions X And Y. That’s all I have for now. Probably this is still about algorithmization, but it’s unlikely that it would point to a specific programming language. But all programming languages ​​in one way or another strive for nature, which means this probably still somehow relates to their study. For me, for example, it is natural not to endow a machine with any super-complex all-replacing operations, since everything complex consists of simple things, which in reality are always studied and improved.

I hope that I have technically developed the main idea of ​​the map generator. It remains to finish it a little (add “symmetrical” calculations for angles from 90 before 180, and that’s all), the bulk of the time was spent on general debugging and not useless “wandering” with an assembler instead of a flashlight, and quite a bit on describing my wishes and ideas about the prospects of architectures and programming languages. I used the table to visualize the debugging process outside the debugger (the more debugging tools, the better).

That’s all for now, please forgive me if I took up someone’s time in vain. I wish everyone mutual understanding. Just for fun, I added another survey, with a slightly strange structure; if anything is wrong, I apologize.