英文:
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<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("\nReloj de Ajedrez de Leo, seleccione un ritmo de juego:\n");
printf("1.-Blitz (3:00)\n");
printf("2.-Blitz (5:00)\n");
printf("3.-Rapida (10:00)");
printf("\nSeleccione su opcion:");
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("\nOpcion Incorrecta, seleccione nuevamente.\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;
}
//////////////////////////////////////////////WHY ?
*sp == 0 ? *sp = 59 : -- * sp;
system("cls");
if (cc == 'l') {
mp == &wmin ? mp = &bmin : mp = &wmin;
sp == &wsec ? sp = &bsec : sp = &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 == '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;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论