reversi working, fixes
This commit is contained in:
@@ -63,15 +63,17 @@ impl WindowLike for AudioPlayer {
|
||||
fn draw(&self, theme_info: &ThemeInfo) -> Vec<DrawInstructions> {
|
||||
let mut instructions = vec![DrawInstructions::Text([2, self.dimensions[1] - LINE_HEIGHT], vec!["times-new-roman".to_string()], if self.command.len() > 0 { self.command.clone() } else { self.response.clone() }, theme_info.text, theme_info.background, None, None)];
|
||||
if let Some(sink) = &self.sink {
|
||||
let current = &self.queue[self.queue.len() - sink.len()];
|
||||
let current_name = current.0.file_name().unwrap().to_string_lossy().into_owned();
|
||||
instructions.push(DrawInstructions::Text([self.dimensions[0] / 2 - current_name.len() * MONO_WIDTH as usize / 2, 2], vec!["times-new-romono".to_string(), "shippori-mincho".to_string()], current_name.clone(), theme_info.text, theme_info.background, Some(0), Some(MONO_WIDTH)));
|
||||
if let Some(artist) = ¤t.2 {
|
||||
let artist_string = "by ".to_string() + &artist;
|
||||
instructions.push(DrawInstructions::Text([self.dimensions[0] / 2 - artist_string.len() * MONO_WIDTH as usize / 2, LINE_HEIGHT + 2], vec!["times-new-romono".to_string()], artist_string, theme_info.text, theme_info.background, Some(0), Some(MONO_WIDTH)));
|
||||
if sink.len() > 0 {
|
||||
let current = &self.queue[self.queue.len() - sink.len()];
|
||||
let current_name = current.0.file_name().unwrap().to_string_lossy().into_owned();
|
||||
instructions.push(DrawInstructions::Text([self.dimensions[0] / 2 - current_name.len() * MONO_WIDTH as usize / 2, 2], vec!["times-new-romono".to_string(), "shippori-mincho".to_string()], current_name.clone(), theme_info.text, theme_info.background, Some(0), Some(MONO_WIDTH)));
|
||||
if let Some(artist) = ¤t.2 {
|
||||
let artist_string = "by ".to_string() + &artist;
|
||||
instructions.push(DrawInstructions::Text([self.dimensions[0] / 2 - artist_string.len() * MONO_WIDTH as usize / 2, LINE_HEIGHT + 2], vec!["times-new-romono".to_string()], artist_string, theme_info.text, theme_info.background, Some(0), Some(MONO_WIDTH)));
|
||||
}
|
||||
let time_string = format!("{}/{}", format_seconds(sink.get_pos().as_secs()), format_seconds(current.1));
|
||||
instructions.push(DrawInstructions::Text([self.dimensions[0] / 2 - time_string.len() * MONO_WIDTH as usize / 2, LINE_HEIGHT * 2 + 2], vec!["times-new-romono".to_string()], time_string, theme_info.text, theme_info.background, Some(0), Some(MONO_WIDTH)));
|
||||
}
|
||||
let time_string = format!("{}/{}", format_seconds(sink.get_pos().as_secs()), format_seconds(current.1));
|
||||
instructions.push(DrawInstructions::Text([self.dimensions[0] / 2 - time_string.len() * MONO_WIDTH as usize / 2, LINE_HEIGHT * 2 + 2], vec!["times-new-romono".to_string()], time_string, theme_info.text, theme_info.background, Some(0), Some(MONO_WIDTH)));
|
||||
}
|
||||
//
|
||||
instructions
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::vec::Vec;
|
||||
use std::vec;
|
||||
use std::fmt;
|
||||
|
||||
use ming_wm::window_manager::{ DrawInstructions, WindowLike, WindowLikeType };
|
||||
use ming_wm::messages::{ WindowMessage, WindowMessageResponse };
|
||||
@@ -8,6 +7,24 @@ use ming_wm::framebuffer::{ Dimensions, RGBColor };
|
||||
use ming_wm::themes::ThemeInfo;
|
||||
use ming_wm::ipc::listen;
|
||||
|
||||
const REVERSI_GREEN: RGBColor = [72, 93, 63];
|
||||
|
||||
struct ValidMove {
|
||||
pub point: [usize; 2],
|
||||
pub will_flip: Vec<[usize; 2]>,
|
||||
}
|
||||
|
||||
//tried to do some PartialEq implementation but didn't play nice with .contains
|
||||
//so just do this instead
|
||||
fn valid_moves_contains(valid_moves: &Vec<ValidMove>, point: &[usize; 2]) -> Option<Vec<[usize; 2]>> {
|
||||
for valid_move in valid_moves {
|
||||
if &valid_move.point == point {
|
||||
return Some(valid_move.will_flip.clone());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq)]
|
||||
enum Tile {
|
||||
#[default]
|
||||
@@ -30,7 +47,9 @@ impl Tile {
|
||||
struct Reversi {
|
||||
dimensions: Dimensions,
|
||||
tiles: [[Tile; 8]; 8],
|
||||
//
|
||||
current_number: Option<u8>, //the first number of the tile that user wants to place piece on
|
||||
valid_moves: Vec<ValidMove>,
|
||||
white_turn: bool, //if false, black turn
|
||||
}
|
||||
|
||||
impl WindowLike for Reversi {
|
||||
@@ -39,16 +58,39 @@ impl WindowLike for Reversi {
|
||||
WindowMessage::Init(dimensions) => {
|
||||
self.dimensions = dimensions;
|
||||
self.new_tiles();
|
||||
self.valid_moves = self.get_valid_moves();
|
||||
WindowMessageResponse::JustRerender
|
||||
},
|
||||
WindowMessage::KeyPress(key_press) => {
|
||||
if let Ok(n) = key_press.key.to_string().parse::<u8>() {
|
||||
if let Some(current_number) = self.current_number {
|
||||
let y = current_number as usize;
|
||||
let x = n as usize;
|
||||
if let Some(mut will_flip) = valid_moves_contains(&self.valid_moves, &[x, y]) {
|
||||
self.tiles[y][x] = if self.white_turn { Tile::White } else { Tile::Black };
|
||||
will_flip.push([x, y]);
|
||||
for point in will_flip {
|
||||
self.tiles[point[1]][point[0]] = if self.white_turn { Tile::White } else { Tile::Black };
|
||||
}
|
||||
self.white_turn = !self.white_turn;
|
||||
self.valid_moves = self.get_valid_moves();
|
||||
}
|
||||
self.current_number = None;
|
||||
} else {
|
||||
self.current_number = Some(n);
|
||||
}
|
||||
} else if key_press.key == '𐘁' { //backspace
|
||||
self.current_number = None;
|
||||
}
|
||||
WindowMessageResponse::JustRerender
|
||||
},
|
||||
//
|
||||
_ => WindowMessageResponse::DoNothing,
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(&self, theme_info: &ThemeInfo) -> Vec<DrawInstructions> {
|
||||
let mut instructions = vec![
|
||||
DrawInstructions::Rect([0, 0], self.dimensions, [72, 93, 63]),
|
||||
DrawInstructions::Rect([0, 0], self.dimensions, REVERSI_GREEN),
|
||||
];
|
||||
let square_width = (self.dimensions[0] - 10) / 8;
|
||||
for l in 0..9 {
|
||||
@@ -67,7 +109,16 @@ impl WindowLike for Reversi {
|
||||
for x in 0..8 {
|
||||
let tile = &self.tiles[y][x];
|
||||
if tile == &Tile::Empty {
|
||||
//
|
||||
instructions.push(DrawInstructions::Text([x * square_width + square_width / 2, y * square_width + square_width / 2], vec!["times-new-roman".to_string()], format!("{}{}", y, x), theme_info.text, REVERSI_GREEN, None, None));
|
||||
if valid_moves_contains(&self.valid_moves, &[x, y]).is_some() {
|
||||
//yellow border
|
||||
instructions.extend([
|
||||
DrawInstructions::Rect([5 + x * square_width, 5 + y * square_width], [square_width + 2, 2], [255, 255, 0]),
|
||||
DrawInstructions::Rect([5 + x * square_width, 5 + y * square_width], [2, square_width], [255, 255, 0]),
|
||||
DrawInstructions::Rect([5 + (x + 1) * square_width, 5 + y * square_width], [2, square_width], [255, 255, 0]),
|
||||
DrawInstructions::Rect([5 + x * square_width + 2, 5 + (y + 1) * square_width], [square_width + 2, 2], [255, 255, 0]),
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
instructions.push(DrawInstructions::Circle([x * square_width + square_width / 2 + 5, y * square_width + square_width / 2 + 5], square_width / 2 - 3, tile.to_color().unwrap()));
|
||||
}
|
||||
@@ -103,6 +154,97 @@ impl Reversi {
|
||||
self.tiles[3][4] = Tile::Black;
|
||||
self.tiles[4][4] = Tile::White;
|
||||
}
|
||||
|
||||
pub fn get_valid_moves(&self) -> Vec<ValidMove> {
|
||||
let mut valid_moves = Vec::new();
|
||||
for y0 in 0..8 {
|
||||
for x0 in 0..8 {
|
||||
let current_tile = &self.tiles[y0][x0];
|
||||
if (current_tile == &Tile::White && self.white_turn) || (current_tile == &Tile::Black && !self.white_turn) {
|
||||
for t in 0..8 {
|
||||
let mut potential_move = false; //true once opposite colour tile found
|
||||
let mut point = [x0, y0];
|
||||
let mut will_flip = Vec::new();
|
||||
loop {
|
||||
let x = point[0];
|
||||
let y = point[1];
|
||||
if t == 0 {
|
||||
//up left
|
||||
if y > 0 && x > 0 {
|
||||
point = [x - 1, y - 1];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if t == 1 {
|
||||
//up
|
||||
if y > 0 {
|
||||
point = [x, y - 1];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if t == 2 {
|
||||
//up right
|
||||
if y > 0 && x < 7 {
|
||||
point = [x, y - 1];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if t == 3 {
|
||||
//left
|
||||
if x > 0 {
|
||||
point = [x - 1, y];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if t == 4 {
|
||||
//right
|
||||
if x < 7 {
|
||||
point = [x + 1, y];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if t == 5 {
|
||||
//down left
|
||||
if y < 7 && x > 0 {
|
||||
point = [x - 1, y + 1];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if t == 6 {
|
||||
//down
|
||||
if y < 7 {
|
||||
point = [x, y + 1];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if t == 7 {
|
||||
//down right
|
||||
if y < 7 && x < 7 {
|
||||
point = [x + 1, y + 1];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let tile = &self.tiles[point[1]][point[0]];
|
||||
if tile == &Tile::Empty && potential_move {
|
||||
valid_moves.push(ValidMove {
|
||||
point,
|
||||
will_flip,
|
||||
});
|
||||
break;
|
||||
} else if (tile == &Tile::Black && self.white_turn) || (tile == &Tile::White && !self.white_turn) {
|
||||
will_flip.push(point);
|
||||
potential_move = true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
valid_moves
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
|
||||
@@ -9,7 +9,7 @@ fn main() {
|
||||
let mut a = Command::new("cargo").arg("run").arg("-q").arg("--bin").arg("start_menu").stdout(Stdio::piped()).stdin(Stdio::piped()).stderr(Stdio::null()).spawn().unwrap();
|
||||
a.stdin.unwrap().write_all("subtype\n".to_string().as_bytes());
|
||||
let mut output = String::new();
|
||||
a.stdout.as_mut().unwrap().read_to_string(&mut output);
|
||||
let _ = a.stdout.as_mut().unwrap().read_to_string(&mut output);
|
||||
println!("{}", output);
|
||||
//println!("{}", &ron::to_string(&[122, 400]).unwrap());
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ impl WindowLike for DesktopBackground {
|
||||
let color = [hex_to_u8(chars.next().unwrap(), chars.next().unwrap()), hex_to_u8(chars.next().unwrap(), chars.next().unwrap()), hex_to_u8(chars.next().unwrap(), chars.next().unwrap())];
|
||||
return vec![DrawInstructions::Rect([0, 0], self.dimensions, color)];
|
||||
}
|
||||
} else {
|
||||
} else if line.len() > 1 {
|
||||
//first character of line is either r or any other character, but is not part of the path
|
||||
return vec![DrawInstructions::Bmp([0, 0], line[1..].to_string(), line.chars().next().unwrap() == 'r')];
|
||||
}
|
||||
|
||||
44
src/ipc.rs
44
src/ipc.rs
@@ -4,6 +4,7 @@ use std::io::{ stdin, BufRead };
|
||||
use ron;
|
||||
|
||||
use crate::window_manager::WindowLike;
|
||||
use crate::logging::log;
|
||||
|
||||
/*
|
||||
pub trait WindowLike {
|
||||
@@ -26,25 +27,44 @@ pub trait WindowLike {
|
||||
}
|
||||
*/
|
||||
|
||||
const LOG: bool = false;
|
||||
|
||||
pub fn listen(mut window_like: impl WindowLike) {
|
||||
let stdin = stdin();
|
||||
for line in stdin.lock().lines() {
|
||||
let line = line.unwrap().clone();
|
||||
if LOG {
|
||||
log(&line);
|
||||
}
|
||||
let mut parts = line.split(" ");
|
||||
let method = parts.next().unwrap();
|
||||
let arg = &parts.collect::<Vec<&str>>().join(" ");
|
||||
if method == "handle_message" {
|
||||
println!("{}", ron::to_string(&window_like.handle_message(ron::from_str(arg).unwrap())).unwrap());
|
||||
} else if method == "draw" {
|
||||
println!("{}", ron::to_string(&window_like.draw(&ron::from_str(arg).unwrap())).unwrap());
|
||||
} else if method == "title" {
|
||||
println!("{}", window_like.title());
|
||||
} else if method == "resizable" {
|
||||
println!("{}", window_like.resizable());
|
||||
} else if method == "subtype" {
|
||||
println!("{}", ron::to_string(&window_like.subtype()).unwrap());
|
||||
} else if method == "ideal_dimensions" {
|
||||
println!("{}", ron::to_string(&window_like.ideal_dimensions(ron::from_str(arg).unwrap())).unwrap());
|
||||
let output = match method {
|
||||
"handle_message" => {
|
||||
format!("{}", ron::to_string(&window_like.handle_message(ron::from_str(arg).unwrap())).unwrap())
|
||||
},
|
||||
"draw" => {
|
||||
format!("{}", ron::to_string(&window_like.draw(&ron::from_str(arg).unwrap())).unwrap())
|
||||
},
|
||||
"title" => {
|
||||
format!("{}", window_like.title())
|
||||
},
|
||||
"resizable" => {
|
||||
format!("{}", window_like.resizable())
|
||||
},
|
||||
"subtype" => {
|
||||
format!("{}", ron::to_string(&window_like.subtype()).unwrap())
|
||||
},
|
||||
"ideal_dimensions" => {
|
||||
format!("{}", ron::to_string(&window_like.ideal_dimensions(ron::from_str(arg).unwrap())).unwrap())
|
||||
},
|
||||
_ => String::new(),
|
||||
};
|
||||
if output != String::new() {
|
||||
if LOG {
|
||||
log(&output);
|
||||
}
|
||||
println!("{}", output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ pub mod themes;
|
||||
pub mod messages;
|
||||
pub mod fs;
|
||||
pub mod utils;
|
||||
pub mod logging;
|
||||
pub mod ipc;
|
||||
mod proxy_window_like;
|
||||
mod keyboard;
|
||||
|
||||
11
src/logging.rs
Normal file
11
src/logging.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
use std::fs::{ OpenOptions, create_dir };
|
||||
use std::io::Write;
|
||||
|
||||
use dirs::data_dir;
|
||||
|
||||
pub fn log(message: &str) {
|
||||
let data = data_dir().unwrap().into_os_string().into_string().unwrap();
|
||||
let _ = create_dir(format!("{}/ming-wm", data));
|
||||
let _ = writeln!(OpenOptions::new().append(true).create(true).open(format!("{}/ming-wm/logs.txt", data)).unwrap(), "{}", message);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ use std::vec::Vec;
|
||||
use std::process::{ Command, Child, Stdio };
|
||||
use std::io::{ BufReader, BufRead, Write };
|
||||
use std::cell::RefCell;
|
||||
use std::path::Path;
|
||||
use std::io::Read;
|
||||
|
||||
use ron;
|
||||
|
||||
@@ -81,7 +83,12 @@ impl ProxyWindowLike {
|
||||
}
|
||||
|
||||
pub fn new_rust(file: &str) -> Self {
|
||||
ProxyWindowLike::new(Command::new("cargo").arg("run").arg("--quiet").arg("--release").arg("--bin").arg(file).stdout(Stdio::piped()).stdin(Stdio::piped()).stderr(Stdio::null()))
|
||||
let loc = format!("./target/release/{}", file);
|
||||
if Path::new(&loc).exists() {
|
||||
ProxyWindowLike::new(Command::new(loc).stdout(Stdio::piped()).stdin(Stdio::piped()).stderr(Stdio::null()))
|
||||
} else {
|
||||
ProxyWindowLike::new(Command::new("cargo").arg("run").arg("--quiet").arg("--release").arg("--bin").arg(file).stdout(Stdio::piped()).stdin(Stdio::piped()).stderr(Stdio::null()))
|
||||
}
|
||||
}
|
||||
|
||||
//return empty string if error, do not propogate Err becuase that's messy
|
||||
|
||||
Reference in New Issue
Block a user