Skip to content

Commit

Permalink
chore: refactor codebase
Browse files Browse the repository at this point in the history
raklaptudirm committed Apr 27, 2024
1 parent aa5fa66 commit 0dee83e
Showing 4 changed files with 203 additions and 139 deletions.
File renamed without changes
File renamed without changes
197 changes: 197 additions & 0 deletions gui/src/gui.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
use std::str::FromStr;

use ataxx::{Board, File, Rank, Square};
use raylib::prelude::*;

use strum::IntoEnumIterator;

pub struct GuiBuilder {
title: String,
fen: String,
width: i32,
height: i32,
scale: f32,
}

impl GuiBuilder {
pub fn new() -> GuiBuilder {
GuiBuilder {
title: "Ataxx GUI".to_string(),
fen: "x5o/7/7/7/7/7/o5x x 0 1".to_string(),
width: 1280,
height: 720,
scale: 3.0,
}
}

pub fn build(&self) -> Gui {
let (mut raylib, thread) = raylib::init()
.size(self.width, self.height)
.title(&self.title)
.build();
let textures = Textures::load(&mut raylib, &thread);
let board = Board::from_str(&self.fen).unwrap();

Gui {
raylib,
thread,
options: GuiOptions {
width: self.width,
height: self.height,
scale: self.scale,
board,
textures,
},
}
}
}

pub struct Gui {
raylib: RaylibHandle,
thread: RaylibThread,

options: GuiOptions,
}

impl Gui {
pub fn new_drawer(&mut self) -> Drawer {
Drawer {
gui: &self.options,
drawer: self.raylib.begin_drawing(&self.thread),
}
}

pub fn should_quit(&self) -> bool {
self.raylib.window_should_close()
}
}

pub struct GuiOptions {
width: i32,
height: i32,

scale: f32,

board: ataxx::Board,

textures: Textures,
}

pub struct Drawer<'a> {
gui: &'a GuiOptions,
drawer: RaylibDrawHandle<'a>,
}

const SQUARE_SIZE: f32 = 27.0;

impl<'a> Drawer<'a> {
pub fn draw(&mut self) {
self.draw_board();
}

pub fn draw_board(&mut self) {
self.drawer.clear_background(Color::BLACK);

for rank in Rank::iter().rev() {
for file in File::iter() {
self.draw_square(Square::new(file, rank));
}
}

let src_rec = Rectangle::new(
0.0,
0.0,
self.gui.textures.border.width() as f32,
self.gui.textures.border.height() as f32,
);
let dst_rec = Rectangle::new(
self.gui.width as f32 / 2.0
- self.gui.textures.border.width() as f32 * self.gui.scale / 2.0,
self.gui.height as f32 / 2.0
- self.gui.textures.border.height() as f32 * self.gui.scale / 2.0,
self.gui.textures.border.width() as f32 * self.gui.scale,
self.gui.textures.border.height() as f32 * self.gui.scale,
);

self.drawer.draw_texture_pro(
&self.gui.textures.border,
src_rec,
dst_rec,
Vector2::zero(),
0.0,
Color::WHITE,
);
}

pub fn draw_square(&mut self, sq: Square) {
let pc = self.gui.board.at(sq);
let a = match pc {
ataxx::Color::White => 0.0,
ataxx::Color::Black => 1.0,
ataxx::Color::None => 0.0, // unused
};

let top_left = Vector2::new(
self.gui.width as f32 / 2.0 - 183.0 * self.gui.scale / 2.0
+ sq.file() as u32 as f32 * (SQUARE_SIZE - 1.0) * self.gui.scale,
self.gui.height as f32 / 2.0 - 183.0 * self.gui.scale / 2.0
+ sq.rank() as u32 as f32 * (SQUARE_SIZE - 1.0) * self.gui.scale,
);

let sq_src_rec = Rectangle::new(0.0, 0.0, SQUARE_SIZE, SQUARE_SIZE);
let pc_src_rec = Rectangle::new(a * SQUARE_SIZE, 0.0, SQUARE_SIZE, SQUARE_SIZE);

let dst_rec = Rectangle::new(
top_left.x,
top_left.y,
SQUARE_SIZE * self.gui.scale,
SQUARE_SIZE * self.gui.scale,
);

self.drawer.draw_texture_pro(
&self.gui.textures.square,
sq_src_rec,
dst_rec,
Vector2::new(0.0, 0.0),
0.0,
Color::WHITE,
);

if pc == ataxx::Color::None {
return;
}

self.drawer.draw_texture_pro(
&self.gui.textures.pieces,
pc_src_rec,
dst_rec,
Vector2::new(0.0, 0.0),
0.0,
Color::WHITE,
);
}
}

pub struct Textures {
pieces: Texture2D,
square: Texture2D,
border: Texture2D,
}

