package tiny_libs
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
From-scratch libraries for teaching: graphics, audio, compression, crypto, networking and more
Install
dune-project
Dependency
Authors
Maintainers
Sources
0.3.6.tar.gz
md5=7c636383d146d30ac6f2fa234a6253c8
sha512=c79f3823c5f8f57e5038eb640d487c61168b84aa07c61999d6622ef9fd0c890e2b03b4c6a7cdbbe9352a49e25dda00ac7bb14693cee8e3d7beeed251351a2af0
doc/src/tiny_libs.ai_bots/Bot.ml.html
Source file Bot.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57(* Claude Code * * Copyright (C) 2026 Yoann Padioleau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * (LGPL) as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. *) (* See Bot.mli *) type ('world, 'senses, 'intent) t = { sense : 'senses option -> 'world -> 'senses; decide : 'senses -> 'intent; delay : int; rate : int; reflex : 'world -> 'intent -> 'intent; } let make ?(delay = 0) ?(rate = 1) ?(reflex = fun _ intent -> intent) ~(sense : 'senses option -> 'world -> 'senses) ~(decide : 'senses -> 'intent) () : ('world, 'senses, 'intent) t = { sense; decide; delay; rate = max 1 rate; reflex } (* [memory] holds the last [delay] + 1 senses, the newest first *) type ('senses, 'intent) running = { memory : 'senses list; last : 'intent; frame : int } let start (intent : 'intent) : ('senses, 'intent) running = { memory = []; last = intent; frame = 0 } let rec nth_or_last (l : 'a list) (n : int) : 'a option = match l with [] -> None | [ x ] -> Some x | x :: rest -> if n <= 0 then Some x else nth_or_last rest (n - 1) let step (bot : ('world, 'senses, 'intent) t) (world : 'world) (r : ('senses, 'intent) running) : 'intent * ('senses, 'intent) running = let memory = bot.sense (match r.memory with s :: _ -> Some s | [] -> None) world :: r.memory in (* keep what the delay needs, no more *) let memory = List.filteri (fun i _ -> i <= bot.delay) memory in let intent = if r.frame mod bot.rate <> 0 then r.last else match nth_or_last memory bot.delay with Some s -> bot.decide s | None -> r.last in (* claude: the decision is what is kept and repeated; the reflex * adjusts it to the world of this frame, every frame *) (bot.reflex world intent, { memory; last = intent; frame = r.frame + 1 }) let last_senses (r : ('senses, 'intent) running) : 'senses option = match r.memory with s :: _ -> Some s | [] -> None (* a smooth wobble in [-1, 1]: two sines that don't share a period, so * it doesn't repeat visibly *) let wobble (t : float) (seed : int) : float = let s = float_of_int seed in (sin ((t *. 0.37) +. (s *. 1.7)) +. sin ((t *. 0.11) +. (s *. 0.9))) /. 2. let aim_error ~(spread : float) ~(settle : float) ~(seen_for : int) ~(seed : int) () : float = let decay = if settle <= 0. then 0. else 0.5 ** (float_of_int seen_for /. settle) in spread *. decay *. wobble (float_of_int seen_for) seed
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>