Skip to content

Commit 76babe5

Browse files
committed
Rendering a random assortment of blocks
This demonstrates use of the TUI library and helped me regain some basic rust familiarity
1 parent 2daf62d commit 76babe5

File tree

6 files changed

+339
-12
lines changed

6 files changed

+339
-12
lines changed

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* text=auto eol=lf

Cargo.lock

+192
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ authors = ["Scott Munro <scottnmunro@gmail.com>"]
55
edition = "2018"
66

77
[dependencies]
8+
pancurses = "0.16"
9+
rand = "0.7.0"

doc.md

+13-11
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,28 @@
1010
## Goals
1111

1212
- Basic tetris mechanics
13-
- tetrimino gravity
14-
- rotating tetriminos
15-
- dropping tetriminos
13+
- tetromino gravity
14+
- rotating tetrominos
15+
- dropping tetrominos
1616
- clearing lines
1717
- score
1818
- end game when top of screen reached
1919

2020
- Extensions
2121
- game music
22+
- ai/autoplay
23+
- ai/competitive
2224
- multiplayer
2325
- network multiplayer
2426

2527
### Steps
2628

27-
- Get a tetrimino to render
28-
- Get a tetrimino to fall
29-
- Get a tetrimino to stick
30-
- Get two tetriminos to stack
31-
- Allow clearing lines
32-
- Generate/Preview random blocks
33-
- Handle game lose state
34-
- Handle scoring
29+
- [X] Get a tetromino to render
30+
- [ ] Get a tetromino to fall
31+
- [ ] Get a tetromino to stick
32+
- [ ] Get two tetrominos to stack
33+
- [ ] Allow clearing lines
34+
- [ ] Generate/Preview random blocks
35+
- [ ] Handle game lose state
36+
- [ ] Handle scoring
3537

src/block.rs

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
extern crate rand;
2+
use rand::{rngs, Rng};
3+
4+
#[derive(Clone, Copy)]
5+
pub enum BlockType {
6+
I,
7+
O,
8+
T,
9+
S,
10+
Z,
11+
J,
12+
L,
13+
}
14+
15+
pub static BLOCKTYPES: [BlockType; 7] = [
16+
BlockType::I,
17+
BlockType::O,
18+
BlockType::T,
19+
BlockType::S,
20+
BlockType::Z,
21+
BlockType::J,
22+
BlockType::L,
23+
];
24+
25+
impl BlockType {
26+
pub fn random(rng: &mut rngs::ThreadRng) -> BlockType {
27+
BLOCKTYPES[rng.gen_range(0, BLOCKTYPES.len())]
28+
}
29+
30+
pub fn to_char(&self) -> char {
31+
match *self {
32+
BlockType::I => 'O',
33+
BlockType::O => 'X',
34+
BlockType::T => '+',
35+
BlockType::S => '>',
36+
BlockType::Z => '<',
37+
BlockType::J => '/',
38+
BlockType::L => '\\',
39+
}
40+
}
41+
42+
#[rustfmt::skip]
43+
pub fn to_block_array(&self) -> [(i32, i32); 4] {
44+
match *self {
45+
BlockType::I =>
46+
[
47+
(0, 0),
48+
(1, 0),
49+
(2, 0),
50+
(3, 0),
51+
],
52+
53+
BlockType::O =>
54+
[
55+
(0, 0), (0, 1),
56+
(1, 0), (1, 1),
57+
],
58+
59+
BlockType::T =>
60+
[
61+
(0, 0), (0, 1), (0, 2),
62+
(1, 1),
63+
],
64+
65+
BlockType::S =>
66+
[
67+
(0, 1), (0, 2),
68+
(1, 0), (1, 1),
69+
],
70+
71+
BlockType::Z =>
72+
[
73+
(0, 0), (0, 1),
74+
(1, 1), (1, 2),
75+
],
76+
77+
BlockType::J =>
78+
[
79+
(0, 1),
80+
(1, 1),
81+
(2, 0), (2, 1),
82+
],
83+
84+
BlockType::L =>
85+
[
86+
(0, 0),
87+
(1, 0),
88+
(2, 0), (2, 1),
89+
],
90+
}
91+
}
92+
}

src/main.rs

+39-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,41 @@
1+
mod block;
2+
use crate::block::*;
3+
4+
extern crate pancurses;
5+
extern crate rand;
6+
7+
use pancurses::{endwin, initscr, Window};
8+
use rand::{thread_rng, Rng};
9+
use std::{thread, time};
10+
11+
fn in_bounds(window: &Window, row: i32, col: i32) -> bool {
12+
row >= 0 && row < window.get_max_y() && col >= 0 && col < window.get_max_x()
13+
}
14+
15+
fn render_block(window: &Window, row: i32, col: i32, b: BlockType) {
16+
let block_char = b.to_char();
17+
let tetromino_pos = b.to_block_array();
18+
for block_pos in tetromino_pos.iter() {
19+
if in_bounds(window, block_pos.0, block_pos.1) {
20+
window.mvaddch(block_pos.0 + row, block_pos.1 + col, block_char);
21+
}
22+
}
23+
}
24+
125
fn main() {
2-
println!("Hello, world!");
26+
let window = initscr();
27+
let mut rng = thread_rng();
28+
for _dashgroup in 0..10 {
29+
window.erase();
30+
for _dashiter in 0..5 {
31+
let x: i32 = rng.gen_range(0, window.get_max_x());
32+
let y: i32 = rng.gen_range(0, window.get_max_y());
33+
render_block(&window, y, x, BlockType::random(&mut rng));
34+
35+
thread::sleep(time::Duration::from_millis(200));
36+
window.refresh();
37+
}
38+
}
39+
window.getch();
40+
endwin();
341
}

0 commit comments

Comments
 (0)