Skip to content

Instantly share code, notes, and snippets.

@abaines
Last active April 1, 2025 13:16
Show Gist options
  • Save abaines/5fd0352d55644da7c99cdd9d05c61be9 to your computer and use it in GitHub Desktop.
Save abaines/5fd0352d55644da7c99cdd9d05c61be9 to your computer and use it in GitHub Desktop.
Oort scenario/tutorial https://oort.rs/scenario/tutorial
// Tutorial: Lead
// Destroy the enemy ship. Its position is given by the "target" function and velocity by the
// "target_velocity" function. Your ship is not able to accelerate in this scenario.
//
// This is where the game becomes challenging! You'll need to lead the target
// by firing towards where the target will be by the time the bullet gets there.
//
// Hint: target() + target_velocity() * t gives the position of the target after t seconds.
//
// You can scale a vector by a number: vec2(a, b) * c == vec2(a * c, b * c)
//
// p.s. You can change your username by clicking on it at the top of the page.
use oort_api::prelude::*;
const BULLET_SPEED: f64 = 1000.0; // m/s
pub struct Ship {}
impl Ship {
pub fn new() -> Ship {
Ship {}
}
pub fn radian_to_vec2(angle_radians: f64) -> Vec2 {
Vec2::new(angle_radians.cos(), angle_radians.sin())
}
pub fn calculate() -> Vec2 {
let relative_position = target() - position();
let a = target_velocity().dot(target_velocity()) - (BULLET_SPEED * BULLET_SPEED);
let b = 2.0 * relative_position.dot(target_velocity());
let c = relative_position.dot(relative_position);
debug!("{} {} {}",a,b,c);
let discriminant = (b * b) - (4.0 * a * c);
let t1 = (-b + discriminant.sqrt()) / (2.0 * a);
let t2 = (-b - discriminant.sqrt()) / (2.0 * a);
let t = if t1 > 0.0 && t2 > 0.0 {
t1.min(t2) // Choose the earlier time.
} else if t1 > 0.0 {
t1
} else if t2 > 0.0 {
t2
} else {
// No positive time solution, target is behind us or we can't catch it.
-1.0
};
debug!("{}",t);
let intercept_position = target() + target_velocity() * t;
//let firing_direction = (intercept_position - position()).normalize();
return intercept_position
}
pub fn tick(&mut self) {
//draw_line(position(), target(), 0x00ff00);
// let dp = target() - position();
// debug!("distance to target: {}", dp.length());
// let time_to_target_guess = dp.length() / BULLET_SPEED;
// debug!("time to target: {}", time_to_target_guess );
// let predicted_target_pos = target()+(target_velocity()*time_to_target_guess );
//draw_line(target(),predicted_target_pos ,0xaa0000);
//draw_line(position(),predicted_target_pos ,0x0000aa);
// let predicted_dp = predicted_target_pos - position();
// let time_to_intercept = predicted_dp.length() / BULLET_SPEED;
// let intercept_point = target() + target_velocity() * time_to_intercept;
// draw_line(target(), intercept_point, 0xaaFF00);
// draw_line(position(), intercept_point, 0xFF00aa);
// let aim_angle = intercept_point.angle();
// debug!("aim_angle {}",aim_angle);
let intercept_position = Self::calculate();
draw_line(target(), intercept_position, 0xaaFF00);
draw_line(position(), intercept_position, 0xFF00aa);
let x:Vec2 = Self::radian_to_vec2(heading());
draw_line(position(), 1000.0*x, 0xFFbbaa);
let aim_angle = intercept_position.angle();
//debug!("calc {}",calc);
//debug!("calc.angle {}",calc.angle());
let turn_angle = angle_diff(heading(), aim_angle );
turn(turn_angle*99.0);
//fire(0);
debug!("turn_angle {}",turn_angle );
if turn_angle.abs()<0.019
{
fire(0);
}
//turn(1.0);
//fire(0);
//debug!("{}",target_velocity());
//debug!("{}",target_velocity().length());
}
}
// Tutorial: Radar
// Destroy the enemy ships. Use your radar to find them.
// Hint: Press 'g' in-game to show where your radar is looking.
// Hint: Press 'n' to single-step.
// Hint: Use the set_radar_heading() function to keep your radar pointed at a
// target, or to search for a new one.
//
// Join the Discord at https://discord.gg/vYyu9EhkKH for Oort discussion and
// tournament results.
use oort_api::prelude::*;
const BULLET_SPEED: f64 = 1000.0; // m/s
pub struct Ship {}
impl Ship {
pub fn new() -> Ship {
Ship {}
}
pub fn radian_to_vec2(angle_radians: f64) -> Vec2
{
Vec2::new(angle_radians.cos(), angle_radians.sin())
}
pub fn calculate() -> Vec2 {
let relative_position = target() - position();
let a = target_velocity().dot(target_velocity()) - (BULLET_SPEED * BULLET_SPEED);
let b = 2.0 * relative_position.dot(target_velocity());
let c = relative_position.dot(relative_position);
debug!("πŸ”€ {} {} {}",a,b,c);
let discriminant = (b * b) - (4.0 * a * c);
let t1 = (-b + discriminant.sqrt()) / (2.0 * a);
let t2 = (-b - discriminant.sqrt()) / (2.0 * a);
let t = if t1 > 0.0 && t2 > 0.0 {
t1.min(t2) // Choose the earlier time.
} else if t1 > 0.0 {
t1
} else if t2 > 0.0 {
t2
} else {
// No positive time solution, target is behind us or we can't catch it.
-1.0
};
debug!("⌚ {}",t);
let intercept_position = relative_position + target_velocity() * t;
return intercept_position
}
pub fn tick(&mut self) {
let intercept_position = Self::calculate();
draw_line(target(), intercept_position, 0xaaFF00);
draw_line(position(), intercept_position, 0xFF00aa);
let x:Vec2 = Self::radian_to_vec2(heading());
draw_line(position(), 1000.0*x, 0xFFbbaa);
let aim_angle = intercept_position.angle();
let turn_angle = angle_diff(heading(), aim_angle );
turn(turn_angle*99.0);
//turn(0.3);
debug!("🧭 {}",turn_angle );
if turn_angle.abs()<0.019
{
fire(0);
}
if let Some(contact) = scan() {
debug!("πŸ“» {:?}",contact );
set_radar_heading((contact.position-position()).angle())
}
else {
debug!("πŸ“» {}","no contact" );
set_radar_heading(radar_heading() - radar_width()/2.0);
}
}
}
// Tutorial: Search
// Destroy the enemy ship. It is initially outside of your radar range.
// Hint: The set_radar_width() function can be used to create a tighter radar
// beam that's effective at longer distances.
use oort_api::prelude::*;
const BULLET_SPEED: f64 = 1000.0; // m/s
pub struct Ship {}
impl Ship {
pub fn new() -> Ship {
Ship {}
}
pub fn radian_to_vec2(angle_radians: f64) -> Vec2
{
Vec2::new(angle_radians.cos(), angle_radians.sin())
}
pub fn calculate() -> Vec2
{
let relative_position = target() - position();
let a = target_velocity().dot(target_velocity()) - (BULLET_SPEED * BULLET_SPEED);
let b = 2.0 * relative_position.dot(target_velocity());
let c = relative_position.dot(relative_position);
debug!("πŸ”€ {} {} {}",a,b,c);
let discriminant = (b * b) - (4.0 * a * c);
let t1 = (-b + discriminant.sqrt()) / (2.0 * a);
let t2 = (-b - discriminant.sqrt()) / (2.0 * a);
let t = if t1 > 0.0 && t2 > 0.0 {
t1.min(t2) // Choose the earlier time.
} else if t1 > 0.0 {
t1
} else if t2 > 0.0 {
t2
} else {
// No positive time solution, target is behind us or we can't catch it.
-1.0
};
debug!("⌚ {}",t);
let intercept_position = relative_position + target_velocity() * t;
return intercept_position
}
pub fn tick(&mut self) {
set_radar_width(0.2);
let intercept_position = Self::calculate();
draw_line(target(), intercept_position, 0xaaFF00);
draw_line(position(), intercept_position, 0xFF00aa);
let x:Vec2 = Self::radian_to_vec2(heading());
draw_line(position(), 1000.0*x, 0xFFbbaa);
let aim_angle = intercept_position.angle();
let turn_angle = angle_diff(heading(), aim_angle );
turn(turn_angle*99.0);
//turn(0.3);
debug!("🧭 {}",turn_angle );
if turn_angle.abs()<0.019
{
fire(0);
}
if let Some(contact) = scan() {
debug!("πŸ“» {:?}",contact );
set_radar_heading((contact.position-position()).angle())
}
else {
debug!("πŸ“» {}","no contact" );
set_radar_heading(radar_heading() - radar_width()/2.0);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment