From ea64a7c7bbc105000585b7c4c27c515dbd2bf9c3 Mon Sep 17 00:00:00 2001 From: Vegard Matthey Date: Fri, 24 May 2024 20:31:45 +0200 Subject: [PATCH] initial --- .gitignore | 2 + Cargo.toml | 7 +++ src/main.rs | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..cfaab32 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "term_tetris" +version = "0.1.0" +edition = "2021" + +[dependencies] +rand = "0.8.5" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..f77a29c --- /dev/null +++ b/src/main.rs @@ -0,0 +1,162 @@ +// use rand::prelude::*; +use std::time::Instant; +use std::{io, io::Write}; +// https://tetris.wiki/Super_Rotation_System + +const RED_BLOCK: &str = "\x1b[48;2;255;0;0m \x1b[0m"; +const GREEN_BLOCK: &str = "\x1b[48;2;0;255;0m \x1b[0m"; +const BLUE_BLOCK: &str = "\x1b[48;2;0;0;255m \x1b[0m"; +const YELLOW_BLOCK: &str = "\x1b[48;2;255;255;0m \x1b[0m"; +const ORANGE_BLOCK: &str = "\x1b[48;2;255;166;0m \x1b[0m"; +const PURPLE_BLOCK: &str = "\x1b[48;2;128;0;128m \x1b[0m"; +const CYAN_BLOCK: &str = "\x1b[48;2;0;255;255m \x1b[0m"; + +const I: [(i8, i8); 4] = [(-1, 0), (0, 0), (1, 0), (2, 0)]; +const J: [(i8, i8); 4] = [(0, 0), (-1, 0), (1, 0), (-1, 1)]; +const L: [(i8, i8); 4] = [(0, 0), (-1, 0), (1, 0), (1, 1)]; +const T: [(i8, i8); 4] = [(0, 0), (0, 1), (-1, 0), (1, 0)]; + +fn main() { + let instant = Instant::now(); + std::thread::sleep(std::time::Duration::from_millis(3)); + let mut tetromino = Tetromino::new(&instant); + let mut blocks = vec![]; + loop { + render(&tetromino, &blocks); + std::thread::sleep(std::time::Duration::from_millis(100)); + } +} + +enum TetrominoKind { + I, + O, + T, + J, + L, + S, + Z, +} + +struct Tetromino { + kind: TetrominoKind, + pos: (i8, i8), + b: [(i8, i8); 4], +} + +struct Block { + pos: (i8, i8), + kind: TetrominoKind, +} + +// impl TetrominoKind { +// fn to_str(&self) -> &str { +// match self { +// Color::Red => RED_BLOCK, +// Color::Blue => BLUE_BLOCK, +// Color::Green => GREEN_BLOCK, +// Color::Yellow => YELLOW_BLOCK, +// Color::Orange => ORANGE_BLOCK, +// Color::Purple => PURPLE_BLOCK, +// Color::Cyan => CYAN_BLOCK, +// } +// } +// } +// + +impl Tetromino { + fn new(instant: &Instant) -> Self { + let kind = TetrominoKind::new(instant); + Self { + b: kind.get_blocks(), + kind, + pos: (5, 5), + } + } +} + +impl TetrominoKind { + fn new(instant: &Instant) -> Self { + match instant.elapsed().as_millis() % 7 { + 0 => Self::I, + 1 => Self::O, + 2 => Self::T, + 3 => Self::J, + 4 => Self::L, + 5 => Self::S, + 6 => Self::Z, + 7 => Self::O, + _ => unreachable!(), + } + } + + fn get_blocks(&self) -> [(i8, i8); 4] { + match self { + Self::I => I, + Self::O => T, + Self::T => T, + Self::J => J, + Self::L => L, + Self::S => T, + Self::Z => T, + } + } + + fn to_block(&self) -> &str { + match self { + Self::I => CYAN_BLOCK, + Self::O => YELLOW_BLOCK, + Self::T => PURPLE_BLOCK, + Self::J => BLUE_BLOCK, + Self::L => ORANGE_BLOCK, + Self::S => GREEN_BLOCK, + Self::Z => RED_BLOCK, + } + } +} + +fn render(tetromino: &Tetromino, blocks: &Vec) { + let mut s = String::with_capacity(2 * 22 * 22); + s.push('┏'); + s.push_str("━━━━━━━━━━━━━━━━━━━━"); + s.push_str("┓\n"); + for y in (0..20).rev() { + s.push('┃'); + for x in 0..10 { + let mut found = false; + for block in blocks { + if block.pos == (x, y) { + s.push_str(block.kind.to_block()); + found = true; + break; + } + } + for block in tetromino.b { + if (block.0 + tetromino.pos.0, block.1 + tetromino.pos.1) == (x, y) { + s.push_str(tetromino.kind.to_block()); + found = true; + break; + } + } + if !found { + s.push_str(" "); + } + } + s.push_str("┃\n"); + } + s.push('┗'); + s.push_str("━━━━━━━━━━━━━━━━━━━━"); + s.push('┛'); + print!("\x1b[2J\x1b[H{s}"); + io::stdout().flush().unwrap(); +} + +#[test] +fn color() { + println!("red: {RED_BLOCK}"); + println!("green: {GREEN_BLOCK}"); + println!("blue: {BLUE_BLOCK}"); + println!("yellow: {YELLOW_BLOCK}"); + println!("orange: {ORANGE_BLOCK}"); + println!("purple: {PURPLE_BLOCK}"); + println!("cyan: {CYAN_BLOCK}"); +}