/*

* Inspired by http://loopgame.co/
*/

Size = randint(3,16) spacing = 3.9 CF::MaxNatural = 2^30 CF::Background = [ b -1 ]

startshape Rows(0, Size) //startshape test

shape Rows(natural top, natural n) {

middle = bitand(randint(2^Size), bitnot(1))
bottom = if(n, randint(2^Size), 0)

Row(top,middle,bottom,Size) [ ]
if (n)
  Rows(bottom, n--1) [ y -spacing ]

}

shape Row(natural top, natural middle, natural bottom, natural expo) {

Cell(bitand(middle,1), bitand(top,1),
  bitand(middle,2), bitand(bottom,1)) []

if (expo)
  Row(div(top,2), div(middle,2), div(bottom,2),

expo–1) [ x spacing ] }

shape Cell(natural left, natural top, natural right, natural bottom) {

if (top && bottom && !left && !right)
  segment []

if (!top && !bottom && left && right)
  segment [ r 90 ]

if (bottom && right)
  turn_right [ ]

if (right && top)
  turn_right [ r 90 ]

if (top && left)
  turn_right [ r 180 ]

if (left && bottom)
  turn_right [ r -90 ]

if (left && !top && !right && !bottom)
  station [ r 90 ]

if (!left && top && !right && !bottom)
  station [ ]

if (!left && !top && right && !bottom)
  station [ r -90 ]

if (!left && !top && !right && bottom)
  station [ r 180 ]

//TestCell(left,top,right,bottom) []

}

path segment {

MOVETO(-0.5,-2)
LINETO(-0.5,2)
LINETO(0.5,2)
LINETO(0.5,-2)
FILL()[b 1]

MOVETO(0.5,-2)
LINEREL(0,4)
STROKE(0.1)[]

MOVETO(-0.5,-2)
LINEREL(0,4)
STROKE(0.1)[]

}

path turn_right {

MOVETO(-0.5, -2)
ARCTO(2, 0.5, 2.5, CF::ArcCW)
LINETO(2, -0.5)
ARCTO(0.5, -2, 1.5)
CLOSEPOLY()
FILL[b 1]

MOVETO(-0.5, -2)
ARCTO(2, 0.5, 2.5, CF::ArcCW)
STROKE(0.1)[]

MOVETO(0.5, -2)
ARCTO(2, -0.5, 1.5, CF::ArcCW)
STROKE(0.1)[]

}

path station {

ray = 0.65
h2 = 1.41

MOVETO(-0.5, 2)
LINETO(-0.5,h2)
ARCTO(0, -1.5, 1.5)
ARCTO(0.5, h2, 1.5)
LINETO(0.5, 2)

MOVETO(0, ray)
ARCTO(0, -ray, -ray)
ARCTO(0, ray, -ray)

FILL()[b 1]
STROKE(0.1, CF::RoundJoin)[]

}

shape TestCell(natural left, natural top, natural right, natural bottom) {

transform [ y 1 ]
if (top) {
  SQUARE [ ]
} else {
  CIRCLE [ ]
}

transform [ y -1 ]
if (bottom ) {
  SQUARE [ ]
} else {
  CIRCLE [ ]
}

transform [ x -1 ]
if (left ) {
  SQUARE [ ]
} else {
  CIRCLE [ ]
}

transform [ x 1 ]
if (right) {
  SQUARE [ ]
} else {
  CIRCLE [ ]
}

}

shape test {

 Cell(0,0,0,0)[ x 0]
 Cell(0,0,0,1)[ x 8 ]
 Cell(0,0,1,0)[ x 16 ]
 Cell(0,0,1,1)[ x 24 ]

 transform [ y 8 ] {
 Cell(0,1,0,0)[ x 0 ]
 Cell(0,1,0,1)[ x 8 ]
 Cell(0,1,1,0)[ x 16 ]
 Cell(0,1,1,1)[ x 24 ]
 }
 transform [ y 16 ] {
 Cell(1,0,0,0)[ x 0]
 Cell(1,0,0,1)[ x 8 ]
 Cell(1,0,1,0)[ x 16 ]
 Cell(1,0,1,1)[ x 24 ]

 transform [ y 8 ] {
 Cell(1,1,0,0)[ x 0 ]
 Cell(1,1,0,1)[ x 8 ]
 Cell(1,1,1,0)[ x 16 ]
 Cell(1,1,1,1)[ x 24 ]
 }
}

}