Implement board display
This commit is contained in:
		
							parent
							
								
									7e397c3c56
								
							
						
					
					
						commit
						15f4124855
					
				
					 3 changed files with 270 additions and 3 deletions
				
			
		|  | @ -97,7 +97,7 @@ impl Board { | |||
|         for (i, p) in ps[0..18].iter().enumerate() { | ||||
|             if i % 2 == 0 { | ||||
|                 //is a port
 | ||||
|                 if i % 3 != 2 { | ||||
|                 if i % 3 != 1 { | ||||
|                     orientation.rotate(); | ||||
|                 } | ||||
|                 hexes.push(Hex { | ||||
|  |  | |||
							
								
								
									
										234
									
								
								src/display.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								src/display.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,234 @@ | |||
| use crate::logic::{Board, Position}; | ||||
| use ratatui::buffer::Buffer; | ||||
| use ratatui::prelude::*; | ||||
| 
 | ||||
| pub struct BoardView { | ||||
|     buffer: Box<Buffer>, | ||||
| } | ||||
| 
 | ||||
| impl BoardView { | ||||
|     pub fn new(board: Box<Board>) -> BoardView { | ||||
|         let buffer = Box::new(board.draw()); | ||||
|         BoardView { buffer } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ratatui::widgets::Widget for BoardView { | ||||
|     fn render(self, area: ratatui::layout::Rect, buf: &mut Buffer) { | ||||
|         buf.merge(&self.buffer); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Board { | ||||
|     fn draw(&self) -> Buffer { | ||||
|         let mut b = Buffer::empty(Rect { | ||||
|             x: 0, | ||||
|             y: 0, | ||||
|             width: 49, | ||||
|             height: 28, | ||||
|         }); | ||||
|         for i in 0..self.hexes.len() { | ||||
|             for j in 0..self.hexes[i].len() { | ||||
|                 if i + j < 3 || i + j > 9 { | ||||
|                     continue; | ||||
|                 } | ||||
|                 b.merge(&self.draw_hex(&Position(i as i32, j as i32))); | ||||
|             } | ||||
|         } | ||||
|         b | ||||
|     } | ||||
| 
 | ||||
|     pub fn draw_hex(&self, p: &Position) -> Buffer { | ||||
|         let mut b = Buffer::empty(Rect { | ||||
|             x: 0, | ||||
|             y: 0, | ||||
|             width: 7, | ||||
|             height: 5, | ||||
|         }); | ||||
|         let get_edge = |x, y| { | ||||
|             let p = p.edge(&Position(x, y)); | ||||
|             self.edges[p.0 as usize][p.1 as usize] | ||||
|         }; | ||||
|         let get_vertex = |x, y| { | ||||
|             let p = p.vertex(&Position(x, y)); | ||||
|             self.vertices[p.0 as usize][p.1 as usize] | ||||
|         }; | ||||
|         let hex = self.hexes[p.0 as usize][p.1 as usize]; | ||||
|         let edge_NW = get_edge(0, -1); | ||||
|         let edge_SW = get_edge(1, -1); | ||||
|         let edge_S = get_edge(1, 0); | ||||
|         let vertex_SW = get_vertex(1, -1); | ||||
|         let vertex_SE = get_vertex(1, 0); | ||||
|         b.get_mut(0, 0).set_symbol(" "); | ||||
|         draw_edge(&mut b, edge_NW, "⧸", &[(1, 0), (0, 1)]); | ||||
|         draw_edge(&mut b, edge_SW, "⧹", &[(0, 2), (1, 3)]); | ||||
|         draw_edge( | ||||
|             &mut b, | ||||
|             edge_S, | ||||
|             "_", | ||||
|             &[(2, 3), (3, 3), (4, 3), (5, 3), (6, 3)], | ||||
|         ); | ||||
|         draw_vertex(&mut b, vertex_SW, (2, 3)); | ||||
|         draw_vertex(&mut b, vertex_SE, (6, 3)); | ||||
|         match hex { | ||||
|             None => (), | ||||
|             Some(h) => { | ||||
|                 if self.robber.0 == p.0 && self.robber.1 == p.1 { | ||||
|                     b.get_mut(4, 3).set_symbol(""); | ||||
|                 } | ||||
|                 match h.hextype { | ||||
|                     crate::logic::HexType::Desert => (), | ||||
|                     crate::logic::HexType::Port => { | ||||
|                         if h.resource.is_some() { | ||||
|                             draw_resource(&mut b, h.resource.unwrap(), (4, 1)); | ||||
|                         } else { | ||||
|                             b.get_mut(4, 1).set_symbol("?"); | ||||
|                         } | ||||
|                         draw_ports(&mut b, h.orientation.unwrap()); | ||||
|                     } | ||||
|                     crate::logic::HexType::Ocean => (), | ||||
|                     crate::logic::HexType::Resource => { | ||||
|                         draw_resource(&mut b, h.resource.unwrap(), (4, 0)); | ||||
|                         match h.number { | ||||
|                             None => (), | ||||
|                             Some(n) => { | ||||
|                                 draw_number(&mut b, n as u8); | ||||
|                             } | ||||
|                         }; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|         b.resize(Rect { | ||||
|             x: (p.1 * 7) as u16, | ||||
|             y: (p.0 * 4 + p.1 * 2) as u16, | ||||
|             width: 7, | ||||
|             height: 5, | ||||
|         }); | ||||
|         b | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn draw_edge(b: &mut Buffer, edge: Option<crate::logic::Edge>, symbol: &str, ps: &[(u16, u16)]) { | ||||
|     match edge { | ||||
|         None => (), | ||||
|         Some(edge) => { | ||||
|             for &(x, y) in ps { | ||||
|                 b.get_mut(x, y) | ||||
|                     .set_symbol(symbol) | ||||
|                     .set_style(Style::default().bold()); | ||||
|             } | ||||
|             match edge.road { | ||||
|                 None => (), | ||||
|                 Some(road) => { | ||||
|                     for &(x, y) in ps { | ||||
|                         b.get_mut(x, y).set_fg(color_convert(road.0)); | ||||
|                     } | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| fn draw_vertex(b: &mut Buffer, vertex: Option<crate::logic::Vertex>, p: (u16, u16)) { | ||||
|     match vertex { | ||||
|         None => (), | ||||
|         Some(vertex) => { | ||||
|             if vertex.settlement.is_some() { | ||||
|                 b.get_mut(p.0, p.1) | ||||
|                     .set_symbol("") | ||||
|                     .set_fg(color_convert(vertex.settlement.unwrap().0)); | ||||
|             } else if vertex.city.is_some() { | ||||
|                 b.get_mut(p.0, p.1) | ||||
|                     .set_symbol("") | ||||
|                     .set_fg(color_convert(vertex.city.unwrap().0)); | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| fn draw_resource(b: &mut Buffer, resource: crate::logic::Resource, p: (u16, u16)) { | ||||
|     let (bg, fg, symbol) = match resource { | ||||
|         crate::logic::Resource::Brick => (Color::Red, Color::Black, ""), | ||||
|         crate::logic::Resource::Ore => (Color::Blue, Color::Black, ""), | ||||
|         crate::logic::Resource::Sheep => (Color::Gray, Color::Black, ""), | ||||
|         crate::logic::Resource::Wheat => (Color::Yellow, Color::Black, ""), | ||||
|         crate::logic::Resource::Wood => (Color::Green, Color::Black, ""), | ||||
|     }; | ||||
|     b.get_mut(p.0, p.1).set_bg(bg).set_fg(fg).set_symbol(symbol); | ||||
|     // .set_style(Style::default().bold());
 | ||||
|     b.get_mut(p.0 - 1, p.1).set_bg(bg); | ||||
|     b.get_mut(p.0 + 1, p.1).set_bg(bg); | ||||
| } | ||||
| 
 | ||||
| fn draw_ports(b: &mut Buffer, orientation: Position) { | ||||
|     match orientation { | ||||
|         Position(1, 0) => { | ||||
|             b.get_mut(3, 2).set_symbol(""); | ||||
|             b.get_mut(5, 2).set_symbol(""); | ||||
|         } | ||||
|         Position(0, 1) => { | ||||
|             b.get_mut(5, 2).set_symbol(""); | ||||
|             b.get_mut(6, 1).set_symbol(""); | ||||
|         } | ||||
|         Position(-1, 1) => { | ||||
|             b.get_mut(6, 1).set_symbol(""); | ||||
|             b.get_mut(5, 0).set_symbol(""); | ||||
|         } | ||||
|         Position(-1, 0) => { | ||||
|             b.get_mut(5, 0).set_symbol(""); | ||||
|             b.get_mut(3, 0).set_symbol(""); | ||||
|         } | ||||
|         Position(0, -1) => { | ||||
|             b.get_mut(3, 0).set_symbol(""); | ||||
|             b.get_mut(2, 1).set_symbol(""); | ||||
|         } | ||||
|         Position(1, -1) => { | ||||
|             b.get_mut(2, 1).set_symbol(""); | ||||
|             b.get_mut(3, 2).set_symbol(""); | ||||
|         } | ||||
|         _ => (), | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| fn draw_number(b: &mut Buffer, number: u8) { | ||||
|     let style = if number == 6 || number == 8 { | ||||
|         Style::default().fg(Color::Red) | ||||
|     } else { | ||||
|         Style::default() | ||||
|     }; | ||||
|     b.set_string(3, 1, &format!("{number:>2}"), style); | ||||
| 
 | ||||
|     match number { | ||||
|         2 | 12 => { | ||||
|             b.get_mut(4, 2).set_symbol("⠈").set_style(style); | ||||
|         } | ||||
|         3 | 11 => { | ||||
|             b.get_mut(4, 2).set_symbol("⠉").set_style(style); | ||||
|         } | ||||
|         4 | 10 => { | ||||
|             b.get_mut(3, 2).set_symbol("⠈").set_style(style); | ||||
|             b.get_mut(4, 2).set_symbol("⠉").set_style(style); | ||||
|         } | ||||
|         5 | 9 => { | ||||
|             b.get_mut(3, 2).set_symbol("⠈").set_style(style); | ||||
|             b.get_mut(4, 2).set_symbol("⠉").set_style(style); | ||||
|             b.get_mut(5, 2).set_symbol("⠁").set_style(style); | ||||
|         } | ||||
|         6 | 8 => { | ||||
|             b.get_mut(3, 2).set_symbol("⠉").set_style(style); | ||||
|             b.get_mut(4, 2).set_symbol("⠉").set_style(style); | ||||
|             b.get_mut(5, 2).set_symbol("⠁").set_style(style); | ||||
|         } | ||||
|         _ => (), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn color_convert(c: crate::logic::Color) -> Color { | ||||
|     match c { | ||||
|         crate::logic::Color::Red => Color::LightRed, | ||||
|         crate::logic::Color::Green => Color::LightGreen, | ||||
|         crate::logic::Color::Yellow => Color::LightYellow, | ||||
|         crate::logic::Color::Blue => Color::LightBlue, | ||||
|     } | ||||
| } | ||||
							
								
								
									
										37
									
								
								src/main.rs
									
										
									
									
									
								
							
							
						
						
									
										37
									
								
								src/main.rs
									
										
									
									
									
								
							|  | @ -1,10 +1,43 @@ | |||
| mod board; | ||||
| mod display; | ||||
| mod logic; | ||||
| use crossterm::{ | ||||
|     event::{self, KeyCode, KeyEventKind}, | ||||
|     terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, | ||||
|     ExecutableCommand, | ||||
| }; | ||||
| use logic::Board; | ||||
| use ratatui::prelude::{CrosstermBackend, Terminal}; | ||||
| use std::io::{stdout, Result}; | ||||
| 
 | ||||
| /**
 | ||||
| * Three Ore Two Wheat | ||||
| */ | ||||
| 
 | ||||
| fn main() { | ||||
|     println!("Hello, world!"); | ||||
| fn main() -> Result<()> { | ||||
|     stdout().execute(EnterAlternateScreen)?; | ||||
|     enable_raw_mode()?; | ||||
|     let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; | ||||
|     terminal.clear()?; | ||||
| 
 | ||||
|     let board = Box::new(Board::new("example_seed")); | ||||
|     let hex = display::BoardView::new(board); | ||||
| 
 | ||||
|     terminal.draw(|frame| { | ||||
|         frame.render_widget(hex, frame.size()); | ||||
|     })?; | ||||
| 
 | ||||
|     loop { | ||||
|         if event::poll(std::time::Duration::from_millis(16))? { | ||||
|             if let event::Event::Key(key) = event::read()? { | ||||
|                 if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') { | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     stdout().execute(LeaveAlternateScreen)?; | ||||
|     disable_raw_mode()?; | ||||
|     Ok(()) | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 danial23
						danial23