summaryrefslogtreecommitdiffhomepage
path: root/samples/13_path_finding_algorithms/04_early_exit
diff options
context:
space:
mode:
author_Tradam <[email protected]>2021-12-16 19:22:26 -0500
committerGitHub <[email protected]>2021-12-16 19:22:26 -0500
commit5954b9beb4d4a3b4f248d72d1851195f030558a8 (patch)
treefecd8aa840a25afdb502915b0fdb4d03b7ed339a /samples/13_path_finding_algorithms/04_early_exit
parent2f845281f133849256b57bb08fd3e9ae57600784 (diff)
parenteaa29e72939f5edf61735ccbb73c36ee89369f65 (diff)
downloaddragonruby-game-toolkit-contrib-master.tar.gz
dragonruby-game-toolkit-contrib-master.zip
Merge branch 'DragonRuby:master' into masterHEADmaster
Diffstat (limited to 'samples/13_path_finding_algorithms/04_early_exit')
-rw-r--r--samples/13_path_finding_algorithms/04_early_exit/app/main.rb204
-rw-r--r--samples/13_path_finding_algorithms/04_early_exit/replay.txt364
2 files changed, 466 insertions, 102 deletions
diff --git a/samples/13_path_finding_algorithms/04_early_exit/app/main.rb b/samples/13_path_finding_algorithms/04_early_exit/app/main.rb
index 1e9305b..40a3ba5 100644
--- a/samples/13_path_finding_algorithms/04_early_exit/app/main.rb
+++ b/samples/13_path_finding_algorithms/04_early_exit/app/main.rb
@@ -26,8 +26,8 @@ class EarlyExitBreadthFirstSearch
# And calculate the path
calc_path
end
- render
- input
+ render
+ input
end
def defaults
@@ -43,14 +43,14 @@ class EarlyExitBreadthFirstSearch
# This step is roughly the grid's width * height
# When anim_steps equals max_steps no more calculations will occur
# and the slider will be at the end
- state.max_steps ||= args.state.grid.width * args.state.grid.height
+ state.max_steps ||= args.state.grid.width * args.state.grid.height
# The location of the star and walls of the grid
# They can be modified to have a different initial grid
# Walls are stored in a hash for quick look up when doing the search
state.star ||= [2, 8]
state.target ||= [10, 5]
- state.walls ||= {}
+ state.walls ||= {}
# Variables that are used by the breadth first search
# Storing cells that the search has visited, prevents unnecessary steps
@@ -73,12 +73,12 @@ class EarlyExitBreadthFirstSearch
# We store this value, because we want to remember the value even when
# the user's cursor is no longer over what they're interacting with, but
# they are still clicking down on the mouse.
- state.current_input ||= :none
+ state.current_input ||= :none
end
# Draws everything onto the screen
def render
- render_background
+ render_background
render_heat_map
render_walls
render_path
@@ -91,8 +91,8 @@ class EarlyExitBreadthFirstSearch
# Draws what the grid looks like with nothing on it
def render_background
- render_unvisited
- render_grid_lines
+ render_unvisited
+ render_grid_lines
end
# Draws both grids
@@ -109,7 +109,7 @@ class EarlyExitBreadthFirstSearch
end
for y in 0..grid.height
- outputs.lines << horizontal_line(y)
+ outputs.lines << horizontal_line(y)
outputs.lines << early_exit_horizontal_line(y)
end
end
@@ -136,7 +136,7 @@ class EarlyExitBreadthFirstSearch
# Draws the walls on both grids
def render_walls
- state.walls.each_key do |wall|
+ state.walls.each_key do |wall|
outputs.solids << [scale_up(wall), wall_color]
outputs.solids << [early_exit_scale_up(wall), wall_color]
end
@@ -146,13 +146,13 @@ class EarlyExitBreadthFirstSearch
def render_star
outputs.sprites << [scale_up(state.star), 'star.png']
outputs.sprites << [early_exit_scale_up(state.star), 'star.png']
- end
+ end
# Renders the target on both grids
def render_target
outputs.sprites << [scale_up(state.target), 'target.png']
outputs.sprites << [early_exit_scale_up(state.target), 'target.png']
- end
+ end
# Labels the grids
def render_labels
@@ -244,8 +244,8 @@ class EarlyExitBreadthFirstSearch
# The program has to remember that the user is dragging an object
# even when the mouse is no longer over that object
# So detecting input and processing input is separate
- detect_input
- process_input
+ detect_input
+ process_input
end
# Determines what the user is editing and stores the value
@@ -253,53 +253,53 @@ class EarlyExitBreadthFirstSearch
# mouse left click is held
def detect_input
# When the mouse is up, nothing is being edited
- if inputs.mouse.up
- state.current_input = :none
+ if inputs.mouse.up
+ state.current_input = :none
# When the star in the no second grid is clicked
- elsif star_clicked?
- state.current_input = :star
+ elsif star_clicked?
+ state.current_input = :star
# When the star in the second grid is clicked
- elsif star2_clicked?
- state.current_input = :star2
+ elsif star2_clicked?
+ state.current_input = :star2
# When the target in the no second grid is clicked
- elsif target_clicked?
- state.current_input = :target
+ elsif target_clicked?
+ state.current_input = :target
# When the target in the second grid is clicked
- elsif target2_clicked?
- state.current_input = :target2
+ elsif target2_clicked?
+ state.current_input = :target2
# When a wall in the first grid is clicked
- elsif wall_clicked?
- state.current_input = :remove_wall
+ elsif wall_clicked?
+ state.current_input = :remove_wall
# When a wall in the second grid is clicked
- elsif wall2_clicked?
+ elsif wall2_clicked?
state.current_input = :remove_wall2
# When the first grid is clicked
- elsif grid_clicked?
+ elsif grid_clicked?
state.current_input = :add_wall
# When the second grid is clicked
- elsif grid2_clicked?
+ elsif grid2_clicked?
state.current_input = :add_wall2
end
end
# Processes click and drag based on what the user is currently dragging
def process_input
- if state.current_input == :star
- input_star
+ if state.current_input == :star
+ input_star
elsif state.current_input == :star2
- input_star2
- elsif state.current_input == :target
- input_target
- elsif state.current_input == :target2
- input_target2
- elsif state.current_input == :remove_wall
- input_remove_wall
+ input_star2
+ elsif state.current_input == :target
+ input_target
+ elsif state.current_input == :target2
+ input_target2
+ elsif state.current_input == :remove_wall
+ input_remove_wall
elsif state.current_input == :remove_wall2
- input_remove_wall2
- elsif state.current_input == :add_wall
- input_add_wall
- elsif state.current_input == :add_wall2
- input_add_wall2
+ input_remove_wall2
+ elsif state.current_input == :add_wall
+ input_add_wall
+ elsif state.current_input == :add_wall2
+ input_add_wall2
end
end
@@ -307,10 +307,10 @@ class EarlyExitBreadthFirstSearch
# Only resets the search if the star changes position
# Called whenever the user is editing the star (puts mouse down on star)
def input_star
- old_star = state.star.clone
+ old_star = state.star.clone
state.star = cell_closest_to_mouse
- unless old_star == state.star
- reset_search
+ unless old_star == state.star
+ reset_search
end
end
@@ -318,10 +318,10 @@ class EarlyExitBreadthFirstSearch
# Only resets the search if the star changes position
# Called whenever the user is editing the star (puts mouse down on star)
def input_star2
- old_star = state.star.clone
+ old_star = state.star.clone
state.star = cell_closest_to_mouse2
- unless old_star == state.star
- reset_search
+ unless old_star == state.star
+ reset_search
end
end
@@ -329,10 +329,10 @@ class EarlyExitBreadthFirstSearch
# Only reset_searchs the search if the target changes position
# Called whenever the user is editing the target (puts mouse down on target)
def input_target
- old_target = state.target.clone
+ old_target = state.target.clone
state.target = cell_closest_to_mouse
- unless old_target == state.target
- reset_search
+ unless old_target == state.target
+ reset_search
end
end
@@ -340,10 +340,10 @@ class EarlyExitBreadthFirstSearch
# Only reset_searchs the search if the target changes position
# Called whenever the user is editing the target (puts mouse down on target)
def input_target2
- old_target = state.target.clone
+ old_target = state.target.clone
state.target = cell_closest_to_mouse2
- unless old_target == state.target
- reset_search
+ unless old_target == state.target
+ reset_search
end
end
@@ -352,10 +352,10 @@ class EarlyExitBreadthFirstSearch
# The mouse needs to be inside the grid, because we only want to remove walls
# the cursor is directly over
# Recalculations should only occur when a wall is actually deleted
- if mouse_inside_grid?
+ if mouse_inside_grid?
if state.walls.has_key?(cell_closest_to_mouse)
- state.walls.delete(cell_closest_to_mouse)
- reset_search
+ state.walls.delete(cell_closest_to_mouse)
+ reset_search
end
end
end
@@ -365,31 +365,31 @@ class EarlyExitBreadthFirstSearch
# The mouse needs to be inside the grid, because we only want to remove walls
# the cursor is directly over
# Recalculations should only occur when a wall is actually deleted
- if mouse_inside_grid2?
+ if mouse_inside_grid2?
if state.walls.has_key?(cell_closest_to_mouse2)
- state.walls.delete(cell_closest_to_mouse2)
- reset_search
+ state.walls.delete(cell_closest_to_mouse2)
+ reset_search
end
end
end
# Adds a wall in the first grid in the cell the mouse is over
def input_add_wall
- if mouse_inside_grid?
+ if mouse_inside_grid?
unless state.walls.has_key?(cell_closest_to_mouse)
- state.walls[cell_closest_to_mouse] = true
- reset_search
+ state.walls[cell_closest_to_mouse] = true
+ reset_search
end
end
end
-
+
# Adds a wall in the second grid in the cell the mouse is over
def input_add_wall2
- if mouse_inside_grid2?
+ if mouse_inside_grid2?
unless state.walls.has_key?(cell_closest_to_mouse2)
- state.walls[cell_closest_to_mouse2] = true
- reset_search
+ state.walls[cell_closest_to_mouse2] = true
+ reset_search
end
end
end
@@ -399,10 +399,10 @@ class EarlyExitBreadthFirstSearch
# with the current grid as the initial state of the grid
def reset_search
# Reset_Searchs the search
- state.frontier = []
- state.visited = {}
- state.early_exit_visited = {}
- state.came_from = {}
+ state.frontier = []
+ state.visited = {}
+ state.early_exit_visited = {}
+ state.came_from = {}
state.path = {}
end
@@ -410,23 +410,23 @@ class EarlyExitBreadthFirstSearch
def step
# The setup to the search
# Runs once when there are no visited cells
- if state.visited.empty?
- state.visited[state.star] = true
- state.early_exit_visited[state.star] = true
- state.frontier << state.star
+ if state.visited.empty?
+ state.visited[state.star] = true
+ state.early_exit_visited[state.star] = true
+ state.frontier << state.star
state.came_from[state.star] = nil
end
# A step in the search
- unless state.frontier.empty?
+ unless state.frontier.empty?
# Takes the next frontier cell
- new_frontier = state.frontier.shift
+ new_frontier = state.frontier.shift
# For each of its neighbors
- adjacent_neighbors(new_frontier).each do |neighbor|
+ adjacent_neighbors(new_frontier).each do |neighbor|
# That have not been visited and are not walls
- unless state.visited.has_key?(neighbor) || state.walls.has_key?(neighbor)
+ unless state.visited.has_key?(neighbor) || state.walls.has_key?(neighbor)
# Add them to the frontier and mark them as visited in the first grid
- state.visited[neighbor] = true
+ state.visited[neighbor] = true
# Unless the target has been visited
unless state.visited.has_key?(state.target)
# Mark the neighbor as visited in the second grid as well
@@ -434,32 +434,32 @@ class EarlyExitBreadthFirstSearch
end
# Add the neighbor to the frontier and remember which cell it came from
- state.frontier << neighbor
+ state.frontier << neighbor
state.came_from[neighbor] = new_frontier
end
end
end
end
-
+
# Returns a list of adjacent cells
# Used to determine what the next cells to be added to the frontier are
def adjacent_neighbors(cell)
- neighbors = []
+ neighbors = []
# Gets all the valid neighbors into the array
# From southern neighbor, clockwise
- neighbors << [cell.x, cell.y - 1] unless cell.y == 0
- neighbors << [cell.x - 1, cell.y] unless cell.x == 0
- neighbors << [cell.x, cell.y + 1] unless cell.y == grid.height - 1
- neighbors << [cell.x + 1, cell.y] unless cell.x == grid.width - 1
+ neighbors << [cell.x, cell.y - 1] unless cell.y == 0
+ neighbors << [cell.x - 1, cell.y] unless cell.x == 0
+ neighbors << [cell.x, cell.y + 1] unless cell.y == grid.height - 1
+ neighbors << [cell.x + 1, cell.y] unless cell.x == grid.width - 1
# Sorts the neighbors so the rendered path is a zigzag path
# Cells in a diagonal direction are given priority
# Comment this line to see the difference
neighbors = neighbors.sort_by { |neighbor_x, neighbor_y| proximity_to_star(neighbor_x, neighbor_y) }
- neighbors
+ neighbors
end
# Finds the vertical and horizontal distance of a cell from the star
@@ -484,13 +484,13 @@ class EarlyExitBreadthFirstSearch
# Finding the cell closest to the mouse helps with this
def cell_closest_to_mouse
# Closest cell to the mouse in the first grid
- x = (inputs.mouse.point.x / grid.cell_size).to_i
- y = (inputs.mouse.point.y / grid.cell_size).to_i
+ x = (inputs.mouse.point.x / grid.cell_size).to_i
+ y = (inputs.mouse.point.y / grid.cell_size).to_i
# Bound x and y to the grid
- x = grid.width - 1 if x > grid.width - 1
- y = grid.height - 1 if y > grid.height - 1
+ x = grid.width - 1 if x > grid.width - 1
+ y = grid.height - 1 if y > grid.height - 1
# Return closest cell
- [x, y]
+ [x, y]
end
# When the user grabs the star and puts their cursor to the far right
@@ -498,15 +498,15 @@ class EarlyExitBreadthFirstSearch
# Finding the cell closest to the mouse in the second grid helps with this
def cell_closest_to_mouse2
# Closest cell grid to the mouse in the second
- x = (inputs.mouse.point.x / grid.cell_size).to_i
- y = (inputs.mouse.point.y / grid.cell_size).to_i
+ x = (inputs.mouse.point.x / grid.cell_size).to_i
+ y = (inputs.mouse.point.y / grid.cell_size).to_i
# Translate the cell to the first grid
x -= grid.width + 1
# Bound x and y to the first grid
- x = grid.width - 1 if x > grid.width - 1
- y = grid.height - 1 if y > grid.height - 1
+ x = grid.width - 1 if x > grid.width - 1
+ y = grid.height - 1 if y > grid.height - 1
# Return closest cell
- [x, y]
+ [x, y]
end
# Signal that the user is going to be moving the star from the first grid
@@ -585,12 +585,12 @@ class EarlyExitBreadthFirstSearch
# Light brown
def unvisited_color
- [221, 212, 213]
+ [221, 212, 213]
end
# Camo Green
def wall_color
- [134, 134, 120]
+ [134, 134, 120]
end
# Pastel White
@@ -620,7 +620,7 @@ def tick args
end
# Every tick, new args are passed, and the Breadth First Search tick is called
- $early_exit_breadth_first_search ||= EarlyExitBreadthFirstSearch.new(args)
+ $early_exit_breadth_first_search ||= EarlyExitBreadthFirstSearch.new
$early_exit_breadth_first_search.args = args
$early_exit_breadth_first_search.tick
end
diff --git a/samples/13_path_finding_algorithms/04_early_exit/replay.txt b/samples/13_path_finding_algorithms/04_early_exit/replay.txt
new file mode 100644
index 0000000..3ec9254
--- /dev/null
+++ b/samples/13_path_finding_algorithms/04_early_exit/replay.txt
@@ -0,0 +1,364 @@
+replay_version 2.0
+stopped_at 322
+seed 100
+recorded_at 2021-11-20 11:19:30 -0600
+[:mouse_button_up, 1, 0, 1, 1, 1]
+[:mouse_move, 806, 92, 2, 2, 12]
+[:mouse_move, 799, 105, 2, 3, 13]
+[:mouse_move, 786, 126, 2, 4, 13]
+[:mouse_move, 761, 154, 2, 5, 13]
+[:mouse_move, 722, 199, 2, 6, 14]
+[:mouse_move, 692, 230, 2, 7, 14]
+[:mouse_move, 659, 263, 2, 8, 14]
+[:mouse_move, 629, 297, 2, 9, 14]
+[:mouse_move, 598, 337, 2, 10, 15]
+[:mouse_move, 569, 376, 2, 11, 15]
+[:mouse_move, 538, 412, 2, 12, 15]
+[:mouse_move, 510, 438, 2, 13, 16]
+[:mouse_move, 488, 456, 2, 14, 16]
+[:mouse_move, 471, 467, 2, 15, 16]
+[:mouse_move, 459, 477, 2, 16, 17]
+[:mouse_move, 455, 481, 2, 17, 17]
+[:mouse_move, 455, 484, 2, 18, 18]
+[:mouse_move, 454, 485, 2, 19, 18]
+[:mouse_move, 464, 481, 2, 20, 23]
+[:mouse_move, 482, 477, 2, 21, 23]
+[:mouse_move, 490, 470, 2, 22, 23]
+[:mouse_move, 491, 469, 2, 23, 24]
+[:mouse_move, 492, 467, 2, 24, 24]
+[:mouse_move, 493, 466, 2, 25, 25]
+[:mouse_move, 485, 466, 2, 26, 26]
+[:mouse_move, 474, 468, 2, 27, 27]
+[:mouse_move, 460, 472, 2, 28, 27]
+[:mouse_move, 441, 476, 2, 29, 27]
+[:mouse_move, 419, 479, 2, 30, 27]
+[:mouse_move, 392, 480, 2, 31, 28]
+[:mouse_move, 359, 480, 2, 32, 28]
+[:mouse_move, 329, 483, 2, 33, 29]
+[:mouse_move, 306, 486, 2, 34, 29]
+[:mouse_move, 281, 493, 2, 35, 30]
+[:mouse_move, 271, 496, 2, 36, 30]
+[:mouse_move, 270, 496, 2, 37, 30]
+[:mouse_move, 272, 496, 2, 38, 32]
+[:mouse_move, 275, 496, 2, 39, 32]
+[:mouse_move, 279, 495, 2, 40, 32]
+[:mouse_move, 283, 494, 2, 41, 33]
+[:mouse_move, 289, 494, 2, 42, 33]
+[:mouse_move, 292, 494, 2, 43, 34]
+[:mouse_move, 293, 495, 2, 44, 35]
+[:mouse_button_pressed, 1, 0, 1, 45, 39]
+[:mouse_button_up, 1, 0, 1, 46, 40]
+[:mouse_move, 294, 495, 2, 47, 49]
+[:mouse_move, 294, 494, 2, 48, 50]
+[:mouse_move, 295, 491, 2, 49, 50]
+[:mouse_move, 296, 488, 2, 50, 50]
+[:mouse_move, 297, 484, 2, 51, 50]
+[:mouse_move, 297, 481, 2, 52, 51]
+[:mouse_move, 298, 477, 2, 53, 51]
+[:mouse_move, 298, 476, 2, 54, 51]
+[:mouse_move, 299, 475, 2, 55, 52]
+[:mouse_move, 300, 473, 2, 56, 52]
+[:mouse_move, 300, 472, 2, 57, 53]
+[:mouse_move, 300, 471, 2, 58, 55]
+[:mouse_move, 300, 470, 2, 59, 56]
+[:mouse_move, 300, 469, 2, 60, 57]
+[:mouse_move, 300, 467, 2, 61, 57]
+[:mouse_move, 300, 466, 2, 62, 57]
+[:mouse_button_pressed, 1, 0, 1, 63, 59]
+[:mouse_button_up, 1, 0, 1, 64, 61]
+[:mouse_move, 300, 465, 2, 65, 61]
+[:mouse_move, 300, 462, 2, 66, 62]
+[:mouse_move, 300, 456, 2, 67, 62]
+[:mouse_move, 300, 449, 2, 68, 62]
+[:mouse_move, 300, 443, 2, 69, 63]
+[:mouse_move, 299, 441, 2, 70, 63]
+[:mouse_move, 299, 440, 2, 71, 63]
+[:mouse_move, 299, 438, 2, 72, 64]
+[:mouse_move, 299, 437, 2, 73, 65]
+[:mouse_move, 299, 436, 2, 74, 65]
+[:mouse_move, 299, 434, 2, 75, 65]
+[:mouse_move, 299, 432, 2, 76, 65]
+[:mouse_move, 299, 431, 2, 77, 67]
+[:mouse_move, 299, 430, 2, 78, 67]
+[:mouse_move, 299, 429, 2, 79, 68]
+[:mouse_move, 299, 428, 2, 80, 68]
+[:mouse_move, 299, 424, 2, 81, 68]
+[:mouse_move, 300, 417, 2, 82, 69]
+[:mouse_move, 301, 413, 2, 83, 69]
+[:mouse_move, 302, 412, 2, 84, 70]
+[:mouse_button_pressed, 1, 0, 1, 85, 72]
+[:mouse_move, 302, 411, 2, 86, 72]
+[:mouse_button_up, 1, 0, 1, 87, 74]
+[:mouse_move, 302, 408, 2, 88, 94]
+[:mouse_move, 302, 396, 2, 89, 94]
+[:mouse_move, 302, 383, 2, 90, 95]
+[:mouse_move, 302, 375, 2, 91, 95]
+[:mouse_move, 303, 374, 2, 92, 95]
+[:mouse_move, 303, 373, 2, 93, 95]
+[:mouse_move, 303, 374, 2, 94, 99]
+[:mouse_button_pressed, 1, 0, 1, 95, 101]
+[:mouse_button_up, 1, 0, 1, 96, 103]
+[:mouse_move, 303, 375, 2, 97, 103]
+[:mouse_move, 306, 375, 2, 98, 132]
+[:mouse_move, 317, 376, 2, 99, 132]
+[:mouse_move, 333, 380, 2, 100, 133]
+[:mouse_move, 352, 384, 2, 101, 133]
+[:mouse_move, 374, 385, 2, 102, 133]
+[:mouse_move, 401, 390, 2, 103, 134]
+[:mouse_move, 424, 392, 2, 104, 134]
+[:mouse_move, 442, 395, 2, 105, 134]
+[:mouse_move, 455, 397, 2, 106, 135]
+[:mouse_move, 458, 398, 2, 107, 135]
+[:mouse_move, 460, 398, 2, 108, 136]
+[:mouse_move, 466, 398, 2, 109, 136]
+[:mouse_move, 473, 398, 2, 110, 136]
+[:mouse_move, 477, 398, 2, 111, 136]
+[:mouse_move, 478, 397, 2, 112, 136]
+[:mouse_move, 479, 397, 2, 113, 137]
+[:mouse_move, 480, 396, 2, 114, 137]
+[:mouse_move, 480, 395, 2, 115, 138]
+[:mouse_move, 480, 396, 2, 116, 138]
+[:mouse_move, 478, 404, 2, 117, 139]
+[:mouse_move, 474, 418, 2, 118, 139]
+[:mouse_move, 472, 426, 2, 119, 139]
+[:mouse_move, 466, 438, 2, 120, 140]
+[:mouse_move, 461, 453, 2, 121, 140]
+[:mouse_move, 453, 466, 2, 122, 140]
+[:mouse_move, 448, 473, 2, 123, 141]
+[:mouse_move, 446, 475, 2, 124, 141]
+[:mouse_move, 444, 477, 2, 125, 142]
+[:mouse_move, 441, 481, 2, 126, 142]
+[:mouse_move, 435, 489, 2, 127, 142]
+[:mouse_move, 426, 496, 2, 128, 143]
+[:mouse_move, 422, 498, 2, 129, 143]
+[:mouse_move, 422, 499, 2, 130, 143]
+[:mouse_move, 421, 499, 2, 131, 145]
+[:mouse_move, 420, 499, 2, 132, 145]
+[:mouse_button_pressed, 1, 0, 1, 133, 147]
+[:mouse_move, 419, 499, 2, 134, 148]
+[:mouse_move, 419, 497, 2, 135, 148]
+[:mouse_move, 421, 494, 2, 136, 149]
+[:mouse_move, 426, 484, 2, 137, 149]
+[:mouse_move, 432, 472, 2, 138, 149]
+[:mouse_move, 439, 460, 2, 139, 150]
+[:mouse_move, 445, 450, 2, 140, 150]
+[:mouse_move, 456, 434, 2, 141, 150]
+[:mouse_move, 466, 422, 2, 142, 150]
+[:mouse_move, 474, 411, 2, 143, 151]
+[:mouse_move, 480, 403, 2, 144, 151]
+[:mouse_move, 485, 397, 2, 145, 151]
+[:mouse_move, 489, 392, 2, 146, 151]
+[:mouse_move, 491, 389, 2, 147, 151]
+[:mouse_move, 494, 384, 2, 148, 151]
+[:mouse_move, 495, 381, 2, 149, 152]
+[:mouse_move, 497, 378, 2, 150, 152]
+[:mouse_move, 499, 376, 2, 151, 152]
+[:mouse_move, 500, 373, 2, 152, 152]
+[:mouse_move, 501, 372, 2, 153, 152]
+[:mouse_move, 501, 371, 2, 154, 152]
+[:mouse_move, 502, 370, 2, 155, 153]
+[:mouse_move, 502, 369, 2, 156, 153]
+[:mouse_move, 503, 369, 2, 157, 157]
+[:mouse_move, 504, 369, 2, 158, 158]
+[:mouse_move, 505, 368, 2, 159, 158]
+[:mouse_move, 508, 366, 2, 160, 158]
+[:mouse_move, 512, 364, 2, 161, 159]
+[:mouse_move, 513, 364, 2, 162, 159]
+[:mouse_move, 514, 364, 2, 163, 159]
+[:mouse_move, 515, 364, 2, 164, 160]
+[:mouse_move, 519, 364, 2, 165, 161]
+[:mouse_move, 526, 366, 2, 166, 161]
+[:mouse_move, 538, 372, 2, 167, 161]
+[:mouse_move, 550, 382, 2, 168, 161]
+[:mouse_move, 563, 397, 2, 169, 162]
+[:mouse_move, 570, 411, 2, 170, 162]
+[:mouse_move, 574, 425, 2, 171, 162]
+[:mouse_move, 576, 439, 2, 172, 163]
+[:mouse_move, 576, 448, 2, 173, 163]
+[:mouse_move, 576, 459, 2, 174, 163]
+[:mouse_move, 576, 470, 2, 175, 163]
+[:mouse_move, 576, 477, 2, 176, 163]
+[:mouse_move, 576, 481, 2, 177, 163]
+[:mouse_move, 576, 483, 2, 178, 163]
+[:mouse_move, 576, 485, 2, 179, 164]
+[:mouse_move, 576, 488, 2, 180, 164]
+[:mouse_move, 576, 494, 2, 181, 164]
+[:mouse_move, 577, 500, 2, 182, 164]
+[:mouse_move, 577, 501, 2, 183, 164]
+[:mouse_move, 579, 504, 2, 184, 164]
+[:mouse_move, 579, 505, 2, 185, 164]
+[:mouse_move, 581, 509, 2, 186, 165]
+[:mouse_move, 583, 512, 2, 187, 165]
+[:mouse_move, 584, 514, 2, 188, 165]
+[:mouse_move, 585, 516, 2, 189, 165]
+[:mouse_move, 586, 519, 2, 190, 165]
+[:mouse_move, 587, 521, 2, 191, 165]
+[:mouse_move, 588, 523, 2, 192, 166]
+[:mouse_move, 588, 524, 2, 193, 166]
+[:mouse_move, 588, 525, 2, 194, 166]
+[:mouse_move, 588, 526, 2, 195, 167]
+[:mouse_move, 588, 527, 2, 196, 167]
+[:mouse_move, 588, 526, 2, 197, 173]
+[:mouse_move, 586, 521, 2, 198, 173]
+[:mouse_move, 586, 516, 2, 199, 174]
+[:mouse_move, 585, 508, 2, 200, 174]
+[:mouse_move, 582, 500, 2, 201, 174]
+[:mouse_move, 578, 489, 2, 202, 174]
+[:mouse_move, 573, 476, 2, 203, 175]
+[:mouse_move, 568, 466, 2, 204, 175]
+[:mouse_move, 566, 461, 2, 205, 176]
+[:mouse_move, 565, 460, 2, 206, 176]
+[:mouse_move, 564, 460, 2, 207, 176]
+[:mouse_move, 563, 459, 2, 208, 176]
+[:mouse_move, 562, 459, 2, 209, 177]
+[:mouse_move, 561, 459, 2, 210, 177]
+[:mouse_move, 549, 459, 2, 211, 177]
+[:mouse_move, 522, 456, 2, 212, 177]
+[:mouse_move, 484, 456, 2, 213, 177]
+[:mouse_move, 423, 456, 2, 214, 177]
+[:mouse_move, 385, 454, 2, 215, 177]
+[:mouse_move, 359, 454, 2, 216, 178]
+[:mouse_move, 345, 452, 2, 217, 178]
+[:mouse_move, 343, 452, 2, 218, 178]
+[:mouse_move, 342, 451, 2, 219, 180]
+[:mouse_move, 343, 451, 2, 220, 180]
+[:mouse_move, 344, 449, 2, 221, 180]
+[:mouse_move, 348, 446, 2, 222, 180]
+[:mouse_move, 352, 444, 2, 223, 180]
+[:mouse_move, 362, 442, 2, 224, 181]
+[:mouse_move, 369, 441, 2, 225, 181]
+[:mouse_move, 376, 440, 2, 226, 181]
+[:mouse_move, 381, 439, 2, 227, 182]
+[:mouse_move, 385, 438, 2, 228, 182]
+[:mouse_move, 386, 438, 2, 229, 182]
+[:mouse_move, 387, 437, 2, 230, 183]
+[:mouse_move, 387, 436, 2, 231, 183]
+[:mouse_move, 388, 434, 2, 232, 183]
+[:mouse_move, 388, 430, 2, 233, 183]
+[:mouse_move, 387, 428, 2, 234, 183]
+[:mouse_move, 387, 427, 2, 235, 183]
+[:mouse_move, 386, 425, 2, 236, 184]
+[:mouse_move, 383, 425, 2, 237, 184]
+[:mouse_move, 382, 425, 2, 238, 185]
+[:mouse_move, 381, 425, 2, 239, 185]
+[:mouse_move, 380, 424, 2, 240, 185]
+[:mouse_move, 379, 424, 2, 241, 187]
+[:mouse_move, 378, 424, 2, 242, 189]
+[:mouse_move, 377, 424, 2, 243, 192]
+[:mouse_move, 376, 424, 2, 244, 192]
+[:mouse_move, 375, 424, 2, 245, 194]
+[:mouse_move, 374, 424, 2, 246, 195]
+[:mouse_move, 373, 424, 2, 247, 196]
+[:mouse_move, 372, 424, 2, 248, 197]
+[:mouse_move, 370, 425, 2, 249, 197]
+[:mouse_move, 368, 425, 2, 250, 198]
+[:mouse_move, 367, 425, 2, 251, 198]
+[:mouse_move, 366, 425, 2, 252, 198]
+[:mouse_button_up, 1, 0, 1, 253, 203]
+[:mouse_move, 365, 423, 2, 254, 204]
+[:mouse_move, 360, 418, 2, 255, 204]
+[:mouse_move, 356, 413, 2, 256, 205]
+[:mouse_move, 350, 407, 2, 257, 205]
+[:mouse_move, 344, 401, 2, 258, 205]
+[:mouse_move, 337, 396, 2, 259, 206]
+[:mouse_move, 326, 390, 2, 260, 206]
+[:mouse_move, 311, 381, 2, 261, 207]
+[:mouse_move, 303, 377, 2, 262, 207]
+[:mouse_move, 297, 374, 2, 263, 207]
+[:mouse_move, 296, 374, 2, 264, 207]
+[:mouse_button_pressed, 1, 0, 1, 265, 211]
+[:mouse_button_up, 1, 0, 1, 266, 212]
+[:mouse_move, 297, 374, 2, 267, 213]
+[:mouse_move, 298, 374, 2, 268, 220]
+[:mouse_move, 300, 378, 2, 269, 221]
+[:mouse_move, 301, 384, 2, 270, 221]
+[:mouse_move, 301, 393, 2, 271, 222]
+[:mouse_move, 301, 401, 2, 272, 222]
+[:mouse_move, 301, 409, 2, 273, 223]
+[:mouse_move, 301, 412, 2, 274, 223]
+[:mouse_move, 301, 413, 2, 275, 224]
+[:mouse_move, 301, 415, 2, 276, 224]
+[:mouse_move, 302, 418, 2, 277, 225]
+[:mouse_move, 303, 419, 2, 278, 225]
+[:mouse_move, 303, 420, 2, 279, 226]
+[:mouse_button_pressed, 1, 0, 1, 280, 228]
+[:mouse_button_up, 1, 0, 1, 281, 230]
+[:mouse_move, 303, 421, 2, 282, 230]
+[:mouse_move, 303, 422, 2, 283, 231]
+[:mouse_move, 303, 426, 2, 284, 231]
+[:mouse_move, 302, 429, 2, 285, 232]
+[:mouse_move, 302, 430, 2, 286, 232]
+[:mouse_move, 302, 432, 2, 287, 232]
+[:mouse_move, 302, 436, 2, 288, 233]
+[:mouse_move, 302, 438, 2, 289, 233]
+[:mouse_move, 302, 440, 2, 290, 233]
+[:mouse_move, 302, 441, 2, 291, 234]
+[:mouse_move, 302, 442, 2, 292, 234]
+[:mouse_move, 302, 443, 2, 293, 235]
+[:mouse_move, 302, 444, 2, 294, 236]
+[:mouse_move, 302, 445, 2, 295, 236]
+[:mouse_move, 303, 447, 2, 296, 237]
+[:mouse_move, 304, 451, 2, 297, 237]
+[:mouse_move, 304, 454, 2, 298, 237]
+[:mouse_move, 304, 456, 2, 299, 238]
+[:mouse_move, 304, 458, 2, 300, 238]
+[:mouse_move, 304, 460, 2, 301, 238]
+[:mouse_move, 304, 463, 2, 302, 239]
+[:mouse_button_pressed, 1, 0, 1, 303, 242]
+[:mouse_button_up, 1, 0, 1, 304, 244]
+[:mouse_move, 304, 464, 2, 305, 244]
+[:mouse_move, 304, 465, 2, 306, 245]
+[:mouse_move, 304, 470, 2, 307, 246]
+[:mouse_move, 304, 476, 2, 308, 246]
+[:mouse_move, 303, 485, 2, 309, 246]
+[:mouse_move, 301, 495, 2, 310, 247]
+[:mouse_move, 300, 500, 2, 311, 247]
+[:mouse_move, 300, 503, 2, 312, 247]
+[:mouse_move, 300, 506, 2, 313, 248]
+[:mouse_move, 301, 508, 2, 314, 248]
+[:mouse_move, 302, 510, 2, 315, 248]
+[:mouse_move, 302, 511, 2, 316, 249]
+[:mouse_move, 303, 512, 2, 317, 249]
+[:mouse_move, 303, 513, 2, 318, 251]
+[:mouse_button_pressed, 1, 0, 1, 319, 253]
+[:mouse_button_up, 1, 0, 1, 320, 255]
+[:mouse_move, 303, 512, 2, 321, 255]
+[:mouse_move, 304, 511, 2, 322, 265]
+[:mouse_move, 305, 511, 2, 323, 265]
+[:mouse_move, 307, 510, 2, 324, 266]
+[:mouse_move, 311, 509, 2, 325, 266]
+[:mouse_move, 315, 505, 2, 326, 266]
+[:mouse_move, 317, 504, 2, 327, 267]
+[:mouse_move, 317, 503, 2, 328, 268]
+[:mouse_move, 316, 503, 2, 329, 269]
+[:mouse_move, 316, 502, 2, 330, 289]
+[:mouse_move, 317, 501, 2, 331, 291]
+[:mouse_move, 318, 501, 2, 332, 292]
+[:mouse_move, 319, 501, 2, 333, 302]
+[:mouse_move, 319, 500, 2, 334, 303]
+[:key_down_raw, 96, 0, 2, 335, 303]
+[:mouse_move, 320, 500, 2, 336, 304]
+[:mouse_move, 323, 498, 2, 337, 304]
+[:mouse_move, 331, 496, 2, 338, 305]
+[:key_up_raw, 96, 0, 2, 339, 305]
+[:mouse_move, 341, 493, 2, 340, 305]
+[:mouse_move, 351, 489, 2, 341, 305]
+[:mouse_move, 363, 484, 2, 342, 306]
+[:mouse_move, 372, 482, 2, 343, 306]
+[:mouse_move, 384, 479, 2, 344, 306]
+[:mouse_move, 395, 479, 2, 345, 307]
+[:mouse_move, 402, 477, 2, 346, 307]
+[:mouse_move, 406, 475, 2, 347, 308]
+[:mouse_move, 403, 475, 2, 348, 308]
+[:mouse_move, 397, 473, 2, 349, 309]
+[:mouse_move, 394, 467, 2, 350, 311]
+[:mouse_move, 393, 467, 2, 351, 311]
+[:mouse_move, 397, 466, 2, 352, 312]
+[:mouse_move, 398, 465, 2, 353, 313]
+[:mouse_move, 399, 465, 2, 354, 313]
+[:mouse_move, 399, 464, 2, 355, 313]
+[:mouse_move, 400, 464, 2, 356, 314]
+[:mouse_move, 400, 463, 2, 357, 316]
+[:mouse_move, 401, 463, 2, 358, 318]
+[:mouse_move, 401, 462, 2, 359, 319]
+[:key_down_raw, 13, 0, 2, 360, 322]