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() {
|
use std::fmt::Display;
|
||||||
println!("Hello, world!");
|
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