[Question]
  [
> 
> This challenge is inspired from [this](https://askubuntu.com/a/699587) answer at the Ask Ubuntu Stack Exchange.
> 
> 
> 
# Intro
Remember the [Windows ME screensaver with the pipes](https://www.youtube.com/watch?v=Uzx9ArZ7MUU)? Time to bring the nostalgia back!
[![enter image description here](https://i.stack.imgur.com/U5PrJ.gif)](https://i.stack.imgur.com/U5PrJ.gif)
# Challenge
You should write a program or function which will output an ASCII representation of the screensaver. In the screensaver there should be a single pipe which will grow in semi-random directions.  
The start of the pipe will be randomly placed at any of the borders of the screen and the pipe piece should be perpendicular to the border (corner first-pipes can either be horizontal or vertical). Each tick the pipe will grow in the direction it is facing (horizontal/vertical) at an `80%` chance or take a corner at a `20%` chance.
# Pipe representation
To create the pipe, 6 unicode characters will be used
```
─    \u2500    horizontal pipe
│    \u2502    vertical pipe
┌    \u250C    upper left corner pipe
┐    \u2510    upper right corner pipe
└    \u2514    lower left corner pipe
┘    \u2518    lower right corner pipe
```
# Input
The program / function will take 3 values of input, which can be gathered through function parameters or prompted to the user.
* Amount of ticks
* Screen width
* Screen height
### Amount of ticks
For every tick, a piece of pipe will be added to the screen. Pipes will overwrite old pipe pieces if they spawn at the same position.
For example, take a screen of size 3x3
```
ticks == 3
─┐ 
 ┘ 
ticks == 4
─┐ 
└┘ 
ticks == 5
│┐ 
└┘ 
```
Whenever a pipe exits the screen, as in the last example at 5 ticks, then a new pipe will spawn at a random border. For example:
```
ticks == 6
│┐ 
└┘ 
  ─
```
The new pipe should have a 50% chance of being horizontal or vertical.
### Screen width/height
The screen width and height can be combined into a single value if that's preferrable in your language of choice. The screen width and height will always have a minimum value of 1 and a maximum value of 255. If your language of choice supports a console or output screen which is smaller than a 255x255 grid of characters then you may assume that the width and height will never exceed the boundaries of your console. (Example: Windows 80x25 cmd window)
# Output
The output of your program/function should be printed to the screen, or returned from a function. For every run of your program, a different set of pipes should be generated.
# Test cases
The following test cases are all random examples of valid outputs
```
f(4, 3, 3)
 │
─┘
  │
f(5, 3, 3)
 │
─┘┌
  │
f(6, 3, 3)
─│
─┘┌
  │
f(7, 3, 3)
──
─┘┌
  │
```
Obviously, the more ticks that have occured, the harder it becomes to prove the validity of your program. Hence, posting a gif of your output running will be preferred. If this is not possible, please post a version of your code which includes printing the output. Obviously, this will not count towards your score.
# Rules
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), shortest amount of bytes wins
* Standard loopholes apply
* If you use the unicode pipe characters in your source code, you may count them as a single byte
This is quite a hard challenge that can possibly be solved in many creative ways, you are encouraged to write an answer in a more verbose language even though there are already answers in short esolangs. This will create a catalog of shortest answers per language. Bonus upvotes for fancy coloured gifs ;)
Happy golfing!
Disclaimer: I am aware that Unicode characters aren't ASCII, but in lack of a better name I just call it ASCII art. Suggestions are welcome :)
  
[Answer]
Nothing says nostalgia quite like...
## QBasic, 332 bytes
```
INPUT t,w,h
RANDOMIZE
CLS
1b=INT(RND*4)
d=b
IF b MOD 2THEN c=(b-1)/2*(w-1)+1:r=1+INT(RND*h)ELSE c=1+INT(RND*w):r=b/2*(h-1)+1
WHILE t
LOCATE r,c
m=(b+d)MOD 4
IF b=d THEN x=8.5*m ELSE x=13*m+(1<((b MOD m*3)+m)MOD 5)
?CHR$(179+x);
r=r-(d-1)MOD 2
c=c-(d-2)MOD 2
b=d
d=(4+d+INT(RND*1.25-.125))MOD 4
t=t-1
IF(r<=h)*(c<=w)*r*c=0GOTO 1
WEND
```
QBasic is the right language for the task because:
* Its encoding includes box drawing characters--no need for Unicode
* `LOCATE` allows you to print to any location on the screen, overwriting what was there previously
* Microsoft®
### Specifics
This is golfed QBasic, written and tested on [QB64](http://qb64.net) with autoformatting turned off. If you type/paste it into the actual QBasic IDE, it will add a bunch of spaces and expand `?` into `PRINT`, but it should run exactly the same.
The program inputs three comma-separated values: ticks, width, and height. It then asks for a random-number seed. (If this behavior isn't acceptable, change the second line to `RANDOMIZE TIMER` for +6 bytes.) Finally, it draws the pipes to the screen.
The maximum dimensions that can be entered are 80 (width) by 25 (height). Giving a height of 25 will result in the bottom row getting cut off when QBasic says "Press any key to continue."
### How?
TL;DR: A lot of math.
The current row and column are `r` and `c`; the current direction is `d` and the previous direction is `b`. Direction values 0-3 are down, right, up, left. Arithmetic translates those into the correct step values for `r` and `c`, as well as the correct edge coordinates to start on.
The box drawing characters `│┐└─┘┌` are code points 179, 191, 192, 196, 217, and 218 in QBasic. Those appear pretty random, but it still used fewer characters to generate the numbers with some (pretty convoluted, I'm-not-sure-even-I-understand-it) math than to do a bunch of conditional statements.
The code for changing direction generates a random number between -0.125 and 1.125 and takes its floor. This gives `-1` 10% of the time, `0` 80% of the time, and `1` 10% of the time. We then add this to the current value of `d`, mod 4. Adding 0 keeps the current direction; adding +/-1 makes a turn.
As for control flow, the `WHILE t ... WEND` is the main loop; the section before it, starting with line number `1` (`1b=INT(RND*4)`), restarts the pipe at a random edge. Whenever `r` and `c` are outside the window, we `GOTO 1`.
### Show me the GIF!
Here you go:
[![Pipes!](https://i.stack.imgur.com/Ir5gg.gif)](https://i.stack.imgur.com/Ir5gg.gif)
This was generated by a somewhat ungolfed version with animation, color, and an automatic random seed:
```
INPUT t, w, h
RANDOMIZE TIMER
CLS
restart:
' Calculate an edge to start from
b = INT(RND * 4)
'0: top edge (moving down)
'1: left edge (moving right)
'2: bottom edge (moving up)
'3: right edge (moving left)
d = b
' Calculate column and row for a random point on that edge
IF b MOD 2 THEN
    c = (b - 1) / 2 * (w - 1) + 1
    r = 1 + INT(RND * h)
ELSE
    c = 1 + INT(RND * w)
    r = b / 2 * (h - 1) + 1
END IF
COLOR INT(RND * 15) + 1
WHILE t
    ' Mathemagic to generate the correct box-drawing character
    m = (b + d) MOD 4
    IF b = d THEN
        x = 17 * m / 2
    ELSE
        x = 13 * m + (1 < ((b MOD m * 3) + m) MOD 5)
    END IF
    LOCATE r, c
    PRINT CHR$(179 + x);
    ' Update row and column
    r = r - (d - 1) MOD 2
    c = c - (d - 2) MOD 2
    ' Generate new direction (10% turn one way, 10% turn the other way,
    ' 80% go straight)
    b = d
    d = (4 + d + INT(RND * 1.25 - .125)) MOD 4
    ' Pause
    z = TIMER
    WHILE TIMER < z + 0.01
        IF z > TIMER THEN z = z - 86400
    WEND
    t = t - 1
    IF r > h OR c > w OR r = 0 OR c = 0 THEN GOTO restart
WEND
```
[Answer]
# JavaScript (ES6), 264 ~~266 274 281~~
```
(t,w,h,r=n=>Math.random()*n|0,g=[...Array(h)].map(x=>Array(w).fill` `))=>((y=>{for(x=y;t--;d&1?y+=d-2:x+=d-1)x<w&y<h&&~x*~y?0:(d=r(4))&1?x=r(w,y=d&2?0:h-1):y=r(h,x=d?0:w-1),e=d,d=r(5)?d:2*r(2)-~d&3,g[y][x]="─└ ┌┐│┌  ┘─┐┘ └│"[e*4|d]})(w),g.map(x=>x.join``).join`
`)
```
Counting unicode drawing characters as 1 byte each. (As specified by OP)
*Less golfed*
```
(t,w,h)=>{
  r=n=>Math.random()*n|0; // integer range random function
  g=[...Array(h)].map(x=>Array(w).fill(' ')); // display grid
  for (x=y=w;t--;)
    x<w & y<h && ~x*~y||( // if passed boundary
      d = r(4), // select random direction
      d & 1? (x=r(w), y=d&2?0:h-1) : (y=r(h), x=d?0:w-1) // choose start position 
    ),
    e=d, d=r(5)?d:2*r(2)-~d&3, // change direction 20% of times
    g[y][x]="─└ ┌┐│┌  ┘─┐┘ └│"[e*4|d], // use char based on current+prev direction
    d&1 ? y+=d-2 : x+=d-1 // change x,y position based on direction
  return g.map(x=>x.join``).join`\n`
}
```
**Animated test**
Note: trying to keep the animation time under 30 sec,more thicks make animation pace faster
```
f=(t,w,h,r=n=>Math.random()*n|0,g=[...Array(h)].map(x=>Array(w).fill` `))=>
{
  z=[]
  for(x=y=w;t--;d&1?y+=d-2:x+=d-1)
    x<w&y<h&&~x*~y?0:(d=r(4))&1?x=r(w,y=d&2?0:h-1):y=r(h,x=d?0:w-1),
    e=d,d=r(5)?d:2*r(2)-~d&3,g[y][x]="─└ ┌┐│┌  ┘─┐┘ └│"[e*4|d],
    z.push(g.map(x=>x.join``).join`\n`)
  return z
}
function go() {
  B.disabled=true
  var [t,w,h]=I.value.match(/\d+/g)
  var r=f(+t,+w,+h)
  O.style.width = w+'ch';
  var step=0
  var animate =_=>{
    S.textContent = step
    var frame= r[step++]
    if (frame) O.textContent = frame,setTimeout(animate, 30000/t);
    else   B.disabled=false
  }
  
  animate()
}
go()
```
```
#O { border: 1px solid #000 }
```
```
Input - ticks,width,height
<input value='600,70,10' id=I><button id=B onclick='go()'>GO</button>
<span id=S></span>
<pre id=O></pre>
```
[Answer]
### Python 2.7, ~~624~~ ~~616~~ ~~569~~ ~~548~~ 552 bytes
```
from random import*
from time import*
i=randint
z=lambda a,b:dict(zip(a,b))
c={'u':z('lur',u'┐│┌'),'d':z('ldr',u'┘│└'),'l':z('uld',u'└─┌'),'r':z('urd',u'┘─┐')}
m=z('udlr',[[0,-1],[0,1],[-1,0],[1,0]])
def f(e,t,w,h):
 seed(e);s=[w*[' ',]for _ in' '*h]
 while t>0:
  _=i(0,1);x,y=((i(0,w-1),i(0,1)*(h-1)),(i(0,1)*(w-1),i(0,h-1)))[_];o=('du'[y>0],'rl'[x>0])[_]
  while t>0:
   d=c[o].keys()[i(7,16)//8];s[y][x]=c[o][d];x+=m[d][0];y+=m[d][1];t-=1;sleep(.5);print'\n'.join([''.join(k)for k in s]);o=d
   if(x*y<0)+(x>=w)+(y>=h):break
```
The first parameter is a seed, same seeds will generate the same output, printing each step with a 500 ms delay.
* **-10 bytes** thanks to @TuukkaX
[repl it](https://repl.it/Dbai/1)
Example run
```
f(5,6,3,3)
```
will output
```
   
  ┐
```
```
   
 ─┐ 
```
```
   
──┐ 
```
```
   
┘─┐ 
```
```
   
┐  
┘─┐ 
```
verbose version 
```
import random as r
from time import *
char={
'u':{'u':'│','l':'┐','r':'┌'},
'd':{'d':'│','l':'┘','r':'└'},
'l':{'u':'└','d':'┌','l':'─'},
'r':{'u':'┘','d':'┐','r':'─'}
}
move={'u':[0,-1],'d':[0,1],'l':[-1,0],'r':[1,0]}
def f(seed,steps,w,h):
 r.seed(seed)
 screen=[[' ',]*w for _ in ' '*h]
 while steps > 0:
  if r.randint(0,1):
   x,y=r.randint(0,w-1),r.randint(0,1)*(h-1)
   origin='du'[y>0]  
  else:
   x,y=r.randint(0,1)*(w-1),r.randint(0,h-1)
   origin = 'rl'[x>0]
  while steps > 0:
   direction = char[origin].keys()[r.randint(0,2)]
   screen[y][x]=char[origin][direction]
   x+=move[direction][0]
   y+=move[direction][1]
   steps-=1
   sleep(0.5)
   print '\n'.join([''.join(k) for k in screen]),''
   if x<0 or y<0 or x>=w or y>=h:
    break
   origin=direction
```
[Answer]
# C (GCC/linux), 402 353 352 302 300 298 296 288 bytes
```
#define R rand()%
x,y,w,h,r;main(c){srand(time(0));scanf(
"%d%d",&w,&h);for(printf("\e[2J");x%~w*
(y%~h)||(c=R 8,(r=R 4)&1?x=1+R w,y=r&2
?1:h:(y=1+R h,x=r&2?1:w));usleep('??'))
printf("\e[%dm\e[%d;%dH\342\224%c\e[H\n",
30+c,y,x,2*"@J_FHAF__L@HL_JA"[r*4|(r^=R 5
?0:1|R 4)]),x+=--r%2,y+=~-r++%2;}
```
Credit to edc65 for storing the direction in a single 4-bit number.
Reads a width/height on stdin before looping the screensaver forever. E.g.:
```
gcc -w golf.c && echo "25 25" | ./a.out
```
Or for a full-screen screensaver:
```
gcc -w golf.c && resize | sed 's/[^0-9]*//g' | ./a.out
```
For readability I added newlines. Requires a linux machine with a terminal respecting ANSI codes. Has colors! If you remove color support it costs 17 bytes less.
[![example](https://i.stack.imgur.com/0oHTf.png)](https://i.stack.imgur.com/0oHTf.png)
[Answer]
# Ruby, ~~413~~ ~~403~~ 396 bytes
![Ruby pipes](https://i.stack.imgur.com/TwPXp.gif)
A function that takes a number of ticks and a width as input and returns the final screen as a string. Could no doubt be golfed more.
```
->t,w{k=[-1,0,1,0,-1]
b=(" "*w+$/)*w
f=->t,a=[[0,m=rand(w),2],[w-1,m,0],[m,0,1],[m,w-1,3]].sample{n,m,i=a
d=k[i,2]
q=->n,m,i{_,g,j=rand>0.2?[[1,0],[3,0],[0,1],[2,1]].assoc(i):"021322033132243140251350".chars.map(&:to_i).each_slice(3).select{|c,|c==i}.sample
v,u=k[j||=i,2]
y=n+v
x=m+u
[g,y,x,j]}
g,y,x,j=q[n,m,i]
b[n*w+n+m]="─│┌┐┘└"[g]
y>=0&&y<w&&x>=0&&x<w ?t>1?f[t-1,[y,x,j]]:b:f[t]}
f[t]}
```
See it on repl.it: <https://repl.it/Db5h/4>
In order to see it in action, insert the following after the line that begins `b[n*w+n+m]=`:
```
puts b; sleep 0.2
```
...then assign the lambda to a variable e.g. `pipes=->...` and call it like `pipes[100,20]` (for 100 ticks and a 20x20 screen).
## Ungolfed & explanation
```
# Anonymous function
# t - Number of ticks
# w - Screen width
->t,w{
  # The cardinal directions ([y,x] vectors)
  # Up = k[0..1], Right = k[1..2] etc.
  k = [-1, 0, 1, 0, -1]
  # An empty screen as a string
  b = (" " * w + $/) * w
  # Main tick function (recursive)
  # t - The number of ticks remaining
  # a - The current position and vector index; if not given is generated randomly
  f = ->t,a=[[0,m=rand(w),2], [w-1,m,0], [m,0,1], [m,w-1,3]].sample{
    # Current row, column, and vector index
    n, m, i = a
    d = k[i,2] # Get vector by index
    # Function to get the next move based on the previous position (n,m) and direction (d)
    q = ->n,m,i{
      # Choose the next pipe (`g` for glyph) and get the subsequent vector index (j)
      _, g, j = (
        rand > 0.2 ?
          [[1,0], [3,0], [0,1], [2,1]].assoc(i) : # 80% of the time go straight
          "021322033132243140251350".chars.map(&:to_i).each_slice(3)
            .select{|c,|c==i}.sample
      )
      # Next vector (`v` for vertical, `u` for horizontal)
      # If straight, `j` will be nil so previous index `i` is used
      v, u = k[j||=i, 2]
      # Calculate next position
      y = n + v
      x = m + u
      # Return next glyph, position and vector index
      [g, y, x, j]
    }
    # Get next glyph, and subsequent position and vector index
    g, y, x, j = q[n, m, i]
    # Draw the glyph
    b[n * w + n + m] = "─│┌┐┘└"[g]
    # Check for out-of-bounds
    y >= 0 && y < w && x >=0 && x < w ?
      # In bounds; check number of ticks remaining
      t > 1 ?
        f[t-1, [y,x,j]] : # Ticks remain; start next iteration
        b : # No more ticks; return final screen
      # Out of bounds; repeat tick with new random start position
      f[t]
  }
  f[t]
}
```
]