Turn your phone or tablet into a chess clock


Playing chess with the kids today, we finally started to feel the need to impose some sort of time constraint on moves. That got me to rustle up this quick program:

Start_time = 12  -- seconds
Curr_color = 'white'
Chess_clock_time = {
  white=Start_time,
  black=Start_time,
}
function car.update(dt)
  Chess_clock_time[Curr_color] = math.max(0,
      Chess_clock_time[Curr_color] - dt)
end
-- initialize space per side
local side_w = floor((Safe_width-60 - 100)/2)
-- initialize font size
local function font_size_for_chess_clock()
  local font_size
  local min_font_size = 20
  local max_font_size = Safe_height
  for i=1,100 do
    if min_font_size >= max_font_size-5 then
      break
    end
    font_size = floor((min_font_size+max_font_size)/2)
    local font = g.newFont(font_size)
    local w = font:getWidth('00:00:00')
    if w < side_w then
      min_font_size = font_size
    elseif w > side_w then
      max_font_size = font_size
    elseif w == side_w then
      break
    end
  end
  return font_size
end
local font_size = font_size_for_chess_clock()
local font = g.newFont(font_size)
function car.draw()
  g.setFont(font)
  local top = Menu_height+20
  local left = 30
  local height = Safe_height-80
  local gutter_width = 100
  -- white side
  local time = Chess_clock_time.white
  if time <= 0 then
    color(1,0,0)
    rect('fill', left, top, side_w, height, 5,5)
  else
    color(0.2,0.2,0.2)
    rect('line', left, top, side_w, height, 5,5)
  end
  local white_time = time_str(time)
  local w = g.getFont():getWidth(white_time)
  if time == 0 then
    color(1,1,1)
  elseif time < 10 then
    color(1,0,0)
  else
    color(0,0,0)
  end
  local x = left + (side_w - w)/2
  local y = top+(height-font_size)/2
  g.print(white_time, x,y)
  -- black side
  time = Chess_clock_time.black
  if time <= 0 then
    color(1,0,0)
  else
    color(0.2,0.2,0.2)
  end
  local black_time = time_str(time)
  local w = g.getFont():getWidth(black_time)
  x = left + side_w + gutter_width
  rect('fill', x, top, side_w, height, 5,5)
  if time == 0 then
    color(0,0,0)
  elseif time < 10 then
    color(1,0,0)
  else
    color(1,1,1)
  end
  x = x + (side_w - w)/2
  g.print(black_time, x,y)
end
function time_str(time)
  if time < 10 then
    local tens = floor(time/10)
    local fractional_part = time - tens
    return ('%d%0.2f'):format(tens, fractional_part)
  end
  local hours = floor(time/3600)
  time = time - hours*3600
  assert(time < 3600)
  local minutes = floor(time/60)
  time = time - minutes*60
  assert(time < 60)
  local seconds = floor(time)
  return ('%02d:%02d:%02d'):format(hours, minutes, seconds)
end
function car.mouse_press(x,y, b)
  if Chess_clock_time.white == 0 or Chess_clock_time.black == 0 then
    return
  end
  if y >= Menu_height + 20 then
    if Curr_color == 'white' then
      -- it's white's move
      if x <= 30+side_w then
        Curr_color = 'black'
      end
    else
      -- it's black's move
      if x >= 30 + side_w + 100 then
        Curr_color = 'white'
      end end end end

No more searching for apps in the app store and trying to ineffectually vet their privacy policies and permissions.

To keep the code short, we're lacking features. There's no UI for setting the time. Just edit the first line of the program. You have to put in the time in seconds even though it'll render in hours:minutes:seconds.

If you try pasting this program into Lua Carousel, remember to first run the abbreviations on one of the example screens. Or if you've deleted that screen, here are the abbreviations I used in this post:

g = love.graphics
rect = g.rectangle
color = g.setColor
max = math.max
floor = math.floor

Get Lua Carousel

Leave a comment

Log in with itch.io to leave a comment.