Žádný typy, pouze inty
This commit is contained in:
parent
f8d03c6162
commit
6ffbfb0d1e
3 changed files with 101 additions and 119 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
"""The Asteracer game implementation. Includes the base movement code + couple of QOL additions (eg. save states)."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
@ -5,14 +6,6 @@ import random
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from math import isqrt
|
from math import isqrt
|
||||||
from typing import List, Union, Tuple, Dict
|
|
||||||
|
|
||||||
# tohle dříve byly numpy typy, ale asi je lepší,
|
|
||||||
# ať účastníci nemusí nic instalovat...
|
|
||||||
InstType = int # np.int8
|
|
||||||
PosType = int # np.int64
|
|
||||||
SpeedType = int # np.int64
|
|
||||||
SizeType = int # np.int64
|
|
||||||
|
|
||||||
|
|
||||||
class TickFlag:
|
class TickFlag:
|
||||||
|
@ -23,18 +16,18 @@ class TickFlag:
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Racer:
|
class Racer:
|
||||||
x: PosType = 0
|
x: int = 0
|
||||||
y: PosType = 0
|
y: int = 0
|
||||||
vx: SpeedType = 0
|
vx: int = 0
|
||||||
vy: SpeedType = 0
|
vy: int = 0
|
||||||
radius: SizeType = 1
|
radius: int = 1
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Asteroid:
|
class Asteroid:
|
||||||
x: PosType = 0
|
x: int = 0
|
||||||
y: PosType = 0
|
y: int = 0
|
||||||
radius: SizeType = 1
|
radius: int = 1
|
||||||
|
|
||||||
Goal = Asteroid
|
Goal = Asteroid
|
||||||
|
|
||||||
|
@ -42,7 +35,7 @@ Goal = Asteroid
|
||||||
class Instruction:
|
class Instruction:
|
||||||
MAX_ACCELERATION = 127
|
MAX_ACCELERATION = 127
|
||||||
|
|
||||||
def __init__(self, vx: Union[int, float] = 0, vy: Union[int, float] = 0):
|
def __init__(self, vx: int | float = 0, vy: int | float = 0):
|
||||||
"""Whatever values we get, normalize them."""
|
"""Whatever values we get, normalize them."""
|
||||||
|
|
||||||
if distance_squared(vx, vy) > Instruction.MAX_ACCELERATION ** 2:
|
if distance_squared(vx, vy) > Instruction.MAX_ACCELERATION ** 2:
|
||||||
|
@ -62,8 +55,8 @@ class Instruction:
|
||||||
|
|
||||||
assert distance_squared(vx, vy) <= Instruction.MAX_ACCELERATION ** 2
|
assert distance_squared(vx, vy) <= Instruction.MAX_ACCELERATION ** 2
|
||||||
|
|
||||||
self.vx = InstType(vx)
|
self.vx = vx
|
||||||
self.vy = InstType(vy)
|
self.vy = vy
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash((self.vx, self.vy))
|
return hash((self.vx, self.vy))
|
||||||
|
@ -90,26 +83,26 @@ class Instruction:
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class BoundingBox:
|
class BoundingBox:
|
||||||
min_x: PosType
|
min_x: int
|
||||||
min_y: PosType
|
min_y: int
|
||||||
max_x: PosType
|
max_x: int
|
||||||
max_y: PosType
|
max_y: int
|
||||||
|
|
||||||
def width(self) -> SizeType:
|
def width(self) -> int:
|
||||||
return SizeType(self.max_x - self.min_x)
|
return int(self.max_x - self.min_x)
|
||||||
|
|
||||||
def height(self) -> SizeType:
|
def height(self) -> int:
|
||||||
return SizeType(self.max_y - self.min_y)
|
return int(self.max_y - self.min_y)
|
||||||
|
|
||||||
|
|
||||||
def distance_squared(x1, y1, x2=0, y2=0) -> PosType:
|
def distance_squared(x1, y1, x2=0, y2=0) -> int:
|
||||||
"""Squared Euclidean distance between two points."""
|
"""Squared Euclidean distance between two points."""
|
||||||
return (PosType(x1) - PosType(x2)) ** 2 + (PosType(y1) - PosType(y2)) ** 2
|
return (int(x1) - int(x2)) ** 2 + (int(y1) - int(y2)) ** 2
|
||||||
|
|
||||||
|
|
||||||
def euclidean_distance(x1, y1, x2=0, y2=0):
|
def euclidean_distance(x1, y1, x2=0, y2=0):
|
||||||
"""Integer Euclidean distance between two points. Uses integer square root."""
|
"""Integer Euclidean distance between two points. Uses integer square root."""
|
||||||
return PosType(isqrt(distance_squared(x1, y1, x2, y2)))
|
return int(isqrt(distance_squared(x1, y1, x2, y2)))
|
||||||
|
|
||||||
|
|
||||||
def signum(x):
|
def signum(x):
|
||||||
|
@ -132,8 +125,8 @@ class Simulation:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
racer: Racer = Racer(),
|
racer: Racer = Racer(),
|
||||||
asteroids: List[Asteroid] = None,
|
asteroids: list[Asteroid] = None,
|
||||||
goals: List[Goal] = None,
|
goals: list[Goal] = None,
|
||||||
bounding_box: BoundingBox = None,
|
bounding_box: BoundingBox = None,
|
||||||
):
|
):
|
||||||
# the initial racer state (used when resetting the simulation)
|
# the initial racer state (used when resetting the simulation)
|
||||||
|
@ -146,7 +139,7 @@ class Simulation:
|
||||||
|
|
||||||
# to speed up the computation, we divide the bounding box (if we have one) into a grid
|
# to speed up the computation, we divide the bounding box (if we have one) into a grid
|
||||||
# we do this so we don't need to check all asteroids at each tick, only those that could collide with the racer
|
# we do this so we don't need to check all asteroids at each tick, only those that could collide with the racer
|
||||||
self._grid: Dict[Tuple[int, int], List[Asteroid]] = defaultdict(list)
|
self._grid: dict[tuple[int, int], list[Asteroid]] = defaultdict(list)
|
||||||
|
|
||||||
for asteroid in asteroids:
|
for asteroid in asteroids:
|
||||||
min_x, min_y = self._coordinate_to_grid(
|
min_x, min_y = self._coordinate_to_grid(
|
||||||
|
@ -163,12 +156,12 @@ class Simulation:
|
||||||
for grid_y in range(min_y, max_y + 1):
|
for grid_y in range(min_y, max_y + 1):
|
||||||
self._grid[(grid_x, grid_y)].append(asteroid)
|
self._grid[(grid_x, grid_y)].append(asteroid)
|
||||||
|
|
||||||
self.reached_goals: List[bool] = [False] * len(self.goals)
|
self.reached_goals: list[bool] = [False] * len(self.goals)
|
||||||
|
|
||||||
# a list of simulation states that can be popped (restored to)
|
# a list of simulation states that can be popped (restored to)
|
||||||
self._pushed_states = []
|
self._pushed_states = []
|
||||||
|
|
||||||
def _coordinate_to_grid(self, x: float, y: float) -> Tuple[int, int]:
|
def _coordinate_to_grid(self, x: float, y: float) -> tuple[int, int]:
|
||||||
"""Translate an (x,y) coordinate into a coordinate of the grid."""
|
"""Translate an (x,y) coordinate into a coordinate of the grid."""
|
||||||
return (x // self.CELL_SIZE, y // self.CELL_SIZE)
|
return (x // self.CELL_SIZE, y // self.CELL_SIZE)
|
||||||
|
|
||||||
|
@ -181,14 +174,14 @@ class Simulation:
|
||||||
self.racer.vy = division(self.racer.vy * self.DRAG_FRACTION[0], self.DRAG_FRACTION[1])
|
self.racer.vy = division(self.racer.vy * self.DRAG_FRACTION[0], self.DRAG_FRACTION[1])
|
||||||
|
|
||||||
# velocity
|
# velocity
|
||||||
self.racer.vx += SpeedType(vx)
|
self.racer.vx += int(vx)
|
||||||
self.racer.vy += SpeedType(vy)
|
self.racer.vy += int(vy)
|
||||||
|
|
||||||
# movement
|
# movement
|
||||||
self.racer.x += self.racer.vx
|
self.racer.x += self.racer.vx
|
||||||
self.racer.y += self.racer.vy
|
self.racer.y += self.racer.vy
|
||||||
|
|
||||||
def _push_out(self, obj: Union[Asteroid, BoundingBox]) -> bool:
|
def _push_out(self, obj: Asteroid | BoundingBox) -> bool:
|
||||||
"""Attempt to push the racer out of the object (if he's colliding), adjusting
|
"""Attempt to push the racer out of the object (if he's colliding), adjusting
|
||||||
his velocity accordingly (based on the angle of collision). Returns True if the
|
his velocity accordingly (based on the angle of collision). Returns True if the
|
||||||
racer was pushed out, otherwise returns False."""
|
racer was pushed out, otherwise returns False."""
|
||||||
|
@ -292,7 +285,7 @@ class Simulation:
|
||||||
|
|
||||||
return (TickFlag.COLLIDED if collided else 0) | (TickFlag.GOAL_REACHED if goal else 0)
|
return (TickFlag.COLLIDED if collided else 0) | (TickFlag.GOAL_REACHED if goal else 0)
|
||||||
|
|
||||||
def simulate(self, instructions: List[Instruction]):
|
def simulate(self, instructions: list[Instruction]):
|
||||||
"""Simulate a number of instructions for the simulation (from the start)."""
|
"""Simulate a number of instructions for the simulation (from the start)."""
|
||||||
self.restart()
|
self.restart()
|
||||||
|
|
||||||
|
@ -337,10 +330,10 @@ class Simulation:
|
||||||
lines = f.read().splitlines()
|
lines = f.read().splitlines()
|
||||||
|
|
||||||
racer_parts = lines[0].split()
|
racer_parts = lines[0].split()
|
||||||
racer = Racer(x=PosType(racer_parts[0]), y=PosType(racer_parts[1]), radius=SizeType(racer_parts[2]))
|
racer = Racer(x=int(racer_parts[0]), y=int(racer_parts[1]), radius=int(racer_parts[2]))
|
||||||
|
|
||||||
bb_parts = lines[1].split()
|
bb_parts = lines[1].split()
|
||||||
bb = BoundingBox(PosType(bb_parts[0]), PosType(bb_parts[1]), PosType(bb_parts[2]), PosType(bb_parts[2]))
|
bb = BoundingBox(int(bb_parts[0]), int(bb_parts[1]), int(bb_parts[2]), int(bb_parts[2]))
|
||||||
|
|
||||||
asteroid_count = int(lines[2])
|
asteroid_count = int(lines[2])
|
||||||
|
|
||||||
|
@ -349,9 +342,9 @@ class Simulation:
|
||||||
asteroid_parts = lines[i].split()
|
asteroid_parts = lines[i].split()
|
||||||
asteroids.append(
|
asteroids.append(
|
||||||
Asteroid(
|
Asteroid(
|
||||||
x=PosType(asteroid_parts[0]),
|
x=int(asteroid_parts[0]),
|
||||||
y=PosType(asteroid_parts[1]),
|
y=int(asteroid_parts[1]),
|
||||||
radius=SizeType(asteroid_parts[2]),
|
radius=int(asteroid_parts[2]),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -362,9 +355,9 @@ class Simulation:
|
||||||
goal_parts = lines[i].split()
|
goal_parts = lines[i].split()
|
||||||
goals.append(
|
goals.append(
|
||||||
Asteroid(
|
Asteroid(
|
||||||
x=PosType(goal_parts[0]),
|
x=int(goal_parts[0]),
|
||||||
y=PosType(goal_parts[1]),
|
y=int(goal_parts[1]),
|
||||||
radius=SizeType(goal_parts[2]),
|
radius=int(goal_parts[2]),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -390,7 +383,7 @@ class Simulation:
|
||||||
self.reached_goals = list(self._pushed_states[-1][1])
|
self.reached_goals = list(self._pushed_states[-1][1])
|
||||||
|
|
||||||
|
|
||||||
def save_instructions(path: str, instructions: List[Instruction]):
|
def save_instructions(path: str, instructions: list[Instruction]):
|
||||||
"""Save a list of instructions to a file:
|
"""Save a list of instructions to a file:
|
||||||
| 4 // number if instructions
|
| 4 // number if instructions
|
||||||
| -16 -127 // instructions...
|
| -16 -127 // instructions...
|
||||||
|
@ -405,13 +398,13 @@ def save_instructions(path: str, instructions: List[Instruction]):
|
||||||
f.write(f"{instruction.vx} {instruction.vy}\n")
|
f.write(f"{instruction.vx} {instruction.vy}\n")
|
||||||
|
|
||||||
|
|
||||||
def load_instructions(path: str) -> List[Instruction]:
|
def load_instructions(path: str) -> list[Instruction]:
|
||||||
"""Load a list of instructions from a file (see save_instructions for the format description)."""
|
"""Load a list of instructions from a file (see save_instructions for the format description)."""
|
||||||
instructions = []
|
instructions = []
|
||||||
|
|
||||||
with open(path) as f:
|
with open(path) as f:
|
||||||
for line in f.read().splitlines()[1:]:
|
for line in f.read().splitlines()[1:]:
|
||||||
instruction_parts = list(map(InstType, line.split()))
|
instruction_parts = list(map(int, line.split()))
|
||||||
instructions.append(Instruction(*instruction_parts))
|
instructions.append(Instruction(*instruction_parts))
|
||||||
|
|
||||||
return instructions
|
return instructions
|
||||||
|
|
|
@ -12,61 +12,50 @@ pub mod TickFlag {
|
||||||
|
|
||||||
pub type TickResult = usize;
|
pub type TickResult = usize;
|
||||||
|
|
||||||
pub type InstType = i8;
|
pub static MAX_ACCELERATION: isize = 127;
|
||||||
pub type PosType = i64;
|
|
||||||
pub type SpeedType = i64;
|
|
||||||
pub type SizeType = i64;
|
|
||||||
|
|
||||||
pub static MAX_ACCELERATION: InstType = 127;
|
pub static DRAG_FRACTION: (isize, isize) = (9, 10);
|
||||||
|
pub static COLLISION_FRACTION: (isize, isize) = (1, 2);
|
||||||
pub static DRAG_FRACTION: (SpeedType, SpeedType) = (9, 10);
|
|
||||||
pub static COLLISION_FRACTION: (SpeedType, SpeedType) = (1, 2);
|
|
||||||
pub static MAX_COLLISION_RESOLUTIONS: usize = 5;
|
pub static MAX_COLLISION_RESOLUTIONS: usize = 5;
|
||||||
|
|
||||||
pub static CELL_SIZE: PosType = 10_000;
|
pub static CELL_SIZE: isize = 10_000;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct Racer {
|
pub struct Racer {
|
||||||
pub x: PosType,
|
pub x: isize,
|
||||||
pub y: PosType,
|
pub y: isize,
|
||||||
pub vx: SpeedType,
|
pub vx: isize,
|
||||||
pub vy: SpeedType,
|
pub vy: isize,
|
||||||
pub radius: SizeType,
|
pub radius: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct Asteroid {
|
pub struct Asteroid {
|
||||||
pub x: PosType,
|
pub x: isize,
|
||||||
pub y: PosType,
|
pub y: isize,
|
||||||
pub radius: SizeType,
|
pub radius: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Goal = Asteroid;
|
pub type Goal = Asteroid;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub(crate) struct Instruction {
|
pub(crate) struct Instruction {
|
||||||
pub vx: InstType,
|
pub vx: isize,
|
||||||
pub vy: InstType,
|
pub vy: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instruction {
|
impl Instruction {
|
||||||
fn valid(vx: PosType, vy: PosType) -> bool {
|
fn valid(vx: isize, vy: isize) -> bool {
|
||||||
distance_squared(vx, vy, 0, 0) <= (MAX_ACCELERATION as PosType).pow(2)
|
distance_squared(vx, vy, 0, 0) <= (MAX_ACCELERATION).pow(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new<T>(vx: T, vy: T) -> Self
|
pub fn new(vx: isize, vy: isize) -> Self {
|
||||||
where
|
|
||||||
T: Copy + Into<PosType>,
|
|
||||||
{
|
|
||||||
let vx: i64 = vx.into();
|
|
||||||
let vy: i64 = vy.into();
|
|
||||||
|
|
||||||
if !Self::valid(vx, vy) {
|
if !Self::valid(vx, vy) {
|
||||||
// use float to properly normalize here
|
// use float to properly normalize here
|
||||||
let float_distance = ((vx as f64).powf(2.) + (vy as f64).powf(2.)).powf(1. / 2.);
|
let float_distance = ((vx as f64).powf(2.) + (vy as f64).powf(2.)).powf(1. / 2.);
|
||||||
|
|
||||||
let mut vx = ((vx as f64 / float_distance) * MAX_ACCELERATION as f64) as PosType;
|
let mut vx = ((vx as f64 / float_distance) * MAX_ACCELERATION as f64) as isize;
|
||||||
let mut vy = ((vy as f64 / float_distance) * MAX_ACCELERATION as f64) as PosType;
|
let mut vy = ((vy as f64 / float_distance) * MAX_ACCELERATION as f64) as isize;
|
||||||
|
|
||||||
// if we're still over, decrement both values
|
// if we're still over, decrement both values
|
||||||
if !Self::valid(vx, vy) {
|
if !Self::valid(vx, vy) {
|
||||||
|
@ -74,14 +63,14 @@ impl Instruction {
|
||||||
vy -= vy.signum();
|
vy -= vy.signum();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Self { vx: vx as InstType, vy: vy as InstType };
|
return Self { vx, vy };
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(Self::valid(vx, vy));
|
assert!(Self::valid(vx, vy));
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
vx: vx as InstType,
|
vx,
|
||||||
vy: vy as InstType,
|
vy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +78,8 @@ impl Instruction {
|
||||||
let mut rng = rand::rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
vx: rng.random::<InstType>(),
|
vx: rng.random::<i64>() as isize,
|
||||||
vy: rng.random::<InstType>(),
|
vy: rng.random::<i64>() as isize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,8 +99,8 @@ impl Instruction {
|
||||||
.collect::<Vec<&str>>();
|
.collect::<Vec<&str>>();
|
||||||
|
|
||||||
instructions.push(Instruction {
|
instructions.push(Instruction {
|
||||||
vx: parts[0].parse::<InstType>().unwrap(),
|
vx: parts[0].parse::<isize>().unwrap(),
|
||||||
vy: parts[1].parse::<InstType>().unwrap(),
|
vy: parts[1].parse::<isize>().unwrap(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,24 +119,24 @@ impl Instruction {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct BoundingBox {
|
pub struct BoundingBox {
|
||||||
pub min_x: SizeType,
|
pub min_x: isize,
|
||||||
pub min_y: SizeType,
|
pub min_y: isize,
|
||||||
pub max_x: SizeType,
|
pub max_x: isize,
|
||||||
pub max_y: SizeType,
|
pub max_y: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BoundingBox {
|
impl BoundingBox {
|
||||||
pub fn width(&self) -> SizeType {
|
pub fn width(&self) -> isize {
|
||||||
self.max_x - self.min_x
|
self.max_x - self.min_x
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn height(&self) -> SizeType {
|
pub fn height(&self) -> isize {
|
||||||
self.max_y - self.min_y
|
self.max_y - self.min_y
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Squared Euclidean distance; useful for distance checks.
|
/// Squared Euclidean distance; useful for distance checks.
|
||||||
fn distance_squared(x1: PosType, y1: PosType, x2: PosType, y2: PosType) -> PosType {
|
fn distance_squared(x1: isize, y1: isize, x2: isize, y2: isize) -> isize {
|
||||||
(x1 - x2).pow(2) + (y1 - y2).pow(2)
|
(x1 - x2).pow(2) + (y1 - y2).pow(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,8 +144,8 @@ fn distance_squared(x1: PosType, y1: PosType, x2: PosType, y2: PosType) -> PosTy
|
||||||
///
|
///
|
||||||
/// Note: this implementation might break for larger position values, but since
|
/// Note: this implementation might break for larger position values, but since
|
||||||
/// the maps are never going to be this large, I'm not fixing it now.
|
/// the maps are never going to be this large, I'm not fixing it now.
|
||||||
pub fn euclidean_distance(x1: PosType, y1: PosType, x2: PosType, y2: PosType) -> PosType {
|
pub fn euclidean_distance(x1: isize, y1: isize, x2: isize, y2: isize) -> isize {
|
||||||
(distance_squared(x1, y1, x2, y2) as f64).sqrt() as PosType
|
(distance_squared(x1, y1, x2, y2) as f64).sqrt() as isize
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -170,8 +159,8 @@ pub struct Simulation {
|
||||||
|
|
||||||
pub reached_goals: Vec<bool>,
|
pub reached_goals: Vec<bool>,
|
||||||
|
|
||||||
_grid: HashMap<(PosType, PosType), Vec<Asteroid>>,
|
_grid: HashMap<(isize, isize), Vec<Asteroid>>,
|
||||||
_cell_size: PosType,
|
_cell_size: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -234,7 +223,7 @@ impl Simulation {
|
||||||
simulation
|
simulation
|
||||||
}
|
}
|
||||||
|
|
||||||
fn coordinate_to_grid(&self, x: PosType, y: PosType) -> (PosType, PosType) {
|
fn coordinate_to_grid(&self, x: isize, y: isize) -> (isize, isize) {
|
||||||
(x / self._cell_size, y / self._cell_size)
|
(x / self._cell_size, y / self._cell_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,11 +231,11 @@ impl Simulation {
|
||||||
self.racer.vx = (self.racer.vx * DRAG_FRACTION.0) / DRAG_FRACTION.1;
|
self.racer.vx = (self.racer.vx * DRAG_FRACTION.0) / DRAG_FRACTION.1;
|
||||||
self.racer.vy = (self.racer.vy * DRAG_FRACTION.0) / DRAG_FRACTION.1;
|
self.racer.vy = (self.racer.vy * DRAG_FRACTION.0) / DRAG_FRACTION.1;
|
||||||
|
|
||||||
self.racer.vx += instruction.vx as SpeedType;
|
self.racer.vx += instruction.vx;
|
||||||
self.racer.vy += instruction.vy as SpeedType;
|
self.racer.vy += instruction.vy;
|
||||||
|
|
||||||
self.racer.x += self.racer.vx as PosType;
|
self.racer.x += self.racer.vx as isize;
|
||||||
self.racer.y += self.racer.vy as PosType;
|
self.racer.y += self.racer.vy as isize;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_from_asteroids(&mut self) -> bool {
|
fn push_from_asteroids(&mut self) -> bool {
|
||||||
|
@ -413,9 +402,9 @@ impl Simulation {
|
||||||
let racer_parts = parts_fn();
|
let racer_parts = parts_fn();
|
||||||
|
|
||||||
let racer = Racer {
|
let racer = Racer {
|
||||||
x: racer_parts[0].parse::<PosType>().unwrap(),
|
x: racer_parts[0].parse::<isize>().unwrap(),
|
||||||
y: racer_parts[1].parse::<PosType>().unwrap(),
|
y: racer_parts[1].parse::<isize>().unwrap(),
|
||||||
radius: racer_parts[2].parse::<SizeType>().unwrap(),
|
radius: racer_parts[2].parse::<isize>().unwrap(),
|
||||||
vx: 0,
|
vx: 0,
|
||||||
vy: 0,
|
vy: 0,
|
||||||
};
|
};
|
||||||
|
@ -423,10 +412,10 @@ impl Simulation {
|
||||||
let bb_parts = parts_fn();
|
let bb_parts = parts_fn();
|
||||||
|
|
||||||
let bbox = BoundingBox {
|
let bbox = BoundingBox {
|
||||||
min_x: bb_parts[0].parse::<SizeType>().unwrap(),
|
min_x: bb_parts[0].parse::<isize>().unwrap(),
|
||||||
min_y: bb_parts[1].parse::<SizeType>().unwrap(),
|
min_y: bb_parts[1].parse::<isize>().unwrap(),
|
||||||
max_x: bb_parts[2].parse::<SizeType>().unwrap(),
|
max_x: bb_parts[2].parse::<isize>().unwrap(),
|
||||||
max_y: bb_parts[3].parse::<SizeType>().unwrap(),
|
max_y: bb_parts[3].parse::<isize>().unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let asteroid_count = parts_fn()[0].parse::<usize>().unwrap();
|
let asteroid_count = parts_fn()[0].parse::<usize>().unwrap();
|
||||||
|
@ -436,9 +425,9 @@ impl Simulation {
|
||||||
let asteroid_parts = parts_fn();
|
let asteroid_parts = parts_fn();
|
||||||
|
|
||||||
asteroids.push(Asteroid {
|
asteroids.push(Asteroid {
|
||||||
x: asteroid_parts[0].parse::<PosType>().unwrap(),
|
x: asteroid_parts[0].parse::<isize>().unwrap(),
|
||||||
y: asteroid_parts[1].parse::<PosType>().unwrap(),
|
y: asteroid_parts[1].parse::<isize>().unwrap(),
|
||||||
radius: asteroid_parts[2].parse::<PosType>().unwrap(),
|
radius: asteroid_parts[2].parse::<isize>().unwrap(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,9 +438,9 @@ impl Simulation {
|
||||||
let goal_parts = parts_fn();
|
let goal_parts = parts_fn();
|
||||||
|
|
||||||
goals.push(Asteroid {
|
goals.push(Asteroid {
|
||||||
x: goal_parts[0].parse::<PosType>().unwrap(),
|
x: goal_parts[0].parse::<isize>().unwrap(),
|
||||||
y: goal_parts[1].parse::<PosType>().unwrap(),
|
y: goal_parts[1].parse::<isize>().unwrap(),
|
||||||
radius: goal_parts[2].parse::<PosType>().unwrap(),
|
radius: goal_parts[2].parse::<isize>().unwrap(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::path::PathBuf;
|
||||||
mod asteracer;
|
mod asteracer;
|
||||||
|
|
||||||
pub fn load_asteroid_graph(path: &PathBuf) -> (
|
pub fn load_asteroid_graph(path: &PathBuf) -> (
|
||||||
Vec<(PosType, PosType)>,
|
Vec<(isize, isize)>,
|
||||||
Vec<(usize, usize)>,
|
Vec<(usize, usize)>,
|
||||||
Vec<(char, usize)>,
|
Vec<(char, usize)>,
|
||||||
) {
|
) {
|
||||||
|
@ -37,7 +37,7 @@ pub fn load_asteroid_graph(path: &PathBuf) -> (
|
||||||
|
|
||||||
// Load vertices
|
// Load vertices
|
||||||
for i in 0..(n_racer + n_asteroid + n_goal) {
|
for i in 0..(n_racer + n_asteroid + n_goal) {
|
||||||
let line: Vec<i64> = iter
|
let line: Vec<isize> = iter
|
||||||
.next()
|
.next()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.split_whitespace()
|
.split_whitespace()
|
||||||
|
@ -120,7 +120,7 @@ fn main() {
|
||||||
// posbíráme zbývající cíle tak, že k nim poletíme přímou čarou
|
// posbíráme zbývající cíle tak, že k nim poletíme přímou čarou
|
||||||
while simulation.reached_goals.iter().any(|&reached| !reached) {
|
while simulation.reached_goals.iter().any(|&reached| !reached) {
|
||||||
let mut nearest_goal = None;
|
let mut nearest_goal = None;
|
||||||
let mut nearest_goal_distance = PosType::MAX;
|
let mut nearest_goal_distance = isize::MAX;
|
||||||
|
|
||||||
for (i, &reached) in simulation.reached_goals.iter().enumerate() {
|
for (i, &reached) in simulation.reached_goals.iter().enumerate() {
|
||||||
if !reached {
|
if !reached {
|
||||||
|
|
Loading…
Reference in a new issue