aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/history.rs39
-rw-r--r--src/main.rs67
-rw-r--r--src/scramble.rs14
-rw-r--r--src/time.rs4
4 files changed, 97 insertions, 27 deletions
diff --git a/src/history.rs b/src/history.rs
index 3238543..6f03d44 100644
--- a/src/history.rs
+++ b/src/history.rs
@@ -6,7 +6,7 @@
/* By: charles <charles.cabergs@gmail.com> /o o \ */
/* / v \ */
/* Created: 2020/06/25 13:24:10 by charles / _ \ */
-/* Updated: 2020/06/25 13:24:12 by charles '-----------' */
+/* Updated: 2020/06/25 15:29:21 by charles '-----------' */
/* */
/* ************************************************************************** */
@@ -20,6 +20,7 @@ use chrono;
use chrono::prelude::*;
use super::scramble::Scramble;
+use super::time::Timer;
pub struct SolveTime(Duration);
@@ -50,17 +51,23 @@ struct Entry {
date: chrono::DateTime<Utc>,
}
-pub struct History(Vec<Entry>);
+pub struct History {
+ entries: Vec<Entry>,
+ deleted: Vec<Entry>,
+}
const VEC_START_SIZE: usize = 200;
impl History {
pub fn from_csv(file_path: &str) -> History {
- let mut history = History(Vec::with_capacity(VEC_START_SIZE));
+ let mut history = History {
+ entries: Vec::with_capacity(VEC_START_SIZE),
+ deleted: Vec::new()
+ };
let mut reader = csv::Reader::from_path(file_path).unwrap();
for result in reader.records() {
if let Ok(record) = result {
- history.0.push(Entry{
+ history.entries.push(Entry{
time: record[0].parse::<SolveTime>().unwrap(),
scramble: record[1].parse::<Scramble>().unwrap(),
date: record[2].parse::<chrono::DateTime<Utc>>().unwrap()
@@ -73,7 +80,7 @@ impl History {
pub fn save_csv(&self, file_path: &str) {
let mut writter = csv::Writer::from_path(file_path).unwrap();
writter.write_record(&["time", "scramble", "date"]).unwrap();
- for entry in &self.0 {
+ for entry in &self.entries {
writter.write_record(&[
entry.time.to_string(),
entry.scramble.to_string(),
@@ -84,6 +91,26 @@ impl History {
}
pub fn summarize(&self, n: usize) -> Vec<String> {
- self.0.iter().skip(self.0.len() - n).map(|Entry{time, ..}| time.to_string()).collect()
+ self.entries.iter().skip(self.entries.len() - n).map(|Entry{time, ..}| time.to_string()).collect()
+ }
+
+ pub fn pop(&mut self) {
+ if let Some(e) = self.entries.pop() {
+ self.deleted.push(e);
+ }
+ }
+
+ pub fn undo_pop(&mut self) {
+ if let Some(e) = self.deleted.pop() {
+ self.entries.push(e);
+ }
+ }
+
+ pub fn push(&mut self, timer: &Timer, scramble: &Scramble) {
+ self.entries.push(Entry {
+ time: SolveTime(timer.result),
+ scramble: scramble.clone(),
+ date: chrono::offset::Utc::now(),
+ });
}
}
diff --git a/src/main.rs b/src/main.rs
index eab790e..f431ae7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,8 +5,8 @@
/* / \ */
/* By: charles <charles.cabergs@gmail.com> /o o \ */
/* / v \ */
-/* Created: 2020/06/25 11:42:17 by charles / _ \ */
-/* Updated: 2020/06/25 13:24:00 by charles '-----------' */
+/* Created: 2020/06/25 14:38:48 by charles / _ \ */
+/* Updated: 2020/06/25 15:35:58 by charles '-----------' */
/* */
/* ************************************************************************** */
@@ -37,6 +37,10 @@ const GREEN: Color = Color::RGB(0x1B, 0x5E, 0x20);
const ORANGE: Color = Color::RGB(0xEF, 0x6C, 0x00);
const BLACK: Color = Color::RGB(0x00, 0x00, 0x00);
+const SCRAMBLE_LEN: usize = 14;
+const SUMMARY_LEN: usize = 12;
+const HISTORY_FILE_PATH: &str = "history.csv";
+
fn str_to_tex<'a, T>(s: &str, font: &ttf::Font, creator: &'a TextureCreator<T>, bg: Color) -> Texture<'a> {
let surface = font.render(s).shaded(WHITE, bg).unwrap();
creator.create_texture_from_surface(&surface).unwrap()
@@ -47,6 +51,18 @@ fn pad_rect(rect: &mut Rect, pad: u32) {
rect.offset(pad as i32 / 2, pad as i32 / 2);
}
+fn rect_text(frame: &Rect, len: usize) -> Rect {
+ let mut rect = *frame;
+ rect.set_width(len as u32 * FONT_SIZE);
+ rect.set_height(2 * FONT_SIZE);
+ if rect.width() > frame.width() {
+ rect.set_height(rect.height() * (rect.width() / frame.width()));
+ rect.set_width(frame.width());
+ }
+ rect.center_on(frame.center());
+ rect
+}
+
fn main() {
let sdl = sdl2::init().unwrap();
let ttf = ttf::init().unwrap();
@@ -55,14 +71,17 @@ fn main() {
.window(TITLE, WIDTH, HEIGHT)
.build()
.unwrap();
+ std::fs::copy(HISTORY_FILE_PATH, HISTORY_FILE_PATH.to_owned() + ".backup").unwrap();
let font = ttf.load_font("font/FiraMono-Regular.ttf", FONT_SIZE as u16).unwrap();
let mut canvas = window.into_canvas().build().unwrap();
let mut event_pump = sdl.event_pump().unwrap();
let tex_creator = canvas.texture_creator();
- let hist = History::from_csv("history.csv");
+ let mut hist = History::from_csv(HISTORY_FILE_PATH);
let mut timer = time::Timer::new();
- let mut scramble_tex = str_to_tex(&Scramble::new_rand(10).to_string(), &font, &tex_creator, BLACK);
+ let mut scramble = Scramble::new_rand(SCRAMBLE_LEN);
+ let mut scramble_str = scramble.to_string();
+ let mut scramble_tex = str_to_tex(&scramble_str, &font, &tex_creator, BLACK);
let mut timer_tex = str_to_tex(&timer.to_string(), &font, &tex_creator, BLACK);
'running: loop {
@@ -73,12 +92,16 @@ fn main() {
match timer.state {
time::State::Inactive => {
timer.idle();
- scramble_tex = str_to_tex(&Scramble::new_rand(10).to_string(),
- &font, &tex_creator, BLACK);
- timer_tex = str_to_tex(&timer.to_string(), &font, &tex_creator, BLACK);
},
time::State::Idle => {},
- time::State::Active => timer.stop(),
+ time::State::Active => {
+ timer.stop();
+ timer_tex = str_to_tex(&timer.to_string(), &font, &tex_creator, BLACK);
+ hist.push(&timer, &scramble);
+ scramble = Scramble::new_rand(SCRAMBLE_LEN);
+ scramble_str = scramble.to_string();
+ scramble_tex = str_to_tex(&scramble_str, &font, &tex_creator, BLACK);
+ },
}
}
Event::KeyUp { keycode: Some(Keycode::Space), repeat: false, .. } => {
@@ -86,6 +109,16 @@ fn main() {
timer.start();
}
},
+ Event::KeyDown { keycode: Some(Keycode::D), repeat: false, .. } => {
+ if timer.state == time::State::Inactive {
+ hist.pop();
+ }
+ },
+ Event::KeyDown { keycode: Some(Keycode::U), repeat: false, .. } => {
+ if timer.state == time::State::Inactive {
+ hist.undo_pop();
+ }
+ },
_ => {}
}
}
@@ -99,7 +132,6 @@ fn main() {
match timer.state {
time::State::Inactive => {
-
let mut history_rect = Rect::new(0, 0, WIDTH/ 3, HEIGHT);
let mut scramble_rect = Rect::new(WIDTH as i32 / 3, 0, 2 * WIDTH / 3, HEIGHT / 3);
let mut timer_rect = Rect::new(WIDTH as i32 / 3, HEIGHT as i32 / 3,
@@ -112,19 +144,19 @@ fn main() {
pad_rect(&mut history_rect, 10);
pad_rect(&mut scramble_rect, 20);
pad_rect(&mut timer_rect, 40);
- scramble_rect.set_height(FONT_SIZE * 2);
- timer_rect.set_height(FONT_SIZE * 2);
- timer_rect.set_width(timer.to_string().len() as u32 * FONT_SIZE);
- canvas.copy(&scramble_tex, None, scramble_rect).unwrap();
- canvas.copy(&timer_tex, None, timer_rect).unwrap();
+ let scramble_text_rect = rect_text(&scramble_rect, scramble_str.len());
+ let timer_text_rect = rect_text(&timer_rect, timer.to_string().len());
+
+ canvas.copy(&scramble_tex, None, scramble_text_rect).unwrap();
+ canvas.copy(&timer_tex, None, timer_text_rect).unwrap();
let mut entry_rect = history_rect;
- entry_rect.set_height(entry_rect.height() / 5);
- for entry in hist.summarize(5) {
+ entry_rect.set_height(history_rect.height() / SUMMARY_LEN as u32);
+ for entry in hist.summarize(SUMMARY_LEN) {
let entry_tex = str_to_tex(&entry.to_string(), &font, &tex_creator, BLACK);
canvas.copy(&entry_tex, None, entry_rect).unwrap();
- entry_rect.set_y(entry_rect.y() + history_rect.height() as i32 / 5);
+ entry_rect.set_y(entry_rect.y() + history_rect.height() as i32 / SUMMARY_LEN as i32);
}
},
time::State::Idle => {},
@@ -145,6 +177,7 @@ fn main() {
std::thread::sleep(std::time::Duration::new(0, 10_000_000));
}
}
+ hist.save_csv(HISTORY_FILE_PATH);
}
/* inactive (all black)
diff --git a/src/scramble.rs b/src/scramble.rs
index 061341e..b718cc5 100644
--- a/src/scramble.rs
+++ b/src/scramble.rs
@@ -6,7 +6,7 @@
/* By: charles <charles.cabergs@gmail.com> /o o \ */
/* / v \ */
/* Created: 2020/06/25 13:24:17 by charles / _ \ */
-/* Updated: 2020/06/25 13:24:18 by charles '-----------' */
+/* Updated: 2020/06/25 15:29:01 by charles '-----------' */
/* */
/* ************************************************************************** */
@@ -18,6 +18,7 @@ use rand::{
Rng
};
+#[derive(Clone)]
pub struct Scramble(Vec<Move>);
impl Scramble {
@@ -57,6 +58,13 @@ impl str::FromStr for Scramble {
}
}
+// impl Clone for Scramble {
+// fn clone(&self) -> Scramble {
+// let v = self.0;
+// Scramble(v)
+// }
+// }
+
impl str::FromStr for Move {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
@@ -87,11 +95,13 @@ impl str::FromStr for Move {
}
}
-#[derive(PartialEq)]
+#[derive(PartialEq, Clone)]
enum Direction { Front, Back, Down, Up, Right, Left, }
+#[derive(Clone)]
enum Modifier { No, Twice, Prime, }
+#[derive(Clone)]
struct Move {
direction: Direction,
modifier: Modifier,
diff --git a/src/time.rs b/src/time.rs
index e9fabe9..76cc04e 100644
--- a/src/time.rs
+++ b/src/time.rs
@@ -6,7 +6,7 @@
/* By: charles <charles.cabergs@gmail.com> /o o \ */
/* / v \ */
/* Created: 2020/06/25 13:24:24 by charles / _ \ */
-/* Updated: 2020/06/25 13:24:24 by charles '-----------' */
+/* Updated: 2020/06/25 15:23:01 by charles '-----------' */
/* */
/* ************************************************************************** */
@@ -22,7 +22,7 @@ pub enum State {
pub struct Timer {
pub state: State,
time: SystemTime,
- result: Duration,
+ pub result: Duration,
}
impl Timer {