#!/usr/bin/env stap
# jewel eater
# Copyright (C) 2008 Masami Hiramatsu <masami.hiramatsu@gmail.com>
#
# This file is free software and is distributed under the terms of the GNU
# General Public License (GPL); either version 2, or (at your option) any
# later version.

#TODO:
# - power jewel
# - increase snakes
# - don't stop eater
# - shortcut corner

global pm=0, px=10, py=10, jewels=0
global pkm[4], mv, map, data, sx, sy, sm, _c
global ph = 0

probe begin {
  pkm[0] = ">"
  pkm[1] = "<"
  pkm[2] = "V"
  pkm[3] = "A"
  data[1]  = "#######################"
  data[2]  = "##...................##"
  data[3]  = "#..#.###.#####.###.#..#"
  data[4]  = "#.##.o.#.......#.o.##.#"
  data[5]  = "#.####.#.#####.#.####.#"
  data[6]  = "#.....................#"
  data[7]  = "###.####.## ##.####.###"
  data[8]  = "##.......##U##.......##"
  data[9]  = "#..#.###.#####.#.###..#"
  data[10] = "#.##.o.#.......#.o.##.#"
  data[11] = "#.####.#.#####.###.##.#"
  data[12] = "#.....................#"
  data[13] = "#######################"
  cursor_cls()

  for (y=1;y<14;y++) {
    x=0
    c = substr(data[y], x, 1)
    cursor_move(x+1,y)
    while (c!="") {
      x++
      map[x,y] = c
      print(c)
      c = substr(data[y], x, 1)
      if (c == ".")
        jewels++
      if (c == "U") {
        sx[0]=x;sy[0]=y
        sx[1]=x;sy[1]=y
      }
    }
  }
}

probe game.kbd {
  if (down) {
    mv = 1
    if (code == GM_KBD_LEFT)
      pm = 0
    else if (code == GM_KBD_RIGHT)
      pm = 1
    else if (code == GM_KBD_UP)
      pm = 2
    else if (code == GM_KBD_DOWN)
      pm = 3
  }
}

function crit(x, y, tx, ty) {
  dx = tx-x
  dy = ty-y
  if(map[x,y] != "#")
    return dx*dx+dy*dy
  return 1000000
}

function dir_snake(x, y, tx, ty, m) {
  _c[0] = crit(x-1, y, tx, ty)
  _c[1] = crit(x+1, y, tx, ty)
  _c[2] = crit(x, y-1, tx, ty)
  _c[3] = crit(x, y+1, tx, ty)
  j=0
  tc = _c[0]
  for (i=1;i<4;i++) {
    if (_c[i] <= _c[j]) j = i
    tc+=_c[i]
  }
  if (tc > 2000000 && _c[m]!=1000000) {
    return m
  }
  return j
}

function move_snake(i) {
  if (i==0) {
    tx = px; ty = py
  } else if (i==1) {
    tx = px; ty = py
    if (pm&2)
      ty += (pm&1)?3:-3
    else
      tx += (pm&1)?3:-3
  }
  sm[i] = dir_snake(sx[i], sy[i], tx, ty, sm[i])
  if (sm[i]&2)
    dy = (sm[i]&1)?1:-1
  else
    dx = (sm[i]&1)?1:-1
  cursor_move(sx[i], sy[i]); print(map[sx[i], sy[i]])
  sx[i]+=dx
  sy[i]+=dy
  cursor_move(sx[i], sy[i]); print("W")
}

probe timer.ms(200) {
  ph = 1 - ph
  for (i=0;i<2;i++)
    if (ph) {
      move_snake(i)
    } else {
      cursor_move(sx[i], sy[i]); print("M")
      if (sx[i] == px && sy[i] == py)
        exit()
    }
  cursor_move(1,25)
}

probe timer.ms(200) {
  if (mv == 1) {
    cursor_move(px,py); print(map[px,py])
    if (pm&2)
      dy = (pm&1)?1:-1
    else
      dx = (pm&1)?1:-1
    if (map[px+dx, py+dy] != "#") {
      px += dx; py += dy
    }
    cursor_move(px,py); print(pkm[pm])
    if (map[px, py] == ".") {
      jewels--
      if (jewels == 0)
        exit()
      map[px, py] = " "
    }
    mv = 0
  } else {
    cursor_move(px,py); print("O")
  }
  cursor_move(1,25)
}

probe end {
  if (jewels == 0) {
    cursor_move(1,10); print("     Game Clear     ")
  } else {
    cursor_move(1,10); print("     Game Over!     ")
  }
  cursor_move(1,25)
}
