Advertisement
loloof64

Chessboard rust : closure and Rc

Nov 25th, 2018
485
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 8.98 KB | None | 0 0
  1. use gtk::prelude::*;
  2. use gdk::prelude::*;
  3. use gtk::DrawingArea;
  4. use cairo::Context;
  5. use cairo::enums::{FontSlant, FontWeight};
  6. use shakmaty::Role;
  7. use chess_position_trainer::graphic::PieceImages;
  8. use chess_position_trainer::logic::chessgame::ChessGame;
  9. use std::rc::Rc;
  10.  
  11. #[derive(Clone)]
  12. pub struct ChessBoard
  13. {
  14.     drawing_area: DrawingArea,
  15.     reversed: bool,
  16.     logic: ChessGame,
  17.     cells_size: u32,
  18. }
  19.  
  20. impl ChessBoard
  21. {
  22.     pub fn new_from_default(cells_size: u32) -> Option<Rc<ChessBoard>>
  23.     {
  24.         ChessBoard::get_chessboard(
  25.             cells_size,
  26.             "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
  27.         )
  28.     }
  29.  
  30.     pub fn new_from_fen(cells_size: u32, initial_position: &str) -> Option<Rc<ChessBoard>>
  31.     {
  32.         ChessBoard::get_chessboard(
  33.             cells_size,
  34.             initial_position,
  35.         )
  36.     }
  37.  
  38.     pub fn reverse(&mut self)
  39.     {
  40.         self.reversed = ! self.reversed;
  41.     }
  42.  
  43.     pub fn get_drawing_area(&self) -> &DrawingArea
  44.     {
  45.         &self.drawing_area
  46.     }
  47.  
  48.    
  49.  
  50.     fn get_chessboard(cells_size: u32, initial_position: &str) -> Option<Rc<ChessBoard>>
  51.     {
  52.         let drawing_area = DrawingArea::new();
  53.  
  54.         let logic = ChessGame::new_from_fen(initial_position);
  55.  
  56.         match logic {
  57.             Some(game_logic) => {
  58.                 let chess_board = ChessBoard {
  59.                     drawing_area,
  60.                     reversed: false,
  61.                     logic: game_logic,
  62.                     cells_size,
  63.                 };
  64.  
  65.                 let chess_board_ref1 = Rc::new(chess_board);
  66.                 let chess_board_ref2 = chess_board_ref1.clone();
  67.  
  68.                 chess_board_ref2.drawing_area.connect_draw(move |_drawing_area, cr|{
  69.                     chess_board_ref1.paint(cr);
  70.                     Inhibit(false)
  71.                 });
  72.  
  73.                 Some(chess_board_ref2)
  74.             },
  75.             _ => None
  76.         }
  77.     }
  78.  
  79.     fn paint(&self, cr: &Context){
  80.        self.draw_background(cr);
  81.        self.draw_cells(cr);
  82.        self.draw_pieces(cr);
  83.        self.draw_coordinates(cr);
  84.        self.draw_player_turn(cr);
  85.     }
  86.  
  87.     fn draw_background(&self, cr: &Context)
  88.     {
  89.         let green_color = [60.0/255.0, 204.0/255.0, 100.0/255.0];
  90.         cr.set_source_rgb(
  91.             green_color[0],
  92.             green_color[1],
  93.             green_color[2],
  94.         );
  95.         cr.paint();
  96.     }
  97.  
  98.     fn draw_cells(&self, cr: &Context)
  99.     {
  100.         (0..8).for_each(|rank| {
  101.             (0..8).for_each(|file| {
  102.                 let white_cell_color = [255.0/255.0, 255.0/255.0, 179.0/255.0];
  103.                 let black_cell_color = [153.0/255.0, 102.0/255.0, 51.0/255.0];
  104.  
  105.                 let is_white_cell = (file + rank) % 2 == 0;
  106.                 let cell_color = if is_white_cell {white_cell_color} else {black_cell_color};
  107.  
  108.                 let rect_x = (self.cells_size as f64) * (0.5 + (file as f64));
  109.                 let rect_y = (self.cells_size as f64) * (0.5 + (rank as f64));
  110.                 let rect_size = self.cells_size as f64;
  111.  
  112.                 cr.rectangle(
  113.                     rect_x,
  114.                     rect_y,
  115.                     rect_size,
  116.                     rect_size,
  117.                 );
  118.                 cr.set_source_rgb(
  119.                     cell_color[0],
  120.                     cell_color[1],
  121.                     cell_color[2],
  122.                 );
  123.                 cr.fill();
  124.             });
  125.         });
  126.     }
  127.  
  128.     fn draw_pieces(&self, cr: &Context)
  129.     {
  130.         (0..8).for_each(|rank| {
  131.             (0..8).for_each(|file| {
  132.                 let real_file = if self.reversed { 7-file } else { file };
  133.                 let real_rank = if self.reversed { 7-rank } else { rank };
  134.  
  135.                 let piece_size = (self.cells_size as f64 * 0.8) as i32;
  136.  
  137.                 if let Some(piece) = self.logic.piece_at_cell(real_file, real_rank) {
  138.                     let image = match piece.role {
  139.                         Role::Pawn => {
  140.                             if piece.color.is_white()
  141.                             {
  142.                                 PieceImages::get_white_pawn(piece_size)
  143.                             }
  144.                             else
  145.                             {
  146.                                 PieceImages::get_black_pawn(piece_size)
  147.                             }
  148.                         },
  149.                         Role::Knight => {
  150.                             if piece.color.is_white()
  151.                             {
  152.                                 PieceImages::get_white_knight(piece_size)
  153.                             }
  154.                             else
  155.                             {
  156.                                 PieceImages::get_black_knight(piece_size)
  157.                             }
  158.                         },
  159.                         Role::Bishop => {
  160.                             if piece.color.is_white()
  161.                             {
  162.                                 PieceImages::get_white_bishop(piece_size)
  163.                             }
  164.                             else
  165.                             {
  166.                                 PieceImages::get_black_bishop(piece_size)
  167.                             }
  168.                         },
  169.                         Role::Rook => {
  170.                             if piece.color.is_white()
  171.                             {
  172.                                 PieceImages::get_white_rook(piece_size)
  173.                             }
  174.                             else
  175.                             {
  176.                                 PieceImages::get_black_rook(piece_size)
  177.                             }
  178.                         },
  179.                         Role::Queen => {
  180.                             if piece.color.is_white()
  181.                             {
  182.                                 PieceImages::get_white_queen(piece_size)
  183.                             }
  184.                             else
  185.                             {
  186.                                 PieceImages::get_black_queen(piece_size)
  187.                             }
  188.                         },
  189.                         Role::King => {
  190.                             if piece.color.is_white()
  191.                             {
  192.                                 PieceImages::get_white_king(piece_size)
  193.                             }
  194.                             else
  195.                             {
  196.                                 PieceImages::get_black_king(piece_size)
  197.                             }
  198.                         },
  199.                     };
  200.  
  201.                     let location_x = (self.cells_size as f64) * (file as f64 + 0.5 + 0.1);
  202.                     let location_y = (self.cells_size as f64) * ((7.0-rank as f64) + 0.5 + 0.1);
  203.                     cr.set_source_pixbuf(
  204.                         &image,
  205.                         location_x,
  206.                         location_y
  207.                     );
  208.                     cr.paint();  
  209.                 }
  210.             });
  211.         });
  212.     }
  213.  
  214.     fn draw_coordinates(&self, cr: &Context)
  215.     {
  216.         let files = ["A", "B", "C", "D", "E", "F", "G", "H"];
  217.         let ranks = ["8", "7", "6", "5", "4", "3", "2", "1"];
  218.  
  219.         cr.set_source_rgb(0.2, 0.4, 1.0);
  220.         cr.select_font_face(
  221.             "Sans Serif",
  222.             FontSlant::Normal,
  223.             FontWeight::Bold
  224.         );
  225.         cr.set_font_size((self.cells_size as f64) * 0.38);
  226.        
  227.         (0..8).for_each(|file_index| {
  228.             let real_file_index = if self.reversed { 7 - file_index } else { file_index };
  229.  
  230.             let letter = files[real_file_index];
  231.             let letter_x = (self.cells_size as f64) * (0.9 + (real_file_index as f64));
  232.             let letter_y_top = (self.cells_size as f64) * 0.4;
  233.             let letter_y_bottom = (self.cells_size as f64) * 8.9;
  234.  
  235.             cr.move_to(letter_x, letter_y_top);
  236.             cr.show_text(letter);
  237.  
  238.             cr.move_to(letter_x, letter_y_bottom);
  239.             cr.show_text(letter);
  240.         });
  241.  
  242.         (0..8).for_each(|rank_index| {
  243.             let real_rank_index = if self.reversed { 7 - rank_index } else { rank_index };
  244.  
  245.             let letter = ranks[real_rank_index];
  246.             let letter_y = (self.cells_size as f64) * (1.2 + (real_rank_index as f64));
  247.             let letter_x_left = (self.cells_size as f64) * 0.1;
  248.             let letter_x_right = (self.cells_size as f64) * 8.6;
  249.  
  250.             cr.move_to(letter_x_left, letter_y);
  251.             cr.show_text(letter);
  252.  
  253.             cr.move_to(letter_x_right, letter_y);
  254.             cr.show_text(letter);
  255.         });
  256.     }
  257.  
  258.     fn draw_player_turn(&self, cr: &Context)
  259.     {
  260.         let color = if self.logic.is_white_turn() { [1.0, 1.0, 1.0] } else { [0.0, 0.0, 0.0] };
  261.         let center = (self.cells_size as f64) * 8.75;
  262.         let radius = (self.cells_size as f64) * 0.25;
  263.         cr.arc(center, center, radius, 0.0, 2.0 * std::f64::consts::PI);
  264.         cr.set_source_rgb(
  265.             color[0],
  266.             color[1],
  267.             color[2],
  268.         );
  269.         cr.fill();
  270.     }
  271. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement