Turn your phone or tablet into a chess clock

(akkartik.itch.io)

44 points | by surprisetalk 5 days ago ago

36 comments

  • akkartik 3 days ago

    Author here. The point of posts on this devlog is to show ways in which you can replace a bunch of different specialized, proprietary mobile apps of dubious provenance with a single general, reputable open source app (LÖVE running my carousel.love file, which is a cross-platform zip file containing all source code and live-editable on a computer).

    If you have a favorite chess clock product you use, and it has any niceties or features that cause you to favor it over this little thing made with 100 lines of code, I'd love to hear about them. I want this thing to be a real product that competes with real products on mobile devices, but that can also stabilize and become a durable artifact that doesn't require funding or a business underlying it. I don't have the product/UX chops to do this, but it has time since it'll never run out of money. So all we all have to do is spend 10 years polishing and refining it without adding too many features :)

    • naet 3 days ago

      The Lichess app has had a built in clock that works very well and has all the time settings you would want. You can find it in the menu under the analysis board. I think a lot of people don't know that it's included even if they use Lichess.

      Been using that for at least five years when I need a phone based chess clock on the go. I didn't try yours, but it has all the options for stuff like increments, handicap, stages, etc.

    • tzs 3 days ago

      Does the environment you wrote it in support networking? If so an interesting option would be two have it run on two phones. Each phone would show both times.

      This would have two advantages over other phone chess clock apps I've seen.

      1. Convenient placement. Each player could have their phone where it is most convenient for them instead of it having to be in the usual place on the side of the board.

      2. Others have brought up the concern that people might hit the phone too hard after their move. In a time scramble people do sometimes hit pretty hard because they are trying to hit it as fast as possible. Also, they don't always hit it with relatively soft flesh. They often hit it with the bottom of the piece they just captured. Imagine what repeated hits to the phone from pieces from a tournament sized triple weighted set could do.

      If each player is hitting their own phone they might be more careful.

      • akkartik 3 days ago

        Really good points. LÖVE doesn't support https yet (that's coming in the next version) but for this I think pure http should suffice. I'm going to try to put this together with a tiny server shim to forward messages to each other. That way it should be robust to firewalls and so on.

    • mafuyu 3 days ago

      Carousel looks neat! I haven’t played around with Lua or LÖVE much, but this reminds me of Processing, except with more of a focus on creating useful mini-apps instead of visual art. It also reminds me SmileBASIC for the Nintendo 3DS.

      What would distributing this for iOS look like? I guess it would be publishable on the App Store, since there are apps like Pythonista out there?

      • akkartik 3 days ago

        You can run LÖVE on iOS: https://www.love2d.org/wiki/Getting_Started#iOS

        You "just" need XCode, and to recompile it once a year. Sigh, ugh.

        I believe there are third parties distributing it on iOS as well. But then you need to trust an additional entity.

        • mafuyu a day ago

          Gotcha, thanks! I'm not in the Apple Developer Program, but I'm tempted to do it just to be able to experiment with sideloading all sorts of LÖVE programs.

    • throawayonthe 3 days ago

      there is https://github.com/ldeso/blitz which looks quite nice

  • j_leboulanger 3 days ago

    I use lichess as a chess clock, works like a charm

    • akkartik 3 days ago

      The native app or website? Does the app have a clock tool? I use lichess a lot, but only on the web, and I haven't seen a chess clock on the website. (I'm the author of OP.)

      • xcombelle 2 days ago

        The website has no clock. Both android and iphone lichess app has clock.

      • nilsherzig 3 days ago

        At least the beta android app has one

  • dataspun 3 days ago
    • tacone 3 days ago

      I love it, but it looks too easy to reset the time by mistake.

  • tzs 3 days ago

    I can think of two main reasons for a phone chess clock.

    1. To paraphrase what is said about cameras, the best chess clock is the one that you have with you. People usually have their phone with them, so should the need arise to have a chess clock they are covered. Not many people want to always carry a physical chess clock around just in case the opportunity to play chess arises.

    2. It is cheap or free. The phone is expensive but people are going to have that anyway so that doesn't count. A decent chess clock from a known company will probably run you are least $30.

    For people whose main reason for a phone clock is #2 and would not have a problem with having to carry something with them I've always thought it would be interesting to make some sort of holder that you can put a phone in when using it as a chess clock.

    The holder could hold the phone at a better viewing angle, and could incorporate some sort of rocker mechanism so that the phone tilts slightly to one side or the other. The app on the phone could sense which side the tilt is toward and use that to know which clock should be running. (The app could also correct the display for the tilt so the display remains level despite the clock body being tilted).

    When you move instead of having to hit something on the touch screen you'd hit your side of the top of the holder to flip the tilt.

  • fph 3 days ago

    I have seen people play 5-0 games on the board at my university; my phone would not survive one day of play.

    • qsort 3 days ago

      (Sorry for the OT mini-speech)

      I don't really like 0 increment games OTB. Online it's fine and you could argue that time management is part of the game, but on a physical board you end up knocking down pieces and having a lot of arguments about whether moves were legal or not.

      5 minutes became popular when digital clocks were rare and expensive, but these days a digital clock that does Fischer increment is like $50. 3 minutes + 2 seconds is about the same length as 5 minutes and much better suited to OTB play IMO.

    • akkartik 3 days ago

      Totally valid criticism. I'm not competing with specialized chess clock devices used in professional settings, only chess clock apps on mobile devices that people use in more informal settings.

      • ryandv 3 days ago

        I think this is more a comment on how hard people slam physical clock devices after they've made their move, not about the feature set of any given chess clock solution.

        • fph 2 days ago

          Exactly, thanks for explaining it better than I did in my original comment. When they are in a time crunch, players often slam down on chess clocks ridiculously hard; those devices must be very solid.

        • akkartik 3 days ago

          Ah. I thought it was a comment on battery life. LÖVE is definitely not the most power-efficient way to run code on a mobile device.

    • naet 3 days ago

      I have played a ton of 3 min flat blitz games at the local bar using my phone as a click and my phone has never been broken, maybe due to a little good luck. Not as satisfying to tap the screen compared to slamming a button on a physical clock, but nobody has ever slammed the phone like that even if they've been drinking.

      Seen plenty of liquids spilled on the board though so there is always that hazard...

  • eesmith 3 days ago

    Back in the 1980s, I would write a BASIC program on my PC to be a chess clock.

    I think I wrote it anew each time? It was really easy to do.

    • akkartik 3 days ago

      Yes! That is the world I want to bring back. No package manager and whatnot, just copy paste code from a website and keep going.

      (I'm ok with not having to type it in every time. Though you're welcome to do that if you like.)

      • eesmith 3 days ago

        I probably wrote it anew each time because I wanted to try something different.

        Or, in modern speak, it was a code kata.

        I did the same when I needed to memorize a word list for Spanish class.

  • BrandoElFollito 3 days ago

    I use Chess Clock (https://play.google.com/store/apps/details?id=com.chess.cloc...) to play with my children - does the job, simple to use, free

    • akkartik 3 days ago

      This seems pretty decent. It's 1) by a reputable site, 2) says it doesn't collect any data, 3) doesn't share any data with third parties. Only criticism I have is that 4) it's proprietary and liable to stop working on new devices if the for-profit company funding it loses interest in it. Whereas OP depends on an open source project with very different incentives (won't lose interest; someone with interest will fork it; but on the other hand it's not going to be arsed to go through painful app store review. You'll need to download and run the raw apk. For as long as Android phones owned by an ad company allow that.)

      Still, 3/4 is pretty good!

      • BrandoElFollito 3 days ago

        Now you made me want to write a PWA for a chess clock... This is not really nice of you, I already have a pile of things I plan to do and my wife is looking weird at me because I am typing at the computer instead of fixing the dinner as I said I would do :)

  • styczen 3 days ago

    please add go clock to (additional time)

    • akkartik 3 days ago

      I'm the author, but I don't follow your comment. Could you elaborate?

      • sugarkjube 3 days ago

        Google byo yomi

        • akkartik 3 days ago

          Ohh, you mean a clock for the game Go (wei qi, baduk)

          Sure thing, that should be doable.

    • akkartik 3 days ago

      What do you think of this design?

          -- run within https://akkartik.itch.io/carousel
          g = love.graphics
          rect = g.rectangle
          color = g.setColor
          floor = math.floor
      
          Limit = 13
          Byo_yomi_period = 30  -- seconds
      
          Curr_color = 'black'
          Byo_yomi = {
            black=0,
            white=0,
          }
      
          Curr_time = 0
      
          function car.update(dt)
            if Byo_yomi.black == Limit or Byo_yomi.white == Limit then
              return
            end
            Curr_time = Curr_time + dt
            if Curr_time > Byo_yomi_period then
              Byo_yomi[Curr_color] = Byo_yomi[Curr_color] + 1
              Curr_time = Curr_time - Byo_yomi_period
            end 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 large_font_size = font_size_for_chess_clock()
          local large_font = g.newFont(large_font_size)
          local small_font_size = 20
          local small_font = g.newFont(small_font_size)
      
          function car.draw()
            local top = Menu_height+20
            local x = 30
            local height = Safe_height-80
            local gutter_width = 100
            -- black side
            color(0.2,0.2,0.2)
            rect('fill', x, top, side_w, height, 5,5)
            color(1,1,1)
            local y
            if Byo_yomi.black < Limit - 10 then
              y = top + (height-large_font_size)/2
              print_centered(large_font, Byo_yomi.black, y, x, side_w)
              if Curr_color == 'black' then
                y = y + large_font_size + 10
                print_centered(small_font, floor(Curr_time), y, x, side_w)
              end
            elseif Byo_yomi.black < Limit-1 then
              y = top + (height - large_font_size*2 - 10)/2
              local s = ('%d left'):format(Limit - Byo_yomi.black)
              print_centered(large_font, s, y, x, side_w)
              if Curr_color == 'black' then
                y = y + large_font_size + 10
                print_centered(large_font, floor(Curr_time), y, x, side_w)
              end
            elseif Byo_yomi.black == Limit-1 then
              y = top + (height - large_font_size - 10 - small_font_size)/2
              print_centered(small_font, "no time left", y, x, side_w)
              if Curr_color == 'black' then
                y = y + small_font_size + 10
                print_centered(large_font, floor(Curr_time), y, x, side_w)
              end
            else
              -- out of time; Byo_yomi.black == Limit
              -- print nothing
            end
            -- white side
            x = x + side_w + gutter_width
            color(0,0,0)
            rect('line', x, top, side_w, height, 5,5)
            if Byo_yomi.white < Limit-10 then
              y = top + (height-large_font_size)/2
              print_centered(large_font, Byo_yomi.white, y, x, side_w)
              if Curr_color == 'white' then
                y = y + large_font_size + 10
                print_centered(small_font, floor(Curr_time), y, x, side_w)
              end
            elseif Byo_yomi.white < Limit-1 then
              y = top + (height - large_font_size*2 - 10)/2
              local s = ('%d left'):format(Limit - Byo_yomi.white)
              print_centered(large_font, s, y, x, side_w)
              if Curr_color == 'white' then
                y = y + large_font_size + 10
                print_centered(large_font, floor(Curr_time), y, x, side_w)
              end
            elseif Byo_yomi.white == Limit-1 then
              y = top + (height - large_font_size - 10 - small_font_size)/2
              print_centered(small_font, "no time left", y, x, side_w)
              if Curr_color == 'white' then
                y = y + small_font_size + 10
                print_centered(large_font, floor(Curr_time), y, x, side_w)
              end
            else
              -- out of time; Byo_yomi.white == Limit
              -- print nothing
            end end
      
          function print_centered(font, msg, y, left, width)
            local w = font:getWidth(msg)
            local x = left + (width-w)/2
            g.setFont(font)
            g.print(msg, x,y)
          end
      
          function car.mouse_press(x,y, b)
            if Byo_yomi.black == Limit or Byo_yomi.white == Limit then
              return
            end
            if y >= Menu_height + 20 then
              if Curr_color == 'black' then
                -- it's black's move
                if x <= 30+side_w then
                  Curr_color = 'white'
                  Curr_time = 0
                end
              else
                -- it's white's move
                if x >= 30 + side_w + 100 then
                  Curr_color = 'black'
                  Curr_time = 0
                end end end end
      
      I'm going by the description in https://www.britgo.org/bgj/10643.html, but I haven't actually seen a Go clock before, so feedback appreciated.