void canvas_fill_with_image (Canvas *canvas, Image image) { size_t width, height; size_t x, y, i; size_t amount; size_t size; size_t doubled; if (!canvas) { error (InvalidArgument); return; } width = canvas->image.width < image.width ? canvas->image.width : image.width; height = canvas->image.height < image.height ? canvas->image.height : image.height; if (!canvas_lock (canvas)) { error_code (FunctionCall, 1); return; } for (y = 0; y < height; y++) { memcpy (&canvas->image.map[y * canvas->image.width], &image.map[y * image.width], width * sizeof (Color)); } for (x = width; x < canvas->image.width; x += amount) { if (size_t_add (x, x, &doubled)) { amount = doubled < canvas->image.width ? x : canvas->image.width - x; } else { amount = canvas->image.width - x; } for (y = 0; y < height; y++) { memmove (&canvas->image.map[(y * canvas->image.width) + x], &canvas->image.map[(y * canvas->image.width)], amount * sizeof (Color)); } } size = canvas->image.width * canvas->image.height; for (i = canvas->image.width * height; i < canvas->image.width * canvas->image.height; i += amount) { if (size_t_add (i, i, &doubled)) { amount = doubled < size ? i : size - i; } else { amount = size - i; } memmove (&canvas->image.map[i], &canvas->image.map[0], amount * sizeof (Color)); } set_changed (canvas, position_value (0, 0), position_value (canvas->image.width - 1, canvas->image.height - 1)); if (!canvas_unlock (canvas)) { error_code (FunctionCall, 2); return; } }
//! The evaluation function is especially complex given that it had to be run on pencil and paper. const Move& Alan_Turing_AI::choose_move(const Board& board, const Clock&) const { // Every possible first move is considerable std::pair<double, double> best_first_move_score = {-1001.0, -1001.0}; // maximize auto best_first_move = board.legal_moves().front(); for(auto first_move : board.legal_moves()) { auto first_board = board; auto first_move_result = first_board.submit_move(*first_move); std::pair<double, double> first_move_score; if(first_move_result.game_has_ended()) { first_move_score = position_value(first_board, board.whose_turn(), first_move_result); } else { // Every possible reply is considerable std::pair<double, double> worst_second_move_score = {1001.0, 1001.0}; // minimize for(auto second_move : first_board.legal_moves()) { auto second_board = first_board; std::pair<double, double> second_move_score; auto second_move_result = second_board.submit_move(*second_move); if(second_move_result.game_has_ended()) { second_move_score = position_value(second_board, board.whose_turn(), second_move_result); } else { std::pair<double, double> best_third_move_score = {-1001.0, -1001.0}; // maximize for(auto third_move : second_board.legal_moves()) { auto third_board = second_board; auto third_move_result = third_board.submit_move(*third_move); auto third_move_score = position_value(third_board, board.whose_turn(), third_move_result); best_third_move_score = std::max(best_third_move_score, third_move_score); } second_move_score = best_third_move_score; } worst_second_move_score = std::min(worst_second_move_score, second_move_score); } first_move_score = worst_second_move_score; } if(first_move_score > best_first_move_score) { best_first_move = first_move; best_first_move_score = first_move_score; } } return *best_first_move; }
void canvas_fill_with_color (Canvas *canvas, Color color) { size_t size; size_t amount = 32; size_t i; size_t doubled; (void)color; if (!canvas) { error (InvalidArgument); return; } size = canvas->image.width * canvas->image.height; if (!canvas_lock (canvas)) { error_code (FunctionCall, 1); return; } for (i = 0; i < size && i < amount; i++) { canvas->image.map[i] = color; } for (; i < size; i += amount) { if (size_t_add (i, i, &doubled)) { amount = doubled < size ? i : size - i; } else { amount = size - i; } memmove (&canvas->image.map[i], &canvas->image.map[0], amount * sizeof (Color)); } set_changed (canvas, position_value (0, 0), position_value (canvas->image.width - 1, canvas->image.height - 1)); if (!canvas_unlock (canvas)) { error_code (FunctionCall, 2); return; } }
void canvas_draw_image (Canvas *canvas, Position position, Image image) { size_t right; size_t bottom; size_t row; if (!canvas) { error (InvalidArgument); return; } if (!size_t_add (position.x, image.width, &right)) { error_code (Overflow, 1); return; } if (!size_t_add (position.y, image.height, &bottom)) { error_code (Overflow, 2); return; } if (canvas->image.width < right) { error_code (GraphicsOutOfRange, 1); return; } if (canvas->image.height < bottom) { error_code (GraphicsOutOfRange, 2); return; } if (!canvas_lock (canvas)) { error_code (FunctionCall, 1); return; } for (row = 0; row < image.height; row++) { memcpy (&canvas->image.map[(position.y * canvas->image.width) + position.x + (row * canvas->image.width)], &image.map[row * image.width], image.width * sizeof (Color)); } set_changed (canvas, position, position_value (position.x + image.width - 1, position.y + image.height - 1)); if (!canvas_unlock (canvas)) { error_code (FunctionCall, 2); return; } }
void canvas_fill_rectangle_with_image (Canvas *canvas, Rectangle rectangle, Image image) { size_t width, height; size_t x, y; size_t amount; size_t doubled; size_t right; size_t bottom; if (!canvas) { error (InvalidArgument); return; } if (!size_t_add (rectangle.x, rectangle.width, &right)) { error_code (Overflow, 1); return; } if (!size_t_add (rectangle.y, rectangle.height, &bottom)) { error_code (Overflow, 2); return; } if (canvas->image.width < right) { error_code (GraphicsOutOfRange, 1); return; } if (canvas->image.height < bottom) { error_code (GraphicsOutOfRange, 2); return; } width = rectangle.width < image.width ? rectangle.width : image.width; height = rectangle.height < image.height ? rectangle.height : image.height; if (!canvas_lock (canvas)) { error_code (FunctionCall, 1); return; } /* Copy image to rectangle top corner. */ for (y = 0; y < height; y++) { memcpy (&canvas->image.map[((y + rectangle.y) * canvas->image.width) + rectangle.x], &image.map[y * image.width], width * sizeof (Color)); } /* Tile horizontally. */ for (x = width; x < rectangle.width; x += amount) { if (size_t_add (x, x, &doubled)) { amount = doubled < rectangle.width ? x : rectangle.width - x; } else { amount = rectangle.width - x; } for (y = 0; y < height; y++) { memmove (&canvas->image.map[((y + rectangle.y) * canvas->image.width) + rectangle.x + x], &canvas->image.map[((y + rectangle.y) * canvas->image.width) + rectangle.x], amount * sizeof (Color)); } } /* Tile vertically. */ for (y = rectangle.y; y + height < rectangle.y + rectangle.height; y++) { memmove (&canvas->image.map[((y + height) * canvas->image.width) + rectangle.x], &canvas->image.map[(y * canvas->image.width) + rectangle.x], rectangle.width * sizeof (Color)); } set_changed (canvas, position_value (rectangle.x, rectangle.y), position_value (rectangle.x + rectangle.width - 1, rectangle.y + rectangle.height - 1)); if (!canvas_unlock (canvas)) { error_code (FunctionCall, 1); return; } }
void canvas_fill_rectangle_with_color (Canvas *canvas, Rectangle rectangle, Color color) { size_t amount = 32; size_t i; size_t doubled; size_t right; size_t bottom; if (!canvas) { error (InvalidArgument); return; } if (!size_t_add (rectangle.x, rectangle.width, &right)) { error_code (Overflow, 1); return; } if (!size_t_add (rectangle.y, rectangle.height, &bottom)) { error_code (Overflow, 2); return; } if (canvas->image.width < right) { error_code (GraphicsOutOfRange, 1); return; } if (canvas->image.height < bottom) { error_code (GraphicsOutOfRange, 2); return; } if (!canvas_lock (canvas)) { error_code (FunctionCall, 1); return; } /* Manually copy 32 pixels horizontally */ for (i = 0; i < rectangle.width && i < amount; i++) { canvas->image.map[(rectangle.y * canvas->image.width) + rectangle.x + i] = color; } /* Copy pixels horizontally until full. */ for (; i < rectangle.width; i += amount) { if (size_t_add (i, i, &doubled)) { amount = i + i < rectangle.width ? i : rectangle.width - i; } else { amount = rectangle.width - i; } memmove (&canvas->image.map[(rectangle.y * canvas->image.width) + rectangle.x + i], &canvas->image.map[(rectangle.y * canvas->image.width) + rectangle.x], amount * sizeof (Color)); } /* Copy vertically. */ for (i = 0; i < rectangle.height; i++) { memmove (&canvas->image.map[(rectangle.y * canvas->image.width) + rectangle.x + (i * canvas->image.width)], &canvas->image.map[(rectangle.y * canvas->image.width) + rectangle.x], rectangle.width * sizeof (Color)); } set_changed (canvas, position_value (rectangle.x, rectangle.y), position_value (rectangle.x + rectangle.width - 1, rectangle.y + rectangle.height - 1)); if (!canvas_unlock (canvas)) { error_code (FunctionCall, 1); return; } }
int Fl_Slider::handle(int event, int x, int y, int w, int h) { switch (event) { case FL_FOCUS: case FL_UNFOCUS: redraw(FL_DAMAGE_ALL); return 1; case FL_PUSH: redraw(FL_DAMAGE_HIGHLIGHT); handle_push(); case FL_DRAG: { // figure out the space the slider moves in and where the event is: int mx; if (horizontal()) { w = w-box()->dw(); mx = Fl::event_x()-x-box()->dx(); } else { w = h-box()->dh(); mx = Fl::event_y()-y-box()->dy(); } if (w <= slider_size_) return 1; static int offcenter; int X = slider_position(value(), w); if (event == FL_PUSH) { offcenter = mx-X; // we are done if they clicked on the slider: if (offcenter >= (slider_size() ? 0 : -8) && offcenter <= slider_size_) return 1; if (Fl::event_button() > 1) { // Move the near end of the slider to the cursor. This is good // for scrollbars. offcenter = (offcenter < 0) ? 0 : slider_size_; } else { // Center the slider under the cursor, what most toolkits do offcenter = slider_size_/2; } } double v; RETRY: X = mx-offcenter; if (X < 0) { X = 0; offcenter = mx; if (offcenter < 0) offcenter = 0; } else if (X > (w-slider_size_)) { X = w-slider_size_; offcenter = mx-X; if (offcenter > slider_size_) offcenter = slider_size_; } v = position_value(X, w); handle_drag(v); // make sure a click outside the sliderbar moves it: if (event == FL_PUSH && value() == previous_value()) { offcenter = slider_size_/2; event = FL_DRAG; goto RETRY; } return 1; } case FL_RELEASE: handle_release(); redraw(FL_DAMAGE_HIGHLIGHT); return 1; case FL_KEY: // Only arrows in the correct direction are used. This allows the // opposite arrows to be used to navigate between a set of parellel // sliders. switch (Fl::event_key()) { case FL_Up: case FL_Down: if (horizontal()) return 0; break; case FL_Left: case FL_Right: if (!horizontal()) return 0; } default: return Fl_Valuator::handle(event); } }