gpt4 book ai didi

更改结构中定义的 int 值

转载 作者:太空宇宙 更新时间:2023-11-04 02:58:26 25 4
gpt4 key购买 nike

我用一个int n定义了一个struct Board,它的值是一个小整数。在 gtk 信号“点击”调用此方法之前,board->n 具有正确的值。但是,当调用此函数时,第一个 printf 语句打印出的 n 值非常大,为 32665。

draw_token (GtkButton *button, cairo_t *cr, Board *board){

printf("n: %d\n", board->n);

printf("button clicked\n");

//parse label of a button into the corresponding column number
guint col = (int)strtol(gtk_button_get_label(button), NULL, 0);

if (make_move(board, col) == false){
printf("draw cairo\n");
}
}

结构:

typedef struct board Board;
struct board{
int k;
int n;
char *moves;
int player;
};

回调所在的函数:

void gui_make_buttons(GtkWidget *box, Board *board){

guint n = board->n;
for (int i = 1 ; i <= n ; i++){
GtkWidget *button = gtk_button_new();
//make label for button
char label[3];
sprintf(label, "%d", i-1);

gtk_button_set_label((GtkButton*)button,label);

// gtk_widget_show(button);
gtk_container_add(GTK_CONTAINER(box), button);
g_signal_connect(button, "clicked",G_CALLBACK(gui_draw_token), board);
}
}

有人可以向我解释一下为什么每次单击按钮时 n 的值都会变为 36751 这样的大值吗?非常感谢

完整代码与main图形用户界面:

#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <stdbool.h>
#include "gui.h"
#include "board.h"
#include "connect.h"


gboolean draw_board (GtkWidget *widget, cairo_t *cr, gpointer board){

guint width, height;

width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);

guint row = height/((Board*)board)->n;
guint col = width/((Board*)board)->n;
printf("%d\n", row);
printf("%d\n", col);
// cairo_set_source_rgb (cr, 100, 100, 255);
// cairo_paint (cr);

cairo_set_source_rgb(cr, 0, 0, 255);
for (int i = 1; i < ((Board*)board)->n ; i++){
//draw horizontal grids;
cairo_move_to (cr, 0, row*i);
cairo_line_to (cr, width, row*i);
//draw vertical grids;
cairo_move_to (cr, col*i, 0);
cairo_line_to (cr, col*i, height);
}
// cairo_arc (cr, 100, 100, 50, 0, 2 * G_PI);

// cairo_move_to (cr, 30, 30);
// cairo_line_to (cr, 50, 50);
cairo_stroke (cr);
return false;
}


int main (int argc, char *argv[]){

//check for correct number of arguments.
if (!check_argument(argc, argv))
return EXIT_FAILURE;

int k = strtol(argv[1], NULL, 0);
int n = strtol(argv[2], NULL, 0);

play_game(k, n);

return EXIT_SUCCESS;
}

//show widgets and get gtk going
CGUI *gui_start_gtk(Board *board){

//assigns board to the gui struct at beginning of game
CGUI *gui = make_gui (board);
// gtk_widget_queue_draw (gui->drawing_area);
// gui_draw_init_board(gui);
gtk_widget_show_all (gui->window);
gtk_main ();
return gui;
}
/*
void gui_draw_init_board(GtkWidget *widget, cairo_t *cr, CGUI *gui){
printf("HI\n");
if (gui) {
guint k = gui->board->k;
guint n = gui->board->n;
printf("%d\n", k);
}
}
*/

void gui_make_buttons(GtkWidget *box, Board *board){

// guint n = board->n;
for (int i = 1 ; i <= (board->n) ; i++){
GtkWidget *button = gtk_button_new();
//make label for button
char label[3];
// sprintf(label, "%d", i-1);
sprintf(label, "%d", i-1);
gtk_button_set_label((GtkButton*)button,label);

// gtk_widget_show(button);
gtk_container_add(GTK_CONTAINER(box), button);
g_signal_connect(button, "clicked",G_CALLBACK(gui_draw_token), board);
}
}

void gui_draw_token (GtkButton *button, cairo_t *cr, gpointer board){

printf("button clicked\n");
printf("n: %d\n", ((Board*)board)->n);
//parse label of a button into the corresponding column number
guint col = (int)strtol(gtk_button_get_label(button), NULL, 0);
printf("%d\n", col);
printf("n: %d\n", ((Board*)board)->n);
if (make_move(board, col) == false){
printf("draw cairo\n");
}
}

CGUI *make_gui(Board *board){
CGUI *gui = (CGUI*) malloc(sizeof(CGUI));
//assign variables to gui object
gui->board = board;
GtkWidget *window;
GtkWidget *frame;
GtkWidget *drawing_area;

gtk_init(NULL, NULL);

//set up initial window
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Connect-N-K");

gtk_window_set_default_size (GTK_WINDOW(window), 600, 650);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_widget_show(window);
g_signal_connect_swapped(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), gui);
// g_signal_connect (window, "draw", G_CALLBACK (gui_draw_buttons), board);

