Skip to content

Commit

Permalink
chore: refactor codebase
Browse files Browse the repository at this point in the history
raklaptudirm committed Apr 27, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
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.