aboutsummaryrefslogtreecommitdiff
path: root/src/layout.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/layout.rs')
-rw-r--r--src/layout.rs169
1 files changed, 145 insertions, 24 deletions
diff --git a/src/layout.rs b/src/layout.rs
index 4c77be4..fe853ad 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -4,6 +4,120 @@ use rand::prelude::*;
use std::fmt;
#[derive(Copy, Clone)]
+pub struct Prelayout {
+ standard_columns: [[char; 3]; 6],
+ index_columns: [[char; 6]; 2],
+}
+
+impl Prelayout {
+ pub fn get_standard_column(&self, index: usize) -> &[char; 3] {
+ &self.standard_columns[index]
+ }
+
+ pub fn get_index_column(&self, index: usize) -> &[char; 6] {
+ &self.index_columns[index]
+ }
+
+ pub fn new_random_from<R: RngCore>(pl: &Prelayout, rng: &mut R) -> Prelayout {
+ let mut standard_columns = pl.standard_columns.clone();
+ let mut index_columns = pl.index_columns.clone();
+
+ let mut count = rng.gen_range(1..=NUM_KEYS / 2);
+ while count > 0 {
+ let source_index: bool = rng.gen();
+ let target_index: bool = rng.gen();
+
+ let saved;
+ let target_col: usize;
+ let target_idx: usize;
+ if target_index {
+ target_col = rng.gen_range(0..2);
+ target_idx = rng.gen_range(0..6);
+ saved = index_columns[target_col][target_idx];
+ } else {
+ target_col = rng.gen_range(0..6);
+ target_idx = rng.gen_range(0..3);
+ saved = standard_columns[target_col][target_idx];
+ }
+
+ let source_col: usize;
+ let source_idx: usize;
+ if source_index {
+ source_col = rng.gen_range(0..2);
+ source_idx = rng.gen_range(0..6);
+ if target_index {
+ index_columns[target_col][target_idx] = index_columns[source_col][source_idx];
+ } else {
+ standard_columns[target_col][target_idx] =
+ index_columns[source_col][source_idx];
+ }
+ index_columns[source_col][source_idx] = saved;
+ } else {
+ source_col = rng.gen_range(0..6);
+ source_idx = rng.gen_range(0..3);
+ if target_index {
+ index_columns[target_col][target_idx] =
+ standard_columns[source_col][source_idx];
+ } else {
+ standard_columns[target_col][target_idx] =
+ standard_columns[source_col][source_idx];
+ }
+ standard_columns[source_col][source_idx] = saved;
+ }
+ count -= 1;
+ }
+ Prelayout {
+ standard_columns,
+ index_columns,
+ }
+ }
+
+ fn from_char_array(ca: &[char; NUM_KEYS]) -> Prelayout {
+ let mut standard_columns = [['x'; 3]; 6];
+ let mut index_columns = [['x'; 6]; 2];
+
+ for i in 0..6 {
+ let ind = if i < 3 { i } else { i + 4 };
+ for j in 0..3 {
+ standard_columns[i][j] = ca[ind + j * ROW_LENGTH];
+ }
+ }
+
+ for j in 0..3 {
+ index_columns[0][j] = ca[3 + j * ROW_LENGTH];
+ index_columns[1][j] = ca[6 + j * ROW_LENGTH];
+ index_columns[0][j + 3] = ca[4 + j * ROW_LENGTH];
+ index_columns[1][j + 3] = ca[5 + j * ROW_LENGTH];
+ }
+
+ Prelayout {
+ standard_columns,
+ index_columns,
+ }
+ }
+
+ fn to_char_array(&self) -> [char; NUM_KEYS] {
+ let mut result = ['x'; NUM_KEYS];
+
+ for i in 0..6 {
+ let ind = if i < 3 { i } else { i + 4 };
+ for j in 0..3 {
+ result[ind + j * ROW_LENGTH] = self.standard_columns[i][j];
+ }
+ }
+
+ for j in 0..3 {
+ result[3 + j * ROW_LENGTH] = self.index_columns[0][j];
+ result[6 + j * ROW_LENGTH] = self.index_columns[1][j];
+ result[4 + j * ROW_LENGTH] = self.index_columns[0][j + 3];
+ result[5 + j * ROW_LENGTH] = self.index_columns[1][j + 3];
+ }
+
+ result
+ }
+}
+
+#[derive(Copy, Clone)]
pub struct Layout {
keys: [char; NUM_KEYS],
// index in KEY_CHAR -> index in layout
@@ -11,15 +125,16 @@ pub struct Layout {
}
impl Layout {
- pub fn get_key(&self, index: usize) -> char {
- self.keys[index]
+ pub fn as_prelayout(&self) -> Prelayout {
+ Prelayout::from_char_array(&self.keys)
}
- pub fn translate_index(&self, i: usize) -> usize {
- self.translate_index[i]
+ pub fn from_prelayout(pl: &Prelayout) -> Layout {
+ // TODO: something more clever about permuting colums, keys within columns etc
+ Layout::char_array_to_layout(pl.to_char_array())
}
- fn keys_to_layout(layout: [char; NUM_KEYS]) -> Layout {
+ fn char_array_to_layout(layout: [char; NUM_KEYS]) -> Layout {
let mut translate_index: [usize; NUM_KEYS] = [0; NUM_KEYS];
for (i, seek) in KEY_CHARS.iter().enumerate() {
@@ -36,6 +151,14 @@ impl Layout {
};
}
+ pub fn get_key(&self, index: usize) -> char {
+ self.keys[index]
+ }
+
+ pub fn translate_index(&self, i: usize) -> usize {
+ self.translate_index[i]
+ }
+
pub fn from_verbose(inp: &str) -> Option<Layout> {
let mut layout: [char; NUM_KEYS] = ['x'; NUM_KEYS];
@@ -55,23 +178,23 @@ impl Layout {
}
}
- return Some(Layout::keys_to_layout(layout));
+ return Some(Layout::char_array_to_layout(layout));
}
- pub fn new_random_from<R: RngCore>(kbd: &Layout, rng: &mut R) -> Layout {
- let mut layout = kbd.keys;
- // layout.shuffle(rng);
- let mut count = rng.gen_range(1..=15);
- while count > 0 {
- let a = rng.gen_range(0..NUM_KEYS);
- let b = rng.gen_range(0..NUM_KEYS);
- let k = layout[b];
- layout[b] = layout[a];
- layout[a] = k;
- count -= 1;
- }
- Layout::keys_to_layout(layout)
- }
+ // pub fn new_random_from<R: RngCore>(kbd: &Layout, rng: &mut R) -> Layout {
+ // let mut layout = kbd.keys;
+ // // layout.shuffle(rng);
+ // let mut count = rng.gen_range(1..=NUM_KEYS / 2);
+ // while count > 0 {
+ // let a = rng.gen_range(0..NUM_KEYS);
+ // let b = rng.gen_range(0..NUM_KEYS);
+ // let k = layout[b];
+ // layout[b] = layout[a];
+ // layout[a] = k;
+ // count -= 1;
+ // }
+ // Layout::char_array_to_layout(layout)
+ // }
}
impl fmt::Display for Layout {
@@ -129,10 +252,8 @@ impl Evaluation {
);
}
- result += &format!(
- "\ntotal sfb: {:.2}%",
- self.sfb.iter().sum::<u32>() as f32 / tot * 100.0
- );
+ let sfb = self.sfb.iter().sum::<u32>();
+ result += &format!("\ntotal sfb: {:.2}% ({})", sfb as f32 / tot * 100.0, sfb);
return result;
}