get basic tui set up
This commit is contained in:
commit
22a9742102
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
||||
261
Cargo.lock
generated
Normal file
261
Cargo.lock
generated
Normal file
@ -0,0 +1,261 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
|
||||
dependencies = [
|
||||
"bitflags 2.4.0",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm_winapi"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "shdoku"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"crossterm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-mio"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
||||
12
Cargo.toml
Normal file
12
Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "shdoku"
|
||||
description = "a basic tui-sudoku game"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["markichnich"]
|
||||
license = "GPL-3.0-or-later"
|
||||
keywords = ["sudoku", "tui", "game", "crossterm"]
|
||||
categories = ["games", "mathematics", "science", "algorithms"]
|
||||
|
||||
[dependencies]
|
||||
crossterm = "0.27.0"
|
||||
170
src/main.rs
Normal file
170
src/main.rs
Normal file
@ -0,0 +1,170 @@
|
||||
extern crate crossterm;
|
||||
use crossterm::{
|
||||
cursor::{MoveTo, SetCursorStyle},
|
||||
event::{poll, read, Event::*, KeyCode::*},
|
||||
execute, queue,
|
||||
terminal::{disable_raw_mode, enable_raw_mode, size, Clear, ClearType::All},
|
||||
};
|
||||
|
||||
use std::{
|
||||
io::{self, stdout, Stdout, Write},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let (width, height) = size()?;
|
||||
let (mut width, mut height) = (width as usize, height as usize);
|
||||
|
||||
let mut screen = vec![String::with_capacity(width); height];
|
||||
|
||||
let modifiable = [
|
||||
[false, false, true, true, false, true, true, true, true],
|
||||
[false, true, true, false, false, false, true, true, true],
|
||||
[true, false, false, true, true, true, true, false, true],
|
||||
[false, true, true, true, false, true, true, true, false],
|
||||
[false, true, true, false, true, false, true, true, false],
|
||||
[false, true, true, true, false, true, true, true, false],
|
||||
[true, false, true, true, true, true, false, false, true],
|
||||
[true, true, true, false, false, false, true, true, false],
|
||||
[true, true, true, true, false, true, true, false, false],
|
||||
];
|
||||
|
||||
let mut board = [
|
||||
[5, 3, 0, 0, 7, 0, 0, 0, 0],
|
||||
[6, 0, 0, 1, 9, 5, 0, 0, 0],
|
||||
[0, 9, 8, 0, 0, 0, 0, 6, 0],
|
||||
[8, 0, 0, 0, 6, 0, 0, 0, 3],
|
||||
[4, 0, 0, 8, 0, 3, 0, 0, 1],
|
||||
[7, 0, 0, 0, 2, 0, 0, 0, 6],
|
||||
[0, 6, 0, 0, 0, 0, 2, 8, 0],
|
||||
[0, 0, 0, 4, 1, 9, 0, 0, 5],
|
||||
[0, 0, 0, 0, 8, 0, 0, 7, 9],
|
||||
];
|
||||
|
||||
let mut cur_row = 0;
|
||||
let mut cur_col = 0;
|
||||
|
||||
let mut stdout = stdout();
|
||||
enable_raw_mode()?;
|
||||
|
||||
loop {
|
||||
let (w, h) = size()?;
|
||||
(width, height) = (w as usize, h as usize);
|
||||
|
||||
if poll(Duration::from_millis(250))? {
|
||||
if let Ok(Key(k)) = read() {
|
||||
match k.code {
|
||||
Char('q') => break,
|
||||
Char('h') => cur_col = (cur_col + 8) % 9,
|
||||
Char('j') => cur_row = (cur_row + 1) % 9,
|
||||
Char('k') => cur_row = (cur_row + 8) % 9,
|
||||
Char('l') => cur_col = (cur_col + 1) % 9,
|
||||
Char('H') => cur_col = (cur_col + 6) % 9,
|
||||
Char('J') => cur_row = (cur_row + 3) % 9,
|
||||
Char('K') => cur_row = (cur_row + 6) % 9,
|
||||
Char('L') => cur_col = (cur_col + 3) % 9,
|
||||
Char('x') => board[cur_row][cur_col] = 0,
|
||||
Char(num) if ('1'..='9').contains(&num) => {
|
||||
if modifiable[cur_row][cur_col] {
|
||||
board[cur_row][cur_col] = num as u8 - b'0'
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render_to_screen(&mut screen, width, height, board);
|
||||
draw_screen(&mut stdout, &screen)?;
|
||||
place_cursor(&mut stdout, cur_row, cur_col, width, height)?;
|
||||
}
|
||||
|
||||
disable_raw_mode()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn place_cursor(
|
||||
stdout: &mut Stdout,
|
||||
cur_row: usize,
|
||||
cur_col: usize,
|
||||
width: usize,
|
||||
height: usize,
|
||||
) -> io::Result<()> {
|
||||
let (x, y) = ((width / 2 - 14) as u16, (height / 2 - 7) as u16);
|
||||
let (x, y) = (x + 2, y + 1);
|
||||
let (x, y) = (x + 2 * cur_col as u16, y + cur_row as u16);
|
||||
let x = match cur_col {
|
||||
0..=2 => x,
|
||||
3..=5 => x + 3,
|
||||
_ => x + 6,
|
||||
};
|
||||
let y = match cur_row {
|
||||
0..=2 => y,
|
||||
3..=5 => y + 1,
|
||||
_ => y + 2,
|
||||
};
|
||||
execute!(stdout, MoveTo(x, y), SetCursorStyle::SteadyBlock)
|
||||
}
|
||||
|
||||
fn draw_screen(stdout: &mut Stdout, screen: &[String]) -> io::Result<()> {
|
||||
queue!(stdout, Clear(All))?;
|
||||
let s: String = screen.join("\r\n");
|
||||
write!(stdout, "{}", s)?;
|
||||
stdout.flush()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn render_to_screen(screen: &mut Vec<String>, cols: usize, rows: usize, board: [[u8; 9]; 9]) {
|
||||
let mut lines = Vec::new();
|
||||
lines.push("┌────────┬────────┬────────┐".to_string().chars().collect());
|
||||
|
||||
for (row, row_slice) in board.iter().enumerate() {
|
||||
match row {
|
||||
3 | 6 => {
|
||||
lines.push("├────────┼────────┼────────┤".to_string().chars().collect());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let mut line = String::new();
|
||||
for (col, cur_field) in row_slice.iter().enumerate() {
|
||||
match col {
|
||||
0 => {
|
||||
line.push_str("│ ");
|
||||
}
|
||||
3 | 6 => {
|
||||
line.push_str(" │ ");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
line.push(match cur_field {
|
||||
0 => ' ',
|
||||
n => (b'0' + n) as char,
|
||||
});
|
||||
line.push(' ');
|
||||
}
|
||||
line.push_str(" │");
|
||||
lines.push(line);
|
||||
}
|
||||
lines.push("└────────┴────────┴────────┘".to_string().chars().collect());
|
||||
|
||||
let pad_hori = cols / 2 + lines[0].chars().count() / 2;
|
||||
let pad_vert = rows - lines.len();
|
||||
let pad_top = pad_vert / 2;
|
||||
let pad_bot = pad_vert - pad_top;
|
||||
|
||||
let mut new_screen = Vec::new();
|
||||
|
||||
for _ in 0..pad_top {
|
||||
new_screen.push(String::new());
|
||||
}
|
||||
for line in lines {
|
||||
let padded = format!("{: >width$}", line, width = pad_hori);
|
||||
new_screen.push(padded);
|
||||
}
|
||||
for _ in 0..pad_bot {
|
||||
new_screen.push(String::new());
|
||||
}
|
||||
|
||||
*screen = new_screen;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user