From 3d9f7763d0152d454601c45f634c77a1d261fb3d Mon Sep 17 00:00:00 2001 From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com> Date: Fri, 20 Oct 2023 10:24:17 -0700 Subject: [PATCH] Fix 1989/tromp alt code Originally I put in the author's code without fixes in place. This is one of the reasons I did not see the improvements that he suggested. Several fixes had to be made and now it works. It should be noted I have not tested more than one user updating the high score file but the file is now created (I had to make a similar fix to the original entry as well). Format/typo check README.md file. Not sure I'm done with this one though as presentation might be improved. --- 1989/tromp/README.md | 82 +++++++++++++++++++++++------------------- 1989/tromp/tromp.alt.c | 18 +++++----- thanks-for-fixes.md | 12 ++++++- 3 files changed, 66 insertions(+), 46 deletions(-) diff --git a/1989/tromp/README.md b/1989/tromp/README.md index 89a5b0518..c2757a5b4 100644 --- a/1989/tromp/README.md +++ b/1989/tromp/README.md @@ -1,9 +1,6 @@ # Best game John Tromp\ -Centre for Mathematics and Computer Science (CWI)\ -Oetgensstraat 7\ -1701CK Heerhugowaard\ Netherlands ## To build: @@ -19,39 +16,44 @@ make all ``` ## Try: - ```sh ./tromp 5 -# fast with vim keys -# h - left (left) -# k - rotate (arbitrary, in vim k = up) -# l - right (right) -# j - drop (down) -# space - pause (literal space in vim) -# q - quit (similar to :q in vim) - -./tromp 10 "hklj q" +./tromp 10 "hkl jq" ``` -NOTE: after this game ends a file called `HI` will be in the directory with the +The second command, `./tromp 10 "hkl jq"`, will set up the keys kind of like +vim: + +- h - left (left) +- k - rotate (up) +- l - right (right) +- j - drop (down) +- space - pause (space) +- q - quit (:q) + + +NOTE: after the game ends a file called `HI` will be in the directory with the high scores (up to 20 runs saved) so one can see who has the highest score. The file might look like: ``` 330 by luser 136 by loser +100 by winner ``` -... or so, where in this case the luser is the winner and the loser is the loser :-) +... or so, where in this case the [luser is the winner, the loser is in second +place and the winner is the +loser](https://web.archive.org/web/20181023221954/https://www.chicagotribune.com/news/ct-xpm-2002-07-31-0207310310-story.html) :-) ### Alternate code: -The author provided an alternate version of the code with some improvements. We -were unable to see the improvements in modern systems even after fixing it to -compile (the high score file was not created at all) but if you have an old -compiler you can try compiling it in its original unmodified form by running: +The author provided an alternate version of the code with some improvements. See +the judges' additional remarks in the author's remarks, for more details. + +#### To use: ```sh make alt @@ -59,29 +61,33 @@ make alt Use `tromp.alt` as you would `tromp` above. +NOTE: testing more than one user updating the high score file, one of the +benefits of the alt version, has not been done. + +The original unmodified alternate code is provided later. ## Judges' remarks: -This is a character terminal version of the TETRIS program. +This is a character terminal version of the `TETRIS` game. It runs on a VT100 compatible terminal or emulator. It is best used at 4800 baud or more. -By default, "drops_per_sec", the number of times an object -will drop in a second, is 2. The default "cmd_string" is -"jkl pq". The first 6 characters of "cmd_string" relate +By default, `drops_per_sec`, the number of times a tetrimino +will drop in a second, is 2. The default `cmd_string` is +`jkl pq`. The first 6 characters of `cmd_string` relate to the following 6 game commands: - j - left - k - rotate - l - right -- space - drop +- space - drop - p - pause - q - quit -Specifying "cmd_string" allows one to re-define the commands. +Specifying `cmd_string` allows one to redefine the commands. The pause command pauses the game, clears the screen and prints the current score. To resume, type the pause -character again, which by default is "p". +character again, which by default is `p`. As was stated last year, we are likely to be more strict about portability in the future. [ We mean it this time :-) ] @@ -89,7 +95,7 @@ portability in the future. [ We mean it this time :-) ] ## Author's remarks: -This program plays the familiar game of `TETRIS' with the +This program plays the familiar game of `TETRIS` with the following features: * outputs vt100-like escape-sequences for cursor @@ -98,32 +104,34 @@ following features: * continuously increasing speed (except in pause) -* start speed selectable by giving n as first argument, - where n is the number of drops per second (default=2). +* start speed selectable by giving `n` as first argument, + where `n` is the number of drops per second (default=2). * controls also selectable by giving as the second argument - a string of 6 characters. By default they are "jkl pq". + a string of 6 characters. By default they are `jkl pq`. * screen is blanked during the pause and the score is shown * maintains a high-score table Giving a full path name for the table will result in a -system-wide hiscore allowing a competition between users. +system-wide high-score allowing a competition between users. + +### Additional remarks from the judges: The author provided us with the following notes and new version of the program: Here is a somewhat improved version of my tetris entry. All the -changes are in the popen() at the end. Formerly a move was done +changes are in the `popen()` at the end. Formerly a move was done to the HI score file which is not permitted for other users. Now -other users can change the HI score file. The extra option -m is +other users can change the `HI` score file. The extra option `-m` is passed to sort, so that it knows that its input files are already -sorted. The -o output option of sort is used instead of a +sorted. The `-o` output option of sort is used instead of a temporary file. -You may also want to consider giving just the raw option to stty -at the start and -raw at the end. This further reduces the size of +You may also want to consider giving just the raw option to `stty` +at the start and `-raw` at the end. This further reduces the size of the program, but has the possible disadvantage that the program can only by stopped by 'q' or by the `kill -9' command. @@ -149,6 +157,8 @@ can only by stopped by 'q' or by the `kill -9' command. "%4d from level %1d by %s\n",w,l,getlogin());pclose(d);} ``` +NOTE: the alternate version was fixed for modern systems in 2023. + ## Copyright and CC BY-SA 4.0 License: This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved. diff --git a/1989/tromp/tromp.alt.c b/1989/tromp/tromp.alt.c index 199789a34..cc397cd79 100644 --- a/1989/tromp/tromp.alt.c +++ b/1989/tromp/tromp.alt.c @@ -1,19 +1,19 @@ -long h[4];t(){h[3]-=h[3]/3000;setitimer(0,h,0);}c,d,l,v[]={(int)t,0,2},w,s,I,K +long h[4];t(){h[3]-=h[3]/3000;setitimer(0,h,0);}FILE *d;long c,l,v[]={0,0,2},w,s,I,K =0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-12,-1,9,-1,1, 12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12,1,13,10,-12, 1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,12,16,-11,-12, 12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i<264;)if((k=q[i])-Q[i] -){Q[i]=k;if(i-++I||i%12<1)printf("\033[%d;%dH",(I=i)/12,i%12*2+28);printf( +){Q[i]=k;if(i-++I||i%12<1)printf("\033[%ld;%ldH",(I=i)/12,i%12*2+28);printf( "\033[%dm "+(K-k?0:5),k);K=k;}Q[263]=c=getchar();}G(b){for(i=4;i--;)if(q[i?b+ -n[i]:b])return 0;return 1;}g(b){for(i=4;i--;q[i?x+n[i]:x]=b);}main(C,V,a)char* -*V,*a;{h[3]=1000000/(l=C>1?atoi(V[1]):2);for(a=C>2?V[2]:"jkl pq";i;i--)*n++=i< -25||i%12<2?7:0;srand(getpid());system("stty cbreak -echo stop u");sigvec(14,v, +n[i]:b])return 0;return 1;}g(b){for(i=4;i--;q[i?x+n[i]:x]=b);}main(C,V)char* +*V;{char *a;*v=(long)t;h[3]=1000000/(l=C>1?atoi(V[1]):2);for(a=C>2?V[2]:"jkl pq";i;i--)*n++=i< +25||i%12<2?7:0;srand(getpid());system("stty cbreak -echo");sigaction(14,v, 0);t();puts("\033[H\033[J");for(n=f+rand()%7*4;;g(7),u(),g(0)){if(c<0){if(G(x+ 12))x+=12;else{g(7);++w;for(j=0;j<252;j=12*(j/12+1))for(;q[++j];)if(j%12==10){ for(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+rand()%7*4;G(x=17)||(c =a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n=m);if(c==a[2])G (++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c==a[5]){s=sigblock( -8192);printf("\033[H\033[J\033[0m%d\n",w);if(c==a[5])break;for(j=264;j--;Q[j]= -0);while(getchar()-a[4]);puts("\033[H\033[J\033[7m");sigsetmask(s);}}d=popen( -"stty -cbreak echo stop \023;sort -mnr -o HI - HI;cat HI","w");fprintf(d, -"%4d from level %1d by %s\n",w,l,getlogin());pclose(d);} +8192);printf("\033[H\033[J\033[0m%ld\n",w);if(c==a[5])break;for(j=264;j--;Q[j]= +0);while(getchar()-a[4]);puts("\033[H\033[J\033[7m");sigsetmask(s);}}system( +"stty cbreak echo");d=popen("cat - HI 2>/dev/null|sort -mnr -o HI -;cat HI","w");fprintf(d, +"%4ld from level %1ld by %s\n",w,l,getlogin());pclose(d);} diff --git a/thanks-for-fixes.md b/thanks-for-fixes.md index 0d275ad34..1ee144d44 100644 --- a/thanks-for-fixes.md +++ b/thanks-for-fixes.md @@ -592,11 +592,21 @@ To get it to work with clang the variable `a` had to not be the third argument to `main()` but instead be a variable in `main()`. Cody also fixed a segfault and made it so the that the high score file would -work (it was not even being created but it was supposed to be). +work (it was not even being created but it was supposed to be). This was +happening due to a file pointer being declared as a `long` and more +significantly is the command in `popen(3)` was not correct. Another problem Cody fixed was that the terminal was left in an insane state where you could not type '`u`' and echo was completely disabled. +Cody later on fixed the alt version, provided by the author, so that it would +compile with clang, not abort (with an alarm), would have the tetriminos fall, +it would write to the high score file (the command to `popen(3)` was incorrect +here too but as can be seen it differs from the submitted version), could use +`stty` properly (and thus turn on echo again - it did not work because it was in +the `popen(3)` call rather than using `system(3)`), a couple compiler errors and +various other things, so that now the alt version, which is better, can be used. + Although we appreciate the help here, he cynically noted that he had to have an IOCCC [Tetris](https://en.wikipedia.org/wiki/Tetris) working (this of course was not his only reason :-) )