c - 使用 C 中的二维数组和函数创建井字游戏程序
问题描述
在我的代码中,我总共有十个函数,我只能对其中两个进行完全编码,并且我已经设置了我的主要函数。我完全迷失了其他功能。如果您可以添加示例编码和解释,这将是一个巨大的帮助,以便我更好地理解。
这是我的代码:
#include <stdio.h>
#define SIZE 3
/* main function */
int main ()
{
char board[SIZE][SIZE];
int row, col;
clear_table (board);
display_table (board);
do
{
get_player1_mover (board, row, col);
generate_player2_move (board, row, col);
} while (check_end_of_game (board) == false);
print_winner (board);
return 0;
}
/* display table function */
void display_table (int board[][SIZE], int SIZE)
{
int row, col;
printf ("The current state of the game is:\n");
for (row = 0; row < SIZE; row++)
{
for (col = 0; col < SIZE; col++)
{
char board[row][col];
board[row][col] = '_';
printf ("%c ", board[row][col]);
}
printf ("\n");
}
}
/* clear table function */
void clear_table (int board[][SIZE], int SIZE)
{
int row, col;
char board[row][col];
for (row = 0; row < SIZE; row++) {
for (col = 0; col < SIZE; col++) {
if (board[row][col] == 'x' || array[row][col] == 'o') {
board[row][col] = '_';
}
}
}
}
/* check table full function */
/* return True if board is full */
/* return False if board is not full */
check_table_full (int board[][SIZE], int SIZE)
{
/* update table function */
/* updates board with player moves */
/* return nothing */
void update_table (int board[][SIZE], int SIZE)
{
/* check legal option function */
/* True if legal, False if not */
/* if move is within bounds of board or on empty cell */
check_legal_option (int board[][SIZE], int SIZE)
{
/* generate player2(computer) move function */
/* generate a random move */
/* update board */
/* print out current state of board */
void generate_player2_move (int board[][SIZE], int SIZE)
{
/* check three in a row function */
/* return zero if draw */
/* return one if player1 has three in a row */
/* return two if player2 has three in a row */
check_three_in_a_row (int board[][SIZE], int SIZE)
{
/* check end of game function */
/* return True if game ended */
/* return false if game continues */
check_end_of_game (int board[][SIZE], int SIZE)
{
/* get player 1 move function */
/* if given move is not valid get another move */
/* update board */
/* print out board */
void get_player1_move (int board[][SIZE], int SIZE)
{
int row, col;
printf
("Player 1 enter your selection [row, col]: ");
scanf ("%d,%d", &row, &col);
char board[row][col];
board[row][col] = 'o';
printf ("The current state of the game is:\n");
/* print winner function */
void print_winner (int board[][SIZE], int SIZE)
{
我已经完成的功能是display_table
并且clear_table
我几乎完成了get_player1_move
,但我对如何确保它打印出表格感到困惑。
解决方案
很明显,您被困在理解您的函数声明以及您使用过的int
地方和使用过的地方char
。(类型很重要)。
在解决任何其他问题之前,让编译器帮助您编写代码的第一件事是启用编译器警告。这意味着至少对于 gcc/clang,添加-Wall -Wextra
作为编译器选项(推荐:) -Wall -Wextra -pedantic -Wshadow
,对于 VS ( cl.exe
) 使用/W3
,并且 --在没有警告的情况下干净地编译之前不要接受代码!你的编译器会告诉你它看到有问题的代码的确切行(以及很多次列)。让编译器帮助您编写更好的代码。
接下来,您使用常量SIZE
为您的board
. 好的!如果你需要一个常数——#define
一个或多个——就像你一样。了解,当您定义一个常量时,它具有文件范围,可以在该文件内的任何函数中看到和使用它(或在包含定义常量的标头的任何文件中)。因此,无需将SIZE
参数作为参数传递给您的函数。他们知道是什么SIZE
,例如:
void display_table (char board[][SIZE]);
void clear_table (char board[][SIZE]);
接下来,您不能char board[row][col];
像在clear_table()
. 该声明“遮蔽”了您传递参数的board
from声明,例如. (因此,当你尝试有创意的东西时,包括编译器选项来警告你的建议......)同样适用于.main()
void clear_table (char board[][SIZE]);
-Wshadow
display_table
当您重新声明board
in clear_table
(eg char board[row][col];
) 然后使用board
in 时,您正在更新函数本地clear_table
的重新声明board
(因此在函数返回时被销毁),因此永远不会在.main()
此外,您将 board 声明为 type char
in main()
,例如
char board[SIZE][SIZE] = {{0}}; /* initialize all variables */
但然后尝试board
作为类型传递int
,例如
void display_table (int board[][SIZE], int SIZE) {
您的参数需要与您的声明类型相匹配。
通过这些简单的调整和清理您clear_table
的display_table
一点点,您可以执行以下操作:
/* display table function */
void display_table (char board[][SIZE])
{
int row, col;
printf ("\nThe current state of the game is:\n");
for (row = 0; row < SIZE; row++) {
for (col = 0; col < SIZE; col++) {
putchar (' ');
if (board[row][col])
putchar (board[row][col]); /* use putchar for a single char */
else
putchar ('_');
}
putchar ('\n');
}
}
/* clear table function */
void clear_table (char board[][SIZE])
{
int row, col;
// char board[row][col]; /* don't redeclare board */
/* your compiler should be screaming warnings */
for (row = 0; row < SIZE; row++)
for (col = 0; col < SIZE; col++)
board[row][col] = '_'; /* just clear, no need to check */
}
现在只需确保您在文件中提供上述函数的原型,以便在 调用它们之前知道这两个函数的存在(或者,您可以移动上面两个函数的定义)。(必须先声明一个函数,然后才能使用它——这意味着在文件的“自上而下读取”中调用它的函数之上)main()
main()
main()
main()
您的两个函数的代码并没有那么遥远,您只是缺少一些实现细节(规则)。要提供一个有效的clear_table
and display_table
(以及一个俗气的diagonal_x
函数来初始化对角线到 all'x'
和其余部分到'o'
,你可以这样做:
#include <stdio.h>
#define SIZE 3 /* if you need a constant, #define one (Good!) */
void display_table (char board[][SIZE]);
void clear_table (char board[][SIZE]);
/* cheezy init funciton */
void diagonal_x (char (*board)[SIZE])
{
for (int row = 0; row < SIZE; row++)
for (int col = 0; col < SIZE; col++)
if (row == col)
board[row][col] = 'x';
else
board[row][col] = 'o';
}
int main (void) /* no comment needed, main() is main() */
{
char board[SIZE][SIZE] = {{0}}; /* initialize all variables */
clear_table (board); /* set board to all '_' */
display_table (board); /* output board */
diagonal_x (board); /* init board to diagonal_x */
display_table (board); /* output board */
/*
do {
get_player1_mover (board, row, col);
generate_player2_move (board, row, col);
} while (check_end_of_game (board) == false);
print_winner (board);
*/
return 0;
}
/* display table function */
void display_table (char board[][SIZE])
{
int row, col;
printf ("\nThe current state of the game is:\n");
for (row = 0; row < SIZE; row++) {
for (col = 0; col < SIZE; col++) {
putchar (' ');
if (board[row][col])
putchar (board[row][col]); /* use putchar for a single char */
else
putchar ('_');
}
putchar ('\n');
}
}
/* clear table function */
void clear_table (char board[][SIZE])
{
int row, col;
// char board[row][col]; /* don't redeclare board */
/* your compiler should be screaming warnings */
for (row = 0; row < SIZE; row++)
for (col = 0; col < SIZE; col++)
board[row][col] = '_'; /* just clear, no need to check */
}
(注意:是否包含封闭循环'{'
或'}'
仅包含单个表达式的条件取决于您。它可能有助于使事情变得直接 - 取决于您)
另请注意,您可以board
作为指向数组的指针传递char [SIZE]
,例如char (*board)[SIZE]
和char board[][SIZE]
,它们是等价的。
示例使用/输出
注意:我在板中的每个字符之前添加了一个空格,以使显示更具可读性 - 如果您愿意,可以将其删除。
$ ./bin/checkerinit
The current state of the game is:
_ _ _
_ _ _
_ _ _
The current state of the game is:
x o o
o x o
o o x
这应该会让你继续前进。如果您还有其他问题,请告诉我。
推荐阅读
- java - How to inject beans without interface in Mongock changelogs
- java - 无法通过 Gradle 使用 log4j 将日志写入日志文件
- javascript - TypeError [INVALID_TYPE]:提供的覆盖不是权限覆盖的数组或集合。不和谐 v12
- hyperledger-fabric - Hyperledger Fabric getState 不返回所有数据
- visual-studio - Visual Studio 测试资源管理器 - 使用 CMake 和远程构建的 GTest
- reactjs - 如果记忆化效率不高,我可以在 React 中保持派生状态吗?
- blazor - Blazor - 重新加载网格组件
- php - 如何在一个功能中添加多个简码?
- laravel - Laravel 使用 where 条件更新记录
- swift - 迅速,我怎样才能从我的表格视图中删除一个对象?