accepts command line argument to adjust the speed, 30 is the default, 5 is a good rate (#3) - gnuskii - GNUSki improved for ascii skiing experience.
 (HTM) git clone git://bitreich.org/gnuskii git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/gnuskii
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Tags
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 11cc620aa0c6b69f1540219053d5078bdc8a8990
 (DIR) parent 8ef1f6f6500b7ed6cde5af625c040f9071f121dd
 (HTM) Author: Rudolf Olah <89982117+rudolfolah@users.noreply.github.com>
       Date:   Fri,  8 Aug 2025 11:33:57 -0400
       
       accepts command line argument to adjust the speed, 30 is the default, 5 is a good rate (#3)
       
       * accepts command line argument to adjust the speed, 30 is the default, 5 is a good rate
       
       using usleep instead of REFRESH_RATE and ticker, which have been removed
       
       this could be a good way to present a challenge to a player, start with a low number and every few minutes increase the refresh speed
       
       * updated demo.gif
       
       * updated link
       
       * adjust default fps value from 30 to 20 and removed the conditional for the usleep
       
       * refactor speed handling and movement logic; increase max speed limit and adjust frame-based movement calculation
       Diffstat:
         M README.md                           |       2 +-
         M demo.gif                            |       0 
         M src/main.c                          |      27 ++++++++++++++++-----------
       
       3 files changed, 17 insertions(+), 12 deletions(-)
       ---
 (DIR) diff --git a/README.md b/README.md
       @@ -7,7 +7,7 @@ GNUSki is an open source clone of [Skifree](https://en.wikipedia.org/wiki/SkiFre
        ## GNUSki around the web
        - [homebrew formula for gnuski](https://formulae.brew.sh/formula/gnuski)
          - [formula code for gnuski](https://github.com/Homebrew/homebrew-core/blob/543cd71456e4813de4e12f33fea6f38f875b2327/Formula/g/gnuski.rb)
       -- [ascii cinema recording of gnuski](https://asciinema.org/a/485510)
       +- [ascii cinema recording of gnuski](https://asciinema.org/a/669357)
          - [demo.gif](./demo.gif)
        - [Termux](https://termux.dev/en/), an Android terminal emulator and Linux environment app, has a games package:
          - [gnuski package for Termux](https://github.com/termux/termux-packages/tree/master/packages/gnuski)
 (DIR) diff --git a/demo.gif b/demo.gif
       Binary files differ.
 (DIR) diff --git a/src/main.c b/src/main.c
       @@ -22,16 +22,17 @@
        #include <stdlib.h>
        #include <time.h>
        #include <stdio.h>
       +#include <unistd.h>
        #include <ncurses.h>
        
        #define MAX_OBJECTS 300
       -#define REFRESH_RATE 5000
        
        int main (int argc, char* argv[])
        {
       +  const long fps = argc != 2 ? 20l : strtol(argv[1], NULL, 10);
          struct Object player, objects[MAX_OBJECTS];
       -  unsigned int c = 0, i = 0, maxRows, maxCols, ticker = 0, score = 0,
       -    distance = 0, speed = 1, style = 0;
       +  unsigned int c = 0, i = 0, maxRows, maxCols, score = 0,
       +    distance = 0, speed = 2, style = 0, frame_counter = 0;
          enum mode {loop, lose, win} state = loop;
          char facing[2] = {'s', 'n'};   /* Player facing, object facing */
        
       @@ -77,7 +78,7 @@ int main (int argc, char* argv[])
                  break;
        
                case KEY_DOWN: case 'j': case 'J':
       -          if (speed < 3)
       +          if (speed < 4)
                    speed++;
                  break;
        
       @@ -86,17 +87,22 @@ int main (int argc, char* argv[])
                  break;
                }
        
       -      if (ticker == REFRESH_RATE)
       -        {
                  clear ();
       -          ticker = 0;
        
                  /* Check for collisions and draw the objects */
                  for (i = 0; i < MAX_OBJECTS; i++)
                    {
                      if (objects[i].type != none && collision (player, objects[i]))
                        state = lose;
       -              moveObject (&objects[i], facing[1], speed);
       +              /* Calculate actual movement based on speed and frame counter */
       +              int actual_speed = 0;
       +              if (speed == 0) actual_speed = 0;
       +              else if (speed == 1 && frame_counter % 4 == 0) actual_speed = 1;
       +              else if (speed == 2 && frame_counter % 3 == 0) actual_speed = 1;
       +              else if (speed == 3 && frame_counter % 2 == 0) actual_speed = 1;
       +              else if (speed == 4) actual_speed = 1;
       +              
       +              moveObject (&objects[i], facing[1], actual_speed);
                      if (objects[i].y < 0)
                        setPosition (&objects[i], rand () % (maxCols*2),
                                     rand () % maxRows + maxRows);
       @@ -110,10 +116,9 @@ int main (int argc, char* argv[])
                  printw ("Speed:    %02im/s\n", speed);
                  printw ("Style:    %4i", style);
                  distance += speed;
       -        }
       +          frame_counter++;
              refresh ();
       -      if (speed > 0)
       -        ticker++;
       +      usleep(1000000 / fps);
              c = getch ();
            }
          clear ();