插入移动的格式为xYZ,其中x为'o'或'x',Y为行号,Z为列号。
例如,如果您尝试先播放x11,然后再播放o11,它将正确地指出这是无效的播放,因为(1,1)已被占用。它适用于BUT(0,0)的每个位置,出于某种原因,它使您可以不断重复进行相同的移动。
我也知道在移动后它会正确绘制棋盘,因此如果您玩o00,它将在(0,0)处显示O,但随后它将忘记下一弯的位置。
示例:http://image.prntscr.com/image/e002bb6db5da4c7b823bf9bcac7af5eb.png
代码:
#include <stdio.h>
int main()
{
int board[3][3] = { 0 };
int i, j, linha, coluna, valido, run = 1;
char comando[3], jogador, ultimo_jogador;
while (run) {
//recebe o comando para executar esse turno
valido = 0;
do {
printf("Digite a jogada: ");
scanf(" %3[^\n]", comando);
jogador = comando[0];
linha = comando[1] - 48;
coluna = comando[2] - 48;
if ((jogador == 'x' || jogador == 'o') && jogador != ultimo_jogador && board[linha][coluna] == 0) {
if (jogador == 'x')
board[linha][coluna] = 1;
else if (jogador == 'o')
board[linha][coluna] = 2;
ultimo_jogador = jogador;
valido = 1;
}
else {
printf("Comando inválido\n");
}
} while (!valido);
//desenha o tabuleiro do jogo
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if (i == 0 && j == 0)
printf("Value at 0,0: %d\n", board[i][j]);
if (board[i][j] == 0) {
printf("_|");
}
else if (board[i][j] == 1) {
printf("X|");
}
else if (board[i][j] == 2) {
printf("O|");
}
}
printf("\n");
}
}
return 0;
}
您刚刚访问了未定义行为的aka UB。
我终于找到了一个解释:
您定义comando
的大小为3,但是在扫描字符串时,您输入的是3个字符,但您错过了字符串终止的空间。
在我们的测试中,该值会覆盖一些局部变量,例如i
或j
,这并不引人注目,因为它们是在每次之后都进行初始化的,但是您的编译器似乎board
在comando
缓冲区之后定位了内存(编译器可以对局部变量进行任何所需的操作地址)
结果是您每次输入值时都会覆盖第一个单元格。
解决方案:执行以下操作:
char comando[4];
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句