jsonpiler 0.11.0

a Json syntax programming language for Windows
Documentation
define(square, { n: Float }, Float, n * n)
global(ball_x) = 0.0
global(ball_y) = 0.0
global(ball_vx) = -15.0
global(ball_vy) = 10.0
global(score_p1) = 0
global(score_p2) = 0
global(pos_p1) = 0.0
global(width) = 512.0
global(height) = 512.0
global(paddle_w) = 8.0
global(paddle_h) = 64.0
global(ball_r) = 20.0
global(left_x) = width / -2.0
global(right_x) = width / 2.0
global(paddle_w_half) = 4
global(p_h_half) = paddle_h / 2.0
global(collision_x) = height / 2.0 - ball_r
global(p1_surface) = left_x + paddle_w
global(p1_cx) = -252
global(p2_surface) = right_x - paddle_w
global(p2_cx) = 252
global(p1_cy) = 0.0
import("random.jspl", rand_range)
define(in_bounds, { center: Int; radius: Int; pos: Int }, Bool,
  abs(pos - center) <= radius
)
define(in_bounds_f, { center: Float; radius: Float; pos: Float }, Bool,
  abs(pos - center) <= radius
)
define(rgb, { r: Int; g: Int; b: Int }, Int, r * 256 * 256 + g * 256 + b)
define(paddle_hit, { p_surface: Float; p_cy: Float; dir: Int }, Bool,
{
  let(dx) = ball_x - p_surface
  let(p_bottom) = p_cy - p_h_half
  let(p_top) = p_cy + p_h_half
  let(dy_bottom) = ball_y - p_bottom
  let(dy_top) = ball_y - p_top
  let(rect_x_ok) = in_bounds_f(p_surface, ball_r, ball_x)
  let(rect_y_ok) = in_bounds_f(p_cy, p_h_half, ball_y)
  let(collision_surface) = rect_x_ok and rect_y_ok
  let(d2_corner_bottom) = square(dx) + square(dy_bottom)
  let(d2_corner_top) = square(dx) + square(dy_top)
  if(
    [
      {
        collision_surface
      } or {
        d2_corner_bottom <= square(ball_r)
      } or {
        d2_corner_top <= square(ball_r)
      },
    {
      let(speed) = sqrt(square(ball_vx) + square(ball_vy))
      speed *= 1.05
      let(hit_pos) = { ball_y - p_cy } / p_h_half
      hit_pos = if([ hit_pos > 0.9, 0.9 ], [ hit_pos < -0.9, -0.9 ], [ true, hit_pos ])
      ball_vy = hit_pos * speed
      ball_vx = abs(sqrt(square(speed) - square(ball_vy))) * Float(dir)
      ball_x = p_surface + ball_r * Float(dir)
      true
    }
    ],
    [ true, false ]
  )
}
)
define(in_score_cell, { x: Int; y: Int; score: Int; invert_x: Bool }, Bool,
{
  let(score_per_line) = 5
  let(base_x) = -248
  let(base_y) = 248
  if(invert_x, base_x *= -1)
  let(score_size) = 24
  let(spacing) = 8
  let(score_span) = score_size + spacing
  let(row) = { base_y - y } / score_span
  let(column) = 0
  let(paddle_surface) = x - base_x
  if(invert_x, paddle_surface *= -1)
  column = { paddle_surface / score_span } % score_per_line
  let(index) = row * score_per_line + column
  let(cell_y) = base_y - row * score_span - score_size
  let(cell_offset) = column * score_span
  let(cell_x) = base_x
  if([ invert_x, cell_x -= cell_offset + score_size ], [ true, cell_x += cell_offset ])
  let(in_cell_x) = x + 1 - score_size <= cell_x <= x
  let(in_cell_y) = y + 1 - score_size <= cell_y <= y
  if(index < score and in_cell_x and in_cell_y, ret(true))
  false
}
)
define(update, { p2_cy: Int }, Null,
{
  ball_x += ball_vx
  ball_y += ball_vy
  let(follow_ratio) = { 256.0 - ball_x } / 1024.0
  p1_cy = { pos_p1 + follow_ratio * ball_y } / { 1.0 + follow_ratio }
  if(
    [ pos_p1 - p1_cy > 16.0, p1_cy = pos_p1 - 16.0 ],
    [ pos_p1 - p1_cy < -16.0, p1_cy = pos_p1 + 16.0 ]
  )
  pos_p1 = p1_cy
  paddle_hit(p1_surface, p1_cy, 1)
  paddle_hit(p2_surface, Float(p2_cy), -1)
  ball_y = if(
    [ ball_y < -(collision_x), { ball_vy *= -1.0; -(collision_x) } ],
    [ ball_y > collision_x, { ball_vy *= -1.0; collision_x } ],
    [ true, ball_y ]
  )
  let(left_pass) = ball_x + ball_r < left_x
  let(right_pass) = ball_x - ball_r > right_x
  if(left_pass,
  {
    score_p2 += 1
    ball_x = 0.0
    ball_y = 0.0
    ball_vx = 15.0
    ball_vy = Float(rand_range(21) - 10)
  }
  )
  if(right_pass,
  {
    score_p1 += 1
    ball_x = 0.0
    ball_y = 0.0
    ball_vx = -15.0
    ball_vy = Float(rand_range(21) - 10)
  }
  )
}
)
define(in_rect, { x: Int; y: Int; cx: Int; cy: Int }, Bool,
  in_bounds(cx, paddle_w_half, x) and in_bounds(cy, Int(p_h_half), y)
)
define(ping_pong, { x: Int; y: Int; _frame: Int; _mx: Int; p2_cy: Int }, Int,
{
  if(x == y == -256, update(p2_cy))
  let(ball_d2) = square(Float(x) - ball_x) + square(Float(y) - ball_y)
  if(ball_d2 < square(ball_r), ret(rgb(255, 255, 0)))
  if(in_rect(x, y, p1_cx, Int(p1_cy)), ret(rgb(0, 255, 255)))
  if(in_rect(x, y, p2_cx, p2_cy), ret(rgb(255, 0, 255)))
  if(in_score_cell(x, y, score_p2, true), ret(rgb(255, 0, 255)))
  if(in_score_cell(x, y, score_p1, false), ret(rgb(0, 255, 255)))
  let(in_center_line) = x == 0 and { { abs(y) + 8 } / 16 } % 2 == 0
  if([ in_center_line, rgb(255, 255, 255) ], [ true, rgb(0, 0, 0) ])
}
)
main(
{
  GUI(ping_pong)
  print("CPU Score: ", Str(score_p1), "\n")
  print("Player Score: ", Str(score_p2), "\n")
}
)