add stuf
This commit is contained in:
parent
fc2d7822d4
commit
312f971e5d
213
src/main.rs
213
src/main.rs
|
|
@ -1,3 +1,212 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
use std::fmt::Display;
|
||||
use std::ops::Index;
|
||||
use std::ops::IndexMut;
|
||||
use std::iter;
|
||||
use crossterm::event::Event;
|
||||
use crossterm::event::KeyEvent;
|
||||
use crossterm::event::KeyCode;
|
||||
use crossterm::event::KeyModifiers;
|
||||
use crossterm::event;
|
||||
use crossterm::cursor::*;
|
||||
use std::io::stdout;
|
||||
|
||||
/// board size is 8*8 with 10 bombs
|
||||
#[derive(Debug, Default)]
|
||||
struct Board {
|
||||
board: [[Status; 8]; 8],
|
||||
}
|
||||
impl Index<Point> for Board {
|
||||
type Output = Status;
|
||||
fn index(&self, index: Point) -> &Self::Output {
|
||||
&self.board[index.0][8-index.1]
|
||||
}
|
||||
}
|
||||
impl IndexMut<Point> for Board {
|
||||
fn index_mut(&mut self, index: Point) -> &mut Self::Output {
|
||||
&mut self.board[index.0][8-index.1]
|
||||
}
|
||||
}
|
||||
impl Board {
|
||||
fn get(&self, idx:Point) -> Option<&Status> {
|
||||
self.board.get(idx.0)?.get(7-idx.1)
|
||||
}
|
||||
fn get_mut(&mut self, idx:Point) -> Option<&mut Status> {
|
||||
self.board.get_mut(idx.0)?.get_mut(7-idx.1)
|
||||
}
|
||||
fn insert_bomb(&mut self, idx:Point) {
|
||||
let all = Board::all_points();
|
||||
// all.filter(|a|idx.is_adjacent(&a)).filter_map(|a|self.get_mut(a)).filter_map(|a|a.val()).for_each(|a| {*a += 1;} );
|
||||
for a in all.filter(|a|idx.is_adjacent(&a)) {
|
||||
let val = self.get_mut(a).map(|a| a.val()).flatten();
|
||||
match val {
|
||||
Some(a) => {*a+=1;}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
self[idx] = Status::Bomb;
|
||||
|
||||
}
|
||||
fn all_points() -> impl Iterator<Item = Point> {
|
||||
const WIDTH: usize = 8;
|
||||
const HIGHT: usize = 8;
|
||||
let x = (0..WIDTH)
|
||||
.cycle()
|
||||
.take(WIDTH*HIGHT);
|
||||
let y = (0..(WIDTH*HIGHT)).map(|a| a / WIDTH);
|
||||
x.zip(y).map(|(x, y)| Point(x, y))
|
||||
}
|
||||
}
|
||||
impl Display for Board {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
/* for (i, n) in self.board.iter().enumerate() {
|
||||
if i == 7 {
|
||||
return write!(f, "{}{}{}{}{}{}{}{}", n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7])
|
||||
} else {
|
||||
writeln!(f, "{}{}{}{}{}{}{}{}", n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7])?;
|
||||
}
|
||||
return Ok(());
|
||||
} */
|
||||
write!(f, "\
|
||||
\r{} {} {} {} {} {} {} {}\n\r\
|
||||
{} {} {} {} {} {} {} {}\n\r\
|
||||
{} {} {} {} {} {} {} {}\n\r\
|
||||
{} {} {} {} {} {} {} {}\n\r\
|
||||
{} {} {} {} {} {} {} {}\n\r\
|
||||
{} {} {} {} {} {} {} {}\n\r\
|
||||
{} {} {} {} {} {} {} {}\n\r\
|
||||
{} {} {} {} {} {} {} {}\n\r",
|
||||
self.board[0][7], self.board[1][7], self.board[2][7], self.board[3][7], self.board[4][7], self.board[5][7], self.board[6][7], self.board[7][7],
|
||||
self.board[0][6], self.board[1][6], self.board[2][6], self.board[3][6], self.board[4][6], self.board[5][6], self.board[6][6], self.board[7][6],
|
||||
self.board[0][5], self.board[5][1], self.board[5][2], self.board[5][3], self.board[5][4], self.board[5][5], self.board[5][6], self.board[7][5],
|
||||
self.board[4][0], self.board[4][1], self.board[4][2], self.board[4][3], self.board[4][4], self.board[4][5], self.board[4][6], self.board[7][4],
|
||||
self.board[3][0], self.board[3][1], self.board[3][2], self.board[3][3], self.board[3][4], self.board[3][5], self.board[3][6], self.board[3][7],
|
||||
self.board[2][0], self.board[2][1], self.board[2][2], self.board[2][3], self.board[2][4], self.board[2][5], self.board[2][6], self.board[2][7],
|
||||
self.board[1][0], self.board[1][1], self.board[1][2], self.board[1][3], self.board[1][4], self.board[1][5], self.board[1][6], self.board[1][7],
|
||||
self.board[0][0], self.board[0][1], self.board[0][2], self.board[0][3], self.board[0][4], self.board[0][5], self.board[0][6], self.board[0][7],
|
||||
)
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone)]
|
||||
enum Status {
|
||||
Hidden(u8),
|
||||
Revealed(u8),
|
||||
/// bombs are always hidden
|
||||
Bomb,
|
||||
}
|
||||
impl Default for Status {
|
||||
fn default() -> Self {
|
||||
Self::Hidden(0)
|
||||
}
|
||||
}
|
||||
impl Display for Status {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let val = match self {
|
||||
Self::Hidden(_) => '*',
|
||||
Self::Revealed(n) => num_to_char(*n),
|
||||
Self::Bomb => '*'
|
||||
};
|
||||
write!(f, "{}", val)
|
||||
}
|
||||
}
|
||||
impl Status {
|
||||
fn val(&mut self) -> Option<&mut u8> {
|
||||
match self {
|
||||
Self::Hidden(ref mut val) => Some(val),
|
||||
Self::Revealed(_) => None,
|
||||
Self::Bomb => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
/// (0, 0) is bottom left
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Point(usize, usize);
|
||||
impl Point {
|
||||
fn is_adjacent(&self, rhs: &Self) -> bool {
|
||||
(-1..=1).contains(&(self.0 as isize-rhs.0 as isize))
|
||||
&& (-1..=1).contains(&(self.1 as isize-rhs.1 as isize))
|
||||
}
|
||||
}
|
||||
fn main() {
|
||||
let mut board = Board::default();
|
||||
crossterm::terminal::enable_raw_mode();
|
||||
print!("\n");
|
||||
print!("{}", board);
|
||||
board.insert_bomb(Point(5, 5));
|
||||
let test = board.get_mut(Point(0, 0)).unwrap();
|
||||
*test = Status::Revealed(0);
|
||||
loop {
|
||||
if let Ok(Event::Key(KeyEvent { code, modifiers, kind:_, state: _ })) = event::read() {
|
||||
let cursor = cursor();
|
||||
match (code, modifiers == KeyModifiers::CONTROL) {
|
||||
(KeyCode::Enter, false) => {
|
||||
let selected = board.get_mut(cursor.clone());
|
||||
match selected.as_deref().cloned() {
|
||||
Some(Status::Hidden(a)) => {
|
||||
let selected = selected.unwrap();
|
||||
*selected = Status::Revealed(a);
|
||||
// print!("hidden");
|
||||
}
|
||||
Some(Status::Bomb) => {
|
||||
crossterm::execute!(stdout(), MoveDown(8));
|
||||
// print!("KABOOM");
|
||||
break
|
||||
}
|
||||
None | Some(Status::Revealed(_)) => {
|
||||
print!("do_nothing:{:?}\n\r", cursor);
|
||||
},
|
||||
}
|
||||
clear(10, &board);
|
||||
}
|
||||
(KeyCode::Enter, true) => {}
|
||||
(KeyCode::Left, _) => {
|
||||
crossterm::execute!(stdout(), MoveLeft(1));
|
||||
}
|
||||
(KeyCode::Down, _) => {
|
||||
crossterm::execute!(stdout(), MoveDown(1));
|
||||
}
|
||||
(KeyCode::Right, _) => {
|
||||
crossterm::execute!(stdout(), MoveRight(1));
|
||||
}
|
||||
(KeyCode::Up, _) => {
|
||||
crossterm::execute!(stdout(), MoveUp(1));
|
||||
}
|
||||
(KeyCode::Char('c'), _) => {
|
||||
crossterm::execute!(stdout(), MoveDown(8));
|
||||
break
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fn num_to_char(num:u8) ->char {
|
||||
match num {
|
||||
0 => '0',
|
||||
1 => '1',
|
||||
2 => '2',
|
||||
3 => '3',
|
||||
4 => '4',
|
||||
5 => '5',
|
||||
6 => '6',
|
||||
7 => '7',
|
||||
8 => '8',
|
||||
9 => '9',
|
||||
_ => ' ',
|
||||
}
|
||||
}
|
||||
fn cursor() -> Point {
|
||||
let (_, row) = crossterm::terminal::size().unwrap();
|
||||
let (col, crow) = crossterm::cursor::position().unwrap();
|
||||
let out = Point(( col ) as usize / 2, ( row-crow ) as usize);
|
||||
out
|
||||
}
|
||||
/// row is rows from bottom
|
||||
fn clear(row: u16, board: &Board) {
|
||||
let (_, total) = crossterm::terminal::size().unwrap();
|
||||
let row = total-row;
|
||||
crossterm::execute!(stdout(), SavePosition, MoveToRow(row));
|
||||
print!("\u{1b}[J"); // clear from cursor to end of screen
|
||||
crossterm::execute!(stdout(), MoveDown(1));
|
||||
print!("{}", board); // clear from cursor to end of screen
|
||||
crossterm::execute!(stdout(), RestorePosition);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue