diff --git a/src/apr.rs b/src/apr.rs index ab04574..db08dbc 100644 --- a/src/apr.rs +++ b/src/apr.rs @@ -1,3 +1,13 @@ +//A NOTE TO WHOMSOEVER READS THIS FILE +//EVERYTHING THAT TOUCHES THE BOARD STRUCT IS FUCKED SINCE IT GOES IN ROW-COLUMN AND EVERYTHING ELSE GOES IN COLUMN-ROW +//REFACTORING IS A MUST +//PLEASE LOOK AT ALL USES OF BOARD STRUCT WHEN YOU DO THIS + +//a double note +//I JUST REFACTORED IT +//BUT IM KEEPING THIS COMMENT TIL YOU MOTHERFUCKERS READ IT +//BECAUSE I WANT YOU TO KNOW THE PAIN I HAVE FELT + use ggez::event::EventHandler; use ggez::graphics::{self, Color, DrawMode, Mesh, MeshBuilder}; use ggez::input::mouse::{self, MouseButton}; @@ -19,20 +29,25 @@ pub struct Apr { behaviours: Vec, } -pub fn make_grid(ctx: &mut Context, r: u8, c: u8, board: &[Vec]) -> GameResult { +pub fn make_grid( + ctx: &mut Context, + xlen: u8, + ylen: u8, + board: &[Vec<(u8, u8)>], +) -> GameResult { let mut builder = MeshBuilder::new(); - for row in 0..r { - for col in 0..c { + for x in 0..xlen { + for y in 0..ylen { builder.rectangle( DrawMode::fill(), graphics::Rect { - x: board::START_X + (board::BOARD_SQUARE_SIZE * f32::from(col)), - y: board::START_Y + (board::BOARD_SQUARE_SIZE * f32::from(row)), + x: board::START_X + (board::BOARD_SQUARE_SIZE * f32::from(x)), + y: board::START_Y + (board::BOARD_SQUARE_SIZE * f32::from(y)), w: board::BOARD_SQUARE_SIZE, h: board::BOARD_SQUARE_SIZE, }, - match board[row as usize][col as usize] % 2 { + match board[x as usize][y as usize].0 % 2 { 0 => Color::WHITE, 1 => Color::BLACK, _ => Color::BLACK, //impossible @@ -45,82 +60,37 @@ pub fn make_grid(ctx: &mut Context, r: u8, c: u8, board: &[Vec]) -> GameResu } impl Apr { - pub fn new(_ctx: &mut Context, r: u8, c: u8) -> GameResult { + pub fn new(_ctx: &mut Context, xlen: u8, ylen: u8) -> GameResult { // Load/create resources such as images here. - let board = board::make_board(r, c); + let board = board::make_board(xlen, ylen); let mut actors: Vec = Vec::new(); - let mut behaviours: Vec = Vec::new(); - for i in 0..r { + let mut behaviours: Vec = vec![behaviour::Behaviour { + moves: vec![behaviour::MovePattern { + movement: (0, -1), + amount: 1, + }], + }]; //pawn can move ONE forward, ONCE. not really the best test + for i in 0..xlen { // white side pawns - actors.push(actor::Actor::new( - _ctx, - "/pawn.png", - i, - 1, - behaviours.iter().len() as u8, - )); - behaviours.push(behaviour::Behaviour::new( - vec![(1, 1)], - vec![(1, -1), (-1, -1)], - )); - } - for i in 0..=1 { - // white side knights - actors.push(actor::Actor::new( - _ctx, - "/pawn.png", - i, - 0, - behaviours.iter().len() as u8, - )); - behaviours.push(behaviour::Behaviour::new( - vec![(1, 2)], - vec![(1, -1), (-1, -1)], - )); - } - for i in 0..r { - // black side pawns - actors.push(actor::Actor::new( - _ctx, - "/pawn2.png", - i, - c - 2, - behaviours.iter().len() as u8, - )); - behaviours.push(behaviour::Behaviour::new( - vec![(1, 1)], - vec![(1, 1), (-1, 1)], - )); - } - for i in 0..=1 { - // black side knights - actors.push(actor::Actor::new( - _ctx, - "/pawn2.png", - i, - c - 1, - behaviours.iter().len() as u8, - )); - behaviours.push(behaviour::Behaviour::new( - vec![(1, 2)], - vec![(1, 1), (-1, 1)], - )); + actors.push(actor::Actor::new(_ctx, "/pawn.png", i, 6, 0)); } + actors.push(actor::Actor::new(_ctx, "/pawn.png", 4, 4, 0)); //blocking pawn for testing + Ok(Apr { - grid: make_grid(_ctx, r, c, board.board.as_slice())?, + grid: make_grid(_ctx, xlen, ylen, board.board.as_slice())?, board, should_update_grid: false, actors, dragging: false, - behaviours, //the pawn can go TWO diagonally and to the right and only upwards (4-tile-corner leaper pawn behaviour) + behaviours, }) } #[allow(dead_code)] - pub fn set_colour(&mut self, r: usize, c: usize, clr: u8) { + pub fn set_colour(&mut self, x: usize, y: usize, clr: u8) { //You should only modify self.board through this method. - self.board.board[r][c] = clr; //Making a getter for self.board would sadly break borrowing in the same way that closest_square_coords does. + self.board.board[x][y].0 = clr; //Making a getter for self.board would sadly break borrowing in the same way that closest_square_coords does. self.should_update_grid = true; //Similar solutions apply. } } @@ -143,12 +113,20 @@ impl EventHandler for Apr { let (x, y) = self.board.closest_square_coords(posn.x, posn.y); if self.dragging { // released, so now we check destination - if !self.behaviours[index].validate_dest((prev_x, prev_y), (x, y)) { + if !self.behaviours[usize::from(actor.behaviour)].validate_dest( + (prev_x, prev_y), + (x, y), + &self.board, + ) { actor.posn = actor::ActorPosn::BoardPosn { x: prev_x, y: prev_y, }; } else { + self.board.board[usize::from(prev_y)][usize::from(prev_x)].1 = 255; + self.board.board[usize::from(y)][usize::from(x)].1 = index as u8; //only 255 actors allowed? should be fine (laughing) (we look back at this in 10 years and die) + //[x][y] or [y][x]?? i think its [y][x] since row-column + //update, eveyrthing is fucked actor.posn = actor::ActorPosn::BoardPosn { x, y }; } } @@ -194,8 +172,8 @@ impl EventHandler for Apr { if self.should_update_grid { self.grid = make_grid( ctx, - self.board.row, - self.board.col, + self.board.xlen, + self.board.ylen, self.board.board.as_slice(), )?; self.should_update_grid = false; @@ -210,7 +188,7 @@ impl EventHandler for Apr { ctx, &actor.image, drawparams.dest([ - board::START_X + board::BOARD_SQUARE_SIZE * f32::from(x), + board::START_X + board::BOARD_SQUARE_SIZE * f32::from(x), //i might have to kill myself board::START_Y + board::BOARD_SQUARE_SIZE * f32::from(y), ]), )?, diff --git a/src/behaviour.rs b/src/behaviour.rs index b4dc9af..6ad43db 100644 --- a/src/behaviour.rs +++ b/src/behaviour.rs @@ -1,30 +1,71 @@ +use crate::board; + +pub struct MovePattern { + pub movement: (i8, i8), + pub amount: u8, + /* + pub negx: bool, //some form of symmetry that is expressed by negating x value. whatever comes out of that is what this is + pub negy: bool + */ //commented out because they complicate implementation + + //todo: flags for "on first move only", etc, etc, and corresponding state + //also todo, probably in validate_dest too: implement 'flipped y for enemy' +} + pub struct Behaviour { - pub moves: Vec<(i8, i8)>, //this is a placeholder - pub dirs: Vec<(i8, i8)>, // up right down left + pub moves: Vec, } impl Behaviour { - pub fn new(m: Vec<(i8, i8)>, d: Vec<(i8, i8)>) -> Behaviour { - Behaviour { moves: m, dirs: d } - } + // pub fn new(m: Vec<(i8, i8)>, d: Vec<(i8, i8)>) -> Behaviour { + // Behaviour { moves: m, dirs: d } + // } + //We don't need a `new' until it's not literally just an alias for the name of the struct. + + pub fn validate_dest( + &self, + origin: (u8, u8), + destination: (u8, u8), + board: &board::Board, + ) -> bool { + //todo - this should be memoised. ideally in a transparent fashion? maybe nontransparent would help w/ highlighting + //but dont prematurely optimise, even if you have informaticsbrain + //just write down all you WANT to optimise as a todo. + //will we get around to it? + //who knows + 'moves: for moveset in self.moves.iter() { + let mut posn: (i16, i16) = (origin.0.into(), origin.1.into()); + let mut fuel = moveset.amount; + let dest_from: (i16, i16) = (destination.0.into(), destination.1.into()); + while posn.0 >= 0 + && posn.0 < board.xlen.into() + && posn.1 >= 0 + && posn.1 < board.ylen.into() + { + //println!("{:?}, {:?}", posn, dest_from); + if posn == dest_from { + return true; //hey hey! we got there + } + + if board.board[posn.1 as usize][posn.0 as usize].1 != 255 { + //`as' is safe because we guarantee it's above 0 in the while. + //don't do captures yet + //lol + //mvp + //lol + + continue 'moves; //abort this line of movement + } - pub fn validate_dest(&self, origin: (u8, u8), destination: (u8, u8)) -> bool { - // original plan was to use match but i felt for loops would work better since we dont yet know the extent of moves vector - // println!("origin: ({}, {}), destination: ({}, {})",origin.0, origin.1, destination.0, destination.1); - for moveset in self.moves.iter() { - for dir in self.dirs.iter() { - // mind blanking need to add something to confirm which direction we are iterating through - // println!("Permissible: ({}, {})",(origin.0 as i8) + dir.0 * moveset.0,(origin.1 as i8) - dir.1 * moveset.1); - if ( - ((origin.0 as i8) + moveset.0 * dir.0) as u8, - ((origin.1 as i8) - moveset.1 * dir.1) as u8, - ) == destination - { - return true; - } // flip the second component of calculation because the grid works from top left isntead of bot left like a piss + if fuel == 0 { + //println!("Augh!!"); + continue 'moves; //gone all i can + } + fuel -= 1; + posn.0 += i16::from(moveset.movement.0); + posn.1 += i16::from(moveset.movement.1); } } false } } -// ok remember wghen i said in chat i didnt think enough on the directions concept. well that was pretty fucked up. diff --git a/src/board.rs b/src/board.rs index a444c0a..334550f 100644 --- a/src/board.rs +++ b/src/board.rs @@ -3,22 +3,22 @@ pub const START_Y: f32 = 20.0; pub const BOARD_SQUARE_SIZE: f32 = 20.0; pub struct Board { - pub board: Vec>, - pub row: u8, - pub col: u8, + pub board: Vec>, + pub xlen: u8, //could just use .len() + pub ylen: u8, //ditto [0].len() } -pub fn make_board(r: u8, c: u8) -> Board { - let mut init: Vec> = vec![vec![0u8; r as usize]; c as usize]; - for (row, rowa) in init.iter_mut().enumerate() { - for (col, item) in rowa.iter_mut().enumerate() { - *item = (row + col) as u8 % 8; +pub fn make_board(xlen: u8, ylen: u8) -> Board { + let mut init = vec![vec![(0, 255); xlen as usize]; ylen as usize]; + for (x, xa) in init.iter_mut().enumerate() { + for (y, item) in xa.iter_mut().enumerate() { + (*item).0 = (y + x) as u8 % 8; } } Board { board: init, - row: r, - col: c, + xlen, + ylen, } } @@ -27,11 +27,11 @@ impl Board { //First, normalise to within the grid. let mut x = x; x = x.max(START_X); - x = x.min(START_X + (BOARD_SQUARE_SIZE * f32::from(self.col)) - 1.0); + x = x.min(START_X + (BOARD_SQUARE_SIZE * f32::from(self.xlen)) - 1.0); let mut y = y; y = y.max(START_Y); - y = y.min(START_Y + (BOARD_SQUARE_SIZE * f32::from(self.row)) - 1.0); + y = y.min(START_Y + (BOARD_SQUARE_SIZE * f32::from(self.ylen)) - 1.0); //Then, remove the start x and y x -= START_X;