1. Pascal / Говнокод #12272

    +91

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    procedure RecursiveVisibility(e : PCreature; oct, depth : integer; slopeA, slopeB : single);
    var
      x, y : integer;
    begin
      case oct of
        1 : begin
          y := e^.y - depth;                                                { initialize y }
          x := round(e^.x - slopeA * depth);                                { initialize z }
          while GetSlopeStd(x, y, e^.x, e^.y) >= slopeB do begin            { while in octant }
            if GetVisDistance(x, y, e^.x, e^.y) <= mw then begin            { if within max visual range }
              if WorldSurface[x, y].entity^.obstruct then begin             { if obstruction }
                if not WorldSurface[x - 1, y].entity^.obstruct then begin   { if no prior obstruction }
                  RecursiveVisibility(e, 1, depth + 1, slopeA, GetSlopeStd(x - 0.5, y + 0.5, e^.x, e^.y));
                end;                                                        { ^create recursive scan }
              end else begin                                                { no obstruction }
                if WorldSurface[x - 1, y].entity^.obstruct then begin       { if prior obstruction }
                  slopeA := GetSlopeStd(x - 0.5, y - 0.5, e^.x, e^.y);      { adjust slope for later recursion }
                end;
              end;
              WorldSurface[x, y].visibility := 3;                           { set block visible }
            end;
            inc(x);
          end;
          dec(x)
        end;
        2 : begin
          y := e^.y - depth;                                                { initialize y }
          x := round(e^.x + slopeA * depth);                                { initialize z }
          while GetSlopeStd(x, y, e^.x, e^.y) <= slopeB do begin            { while in octant }
            if GetVisDistance(x, y, e^.x, e^.y) <= mw then begin            { if within max visual range }
              if WorldSurface[x, y].entity^.obstruct then begin             { if obstruction }
                if not WorldSurface[x + 1, y].entity^.obstruct then begin   { if no prior obstruction }
                  RecursiveVisibility(e, 2, depth + 1, slopeA, GetSlopeStd(x + 0.5, y + 0.5, e^.x, e^.y));
                end;                                                        { ^create recursive scan }
              end else begin                                                { no obstruction }
                if WorldSurface[x + 1, y].entity^.obstruct then begin       { if prior obstruction }
                  slopeA := -GetSlopeStd(x + 0.5, y - 0.5, e^.x, e^.y);     { adjust slope for later recursion }
                end;
              end;
              WorldSurface[x, y].visibility := 3;                           { set block visible }
            end;
            dec(x);
          end;
          inc(x)
        end;
     // Далее всё в таком же духе.

    Отсюда: http://roguebasin.roguelikedevelopment.org/index.php?title=FOV_using_recursive_shad owcasting_-_improved
    Можно было сделать менее говнокодистей?

    Запостил: Govnocoder#0xFF, 11 Декабря 2012

    Комментарии (9) RSS

    • Пожалуй, тут трудно что-то усовершенствовать, ведь, во-первых, подвыражения в выражениях вычисляются в циклах, потому GetSlopeStd(x, y, e^.x, e^.y) не вынесешь в какую-то общую переменную; во-вторых, переменным даны вполне осмысленные имена; а в-третьих все действия подробно и красиво прокомментированы.
      Потому этот фрагмент я бы говнокодом не назвал.
      Ответить
    • Можно не делать копипасту из 4х похожих участков, если ввести вспомогательный массив
      const dx : array [0..3] of integer = (0,1,0,-1);
      const dy : array [0..3] of integer = (1,0,-1,0);
      Ответить
      • Массивы не нужны. Можно обойтись джвумя флагами.
        Направление и знак. Как в векторе.
        Использовать тот факт, что
        X ⊕ Y = 1.
        Ответить
        • > Можно обойтись джвумя флагами.
          Да, но зачем?
          Ответить
          • Кода меньше. Удобней.
            Ответить
            • И как же?
              Ответить
              • Экзаменатор спрашивает студента: — Расскажите мне, как работает трансформатор.
                — Ж-ж-ж.
                — Два. Неправильно. Трансформатор работает так: у-у-у.
                Ответить
    • Всем +1 за мой счёт ИТТ!
      Ответить
    • - Так, значит, у тебя всё? - янтарный взгляд погас.
      Ответить

    Добавить комментарий