我正在尝试用C语言制作一个国际象棋计时器,但两个时间都在运行。

huangapple go评论72阅读模式
英文:

I am trying to make a chess clock in C but both times running

问题

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <string.h>
#include <windows.h>

const int milisec = 1000;

int main() {
  char cc = '\0';
  int wsec, wmin, bsec, bmin, choice;
  wsec = 0;
  bsec = 0;

  int* mp = &wmin;
  int* sp = &wsec;

  do {
    printf("\nLeo's Chess Clock, select a game pace:\n");
    printf("1.-Blitz (3:00)\n");
    printf("2.-Blitz (5:00)\n");
    printf("3.-Rapid (10:00)\n");

    printf("Select your choice: ");
    scanf("%d", &choice);

    system("cls");

    switch (choice) {
      case 1: wmin = 3; bmin = 3; break;
      case 2: wmin = 5; bmin = 5; break;
      case 3: wmin = 10, bmin = 10; break;
      default: printf("\nIncorrect choice, please select again.\n");
    }
  } while (choice > 3 || choice < 1);

  while (true) {
    if (kbhit()) {
      cc = getch();
    }

    printf("\nWHITE: %d:%d       BLACK: %d:%d", wmin, wsec, bmin, bsec);

    Sleep(milisec);

    if (*sp == 0) {
      --* mp;
    }

    *sp == 0 ? *sp = 59 : --*sp;

    system("cls");

    if (cc == 'l') {
      mp == &wmin ? mp = &bmin : mp = &wmin;
      sp == &wsec ? sp = &bsec : sp = &wsec;
    }
  }

  return 0;
}

I've translated the code for you. If you have any questions or need further assistance, please feel free to ask.

英文:
#include&lt;stdio.h&gt;
#include&lt;conio.h&gt;
#include&lt;stdlib.h&gt;
#include&lt;stdbool.h&gt;
#include&lt;time.h&gt;
#include&lt;string.h&gt;
#include&lt;windows.h&gt;
const int milisec = 1000;
int main() {
char cc = &#39;\0&#39;;
int wsec, wmin, bsec, bmin, choice;
wsec = 0;
bsec = 0;
int* mp = &amp;wmin;
int* sp = &amp;wsec;
do {
printf(&quot;\nReloj de Ajedrez de Leo, seleccione un ritmo de juego:\n&quot;);
printf(&quot;1.-Blitz (3:00)\n&quot;);
printf(&quot;2.-Blitz (5:00)\n&quot;);
printf(&quot;3.-Rapida (10:00)&quot;);
printf(&quot;\nSeleccione su opcion:&quot;);
scanf(&quot;%d&quot;, &amp;choice);
system(&quot;cls&quot;);
switch (choice) {
case 1: wmin = 3; bmin = 3; break;
case 2: wmin = 5; bmin = 5; break;
case 3: wmin = 10, bmin = 10; break;
default: printf(&quot;\nOpcion Incorrecta, seleccione nuevamente.\n&quot;);
}
} while (choice &gt; 3 || choice &lt; 1);
while (true) {
if (kbhit()) {
cc = getch();
}
printf(&quot;\nWHITE: %d:%d       BLACK: %d:%d&quot;, wmin, wsec, bmin, bsec);
Sleep(milisec);
if (*sp == 0) {
--* mp;
}
//////////////////////////////////////////////WHY ?
*sp == 0 ? *sp = 59 : -- * sp;
system(&quot;cls&quot;);
if (cc == &#39;l&#39;) {
mp == &amp;wmin ? mp = &amp;bmin : mp = &amp;wmin;
sp == &amp;wsec ? sp = &amp;bsec : sp = &amp;wsec;
}
}
return 0;
}

Please I am trying to make a chess clock but the third time I press a key it is both times that start to run down.... Help

I mean, the pinter I am using is changing isnt it?

PS: Please, rate how readable it is, I know it's a bit messy but Im trying to improve

and the genius SO is asking me mre details, ffs LOL.

答案1

得分: 3

以下是已翻译的内容:

Dropping all code irrelevant for illustrating the problem:

    if (kbhit())
    {
        cc = getch();
    }
    if (cc == 'l')
    {
        mp == &wmin ? mp = &bmin : mp = &wmin;
        sp == &wsec ? sp = &bsec : sp = &wsec;
    }

And when do you reset `cc`???

The point is once `cc` is set it will remain there until someone enters another character than `l` and your clock remains toggling with every millisecond! That's a pretty quick toggling time, by the way, most likely `Sleep` won't be that precise itself! You might want to consider longer sleeping times and instead fix any imprecision by checking how many milliseconds actually elapsed by some high precision clock. In any case: To fix, you need to reset the input within the loop; however: You run much less probably into such errors as this one if you limit the scope of variables to not any wider than actually needed; in given case, if you had moved the variable *into* the loop (there are exceptions to this rule, e.g. it is preferable to just clear an existing container instead of constructing and destructing it again and again):

    for(;;)
    {
        if(kbhit())
        {
            char cc = getch();
            if(cc == 'l')
            {
                // TODO: switch your pointers right here!
            }
        }
        // ...
    }

Side note: Consider rather letting the users press the space bar, it is much larger and thus simpler to hit  or accept just *any* character.

I additionally recommend using a struct containing both minutes and seconds:

    typedef struct Duration
    {
        int min;
        int sec;
    } Duration;

for each player, this way you need to exchange just one single pointer. Usually you'd do so rather this way:

    activeDuration = activeDuration == &white ? &black : &white;

Actually even better is one single integer containing minutes converted to seconds (e.g. 300 seconds for 5-minute 'Blitz'; thanks @Allan Wind for that hint), you don't have to care for overflow any more and can print out both minutes and seconds from that value on, e.g. like `<br />`printf("%d:%d", sec / 60, sec % 60);`.

Instead of switching pointers I personally like using an index into an array pretty much, by the way:

    Duration durations[2];
    unsigned int activeDuration = 0;

    // use durations[activeDuration];

    // toggle by:
    activeDuration = 1 - activeDuration;

请注意,我已保留了原始代码中的注释和代码部分,只对文本进行了翻译。

英文:

Dropping all code irrelevant for illustrating the problem:

if (kbhit())
{
cc = getch();
}
if (cc == &#39;l&#39;)
{
mp == &amp;wmin ? mp = &amp;bmin : mp = &amp;wmin;
sp == &amp;wsec ? sp = &amp;bsec : sp = &amp;wsec;
}

And when do you reset cc???

The point is once cc is set it will remain there until someone enters another character than l and your clock remains toggling with every millisecond! That's a pretty quick toggling time, by the way, most likely Sleep won't be that precise itself! You might want to consider longer sleeping times and instead fix any imprecision by checking how many milliseconds actually elapsed by some high precision clock. In any case: To fix, you need to reset the input within the loop; however: You run much less probably into such errors as this one if you limit the scope of variables to not any wider than actually needed; in given case, if you had moved the variable into the loop (there are exceptions to this rule, e.g. it is preferable to just clear an existing container instead of constructing and destructing it again and again):

for(;;)
{
if(kbhit())
{
char cc = getch();
if(cc == &#39;l&#39;)
{
// TODO: switch your pointers right here!
}
}
// ...
}

Side note: Consider rather letting the users press the space bar, it is much larger and thus simpler to hit – or accept just any character.

I additionally recommend using a struct containing both minutes and seconds:

typedef struct Duration
{
int min;
int sec;
} Duration;

for each player, this way you need to exchange just one single pointer. Usually you'd do so rather this way:

activeDuration = activeDuration == &amp;white ? &amp;black : &amp;white;

Actually even better is one single integer containing minutes converted to seconds (e.g. 300 seconds for 5-minute 'Blitz'; thanks @Allan Wind for that hint), you don't have to care for overflow any more and can print out both minutes and seconds from that value on, e.g. like <br />printf(&quot;%d:%d&quot;, sec / 60, sec % 60);.

Instead of switching pointers I personally like using an index into an array pretty much, by the way:

Duration durations[2];
unsigned int activeDuration = 0;
// use durations[activeDuration];
// toggle by:
activeDuration = 1 - activeDuration;

huangapple
  • 本文由 发表于 2023年7月17日 16:02:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76702512.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定