pub mod constants;
use std::fmt::Display;
use constants::{AVAILABLEPLANKS, CUTADJACENCY, PLANKMAX, PLANKMIN, PLAY, ROOMLENGTH, SAWBLADE};
#[derive(Debug)]
pub struct MaterialStorage {
pub total_planks: u32,
pub planks_new: Vec<Plank>,
pub planks_used: Vec<Plank>,
pub planks_too_short: Vec<Plank>,
}
impl Default for MaterialStorage {
fn default() -> Self {
Self {
total_planks: AVAILABLEPLANKS,
planks_new: vec![Plank::default(); AVAILABLEPLANKS as usize],
planks_used: vec![],
planks_too_short: vec![],
}
}
}
impl MaterialStorage {
pub fn new(&self) -> Self {
MaterialStorage::default()
}
pub fn exists_used(&self) -> bool {
!self.planks_used.is_empty()
}
pub fn get_used(&mut self) -> Option<Plank> {
self.planks_used.pop()
}
pub fn store_used(&mut self, plank: Plank) {
self.planks_used.push(plank)
}
pub fn try_get_used(&mut self) -> Option<Plank> {
if let Some(plank) = self.planks_used.pop() {
Some(plank)
} else {
self.get_new()
}
}
pub fn get_used_count(&self) -> u32 {
self.planks_used.len() as u32
}
pub fn exists_new(&self) -> bool {
!self.planks_new.is_empty()
}
pub fn get_new(&mut self) -> Option<Plank> {
self.planks_new.pop()
}
pub fn discard_unusable(&mut self, plank: Plank) {
self.planks_too_short.push(plank)
}
}
#[derive(Debug, Clone, Copy)]
pub struct Cut {
pub coordinate: u32,
}
impl Cut {
pub fn new(coordinate: u32) -> Self {
Cut { coordinate }
}
}
impl Display for Cut {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.coordinate)
}
}
#[derive(Debug, Clone, Copy)]
pub struct Plank {
pub length: u32,
pub endpiece: bool,
pub new: bool,
}
impl Default for Plank {
fn default() -> Self {
Self {
length: PLANKMAX,
endpiece: false,
new: true,
}
}
}
impl Display for Plank {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.length)
}
}
impl Plank {
pub fn new(&self) -> Self {
Plank::default()
}
pub fn is_new(&self) -> bool {
self.new
}
pub fn get_endpiece(&self) -> bool {
self.endpiece
}
pub fn set_endpiece(&mut self) {
self.endpiece = true;
}
pub fn length(&self) -> u32 {
self.length
}
pub fn cut_to_length(mut self, measure: u32) -> (Plank, Plank) {
if measure > PLANKMAX {
panic!("Can't cut a plank longer than it is!");
} else if measure == 0 {
panic!("Cutting a plank to length 0 does not make sense!");
}
let leftover_plank;
let leftover_length;
if self.length() < PLANKMIN {
let new_plank: Plank = Default::default();
leftover_plank = new_plank;
} else {
leftover_length = self.length - (measure + SAWBLADE);
leftover_plank = Plank {
length: leftover_length,
..Default::default()
};
}
self.length = measure;
if self.new {
self.new = false;
}
(self, leftover_plank)
}
}
#[derive(Debug)]
pub struct Row {
planks: Vec<Plank>,
cut_coordinates: Vec<Cut>,
coverage: u32,
full: bool,
row_max_length: u32,
}
impl Default for Row {
fn default() -> Self {
Self {
planks: vec![],
cut_coordinates: vec![],
coverage: 0,
full: false,
row_max_length: ROOMLENGTH - 2 * PLAY,
}
}
}
impl Display for Row {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let scalefactor = 50;
let comp = 50 * self.planks_count();
let mut length_sum = 0;
write!(f, " ")?; for plank in self.planks().iter() {
length_sum += plank.length;
write!(f, "|")?;
for _ in 0..((plank.length()) / scalefactor) {
write!(f, "-")?;
}
}
write!(f, "|")?;
write!(f, " Cut coordinates: ")?;
for cut in self.get_cut_coordinates() {
write!(f, " {cut: ^6}, ")?;
}
writeln!(f)?;
write!(f, "+{PLAY}")?;
for plank in self.planks().iter() {
for _ in 0..((plank.length() - comp) / scalefactor) / 2 {
write!(f, " ")?;
}
write!(f, "{: ^6}", plank.length())?;
for _ in 0..((plank.length() - comp) / scalefactor) / 2 {
write!(f, " ")?;
}
}
write!(f, "+{PLAY}")?;
writeln!(f, "\t Row length: {length_sum}")?;
write!(f, " ")?; for plank in self.planks().iter() {
write!(f, "|")?;
for _ in 0..(plank.length() / scalefactor) {
write!(f, "-")?;
}
}
writeln!(f, "|")
}
}
impl Row {
pub fn get_full(&self) -> bool {
self.full
}
pub fn set_full(&mut self) {
self.full = true;
}
pub fn set_first_and_last_as_endpieces(&mut self) {
self.planks.first_mut().unwrap().set_endpiece();
self.planks.last_mut().unwrap().set_endpiece();
}
pub fn planks_count(&self) -> u32 {
self.planks.len() as u32
}
pub fn planks_mut(&mut self) -> &mut Vec<Plank> {
&mut self.planks
}
pub fn planks(&self) -> &Vec<Plank> {
&self.planks
}
pub fn get_used_planks(&mut self) {
self.planks.len();
}
fn add_coverage(&mut self, coverage: u32) {
self.coverage += coverage;
}
pub fn get_coverage(&self) -> u32 {
self.coverage
}
pub fn get_max_length(&self) -> u32 {
self.row_max_length
}
pub fn add(&mut self, plank: Plank) {
self.add_coverage(plank.length());
let coordinate = self.get_coverage();
if coordinate < self.row_max_length {
self.cut_coordinates.push(Cut::new(coordinate));
}
self.planks.push(plank);
}
pub fn swap_latest(&mut self, ms: &mut MaterialStorage) {
let number_of_planks = self.planks.len();
if number_of_planks >= 2 {
self.pop(ms);
self.pop(ms);
if let Some(plank) = ms.get_used() {
self.add(plank);
}
if let Some(plank) = ms.get_used() {
self.add(plank);
}
}
}
pub fn pop(&mut self, ms: &mut MaterialStorage) {
if let Some(plank) = self.planks.pop() {
ms.store_used(plank);
self.coverage -= plank.length();
}
if let Some(cut) = self.cut_coordinates.pop() {
log::info!("Removed cut at {}", cut.coordinate);
}
}
pub fn get_cut_coordinates(&self) -> Vec<Cut> {
self.cut_coordinates.clone()
}
pub fn check_if_cut_is_valid(&self, new_cut: Cut) -> bool {
if !self.cut_coordinates.is_empty() {
for cut in &self.cut_coordinates {
if cut.coordinate.abs_diff(new_cut.coordinate) < CUTADJACENCY {
return false;
}
}
}
true
}
}
#[derive(Debug)]
pub struct Floor {
rows: Vec<Row>,
coverage: u32,
complete: bool,
}
impl Default for Floor {
fn default() -> Self {
Self {
rows: vec![],
coverage: 0,
complete: false,
}
}
}
impl Display for Floor {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for (num, row) in self.rows().iter().enumerate() {
writeln!(f, "Row: {:#?}", num + 1)?;
writeln!(f, "{row}")?;
}
Ok(())
}
}
impl Floor {
pub fn get_complete(&self) -> bool {
self.complete
}
pub fn set_complete(&mut self) {
self.complete = true;
}
pub fn rows_count(&self) -> usize {
self.rows.len()
}
pub fn rows_mut(&mut self) -> &mut Vec<Row> {
&mut self.rows
}
pub fn rows(&self) -> &Vec<Row> {
&self.rows
}
pub fn last_row(&self) -> Option<&Row> {
self.rows.last()
}
pub fn add(&mut self, row: Row) {
self.rows.push(row);
}
pub fn get_coverage(&self) -> u32 {
self.coverage
}
pub fn add_coverage(&mut self, coverage: u32) {
self.coverage += coverage;
}
}