You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

井字棋(Tic Tac Toe)首步标记不显示问题求助

井字棋首步标记无法显示的问题

我是编程新手,刚接触C语言,目前和伙伴开发井字棋(Tic Tac Toe)项目时遇到问题:首位玩家的第一步标记无法在控制台显示,但后续步骤的标记显示正常,且程序能正确识别该位置已被占用。

问题控制台输出

Welcome to Tic Tac Toe!
To make a selection, enter the row and column of the square you want to play.
Ex. 0,2 for first row, third column.


   |   |   
-----------
   |   |   
-----------
   |   |   



Player 1, choose between X or O to play: X
Do you want to start first? (Y/N): Y
Player , Where would you like to go?
Enter the row and then columns seperated by a comma here (e.g. 0,2): 1,1


   |   |   
-----------
   |  |   
-----------
   |   |   



Player X, Where would you like to go?
Enter the row and then columns seperated by a comma here (e.g. 0,2): 

项目代码

// Tic Tac Toe game

#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>

#define PLAYER_X 'X'
#define PLAYER_O 'O'
#define OPEN ' '

// use globals for now
char player1, player2;  // player is limited to X or O
char winner = '\0';
char board[3][3] =      // board is 3 rows by 3 columns
    {
        {OPEN, OPEN, OPEN},
        {OPEN, OPEN, OPEN},
        {OPEN, OPEN, OPEN}
    };

// declare functions here

void show_directions();
void show_cat(); 
void show_winner(); 
void display_board();
char choose_player1_mark ();
bool select_first_player();
void play(char player);
bool is_winner(char player);
bool is_board_full();
char get_next_player(char current_player);


int main()
{
    char player;

    show_directions();  // welcome text hey this is tic tac toe
    display_board();
    player1 = choose_player1_mark();
    player2 = (player1 == PLAYER_X) ? PLAYER_O : PLAYER_X;
    player = select_first_player();
    
  while(!is_board_full())
    {
        play(player);
        display_board();
        if (is_winner(player))
            break;
        else
            player = get_next_player(player);
    }
  
    if (winner)
        show_winner();
    else
        show_cat();

    return 0;
}

// define functions here
void show_directions()
{
  printf("Welcome to Tic Tac Toe!\n");
  printf("To make a selection, enter the row and column of the square you want to play.\n"); 
  printf("Ex. 0,2 for first row, third column.\n");
}

void display_board()
{
  printf("\n\n");
  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]);
  printf("\n\n\n");
}

char choose_player1_mark()
{
    char choice;
    printf("Player 1, choose between X or O to play: ");
    while (1)
    {
        scanf(" %c", &choice);
        choice = toupper(choice);
        if (choice == PLAYER_X || choice == PLAYER_O)
            return choice;
        else
            printf("Invalid choice. Please enter 'X' or 'O': ");
    }
}


bool select_first_player()
{
  char choice;
  printf("Do you want to start first? (Y/N): ");
  while (1) 
  {
    scanf(" %c", &choice);
    choice = toupper(choice);
    if (choice == 'Y') 
      return true; // player 1 starts first
    else if(choice == 'N') 
      return false; // player 2 starts first
    else 
      printf("Invalid choice. Please enter 'Y' or 'N': ");
  }
}

void play(char player)
{
  int row, column;
  printf("Player %c, Where would you like to go?\n", player);
  printf("Enter the row and then columns seperated by a comma here (e.g. 0,2): ");
  scanf("%d,%d", &row, &column);
  
  while (row < 0 || row > 2 || column < 0 || column > 2 || board[row][column] != OPEN)
    {
      printf("Invalid input. Try again.\n");
      printf("Enter the row and then columns seperated by a comma here (e.g. 0,2): ");
      scanf("%d,%d", &row, &column);
    }
  
    board[row][column] = player;
}

bool is_board_full()
{
  for (int i = 0; i < 3; i++)
    {
      for (int j = 0; j < 3; j++)
        {
          if (board[i][j] == OPEN)
          return false;
        }
    }
  return true;
}

bool is_winner(char player)
{
  // Check rows
  for (int i = 0; i < 3; i++)
    {
      if (board[i][0] == player && board[i][1] == player && board [i][2] == player)
        {
          winner = player;
          return true;
        }
    }

  // Check columns
  for (int j = 0; j < 3; j++)
    {
      if (board[0][j] == player && board[1][j] == player && board[2][j] == player)
        {
          winner = player;
          return true;
        }
    }

  // Check diagonals
  if (board[0][0] == player && board [1][1] == player && board[2][0] == player)
    {
      winner = player;
      return true;
    }

  return false;
}

char get_next_player(char current_player)
{
  return (current_player == PLAYER_X) ? PLAYER_O : PLAYER_X;
}

void show_winner()
{
  if (winner == PLAYER_X || winner == PLAYER_O)
  {
    printf("Player %c wins!\n:", winner);
  }
  else
  {
    printf("It's a tie! Cat game. \n");
  }
}

void show_cat()
{
  printf("It's a tie! Cat game.\n");
}

问题分析与修复

核心问题1:返回值类型不匹配

select_first_player返回bool类型,但main里用char player接收。true对应ASCII码1,false对应0,都是不可见字符,导致:

  • 第一步play函数里的提示打印出Player , ...
  • 落子后棋盘存入的是1/0,display_board打印时无法显示可见标记。

核心问题2:对角线胜利条件错误

is_winner里的对角线判断写错,应该是board[0][0] == player && board[1][1] == player && board[2][2] == player,且遗漏了另一条对角线board[0][2] == player && board[1][1] == player && board[2][0] == player。

修复步骤

1. 修正select_first_player函数

将返回类型改为char,直接返回对应玩家的标记:

// 修改函数声明
char select_first_player();

// 修改函数实现
char select_first_player()
{
  char choice;
  printf("Do you want to start first? (Y/N): ");
  while (1) 
  {
    scanf(" %c", &choice);
    choice = toupper(choice);
    if (choice == 'Y') 
      return player1; // 返回玩家1的标记
    else if(choice == 'N') 
      return player2; // 返回玩家2的标记
    else 
      printf("Invalid choice. Please enter 'Y' or 'N': ");
  }
}

2. 修正对角线判断逻辑

在is_winner函数中替换对角线判断代码:

// Check diagonals
if (board[0][0] == player && board[1][1] == player && board[2][2] == player)
{
  winner = player;
  return true;
}
// 补充另一条对角线判断
if (board[0][2] == player && board[1][1] == player && board[2][0] == player)
{
  winner = player;
  return true;
}

3. 修正show_winner的输出错误

去掉多余的冒号:

printf("Player %c wins!\n", winner);

修复后,第一步的玩家标记会正常显示,落子后棋盘能正确打印标记,对角线胜利条件也能正常触发。


内容的提问来源于stack exchange,提问作者birdawesome

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 02:59:51