Ineluki80

Turtle.awk - ProgForum 2013 Contest

Mar 25th, 2013
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Awk 4.34 KB | None | 0 0
  1. #!/usr/bin/awk -f
  2.  
  3. function begin_SVG() {
  4.   print "<?xml version='1.0' encoding='UTF-8'?>";
  5.   print "  <!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>";
  6.   print "";
  7.   print "<svg xmlns='http://www.w3.org/2000/svg'";
  8.   print "     xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:ev='http://www.w3.org/2001/xml-events'";
  9.   print "     version='1.1' baseProfile='tiny'";
  10.   print "     width='800px' height='800px'";
  11.   print "     viewBox='-1.02 -1.02 2.04 2.04'";
  12.   print "     >";
  13.   print "";
  14.   print "  <rect x='-1.01' y='-1.01' width='2.02' height='2.02' stroke='black' stroke-width='0.25%' fill='none'  />";
  15.   print "  <g stroke='black' stroke-width='0.2%' fill='none' transform='scale( 1 -1 )' stroke-linecap='round' >";
  16.   print "";
  17. }
  18.  
  19. function end_SVG() {
  20.   print "";
  21.   print "  </g>";
  22.   print "</svg>";
  23.   print "";  
  24. }
  25.  
  26. function initTurtle() {
  27.   last_action="";
  28.   stack = 1;
  29.   X[stack] = 0.0;
  30.   Y[stack] = 0.0;
  31.   A[stack] = 90.0;  
  32.   L[stack] = 1.0;
  33.   D[stack] = 90.0;  
  34.   C[stack] = 0;
  35.   setFactor();
  36. }
  37.  
  38. function push() {
  39.   stack++;
  40.   X[stack] = X[stack-1];  # X position
  41.   Y[stack] = Y[stack-1];  # Y position
  42.   A[stack] = A[stack-1];  # moving Angle
  43.   F[stack] = F[stack-1];  # Factor
  44.   L[stack] = L[stack-1];  # Length
  45.   D[stack] = D[stack-1]   # Delta angle
  46.   C[stack] = C[stack-1];  # Colour
  47. }
  48.  
  49. function pop() {
  50.   closePath();
  51.   stack--;
  52.   if (stack < 1) {
  53.     stack = 1;
  54.   }
  55.   openPath();
  56. }
  57.  
  58. function getColour(c) {
  59.   if ( c == 0 ) return "Black";
  60.   if ( c == 1 ) return "Red";
  61.   if ( c == 2 ) return "Green";
  62.   if ( c == 3 ) return "Yellow";
  63.   if ( c == 4 ) return "Blue";
  64.   if ( c == 5 ) return "Magenta";
  65.   if ( c == 6 ) return "Cyan";
  66.   if ( c == 7 ) return "White";
  67.   if ( c ~ /^#[0-9A-Fa-f]+$/ ) return c;
  68.   return "YellowGreen";
  69. }
  70.  
  71. function setColour(c) {
  72.   closePath();
  73.   C[stack] = c;
  74.   openPath();
  75. }
  76.  
  77. function nextColour() {
  78.   setColour((C[stack]+1)%7);
  79. }
  80.  
  81. function mulLength() {
  82.   L[stack] *= F[stack];
  83. }
  84.  
  85. function divLength() {
  86.   L[stack] /= F[stack];
  87. }
  88.  
  89. function turnLeft() {
  90.   updateSVG("turn");
  91.   A[stack] += D[stack];
  92. }
  93.  
  94. function turnRight() {
  95.   updateSVG("turn");
  96.   A[stack] -= D[stack];
  97. }
  98.  
  99. function mulAngle() {
  100.   D[stack] *= F[stack];
  101. }
  102.  
  103. function divAngle() {
  104.   D[stack] /= F[stack];
  105. }
  106.  
  107. function incFactor() {
  108.   F[stack]++;
  109. }
  110.  
  111. function decFactor() {
  112.   F[stack]--;
  113. }
  114.  
  115. function setFactor() {
  116.   F[stack] = 2;
  117. }
  118.  
  119. function openPath() {
  120.   print  "    <path stroke='" getColour(C[stack]) "' d='" ;
  121. #  print  "      M " X[stack] "," Y[stack] " " ;  
  122.   last_action = "move"
  123. }
  124.  
  125. function closePath() {
  126.   updateSVG("");
  127.   print "    ' />" ;
  128. }
  129.  
  130. function updateSVG(action) {
  131.   if ( action != last_action ) {
  132.     if ( last_action == "move" ) {
  133.       printf("      M %10.5f,%10.5f\n", X[stack], Y[stack]);
  134.     } else
  135.     if ( last_action == "draw" ) {
  136.       printf("      L %10.5f,%10.5f\n", X[stack], Y[stack]);
  137.     }
  138.     last_action = action;
  139.   }
  140. }
  141.  
  142. function move() {
  143.   updateSVG("move");
  144.   X[stack] += L[stack] * cos(A[stack]*PI/180.0);
  145.   Y[stack] += L[stack] * sin(A[stack]*PI/180.0);  
  146. }
  147.  
  148. function draw() {
  149.   updateSVG("draw");
  150.   X[stack] += L[stack] * cos(A[stack]*3.1415927/180.0);
  151.   Y[stack] += L[stack] * sin(A[stack]*3.1415927/180.0);
  152. }
  153.  
  154. BEGIN {
  155.   PI = 3.14159265359;
  156.   IGNORECASE = 1;
  157.   initTurtle();
  158.   begin_SVG();
  159.   openPath();
  160. }
  161.  
  162. # for each line in the source code
  163. {
  164.   # split line into characters
  165.   split($0, chars, "");
  166.  
  167.   # for each character
  168.   for ( i=1; i<=length(chars); ++i) {
  169.          if (chars[i] == "F") draw();
  170.     else if (chars[i] == "X") move();
  171.     else if (chars[i] == "*") mulLength();
  172.     else if (chars[i] == "/") divLength();
  173.     else if (chars[i] == "+") turnLeft();
  174.     else if (chars[i] == "-") turnRight();
  175.     else if (chars[i] == ">") mulAngle();
  176.     else if (chars[i] == "<") divAngle();
  177.     else if (chars[i] == "!") incFactor();
  178.     else if (chars[i] == "?") decFactor();
  179.     else if (chars[i] == "$") setFactor();
  180.     else if (chars[i] == "[") push();
  181.     else if (chars[i] == "]") pop();
  182.     else if (chars[i] == "@") nextColour();
  183.     else if (chars[i] == "#") { setColour(substr($0,i,7)); i+=6; continue; }
  184.     else if (chars[i] >= 0 \
  185.           && chars[i] <= 7)   setColour(chars[i]);
  186.   }
  187. }
  188.  
  189. END {
  190.   closePath();
  191.   end_SVG();
  192. }
Advertisement
Add Comment
Please, Sign In to add comment