阻止 Tic Tac Toe 覆盖 C 中的动作
Stop Tic Tac Toe from overwriting moves in C
抱歉,我几个小时前刚问了一个问题,但这是我完成项目所需要做的最后一件事。我的程序允许覆盖移动。就像说如果玩家 1 选择第一个方块,它将允许玩家 2 也选择这个方块。其他所有功能都完美无缺我只是在执行此操作时失败了。
有什么想法吗?我只放了一部分代码,因为很遗憾,我的很多代码都是复制粘贴的。我真的很新,所以我还没有想出优化,我已经没有时间做这个项目了,所以任何帮助将不胜感激。
所以在这段代码中,我只包含了原始棋盘的打印和第一位玩家的第一步(如果有 2 个人)。这应该足以获得帮助,但如果有人想查看其余代码,请告诉我,因为我已经省略了大部分代码。
谢谢!!!
#include <stdio.h>
#include <stdlib.h>
/* known bugs: Allows players to place a 1 or 2 on board even if there is already a 1 or 2 in that spot. */
int main()
{
char board[3][3];
int i,j,k,l, player, move;
for(i=0;i<=3;i++) // prints initial board of 0's
{
for(j=0;j<=3;j++)
{
board[i][j] = '0';
}
}
printf("Hello! Do you want to play alone or with a computer? \n\n"
"Enter 1 for alone or 2 to play with a friend!\n");
scanf("%d", &player);
if (player == 2)
{
for(k=0;k<9;k++) // 9 moves max.
{
printf("\n\n"); // print board again.
printf(" %c | %c | %c\n", board[0][0], board[0][1], board[0][2]);
printf("---+---+---\n");
printf(" %c | %c | %c\n", board[1][0], board[1][1], board[1][2]);
printf("---+---+---\n");
printf(" %c | %c | %c\n", board[2][0], board[2][1], board[2][2]);
do
{
printf("Player 1, where would you like to move? Enter 1-9\n");
scanf("%d", &move);
if (move == 1)
board[0][0] = '1';
if (move == 2)
board[0][1] = '1';
if (move == 3)
board[0][2] = '1';
if (move == 4)
board[1][0] = '1';
if (move == 5)
board[1][1] = '1';
if (move == 6)
board[1][2] = '1';
if (move == 7)
board[2][0] = '1';
if (move == 8)
board[2][1] = '1';
if (move == 9)
board[2][2] = '1';
}while(move>9 && move <1);
当您声明一个大小为 N 的数组时,索引将从零到 X 减一。
所以在你的例子中,board
数组的索引是 0
到 2
。 main
函数中的循环从 0
到 3
,即越界。
越界写入数组会导致 undefined behavior, and undefined behavior makes your program ill-formed. Undefined behavior (or UB) can cause any kind of problems, including seemingly work, just to the next moment lead to nasal demons。
- 我建议在最后一个 do while 循环中使用 switch case(参见示例)
- 我认为您只需要检查您引用的字段是否已被占用!
** check()
**
void check (char *c, int *move){
if(*c == '0'){
*c = '1';
}else {
printf("\nThis field is already taken! Please choose another one.\n");
/* since you repeat this as long as move is bigger than 9 or smaller
than 1, this will have the user make another choice. */
*move = 0;
}
}
** 你最后一次做**
do {
printf("Player 1, where would you like to move? Enter 1-9\n");
scanf("%d", &move);
switch (move){
case 1:
check(&board[0][0], &move);
break;
case 2:
check(&board[0][1], &move);
break;
case 3:
check(&board[0][2], &move);
break;
case 4:
check(&board[1][0], &move);
break;
case 5:
check(&board[1][1], &move);
break;
case 6:
check(&board[1][2], &move);
break;
case 7:
check(&board[2][0], &move);
break;
case 8:
check(&board[2][1], &move);
break;
case 9:
check(&board[2][2], &move);
break;
default:
printf("\nError! Choose a field between 1 and 9\n");
}
}while(move>9 || move <1);
注意:正如其他人所说,您的 for 循环需要迭代直到 i/j < 3,因为您的数组大小为 3(索引 0、1、2);
注意2:while语句必须是move > 9 OR move < 1
,因为int不能同时大于9小于1,会死循环
抱歉,我几个小时前刚问了一个问题,但这是我完成项目所需要做的最后一件事。我的程序允许覆盖移动。就像说如果玩家 1 选择第一个方块,它将允许玩家 2 也选择这个方块。其他所有功能都完美无缺我只是在执行此操作时失败了。
有什么想法吗?我只放了一部分代码,因为很遗憾,我的很多代码都是复制粘贴的。我真的很新,所以我还没有想出优化,我已经没有时间做这个项目了,所以任何帮助将不胜感激。
所以在这段代码中,我只包含了原始棋盘的打印和第一位玩家的第一步(如果有 2 个人)。这应该足以获得帮助,但如果有人想查看其余代码,请告诉我,因为我已经省略了大部分代码。 谢谢!!!
#include <stdio.h>
#include <stdlib.h>
/* known bugs: Allows players to place a 1 or 2 on board even if there is already a 1 or 2 in that spot. */
int main()
{
char board[3][3];
int i,j,k,l, player, move;
for(i=0;i<=3;i++) // prints initial board of 0's
{
for(j=0;j<=3;j++)
{
board[i][j] = '0';
}
}
printf("Hello! Do you want to play alone or with a computer? \n\n"
"Enter 1 for alone or 2 to play with a friend!\n");
scanf("%d", &player);
if (player == 2)
{
for(k=0;k<9;k++) // 9 moves max.
{
printf("\n\n"); // print board again.
printf(" %c | %c | %c\n", board[0][0], board[0][1], board[0][2]);
printf("---+---+---\n");
printf(" %c | %c | %c\n", board[1][0], board[1][1], board[1][2]);
printf("---+---+---\n");
printf(" %c | %c | %c\n", board[2][0], board[2][1], board[2][2]);
do
{
printf("Player 1, where would you like to move? Enter 1-9\n");
scanf("%d", &move);
if (move == 1)
board[0][0] = '1';
if (move == 2)
board[0][1] = '1';
if (move == 3)
board[0][2] = '1';
if (move == 4)
board[1][0] = '1';
if (move == 5)
board[1][1] = '1';
if (move == 6)
board[1][2] = '1';
if (move == 7)
board[2][0] = '1';
if (move == 8)
board[2][1] = '1';
if (move == 9)
board[2][2] = '1';
}while(move>9 && move <1);
当您声明一个大小为 N 的数组时,索引将从零到 X 减一。
所以在你的例子中,board
数组的索引是 0
到 2
。 main
函数中的循环从 0
到 3
,即越界。
越界写入数组会导致 undefined behavior, and undefined behavior makes your program ill-formed. Undefined behavior (or UB) can cause any kind of problems, including seemingly work, just to the next moment lead to nasal demons。
- 我建议在最后一个 do while 循环中使用 switch case(参见示例)
- 我认为您只需要检查您引用的字段是否已被占用!
** check()
**
void check (char *c, int *move){
if(*c == '0'){
*c = '1';
}else {
printf("\nThis field is already taken! Please choose another one.\n");
/* since you repeat this as long as move is bigger than 9 or smaller
than 1, this will have the user make another choice. */
*move = 0;
}
}
** 你最后一次做**
do {
printf("Player 1, where would you like to move? Enter 1-9\n");
scanf("%d", &move);
switch (move){
case 1:
check(&board[0][0], &move);
break;
case 2:
check(&board[0][1], &move);
break;
case 3:
check(&board[0][2], &move);
break;
case 4:
check(&board[1][0], &move);
break;
case 5:
check(&board[1][1], &move);
break;
case 6:
check(&board[1][2], &move);
break;
case 7:
check(&board[2][0], &move);
break;
case 8:
check(&board[2][1], &move);
break;
case 9:
check(&board[2][2], &move);
break;
default:
printf("\nError! Choose a field between 1 and 9\n");
}
}while(move>9 || move <1);
注意:正如其他人所说,您的 for 循环需要迭代直到 i/j < 3,因为您的数组大小为 3(索引 0、1、2);
注意2:while语句必须是move > 9 OR move < 1
,因为int不能同时大于9小于1,会死循环