From 7b1ed2bc9414a02583f8baeb2e36626c182da34e Mon Sep 17 00:00:00 2001 From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com> Date: Fri, 20 Oct 2023 05:00:43 -0700 Subject: [PATCH] Properly fix 1987/lievaart invalid input checks Now the game will re-prompt the player if invalid input is entered both for the level and for the move. The way it was fixed is described in the thanks-for-fixes.md file but here is a summary of the previous problem and the fix. If one entered an invalid level it proceeded to prompt for the move. Thus if one entered '.' or anything other than a number it would still move on. As for the move if one entered invalid input it would prompt again but in an infinite loop, not letting one enter anything and instead flooding the screen. The format specifier was thus a '%d'. Now it's a '%2s' on a 'char A[100]'. After the scanf() it uses atoi(). For the level it checks if > 10 || < 0 || !isdigit(*A) and if the if is 1 it goes back to prompting the level. Of course since '-' is not a digit the check for < 0 is superfluous but I did it anyway. Now prior to prompting the level it zeroes out 'A' (*A='\0'). For the movement the do..while loop condition checks for invalid input but it needed a scanf() with "%2s" also and then use atoi() on the string (A). But in that case there was no need to zero out the string (might not even be in the other but I did it anyway). Now as far as the level goes I checked for > 10 only because later in the code it checks for < 10 and if so it increments it by 2 so I presume that it's invalid if it's >10. This might or might not be correct but I do not know the rules of the game and neither do I know the author's intentions. One more important point is that it does seem to stop playing the game, making the same move again and again, but this might be another problem or maybe it's a draw or something else. As I said I don't know how to play the game so I can't verify it either way. --- 1987/lievaart/Makefile | 4 ++-- 1987/lievaart/lievaart.c | 8 +++++--- 1987/lievaart/lievaart2.c | 8 +++++--- thanks-for-fixes.md | 36 ++++++++++++++++++++++++++++++++++-- todo.md | 5 +---- 5 files changed, 47 insertions(+), 14 deletions(-) diff --git a/1987/lievaart/Makefile b/1987/lievaart/Makefile index 0712ac348..605531004 100644 --- a/1987/lievaart/Makefile +++ b/1987/lievaart/Makefile @@ -62,11 +62,11 @@ CDEFINE= # Include files that are needed to compile # -CINCLUDE= +CINCLUDE= -include stdio.h # Optimization # -OPT= -O3 +OPT= # Default flags for ANSI C compilation # diff --git a/1987/lievaart/lievaart.c b/1987/lievaart/lievaart.c index 70e9cdfc1..79d8b8356 100644 --- a/1987/lievaart/lievaart.c +++ b/1987/lievaart/lievaart.c @@ -6,15 +6,17 @@ #define l int #define C y=v+111;H(x,v)*y++= *x #define H(a,b)R(a=b+11;au){R(w=i=0;i<4;i++)w+=(m=v[h[i]])==f?300:m==q?-300:(t=v[ih[i]])==f?-50 :t==q?50:0;return w;}H(z,0){if(GZ(v,z,f,100)){c++;w= -S(d+1,n,q,-b,-bw);if(w>bw ){zb=z;bw=w;if(w>=b||w>=8003)Y w;}}}if(!c){bz=0;C;Y-S(d+1,n,q,-b,-bw);}bz=zb;Y d>=u-1?bw+(c<<3):bw;}main(){R(;t<1100;t+=100)R(m=0;m<100;m++)V[t+m]=m<11||m>88 -||(m+1)%10<2?3:0;V[44]=V[55]=1;V[45]=V[54]=2;I("Level:");s(u);e(lv>0){do{I("Yo\ -u:");s(m);if(t<1)break;}e(!GZ(V,m,2,0)&&m!=99);if(m!=99)lv--;if(lv<15&&u<10)u+=2;I("Wait\n") +||(m+1)%10<2?3:0;V[44]=V[55]=1;V[45]=V[54]=2;x:*A='\0';I("Level:");s(A);if((u +=atoi(A))>10||u<0||!isdigit(*A))goto x;e(lv>0){do{I("You:");s(A);m=atoi(A);*A='\0'; +}e(!GZ(V,m,2,0)&&m!=99);if(m!=99)lv--;if(lv<15&&u<10)u+=2;I("Wait\n") ;I("Value:%d\n",S(0,V,1,-9000,9000));I("move: %d\n",(lv-=GZ(V,bz,1,0),bz));}}GZ (v,z,f,o)l*v;{l*j,q=3-f,g=0,i,h,*k=v+z;if(*k==0)R(i=7;i>=0;i--){j=k+(h=r[i]);e( *j==q)j+=h;if(*j==f&&j-h!=k){if(!g){g=1;C;}e(j!=k)*((j-=h)+o)=f;}}Y g;} diff --git a/1987/lievaart/lievaart2.c b/1987/lievaart/lievaart2.c index dd9d785dc..25e15cc56 100644 --- a/1987/lievaart/lievaart2.c +++ b/1987/lievaart/lievaart2.c @@ -7,8 +7,9 @@ #define W if #define C y=v+111;H(x,v)*y++= *x #define H(a,b)R(a=b+11;aj){g=bz=z; j=w;W(w>=b||w>=8003)Y w;}}}W(!c){g=0;W(_){H(x,v)c+= *x==f?1:*x==3-f?-1:0;Y c>0? 8000+c:c-8000;}C;j= -S(d+1,n,q,1,-b,-j);}bz=g;Y d>=u-1?j+(c<<3):j;}main(){R(;t< -1600;t+=100)R(m=0;m<100;m++)V[t+m]=m<11||m>88||(m+1)%10<2?3:0;I("Level:");V[44] -=V[55]=1;V[45]=V[54]=2;s(u);e(lv>0){Z do{I("You:");s(m);if(t<1)break;}e(!E(V,m,2,0)&&m!=99); +1600;t+=100)R(m=0;m<100;m++)V[t+m]=m<11||m>88||(m+1)%10<2?3:0;x:I("Level:");V[44] +=V[55]=1;V[45]=V[54]=2;s(A);if(((u=atoi(A))>10)||u<0||!isdigit(*A))goto x;e(lv>0){Z +do{I("You:");s(A);m=atoi(A);*A='\0';}e(!E(V,m,2,0)&&m!=99); W(m!=99)lv--;W(lv<15&&u<10)u+=2;U("Wait\n");I("Value:%d\n",S(0,V,1,0,-9000,9000 ));I("move: %d\n",(lv-=E(V,bz,1,0),bz));}}E(v,z,f,o)l*v;{l*j,q=3-f,g=0,i,w,*k=v +z;W(*k==0)R(i=7;i>=0;i--){j=k+(w=r[i]);e(*j==q)j+=w;W(*j==f&&j-w!=k){W(!g){g=1 diff --git a/thanks-for-fixes.md b/thanks-for-fixes.md index 7b5de90f1..5823f6fa6 100644 --- a/thanks-for-fixes.md +++ b/thanks-for-fixes.md @@ -290,8 +290,40 @@ that for System V we had to do this) Cody added to the Makefile ## [1987/lievaart](1987/lievaart/lievaart.c) ([README.md](1987/lievaart/README.md)) -Cody fixed two infinite loops showing just `You:` by detecting invalid input -which the program was documented to do. But see [bugs.md](/bugs.md). +Cody added back the documented checks for invalid input which no longer worked +and instead resulted in either accepting the level, whether or not it was a +number or out of range (see below on range). For the move it entered an infinite +loop, prompting the player with `"You:"` but not letting the player input +anything so that the screen was flooded and the game could not play. + +For both the level and move it did a `scanf()` with a `%d` specifier but this +resulted in, if invalid input, either proceeding (for the level), presumably +incorrectly done as it might not even be a number (see below) or printing +`"You:"` in an infinite loop, expecting input again but not letting the player +input anything, both as noted above. + +The fix is that now the specifier is a `%2s` for a `char A[100]`. For the level +if `atoi(A)>10||<0` (see next part) or `!isdigit(*A)` it goes back and prompts +again. The level is checked for >=0||<=10, perhaps incorrectly or perhaps not, because +in the code that variable is checked for `<10` and if that is the case it is +incremented by 2. I do not know the rules of the game and neither do I know what +the author had in mind so I chosen 10 as the maximum. + +As for the move the `do..while` loop works properly now that it does it in two +steps (`scanf("%2s", A); m=atoi(A);`) so there's no need to check the value +explicitly, again. Thus it will prompt until valid input is entered, but only +showing `"You:"` once per prompting. + +In the case of the level prior to prompting for the level it does a `*A='\0';` +and in the case of the move it does it after the `m=atoi(A);`. This is done this +way because the check for the value of the level (`atoi(A)`) is done in the +`if()` that also checks for a digit (though it does `(u=atoi(A))>10||u<0` first, +thus checking the level, and `|| !isdigit(*A)`). Of course since `-` is not a +digit the `<0` is superfluous but it's done anyway. If that `if` is 1 then it +immediately goes back to the prompting of the level. + +But for the move it can happen after due to the fact the condition of the +`do..while` loop will take care of things. Cody also made this ever so slightly like the original code by adding back the `#define D define` even though it's unused. This was done for both versions as diff --git a/todo.md b/todo.md index c2d7610b4..76c8aa28e 100644 --- a/todo.md +++ b/todo.md @@ -1,5 +1,5 @@ # A todo list of known things to check and/or do -*Last updated: Thu 19 Oct 18:57:35 UTC 2023* +*Last updated: Fri 20 Oct 11:59:47 UTC 2023* This document is primarily for [Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) as he (that is I :-) ) wanted a way @@ -145,6 +145,3 @@ instead change it to make pull requests. See the - Check the YYYY/README.md files for other things besides the GitHub pull requests rather thane mailing judges. This can be done on the final pass of the files. - -- Consider adding a `1987/lievaart/lievaart3.alt.c` that doesn't forfeit the -game if you input invalid input.