From 553d3f8496ea5476b689a4b1016958eb2f5d349b Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Wed, 5 Apr 2023 09:13:50 -0400 Subject: [PATCH] Rename Goban to Board and create the IntersectionElement --- kifu/kifu-core/src/ui/mod.rs | 5 +- kifu/kifu-core/src/ui/playing_field.rs | 4 +- kifu/kifu-core/src/ui/types.rs | 48 ++++++++++------ kifu/kifu-gtk/src/ui/{goban.rs => board.rs} | 64 +++++++++++---------- kifu/kifu-gtk/src/ui/mod.rs | 4 +- kifu/kifu-gtk/src/ui/playing_field.rs | 14 ++--- 6 files changed, 81 insertions(+), 58 deletions(-) rename kifu/kifu-gtk/src/ui/{goban.rs => board.rs} (81%) diff --git a/kifu/kifu-core/src/ui/mod.rs b/kifu/kifu-core/src/ui/mod.rs index e7b40c0..abe5612 100644 --- a/kifu/kifu-core/src/ui/mod.rs +++ b/kifu/kifu-core/src/ui/mod.rs @@ -2,4 +2,7 @@ mod playing_field; pub use playing_field::{playing_field, PlayingFieldView}; mod types; -pub use types::{ChatElement, GobanElement, PlayerCardElement, StoneElement, TextFieldElement}; +pub use types::{ + BoardElement, ChatElement, IntersectionElement, PlayerCardElement, StoneElement, + TextFieldElement, +}; diff --git a/kifu/kifu-core/src/ui/playing_field.rs b/kifu/kifu-core/src/ui/playing_field.rs index 8787338..70cc951 100644 --- a/kifu/kifu-core/src/ui/playing_field.rs +++ b/kifu/kifu-core/src/ui/playing_field.rs @@ -3,7 +3,7 @@ use crate::ui::types; #[derive(Clone, Debug)] pub struct PlayingFieldView { - pub board: types::GobanElement, + pub board: types::BoardElement, pub player_card_black: types::PlayerCardElement, pub player_card_white: types::PlayerCardElement, pub chat: types::ChatElement, @@ -12,7 +12,7 @@ pub struct PlayingFieldView { } pub fn playing_field() -> PlayingFieldView { - let board = types::GobanElement::default(); + let board = types::BoardElement::default(); let player_card_black = types::PlayerCardElement { color: Color::Black, diff --git a/kifu/kifu-core/src/ui/types.rs b/kifu/kifu-core/src/ui/types.rs index 05092f3..98bbaf1 100644 --- a/kifu/kifu-core/src/ui/types.rs +++ b/kifu/kifu-core/src/ui/types.rs @@ -1,12 +1,12 @@ use crate::types::{Color, Size}; -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub struct Jitter { pub x: i8, pub y: i8, } -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub struct StoneElement { pub color: Color, pub jitter: Jitter, @@ -21,28 +21,44 @@ impl StoneElement { } } -#[derive(Clone, Debug)] -pub struct GobanElement { - pub size: Size, - pub spaces: Vec>, +#[derive(Clone, Copy, Debug)] +pub struct PlayStoneRequest { + col: u8, + row: u8, } -impl GobanElement { +#[derive(Clone, Copy, Debug)] +pub enum IntersectionElement { + Unplayable, + Empty(PlayStoneRequest), + Filled(StoneElement), +} + +#[derive(Clone, Debug)] +pub struct BoardElement { + pub size: Size, + pub spaces: Vec, +} + +impl BoardElement { pub fn new(size: Size) -> Self { - Self { - size: size.clone(), - spaces: (0..((size.width as usize) * (size.height as usize))) - .map(|_| None) - .collect::>>(), - } + let spaces: Vec = (0..size.height) + .map(|row| { + (0..size.width) + .map(|col| IntersectionElement::Empty(PlayStoneRequest { col, row })) + .collect::>() + }) + .collect::>>() + .concat(); + Self { size, spaces } } - pub fn stone_mut<'a>(&'a mut self, row: u8, col: u8) -> &'a mut Option { + pub fn stone_mut<'a>(&'a mut self, row: u8, col: u8) -> &'a mut IntersectionElement { let addr = self.addr(row, col); &mut self.spaces[addr] } - pub fn stone(&self, row: u8, col: u8) -> Option { + pub fn stone(&self, row: u8, col: u8) -> IntersectionElement { self.spaces[self.addr(row, col)].clone() } @@ -51,7 +67,7 @@ impl GobanElement { } } -impl Default for GobanElement { +impl Default for BoardElement { fn default() -> Self { Self::new(Size::default()) } diff --git a/kifu/kifu-gtk/src/ui/goban.rs b/kifu/kifu-gtk/src/ui/board.rs similarity index 81% rename from kifu/kifu-gtk/src/ui/goban.rs rename to kifu/kifu-gtk/src/ui/board.rs index 2580500..20ae649 100644 --- a/kifu/kifu-gtk/src/ui/goban.rs +++ b/kifu/kifu-gtk/src/ui/board.rs @@ -6,7 +6,10 @@ use gtk::{ subclass::prelude::*, }; use image::io::Reader as ImageReader; -use kifu_core::{ui::GobanElement, Color}; +use kifu_core::{ + ui::{BoardElement, IntersectionElement}, + Color, +}; use std::{cell::RefCell, io::Cursor, rc::Rc}; const WIDTH: i32 = 800; @@ -18,36 +21,36 @@ struct Addr { column: u8, } -pub struct GobanPrivate { +pub struct BoardPrivate { drawing_area: gtk::DrawingArea, current_player: Rc>, - goban: Rc>, + board: Rc>, cursor_location: Rc>, } #[glib::object_subclass] -impl ObjectSubclass for GobanPrivate { - const NAME: &'static str = "Goban"; - type Type = Goban; +impl ObjectSubclass for BoardPrivate { + const NAME: &'static str = "Board"; + type Type = Board; type ParentType = gtk::Grid; - fn new() -> GobanPrivate { - GobanPrivate { + fn new() -> BoardPrivate { + BoardPrivate { drawing_area: Default::default(), current_player: Rc::new(RefCell::new(Color::Black)), - goban: Default::default(), + board: Default::default(), cursor_location: Default::default(), } } } -impl ObjectImpl for GobanPrivate { +impl ObjectImpl for BoardPrivate { fn constructed(&self) { self.drawing_area.set_width_request(WIDTH); self.drawing_area.set_height_request(HEIGHT); - let goban = self.goban.clone(); + let board = self.board.clone(); let cursor_location = self.cursor_location.clone(); let current_player = self.current_player.clone(); @@ -75,7 +78,7 @@ impl ObjectImpl for GobanPrivate { self.drawing_area .set_draw_func(move |_, context, width, height| { - let goban = goban.borrow(); + let board = board.borrow(); match background { Ok(Some(ref background)) => { context.set_source_pixbuf(&background, 0., 0.); @@ -87,8 +90,8 @@ impl ObjectImpl for GobanPrivate { context.set_source_rgb(0.1, 0.1, 0.1); context.set_line_width(2.); - let hspace_between = ((width - 40) as f64) / ((goban.size.width - 1) as f64); - let vspace_between = ((height - 40) as f64) / ((goban.size.height - 1) as f64); + let hspace_between = ((width - 40) as f64) / ((board.size.width - 1) as f64); + let vspace_between = ((height - 40) as f64) / ((board.size.height - 1) as f64); let pen = Pen { x_offset: 20., @@ -97,12 +100,12 @@ impl ObjectImpl for GobanPrivate { vspace_between, }; - (0..goban.size.width).for_each(|col| { + (0..board.size.width).for_each(|col| { context.move_to(20.0 + (col as f64) * hspace_between, 20.0); context.line_to(20.0 + (col as f64) * hspace_between, (height as f64) - 20.0); let _ = context.stroke(); }); - (0..goban.size.height).for_each(|row| { + (0..board.size.height).for_each(|row| { context.move_to(20.0, 20.0 + (row as f64) * vspace_between); context.line_to((width - 20) as f64, 20.0 + (row as f64) * vspace_between); let _ = context.stroke(); @@ -117,10 +120,11 @@ impl ObjectImpl for GobanPrivate { (0..19).for_each(|col| { (0..19).for_each(|row| { - match goban.stone(row, col) { - None => {} - Some(element) => { - pen.stone(&context, row, col, element.color); + match board.stone(row, col) { + IntersectionElement::Unplayable => {} + IntersectionElement::Empty(request) => {} + IntersectionElement::Filled(stone) => { + pen.stone(&context, row, col, stone.color); } }; }) @@ -132,14 +136,14 @@ impl ObjectImpl for GobanPrivate { let motion_controller = gtk::EventControllerMotion::new(); { - let goban = self.goban.clone(); + let board = self.board.clone(); let cursor = self.cursor_location.clone(); let drawing_area = self.drawing_area.clone(); motion_controller.connect_motion(move |_, x, y| { - let goban = goban.borrow(); + let board = board.borrow(); let mut cursor = cursor.borrow_mut(); - let hspace_between = ((WIDTH - 40) as f64) / ((goban.size.width - 1) as f64); - let vspace_between = ((HEIGHT - 40) as f64) / ((goban.size.height - 1) as f64); + let hspace_between = ((WIDTH - 40) as f64) / ((board.size.width - 1) as f64); + let vspace_between = ((HEIGHT - 40) as f64) / ((board.size.height - 1) as f64); let addr = Addr { column: ((x.round() - 20.) / hspace_between).round() as u8, @@ -156,22 +160,22 @@ impl ObjectImpl for GobanPrivate { self.drawing_area.add_controller(motion_controller); } } -impl WidgetImpl for GobanPrivate {} -impl GridImpl for GobanPrivate {} +impl WidgetImpl for BoardPrivate {} +impl GridImpl for BoardPrivate {} glib::wrapper! { - pub struct Goban(ObjectSubclass) @extends gtk::Grid, gtk::Widget; + pub struct Board(ObjectSubclass) @extends gtk::Grid, gtk::Widget; } -impl Goban { +impl Board { pub fn new() -> Self { let s: Self = Object::builder().build(); s.attach(&s.imp().drawing_area, 1, 1, 1, 1); s } - pub fn set_board(&self, goban: GobanElement) { - *self.imp().goban.borrow_mut() = goban; + pub fn set_board(&self, board: BoardElement) { + *self.imp().board.borrow_mut() = board; self.imp().drawing_area.queue_draw(); } diff --git a/kifu/kifu-gtk/src/ui/mod.rs b/kifu/kifu-gtk/src/ui/mod.rs index 49630c7..6a469b3 100644 --- a/kifu/kifu-gtk/src/ui/mod.rs +++ b/kifu/kifu-gtk/src/ui/mod.rs @@ -7,8 +7,8 @@ pub use chat::Chat; mod playing_field; pub use playing_field::PlayingField; -mod goban; -pub use goban::Goban; +mod board; +pub use board::Board; #[cfg(feature = "screenplay")] pub use playing_field::playing_field_view; diff --git a/kifu/kifu-gtk/src/ui/playing_field.rs b/kifu/kifu-gtk/src/ui/playing_field.rs index 7ca1589..742754c 100644 --- a/kifu/kifu-gtk/src/ui/playing_field.rs +++ b/kifu/kifu-gtk/src/ui/playing_field.rs @@ -1,10 +1,10 @@ -use crate::ui::{Chat, Goban, PlayerCard}; +use crate::ui::{Board, Chat, PlayerCard}; use glib::Object; use gtk::{prelude::*, subclass::prelude::*}; use kifu_core::{ ui::{ - ChatElement, GobanElement, PlayerCardElement, PlayingFieldView, StoneElement, - TextFieldElement, + BoardElement, ChatElement, IntersectionElement, PlayerCardElement, PlayingFieldView, + StoneElement, TextFieldElement, }, Color, Size, }; @@ -23,7 +23,7 @@ pub struct PlayingFieldView { */ pub struct PlayingFieldPrivate { - goban: Goban, + goban: Board, player_card_white: Rc>>, player_card_black: Rc>>, chat: Rc>>, @@ -32,7 +32,7 @@ pub struct PlayingFieldPrivate { impl Default for PlayingFieldPrivate { fn default() -> Self { Self { - goban: Goban::new(), + goban: Board::new(), player_card_white: Rc::new(RefCell::new(None)), player_card_black: Rc::new(RefCell::new(None)), chat: Rc::new(RefCell::new(None)), @@ -48,7 +48,7 @@ impl ObjectSubclass for PlayingFieldPrivate { fn new() -> Self { Self { - goban: Goban::new(), + goban: Board::new(), player_card_white: Rc::new(RefCell::new(None)), player_card_black: Rc::new(RefCell::new(None)), chat: Rc::new(RefCell::new(None)), @@ -90,7 +90,7 @@ impl PlayingField { #[cfg(feature = "screenplay")] pub fn playing_field_view() -> PlayingFieldView { - let mut board = GobanElement::default(); + let mut board = Board::default(); *board.stone_mut(4, 4) = Some(StoneElement::new(Color::White)); *board.stone_mut(15, 15) = Some(StoneElement::new(Color::Black)); let player_card_black = PlayerCardElement {