Odin SolutionsOdin Solutions

☠️

X Marks the Spot

Week 2, 2026

All Solutions

Odin Plotting with Raylib | greenya | Odin Solutions

// - use "odin run ." to run the code // - input.txt should be nearby with the input data // - map.jpg should be nearby package main import "core:fmt" import "core:strconv" import "core:strings" import rl "vendor:raylib" input_txt_bytes := #load("input.txt") map_jpg_bytes := #load("map.jpg") main :: proc () { rl.SetTraceLogLevel(.WARNING) rl.SetConfigFlags({ .VSYNC_HINT }) map_img := rl.LoadImageFromMemory(".jpg", raw_data(map_jpg_bytes), i32(len(map_jpg_bytes))) rl.InitWindow(map_img.width, map_img.height, "week2") defer rl.CloseWindow() map_tex := rl.LoadTextureFromImage(map_img) rl.UnloadImage(map_img) defer rl.UnloadTexture(map_tex) path_tex, path_map_origin := plot() path_tex_center := [2] f32 { f32(path_tex.width/2), f32(path_tex.height/2) } defer rl.UnloadTexture(path_tex) path_tex_top_left: [2] f32 is_align_mode := true for !rl.WindowShouldClose() { if rl.IsMouseButtonPressed(.LEFT) do is_align_mode ~= true mouse_pos := rl.GetMousePosition() mouse_pos_map := [2] f32 { path_map_origin.x - path_tex_top_left.x + mouse_pos.x, path_map_origin.y + path_tex_top_left.y - mouse_pos.y, } if is_align_mode { path_tex_top_left = mouse_pos - path_tex_center } rl.BeginDrawing() rl.DrawTexture(map_tex, 0, 0, rl.WHITE) rl.DrawTextureV(path_tex, path_tex_top_left, rl.WHITE) hint_cstr := fmt.ctprintf( "1. Align start of the path with the ship\n" + "2. Click with LMB to toggle Align Mode [%s]\n" + "3. Mouse over the cross in the path to see coordinates %v of the treasure", is_align_mode ? "ON" : "OFF", mouse_pos_map, ) rl.DrawText(hint_cstr, 20+1, 20+2, 20, rl.BLACK) rl.DrawText(hint_cstr, 20, 20, 20, rl.YELLOW) rl.EndDrawing() free_all(context.temp_allocator) } } plot :: proc () -> (path_tex: rl.Texture, path_map_origin: [2] f32) { context.allocator = context.temp_allocator path_img := rl.GenImageColor(4000, 4000, {0,0,0,100}) path_off := [2] i32 { path_img.width/2, path_img.height/2 } path_pos := path_off path_box := struct { left, right, top, bottom: i32 } { left = path_pos.x, right = path_pos.x, top = path_pos.y, bottom = path_pos.y, } input := strings.trim(string(input_txt_bytes), "\n\t ") entries := strings.split(input, " ") last_pos: [2] i32 #reverse for entry in entries { values := strings.split(entry, ",") assert(len(values) == 2) v1_str, v2_str := values[0], values[1] if v1_str[0]!='N' && v1_str[0]!='S' { x, x_ok := strconv.parse_f32(v1_str) y, y_ok := strconv.parse_f32(v2_str) assert(x_ok && y_ok) assert(last_pos == {}, "last pos already set") last_pos = { i32(x), i32(y) } continue } for v in values { dist, dist_ok := strconv.parse_int(v[1:], base=10) assert(dist_ok) if dist != 0 { dir: [2] i32 switch v[0] { case 'N': dir = {0,+1} case 'S': dir = {0,-1} case 'W': dir = {+1,0} case 'E': dir = {-1,0} case : panic("unexpected direction") } path_pos += dir * i32(dist) } } assert(path_pos.x>=0 && path_pos.x<path_img.width, "plot x pos overflow") assert(path_pos.y>=0 && path_pos.y<path_img.height, "plot y pos overflow") path_box = { left = min(path_box.left, path_pos.x), right = max(path_box.right, path_pos.x), top = min(path_box.top, path_pos.y), bottom = max(path_box.bottom, path_pos.y), } rl.ImageDrawCircle(&path_img, path_pos.x, path_pos.y, 2, rl.WHITE) } rl.ImageCrop(&path_img, { x = f32(path_box.left), y = f32(path_box.top), width = f32(path_box.right - path_box.left + 1), height = f32(path_box.bottom - path_box.top + 1), }) path_tex = rl.LoadTextureFromImage(path_img) rl.UnloadImage(path_img) path_map_origin = [2] f32 { f32(path_box.left - path_off.x + last_pos.x), f32(-path_box.top + path_off.y + last_pos.y), } fmt.printfln("last pos: %v", last_pos) fmt.printfln("path box: %#v", path_box) fmt.printfln("path box size: %i x %i", path_box.right-path_box.left, path_box.bottom-path_box.top) fmt.printfln("path_map_origin: %v", path_map_origin) return }