//create boxes to fit buttons and drawing area
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
GtkWidget *draw_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget *button_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);

//make all buttons take up even amount of space
gtk_box_set_homogeneous((GtkBox*)button_box, true);

gtk_widget_set_size_request(button_box, 600, 50);

// gtk_box_pack_start (box, window, false, false, false);
gtk_container_add(GTK_CONTAINER(window), box);
gtk_container_add(GTK_CONTAINER(box), draw_box);
gtk_container_add(GTK_CONTAINER(box), button_box);
//set up initial frame
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_widget_set_size_request(frame, 600, 600);
gtk_container_add(GTK_CONTAINER(draw_box), frame);

//create and pack buttons.
gui_make_buttons(button_box, board);


//set up drawing area
drawing_area = gtk_drawing_area_new ();
gtk_widget_set_size_request(drawing_area, 600, 600);
gtk_container_add (GTK_CONTAINER (frame), drawing_area);

g_signal_connect (drawing_area, "draw", G_CALLBACK (draw_board), board);
printf("n: %d\n", board->n);
// printf("board in gui: %d\n", *board);

gui->window = window;
gui->frame = frame;
gui->drawing_area = drawing_area;

/*
//show widgets

连接.c:

/* connect.c */


#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "gui.h"
#include "board.h"
#include "connect.h"

#define BUFFER_SIZE 10

/*
static int check_argument(int argc, char *argv[]);
static void play_game(int k, int n);
*/
/*
int main(int argc, char *argv[]){
//check for correct number of arguments.
if (!check_argument(argc, argv))
return EXIT_FAILURE;

int k = strtol(argv[1], NULL, 0);
int n = strtol(argv[2], NULL, 0);




play_game(k, n);
return EXIT_SUCCESS;
}
*/

int check_argument(int argc, char *argv[]){
if(argc < 3 || argc >3){
fprintf(stderr, "Parameters entered incorrectly. Input two integers for k and n respectively.\n");
return false;
}
else
return true;

}

//go through all steps of the game
void play_game(int k, int n){
//check to see if k and n are appropriate
if(k>n){
fprintf(stderr, "k is greater than n, game will never be won.\n");
return;
}

Board *board = make_board(k, n);
// print_board(board);//print initial board

//initiate gui
// CGUI *gui = make_gui();//set first three vars
// gui_set_board(gui, board);//set the fourth var
// CGUI *gui = gui_start_gtk(board);


// connect_play_game_text(board);
connect_play_game_gui(board);


/* int player = 1; //let first player go first
char *s = (char*)malloc(BUFFER_SIZE);//allocate memory for int to read
int move_result;

do{
fgets(s, BUFFER_SIZE, stdin);
int cols = strtol(s, NULL, 0);
move_result = make_move(board,cols,player);

//switch players if legal move and no one wins
if(move_result == false)
player = 3-player;
//do nothing is move is illegal(move_result = -1, thus letting
//the same player choose again.
}
while(move_result != true);


//free up resources
free(s);
destroy_board(board);
*/
}

int connect_play_game_gui(Board *board){
printf("n in connect: %d\n", board->n);

CGUI *gui = gui_start_gtk(board);

// gui_set_board(gui, board);//set the fourth var
// int player = 1; //let first player go first
// char *s = (char*)malloc(BUFFER_SIZE);//allocate memory for int to read
// int move_result;
// fgets(s, BUFFER_SIZE, stdin);
// int cols = strtol(s, NULL, 0);
// move_result = make_move(board,cols,player);
//switch players if legal move and no one wins
// if(move_result == false){
// player = 3-player;
return true;
// }

//do nothing if move is illegal(move_result = -1, thus letting
//the same player choose again.
// while(move_result != true);

//free up resources
// free(s);
// destroy_board(board);
}

int connect_make_move_gui(int col, Board *board, int player){
return 1;
}

void connect_play_game_text(Board *board){
print_board(board);//print initial board

char *s = (char*)malloc(BUFFER_SIZE);//allocate memory for int to read
int move_result;

do{
fgets(s, BUFFER_SIZE, stdin);
int cols = strtol(s, NULL, 0);
move_result = make_move(board,cols);

}
while(move_result != true);
//free up resources
free(s);
destroy_board(board);
}

//initiate gui
//static void connect_init_gui

board.c:

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "board.h"
#define DRAW 2
#define ILLEGAL_MOVE -1


static char set_player_char(int player);
static int check_draw(Board *board);

//make a new board
Board *make_board(int k, int n){
Board *board = (Board *) malloc(sizeof(Board));
board->moves = (char *)malloc(n*n);
(board->k) = k;
(board->n) = n;
board->player = 1;

//make an array of empty slots based of size n^2
for(int i = 0; i < n*n; i++){
board->moves[i] = '.';
}
return board;
}

//print board with updated moves, print last row first.
void print_board(Board *board){
int n = board->n;
//loop through each row
for(int i = n-1; i >= 0; i--){
//loop through each column
for(int j = 0; j<n; j++){
printf("%c", (board->moves)[i*n+j]);
printf(" ");//add space between columns
}
printf("\n"); //wrap around each row
}
printf("\n");
}

//set char for player
static char set_player_char(int player){
char player_char;

if (player == 1)
player_char = 'o';
else
player_char = '*';

return player_char;
}

//update board based on player's input, return the row move is made
int make_move(Board *board, int x){
printf("inmakemove n: %d\n", board->n);
// printf("board in make_move: %d\n", &board);
//if move is illegal, return
if (!check_legal_move(board, x))
return ILLEGAL_MOVE;

int n = board->n;
int row;

//loop through the rows of the given column to find an empty spot.
for (int i = 0; i < n; i++){
if ((board->moves)[i*n+x] == '.'){
(board->moves)[i*n+x] = set_player_char(board->player);
row = i;
break;
}
}

print_board(board);

//Check to see if a player has won the game.;
int stat = check_win(board, x, row);
if (stat == true){
fprintf(stdout, "Player %d won the game.\n", board->player);
return true;
}

//if all slots are filled, game is a draw.
if(stat == DRAW){
fprintf(stdout, "Game was a draw.\n");
return true;
}

//if no one won, game continues.
else{
board->player = 3-(board->player);
return false;
}
}

//check to see if move x is legal
int check_legal_move(Board *board, int x){
int n = board->n;

//see if column entered is legal.
if (x >= (board->n) || x<0){
fprintf(stderr, "Illegal move by player %d at column %d\
, number entered outside range of available columns.\n", board->player, x);
return false;
}

//see if column entered is already filled
if ((board->moves)[(n-1)*n+x] != '.'){
fprintf(stderr, "Illegal move by player %d at column %d\
, column is already filled.\n", board->player, x);
return false;
}
return true;
}

//check for winning move
int check_win(Board* board, int x, int row){

int n = board->n;
int k = board->k;
int current_move = row*n+x; //slot that the current move fills

char *moves = board->moves;
char player_char = set_player_char(board->player);

int score;
score = 1;

//Check to see how many continuous slots are filled with the current player'
//s token horizontally.
//going right
for (int i = 1; i<k && x+i<n; i++){
if(moves[current_move+i] == player_char)
score ++;
else
break;
}

//going left
for(int i = 1; i<k && x-i>=0; i++){
if(moves[current_move-i] == player_char)
score++;
else
break;
}

//if horizontally connect to k, the player wins.
if (score>=k)
return true;

//if not, check vertical.
score = 1;
//going up
for (int i = 1; i<k && row+i<n; i++){
if(moves[current_move+n*i] == player_char)
score ++;
else
break;
}

//going down
for(int i = 1; i<k && row-i>=0; i++){
if(moves[current_move-n*i] == player_char)
score ++;
else
break;
}

//if vertically connect to k, the player wins.
if (score>=k)
return true;

//if not, check rising to right diagnol. Reset score like previously.
score = 1;

//going right and up
for(int i = 1; i<k && row+i<n && x+i<n; i++){
if(moves[current_move+n*i+i] == player_char)
score ++;
else
break;
}
//going left and down
for(int i = 1; i<k && row-i>=0 && x-i>=0; i++){
if(moves[current_move-n*i-i] == player_char)
score ++;
else
break;
}

//if right diagonally connect to k, the player wins.
if (score>=k)
return true;

//if not, check left rising diagonal.
score = 1;
//check right and down
for(int i = 1; i<k && x+i<n && row-i>=0; i++){
if(moves[current_move-n*i+i] == player_char)
score ++;
else
break;
}
//check left and up
for(int i = 1; i<k && x-i>=0 && row+i<n; i++){
if(moves[current_move+n*i-i] == player_char)
score ++;
else
break;
}

//if left diagonally connect to k, the player wins.
if (score>=k)
return true;

if(check_draw(board))
return DRAW;

//if no k connect is made in any direction, game is not won.
return false;
}

//check to see if game has come to a draw
static int check_draw(Board *board){
int n = board->n;

//loop through the top row to see if there are any empty slots left
for (int i = 0; i<n; i++){
if((board->moves)[n*(n-1)+i] == '.')
return false;
}
//if no empty slots left, game was a draw.
return true;
}

//Free up resources.
void destroy_board(Board *board){
free(board->moves);
free(board);
}

很抱歉,这又长又乱,我仍在编写代码并且是 C 语言的新手。

最佳答案

您需要将 void gui_draw_token (GtkButton *button, cairo_t *cr, gpointer board) 更改为 void gui_draw_token (GtkButton *button, gpointer board)

您不能只是编造回调签名并希望一切正常。对于签名,您需要查看适合信号的文档。例如在这种情况下 GtkButton clicked signal文档。

如果您删除所有不必要的代码并注释掉代码,这也将有助于我们回答您的问题。

关于更改结构中定义的 int 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14840850/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com