- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我用一个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/
我正在尝试使用 y 组合器在 Scala 中定义 gcd: object Main { def y[A,B]( f : (A => B) => A => B ) : A => B = f(y(f)
我正在尝试了解返回指向函数的指针的函数,在我尝试编译代码后,它给了我这种错误: cannot convert int (*(int))(int) to int (*(int))(int) in ass
所以我一直在关注 youtube 上的游戏编程教程,然后弹出了这段代码:bufferedImageObject.getRGB(int, int, int, int, int[], int, int);
我正在将时间现在 与存储在数据库某处的时间进行比较。数据库中存储的时间格式为“yyyyMMddHHmmss”。例如,数据库可能会为存储的时间值返回 201106203354。然后我使用一个函数将时间现
例如 Maze0.bmp (0,0) (319,239) 65 120 Maze0.bmp (0,0) (319,239) 65 120 (254,243,90) Maze0.bmp (0,0) (
评论 Steve Yegge的post关于 server-side Javascript开始讨论语言中类型系统的优点和这个 comment描述: ... examples from H-M style
我正在研究 C 的指针,从 Deitel 的书中我不明白 int(*function)(int,int) 和 int*function(int, int) 表示函数时。 最佳答案 C 中读取类型的经验
您好,我使用 weblogic 11g 创建 war 应用程序,我对 joda time 的方法有疑问 new DateTime(int, int, int, int, int, int); 这抛出了
Create a method called average that calculates the average of the numbers passed as parameters. The
var a11: Int = 0 var a12: Int = 0 var a21: Int = 0 var a22: Int = 0 var valueDeterminant = a11 * a12
我正在为一个项目设置 LED 阵列。我得到了一个 LED 阵列,可以根据引脚变化电压进行更改,但我无法添加更多引脚。 当我尝试时,编译失败并显示错误:函数“int getMode(int, int,
除了创建对列表执行简单操作的函数之外,我对 haskell 还是很陌生。我想创建一个列表,其中包含 Int 类型的内容, 和 Int -> Int -> Int 类型的函数. 这是我尝试过的: dat
这个问题已经有答案了: Java add buttons dynamically as an array [duplicate] (4 个回答) 已关闭 7 年前。 StackOverFlow问题今天
我有几个 EditText View ,我想在其中设置左侧的图像,而 setCompoundDrawablesWithIntrinsicBounds 似乎不起作用。图形似乎没有改变。 有人知道为什么会
#include using namespace std; int main() { static_assert(is_constructible, int(*)(int,int)>::val
fun sum(a: Int, b: Int) = a + b val x = 1.to(2) 我在找: sum.tupled(x),或者 sum(*x) 当然,以上都不能用 Kotlin 1.1.3
有一个函数: func (first: Int) -> Int -> Bool -> String { return ? } 返回值怎么写?我对上面 func 的返回类型感到很困惑。 最
type foo = A of int * int | B of (int * int) int * int 和 (int * int) 有什么区别?我看到的唯一区别在于模式匹配: let test_
我正在尝试制作一个 slider 游戏。在这个类中,我使用 Graphics 对象 g2 的 drawImage 方法来显示“拼图”的 block 。但在绘制类方法中,我收到此错误:找不到符号方法dr
我试着理解这个表达: static Func isOdd = i => (i & 1) == 1; 但是这是什么意思呢? 例如我有 i = 3。然后 (3 & 1) == 1 或 i = 4。然后
我是一名优秀的程序员,十分优秀!