macro_rules! load_png_texture {
($rl:expr, $thread:expr, $file:expr) => {{
let raw = include_bytes!($file);
let img = Image::load_image_from_mem(".png", &raw.to_vec(), raw.len() as i32).unwrap();
$rl.load_texture_from_image($thread, &img).unwrap()
}};
}

impl Textures {
pub fn load(rl: &mut RaylibHandle, thread: &RaylibThread) -> Textures {
Textures {
pieces: load_png_texture!(rl, thread, "../assets/ataxx-pieces.png"),
square: load_png_texture!(rl, thread, "../assets/ataxx-square.png"),
border: load_png_texture!(rl, thread, "../assets/ataxx-border.png"),
}
}
}
145 changes: 6 additions & 139 deletions gui/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,144 +1,11 @@
use std::path::Path;
use std::str::FromStr;

use strum::IntoEnumIterator;

use ataxx::{Board, File, Rank, Square};

use raylib::prelude::*;

const SCALE: f32 = 3.0;
const SQUARE_SIZE: f32 = 27.0;

const WIDTH: i32 = 1280;
const HEIGHT: i32 = 720;
mod gui;
use gui::*;

fn main() {
let board = Board::from_str("x5o/7/7/7/7/7/o5x x 0 1").unwrap();
let (mut rl, thread) = raylib::init()
.size(WIDTH, HEIGHT)
.title("Ataxx GUI")
.build();

while !rl.window_should_close() {
draw_board(&mut rl, &thread, &board).unwrap();
}
}

fn draw_board(rl: &mut RaylibHandle, thread: &RaylibThread, board: &Board) -> Result<(), String> {
let squares_txt = load_texture(rl, thread, "ataxx-squares.png")?;
let pieces_txt = load_texture(rl, thread, "ataxx-pieces.png")?;
let border_txt = load_texture(rl, thread, "ataxx-board-border.png")?;

let mut d = rl.begin_drawing(thread);
d.clear_background(Color::BLACK);

let top_left = Vector2::new(
WIDTH as f32 / 2.0 - 183.0 * SCALE / 2.0,
HEIGHT as f32 / 2.0 - 183.0 * SCALE / 2.0,
);
for rank in Rank::iter().rev() {
for file in File::iter() {
let square = Square::new(file, rank);
draw_square(
&mut d,
&squares_txt,
&pieces_txt,
Vector2::new(
top_left.x + file as u32 as f32 * (SQUARE_SIZE - 1.0) * SCALE,
top_left.y + rank as u32 as f32 * (SQUARE_SIZE - 1.0) * SCALE,
),
board.at(square),
)?;
}
}
let mut gui = GuiBuilder::new().build();

let src_rec = Rectangle::new(
0.0,
0.0,
border_txt.width() as f32,
border_txt.height() as f32,
);
let dst_rec = Rectangle::new(
WIDTH as f32 / 2.0 - border_txt.width() as f32 * SCALE / 2.0,
HEIGHT as f32 / 2.0 - border_txt.height() as f32 * SCALE / 2.0,
border_txt.width() as f32 * SCALE,
border_txt.height() as f32 * SCALE,
);

d.draw_texture_pro(
&border_txt,
src_rec,
dst_rec,
Vector2::zero(),
0.0,
Color::WHITE,
);

Ok(())
}

fn draw_square(
d: &mut RaylibDrawHandle,
sq_txt: &Texture2D,
pc_txt: &Texture2D,
top_left: Vector2,
pc: ataxx::Color,
) -> Result<(), String> {
let a = match pc {
ataxx::Color::White => 0.0,
ataxx::Color::Black => 1.0,
ataxx::Color::None => 0.0, // unused
};

let sq_src_rec = Rectangle::new(0.0, 0.0, SQUARE_SIZE, SQUARE_SIZE);
let pc_src_rec = Rectangle::new(a * SQUARE_SIZE, 0.0, SQUARE_SIZE, SQUARE_SIZE);

let dst_rec = Rectangle::new(
top_left.x,
top_left.y,
SQUARE_SIZE * SCALE,
SQUARE_SIZE * SCALE,
);

d.draw_texture_pro(
sq_txt,
sq_src_rec,
dst_rec,
Vector2::new(0.0, 0.0),
0.0,
Color::WHITE,
);

if pc == ataxx::Color::None {
return Ok(());
while !gui.should_quit() {
let mut drawer = gui.new_drawer();
drawer.draw();
}

d.draw_texture_pro(
pc_txt,
pc_src_rec,
dst_rec,
Vector2::new(0.0, 0.0),
0.0,
Color::WHITE,
);

Ok(())
}

fn load_texture(
rl: &mut RaylibHandle,
thread: &RaylibThread,
name: &str,
) -> Result<Texture2D, String> {
let path = Path::new(file!())
.parent()
.unwrap()
.parent()
.unwrap()
.to_str()
.unwrap()
.to_owned();
let img = Image::load_image(&(path + "/assets/" + name))?;
rl.load_texture_from_image(thread, &img)
}

0 comments on commit 0dee83e

Please sign in to comment.