initial
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/target
|
||||
Cargo.lock
|
||||
7
Cargo.toml
Normal file
7
Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "term_tetris"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
rand = "0.8.5"
|
||||
162
src/main.rs
Normal file
162
src/main.rs
Normal file
@@ -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<Block>) {
|
||||
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}");
|
||||
}
|
||||
Reference in New Issue
Block a user