use blok::*;
#[derive(Clone, Default)]
struct MyBlock {
id: String
}
impl Block for MyBlock {
type CreationInstructions = String;
fn create(id: &String) -> Self {
MyBlock {
id: id.to_owned(),
}
}
fn void() -> Self {
Self::default()
}
fn is_void(&self) -> bool {
self.id.is_empty()
}
}
fn build_cube() -> Stack<MyBlock> {
let mut stack = Stack::new();
let new_block = |id: &str| MyBlock::create(&id.to_string());
let mut base_layer = Layer::new();
base_layer.add_block(new_block("000"));
base_layer.add_blocks(vec![
new_block("001"),
new_block("002"),
new_block("003"),
]);
base_layer.new_row();
base_layer.add_block_to_row(1, new_block("010"))
.expect("Should add block to newly-created row.");
base_layer.add_blocks_to_row(1, vec![
new_block("011"),
new_block("012"),
new_block("013"),
])
.expect("Should add many blocks to newly-created row.");
let mut base_row_3 = Row::new();
base_row_3
.add_block(new_block("030"))
.add_blocks(vec![new_block("031"), new_block("033")])
.insert_block(2, new_block("032"))
.expect("Should insert block '032' at index 2.");
base_layer.add_row(base_row_3);
let row_2 = Row::wrap(vec![
new_block("020"),
new_block("021"),
new_block("022"),
new_block("023"),
]);
base_layer.insert_row(2, row_2)
.expect("Should insert row_2 before the previously-added row.");
stack.add_layer(base_layer);
let mut layer_1 = Layer::new();
layer_1.populate_with_clones(
layout![4; 4],
&MyBlock::void()
);
layer_1.get_all_mut()
.into_iter()
.enumerate()
.for_each(|(r, row_mut)| {
row_mut.into_iter()
.enumerate()
.for_each(|(b, block_mut)| {
block_mut.id = format!("1{}{}", r, b)
});
});
stack.add_layer(layer_1);
stack.populate_with_clones(
vec![ layout!(4; 4), layout!(4; 4) ],
&MyBlock::void()
);
stack.get_all_mut()
.into_iter()
.enumerate()
.for_each(|(l, layer_mut)| { if l > 1 {
layer_mut.into_iter()
.enumerate()
.for_each(|(r, row_mut)| {
row_mut.into_iter()
.enumerate()
.for_each(|(b, block_mut)| {
block_mut.id = format!("{}{}{}", l, r, b)
});
});
}});
stack
}
fn build_cube_quickly() -> Stack<MyBlock> {
let mut stack = Stack::new();
stack
.populate_with_clones(vec!{ layout![4; 4]; 4 }, &MyBlock::void())
.get_all_mut()
.into_iter()
.enumerate()
.for_each(|(l, layer_mut)| {
layer_mut.into_iter()
.enumerate()
.for_each(|(r, row_mut)| {
row_mut.into_iter()
.enumerate()
.for_each(|(b, block_mut)| {
block_mut.id = format!("{}{}{}", l, r, b)
});
});
});
stack
}
fn build_pyramid(base_length: usize) -> Stack<MyBlock> {
let mut stack = Stack::new();
let mut side_length = base_length as i8;
let mut side_lengths = Vec::new();
while side_length > 0 {
side_lengths.push(side_length as usize);
side_length -= 2;
}
let layouts = side_lengths.into_iter().map(|len| layout![len; len]).collect();
stack.populate(layouts, &"Stone".to_string());
let layers = stack.clone_into_layers()
.into_iter()
.map(|mut layer| {
let side_length = layer.layout().len();
let border_width = (base_length - side_length) / 2;
layer
.pad_x(border_width)
.pad_y(border_width)
.offset_x(border_width)
.offset_y(border_width);
layer
})
.collect();
stack.set_from_layers(layers);
stack.fill_voids(&"Air".to_string());
stack }
fn main() {
let cube_stack = build_cube();
let quick_cube = build_cube_quickly();
cube_stack.get_all_ref()
.into_iter()
.enumerate()
.for_each(|(l, layer_ref)| {
layer_ref.into_iter()
.enumerate()
.for_each(|(r, row_ref)| {
row_ref.into_iter()
.enumerate()
.for_each(|(b, block_ref)| {
let quick_block_ref = quick_cube.get_block_ref(l, r, b)
.expect("Should find the corresponding block.");
assert_eq!(block_ref.id, quick_block_ref.id);
});
});
});
let pyramid_scene = build_pyramid(7);
let stone_counts: Vec<usize> =
pyramid_scene.get_all_ref()
.into_iter()
.map(|layer| {
layer.iter()
.map(|row| {
row.iter()
.filter(|block| block.id == "Stone")
.count()
})
.sum()
})
.collect();
assert_eq!(stone_counts, vec![49, 25, 9, 1]);
println!("That's all, folks!");
}