Advertisement
loloof64

Rust chessboard

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