diff --git a/.gitignore b/.gitignore index 6985cf1..57a1303 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ Cargo.lock # MSVC Windows builds of rustc generate these, which store debugging information *.pdb +# Silly swap thingies +*.swp diff --git a/src/gamedata/algorithms.rs b/src/gamedata/algorithms.rs new file mode 100644 index 0000000..6620595 --- /dev/null +++ b/src/gamedata/algorithms.rs @@ -0,0 +1,10 @@ +use super::{heuristic, Board, Disk}; +pub fn minimax_decision(board: &Board, depth: i32) -> Board { + todo!() +} +fn maximise(board: &Board, depth: &i32) -> (Board, i32) { + todo!() +} +fn minimise(board: &Board, depth: &i32) -> (Board, i32) { + todo!() +} diff --git a/src/gamedata/heuristic.rs b/src/gamedata/heuristic.rs new file mode 100644 index 0000000..a16b44c --- /dev/null +++ b/src/gamedata/heuristic.rs @@ -0,0 +1,268 @@ +use array2d::Array2D; + +use super::{ + dec_both, dec_col, dec_inc, dec_row, inc_both, inc_col, inc_dec, inc_row, + score_checkers::{flip_direction, get_legal_moves, variant_eq, Direction}, + Board, Disk, +}; +//multipliers +const POT_STREAK: i32 = 4; //one streak is kind of poopy +const POT_STREAKS: i32 = 6; +const POT_WIN: i32 = 5; // should be nerfed if its just 1 potential win +const POT_WINS: i32 = 8; +const SCORE_DIFF: i32 = 6; +const MAX_WINS: i32 = 17; + +pub fn get_score(board: &Board, disk: Disk) -> i32 { + //this should be summing up a bunch of functions defined below this one + let sequences = get_streaks(&board.columns, &disk); + let score: i32 = match disk { + Disk::RED => board.red_score - board.blu_score, + Disk::BLU => board.blu_score - board.red_score, + Disk::EMPTY => panic!("Why would you ever"), + }; + potential_streaks(&sequences, &disk) + potential_wins(&sequences, &disk) + score * SCORE_DIFF +} +fn potential_wins(sequences: &Vec>, _disk: &Disk) -> i32 { + let count: i32 = sequences.iter().count() as i32; + // for win in sequences { + // if win + // .iter() + // .filter(|&_disk| variant_eq(_disk, &Disk::EMPTY)) + // .count() + // == 1 + // && win.len() == 4 + // { + // count += 1; + // } + // } + match count { + 1 => POT_WIN, + _ => POT_WINS * count, + } +} +fn potential_streaks(sequences: &Vec>, _disk: &Disk) -> i32 { + //This should grab potential streaks (Disk::EMPTY) + // get all "EMPTY" indexes + let streaks = sequences + .iter() + .filter(|&seq| { + seq.iter() + .filter(|&disk| variant_eq(disk, &Disk::EMPTY)) + .count() + > 1 + && seq.len() == 4 + }) + .count(); + + match streaks { + 1 => POT_STREAK, + _ => POT_STREAKS * streaks as i32, + } +} +fn get_streaks(board: &Array2D, player_disk: &Disk) -> Vec> { + let empty_indices: Vec<(usize, usize)> = board + .indices_row_major() + .filter(|&index| variant_eq(board.get(index.0, index.1).expect(""), &Disk::EMPTY)) + .collect(); + //TODO rename this variable + let mut streaks: Vec> = vec![]; + for index in empty_indices { + let moves = get_legal_moves(&index, (board.num_rows(), board.num_columns())); + for direction in moves { + let mut sequence = heur_scan(&board, &index, direction.clone(), 4, *player_disk); + //dbg!(&index, &direction, &poopy); + match sequence + .iter() + .filter(|&disk| variant_eq(disk, player_disk)) + .count() + { + 2 => streaks.push(sequence), + _ => {} + } + } + } + streaks +} +fn get_wins(board: &Array2D, player_disk: &Disk) -> Vec> { + let empty_indices: Vec<(usize, usize)> = board + .indices_row_major() + .filter(|&index| variant_eq(board.get(index.0, index.1).expect(""), &Disk::EMPTY)) + .collect(); + let mut wins: Vec> = vec![]; + for index in empty_indices { + let moves = get_legal_moves(&index, (board.num_rows(), board.num_columns())); + for direction in moves { + let mut win: Vec = Vec::with_capacity(4); + win.append(&mut heur_scan( + &board, + &index, + direction.clone(), + 4, + *player_disk, + )); + match win + .iter() + .filter(|&disk| variant_eq(disk, player_disk)) + .count() + { + 3 => wins.push(win), + 2 => { + for i in 1..win.len() - 1 { + if !variant_eq(player_disk, &win[i]) { + win.remove(i); + } + } + let opp_direction = flip_direction(direction.clone()); + let mut opp_sequence = heur_scan( + &board, + &index, + opp_direction, + (4 - win.len() + 1) as i32, + *player_disk, + ); + opp_sequence.remove(0); + win.append(&mut opp_sequence); + dbg!(&win); + wins.push(win); + } + _ => {} + } + } + } + wins +} + +fn heur_scan( + board: &Array2D, + index: &(usize, usize), + direction: Direction, + depth: i32, + player_disk: Disk, +) -> Vec { + match board.get(index.0, index.1) { + Some(_) => {} + None => return vec![], + }; + let mut current_index = *index; + let mut in_a_row: Vec = vec![]; + // dbg!("Starting new thing", &direction); + for _num in 0..depth { + match board.get(current_index.0, current_index.1) { + Some(_disk) => { + // dbg!(_disk, current_disk, in_a_row); + if variant_eq(&player_disk, _disk) || variant_eq(_disk, &Disk::EMPTY) { + // add in a row by 1 + in_a_row.push(*_disk); + // dbg!(current_index); + //go to next element + match direction { + Direction::DOWN => { + if current_index.0 == 0 { + break; + } + current_index = dec_row(¤t_index, 1); + } + Direction::UP => { + if current_index.0 == board.num_rows() - 1 { + break; + } + current_index = inc_row(¤t_index, 1); + } + Direction::LEFT => { + if current_index.1 == 0 { + break; + } + current_index = dec_col(¤t_index, 1); + } + Direction::RIGHT => { + if current_index.1 == board.num_columns() - 1 { + break; + } + current_index = inc_col(¤t_index, 1); + } + Direction::UPRIGHT => { + if current_index.0 == board.num_rows() - 1 + || current_index.1 == board.num_columns() - 1 + { + break; + } + current_index = inc_both(¤t_index, 1); + } + Direction::UPLEFT => { + if current_index.0 == board.num_columns() - 1 || current_index.1 == 0 { + break; + } + + current_index = inc_dec(¤t_index, 1); + } + Direction::DOWNRIGHT => { + if current_index.0 == 0 || current_index.1 == board.num_columns() - 1 { + break; + } + current_index = dec_inc(¤t_index, 1); + } + Direction::DOWNLEFT => { + if current_index.0 == 0 || current_index.1 == 0 { + break; + } + current_index = dec_both(¤t_index, 1); + } + } + } else { + break; + } + } + + None => break, + } + } + in_a_row +} + +//Tests because I am making everything public +//TODO separate module here +#[test] +fn streak_test_1() { + let mut board = Board::default(); + board.play(Disk::BLU, 3); + board.play(Disk::BLU, 3); + board.play(Disk::BLU, 3); + board.play(Disk::BLU, 2); + board.play(Disk::BLU, 1); + let sequences = get_streaks(&board.columns, &Disk::BLU); + assert_eq!(18, potential_streaks(&sequences, &Disk::BLU)); + board.play(Disk::BLU, 0); + let sequences = get_streaks(&board.columns, &Disk::BLU); + board.play(Disk::BLU, 3); + board.play(Disk::BLU, 3); + board.play(Disk::BLU, 3); + board.play(Disk::BLU, 3); + let sequences = get_streaks(&board.columns, &Disk::BLU); + assert_eq!(12, potential_streaks(&sequences, &Disk::BLU)); +} +#[test] +fn win_test_flipping() { + let mut board = Board::default(); + board.play(Disk::BLU, 3); + board.play(Disk::RED, 4); + board.play(Disk::BLU, 4); + board.play(Disk::RED, 5); + board.play(Disk::RED, 5); + board.play(Disk::RED, 6); + board.play(Disk::RED, 6); + board.play(Disk::RED, 6); + board.play(Disk::BLU, 6); + let sequences = get_wins(&board.columns, &Disk::BLU); + dbg!(&sequences); + assert_eq!(POT_WIN, potential_wins(&sequences, &Disk::BLU)); +} +#[test] +fn win_test_flipping_hard() { + let mut board = Board::default(); + board.play(Disk::BLU, 1); + board.play(Disk::BLU, 2); + board.play(Disk::BLU, 4); + let sequences = get_wins(&board.columns, &Disk::BLU); + assert_eq!(POT_WIN, potential_wins(&sequences, &Disk::BLU)); +} diff --git a/src/gamedata/indices.rs b/src/gamedata/indices.rs new file mode 100644 index 0000000..f49bc40 --- /dev/null +++ b/src/gamedata/indices.rs @@ -0,0 +1,26 @@ +pub fn inc_row((row, col): &(usize, usize), value: usize) -> (usize, usize) { + (row + value as usize, *col) +} +pub fn inc_col((row, col): &(usize, usize), value: usize) -> (usize, usize) { + (*row, col + value as usize) +} + +pub fn dec_row((row, col): &(usize, usize), value: usize) -> (usize, usize) { + (row - value as usize, *col) +} +pub fn dec_col((row, col): &(usize, usize), value: usize) -> (usize, usize) { + (*row, col - value as usize) +} +pub fn inc_both((row, col): &(usize, usize), value: usize) -> (usize, usize) { + (row + value, col + value) +} +pub fn dec_both((row, col): &(usize, usize), value: usize) -> (usize, usize) { + (row - value, col - value) +} +//TODO get better names for these +pub fn inc_dec((row, col): &(usize, usize), value: usize) -> (usize, usize) { + (row + value, col - value) +} +pub fn dec_inc((row, col): &(usize, usize), value: usize) -> (usize, usize) { + (row - value, col + value) +} diff --git a/src/gamedata/mod.rs b/src/gamedata/mod.rs index 444ea2f..8694444 100644 --- a/src/gamedata/mod.rs +++ b/src/gamedata/mod.rs @@ -1,24 +1,27 @@ +mod algorithms; +mod heuristic; +mod indices; mod score_checkers; #[cfg(test)] mod tests; use array2d::Array2D; +pub use indices::*; -use self::score_checkers::{one_direction, two_direction}; #[derive(Clone)] pub struct Board { - p1_score: i32, - p2_score: i32, + red_score: i32, + blu_score: i32, columns: Array2D, } impl Default for Board { fn default() -> Self { - let columns = Array2D::filled_with(Disk::EMPTY, 7, 6); + let columns = Array2D::filled_with(Disk::EMPTY, 6, 7); Self { - p1_score: 0, - p2_score: 0, + red_score: 0, + blu_score: 0, columns, } } @@ -26,28 +29,79 @@ impl Default for Board { impl Board { fn getscore(&self) -> (i32, i32) { - (self.p1_score, self.p2_score) + (self.red_score, self.blu_score) } - fn play(&mut self, disk: Disk, col: i32) -> bool { + fn play(&mut self, disk: Disk, col: usize) -> bool { let column = &self.columns.as_columns()[col as usize]; let empty = column.iter().filter(|&a| matches!(a, Disk::EMPTY)).count(); dbg!(empty); let top = column.len() - empty; match self.columns.set(top, col as usize, disk) { - Ok(_) => true, + Ok(_) => { + self.score_check((top, col)); + true + } Err(_) => false, } } fn score_check(&mut self, index: (usize, usize)) { - unimplemented!() + use score_checkers::*; + let moves = get_legal_moves( + &index, + (self.columns.num_rows(), self.columns.num_columns()), + ); + match self.columns.get(index.0, index.1) { + Some(disk) => match disk { + Disk::RED => { + for _move in moves { + let mut consecutive = scan(&self.columns, &index, _move.clone(), 4); + if consecutive < 4 { + consecutive += scan( + &self.columns, + &index, + flip_direction(_move), + 4 - consecutive + 1, + ) + } + if consecutive - 1 == 4 { + self.red_score += 1 + } + } + } + Disk::BLU => { + for _move in moves { + let mut consecutive = scan(&self.columns, &index, _move.clone(), 4); + if consecutive < 4 { + consecutive += scan( + &self.columns, + &index, + flip_direction(_move), + 4 - consecutive + 1, + ) + } + if consecutive - 1 == 4 { + self.blu_score += 1 + } + } + } + Disk::EMPTY => return, + }, + None => return, + } + } + fn game_over(&self) -> bool { + self.columns + .as_row_major() + .iter() + .filter(|&d| matches!(d, &Disk::EMPTY)) + .count() + == 0 } } -#[derive(Clone)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Disk { RED, - BLUE, + BLU, EMPTY, } - - diff --git a/src/gamedata/score_checkers.rs b/src/gamedata/score_checkers.rs index 8956f7b..387f344 100644 --- a/src/gamedata/score_checkers.rs +++ b/src/gamedata/score_checkers.rs @@ -1,31 +1,91 @@ use array2d::Array2D; -use super::Disk; +use crate::gamedata::{dec_both, dec_inc, dec_row, inc_both, inc_dec, inc_row}; -pub fn one_direction(board: &Array2D, index: &(usize, usize), direction: Direction) -> i32 { - let current_disk = board.get(index.0, index.1); +use super::{dec_col, inc_col, Disk}; + +pub fn scan( + board: &Array2D, + index: &(usize, usize), + direction: Direction, + depth: i32, +) -> i32 { + let current_disk: &Disk; + match board.get(index.0, index.1) { + Some(disk) => current_disk = disk, + None => return 0, + }; let mut current_index = *index; let mut in_a_row = 0; - loop { - dbg!(in_a_row, current_index); + // dbg!("Starting new thing", &direction); + for _num in 0..depth { match board.get(current_index.0, current_index.1) { Some(_disk) => { - if matches!(current_disk, _disk) && !matches!(_disk, Disk::EMPTY) { + // dbg!(_disk, current_disk, in_a_row); + if variant_eq(current_disk, _disk) && !variant_eq(_disk, &Disk::EMPTY) { // add in a row by 1 in_a_row += 1; + // dbg!(current_index); //go to next element match direction { - Direction::BACKWARD => { + Direction::DOWN => { if current_index.0 == 0 { break; } - current_index.0 -= 1; + current_index = dec_row(¤t_index, 1); } - Direction::FORWARD => { + Direction::UP => { if current_index.0 == board.num_rows() - 1 { break; } - current_index.0 += 1; + current_index = inc_row(¤t_index, 1); + } + Direction::LEFT => { + if current_index.1 == 0 { + break; + } + current_index = dec_col(¤t_index, 1); + // current_index.1 -= 1; + } + Direction::RIGHT => { + if current_index.1 == board.num_columns() - 1 { + break; + } + current_index = inc_col(¤t_index, 1); + // current_index.1 += 1; + } + Direction::UPRIGHT => { + if current_index.0 == board.num_rows() - 1 + || current_index.1 == board.num_columns() - 1 + { + break; + } + current_index = inc_both(¤t_index, 1); + // current_index.1 += 1; + // current_index.0 += 1; + } + Direction::UPLEFT => { + if current_index.0 == board.num_columns() - 1 || current_index.1 == 0 { + break; + } + + // current_index.1 -= 1; + // current_index.0 += 1; + current_index = inc_dec(¤t_index, 1); + } + Direction::DOWNRIGHT => { + if current_index.0 == 0 || current_index.1 == board.num_columns() - 1 { + break; + } + current_index = dec_inc(¤t_index, 1); + // current_index.1 += 1; + // current_index.0 -= 1; + } + Direction::DOWNLEFT => { + if current_index.0 == 0 || current_index.1 == 0 { + break; + } + current_index = dec_both(¤t_index, 1); } } } else { @@ -36,32 +96,73 @@ pub fn one_direction(board: &Array2D, index: &(usize, usize), direction: D None => break, } } - if in_a_row == 4 { - //score added - return 1; - } else { - return 0; - } - //+-3 + in_a_row + // //+-3 } // board[(2,3)]; - -pub fn two_direction(board: &Array2D, index: &(usize, usize)) -> i32 { - let current_disk = board.get(index.0, index.1); - unimplemented!() - //+-1 -+2 +pub fn get_legal_moves( + (row, col): &(usize, usize), + (nrow, ncol): (usize, usize), +) -> Vec { + let _max_col = nrow - 1; + let _max_row = ncol - 1; + let mut moves: Vec = vec![]; + match *col { + 0 => moves.push(Direction::UP), + _max_row => moves.push(Direction::DOWN), + _ => { + moves.push(Direction::UP); + moves.push(Direction::DOWN); + } + }; + match *row { + 0 => moves.push(Direction::RIGHT), + _max_row => moves.push(Direction::LEFT), + _ => { + moves.push(Direction::LEFT); + moves.push(Direction::RIGHT) + } + }; + if moves.contains(&Direction::UP) && moves.contains(&Direction::LEFT) { + moves.push(Direction::UPLEFT); + } + if moves.contains(&Direction::UP) && moves.contains(&Direction::RIGHT) { + moves.push(Direction::UPRIGHT); + } + if moves.contains(&Direction::DOWN) && moves.contains(&Direction::LEFT) { + moves.push(Direction::DOWNLEFT); + } + if moves.contains(&Direction::DOWN) && moves.contains(&Direction::RIGHT) { + moves.push(Direction::DOWNRIGHT); + } + moves } -//1 == number -//dbg!() -//println!() -//matches!() -//assert!() -// for _num 0..n {} +#[derive(Clone, Debug, PartialEq, Eq)] pub enum Direction { UP, DOWN, - FORWARD, - BACKWARD, - //TODO add more directions for diagonals + LEFT, + RIGHT, + UPLEFT, + UPRIGHT, + DOWNLEFT, + DOWNRIGHT, +} +// serves nothing except do what matches!() should have done all along +// matches works too I'm just dumb +pub fn variant_eq(a: &T, b: &T) -> bool { + std::mem::discriminant(a) == std::mem::discriminant(b) +} +pub fn flip_direction(direction: Direction) -> Direction { + match direction { + Direction::UP => Direction::DOWN, + Direction::DOWN => Direction::UP, + Direction::LEFT => Direction::RIGHT, + Direction::RIGHT => Direction::LEFT, + Direction::UPLEFT => Direction::DOWNRIGHT, + Direction::UPRIGHT => Direction::DOWNLEFT, + Direction::DOWNLEFT => Direction::UPRIGHT, + Direction::DOWNRIGHT => Direction::UPLEFT, + } } diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index 92190be..b003439 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -1,17 +1,139 @@ -use crate::gamedata::Board; +use self::score_checkers::scan; +use crate::gamedata::score_checkers::Direction; -use super::Disk; +use super::*; + +// #[test] +// fn board_default() { +// unimplemented!() +// } -#[test] -fn board_default() { - assert_eq!(7, Board::default().columns.len()) -} #[test] fn play() { let mut board = Board::default(); - assert!(board.columns.get(0).expect("Nah").is_empty()); - board.play(Disk::BLUE, 0); - assert_eq!(1, board.columns[0].len()); - board.play(Disk::RED, 0); - assert_eq!(2, board.columns[0].len()); + assert!(board.play(Disk::BLU, 0)); + assert!(board.play(Disk::BLU, 0)); + assert!(board.play(Disk::BLU, 0)); + assert!(board.play(Disk::BLU, 0)); + assert_eq!(1, board.blu_score); + assert!(board.play(Disk::BLU, 0)); + assert!(board.play(Disk::BLU, 0)); + assert!(!board.play(Disk::BLU, 0)); + + assert!(board.play(Disk::BLU, 1)); + assert!(board.play(Disk::BLU, 1)); + assert!(board.play(Disk::BLU, 1)); + assert!(board.play(Disk::BLU, 1)); + assert!(board.play(Disk::BLU, 1)); + assert!(board.play(Disk::BLU, 1)); + assert!(!board.play(Disk::BLU, 1)); + + assert!(board.play(Disk::BLU, 2)); + assert!(board.play(Disk::BLU, 2)); + assert!(board.play(Disk::BLU, 2)); + assert!(board.play(Disk::BLU, 2)); + assert!(board.play(Disk::BLU, 2)); + assert!(board.play(Disk::BLU, 2)); + assert!(!board.play(Disk::BLU, 2)); + + assert!(board.play(Disk::BLU, 3)); + assert!(board.play(Disk::BLU, 3)); + assert!(board.play(Disk::BLU, 3)); + assert!(board.play(Disk::BLU, 3)); + assert!(board.play(Disk::BLU, 3)); + assert!(board.play(Disk::BLU, 3)); + assert!(!board.play(Disk::BLU, 3)); +} +#[test] +fn scan_updown() { + let mut board = Board::default(); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 0); + assert_eq!(4, scan(&board.columns, &(4, 0), Direction::DOWN, 4)); + assert_eq!(4, scan(&board.columns, &(3, 0), Direction::DOWN, 4)); +} +#[test] +fn scan_updown2() { + let mut board = Board::default(); + board.play(Disk::BLU, 0); + board.play(Disk::RED, 0); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 0); + assert_eq!(1, scan(&board.columns, &(0, 0), Direction::UP, 4)); +} +#[test] +fn scan_forwardback() { + let mut board = Board::default(); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 1); + board.play(Disk::BLU, 2); + board.play(Disk::BLU, 3); + + assert_eq!(4, scan(&board.columns, &(0, 0), Direction::RIGHT, 4)); + assert_eq!(4, scan(&board.columns, &(0, 3), Direction::LEFT, 4)); +} +#[test] +fn scan_forwardback2() { + let mut board = Board::default(); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 1); + board.play(Disk::RED, 2); + board.play(Disk::BLU, 3); + assert_eq!(2, scan(&board.columns, &(0, 0), Direction::RIGHT, 4)); + assert_eq!(1, scan(&board.columns, &(0, 3), Direction::LEFT, 4)); +} +#[test] +fn scan_diag1() { + let mut board = Board::default(); + board.play(Disk::BLU, 0); + board.play(Disk::RED, 1); + board.play(Disk::BLU, 1); + board.play(Disk::RED, 2); + board.play(Disk::RED, 2); + board.play(Disk::BLU, 2); + board.play(Disk::RED, 3); + board.play(Disk::RED, 3); + board.play(Disk::RED, 3); + board.play(Disk::BLU, 3); + assert_eq!(4, scan(&board.columns, &(0, 0), Direction::UPRIGHT, 4)); + assert_eq!(4, scan(&board.columns, &(3, 3), Direction::DOWNLEFT, 4)); +} +#[test] +fn scan_diag2() { + let mut board = Board::default(); + board.play(Disk::BLU, 3); + board.play(Disk::RED, 2); + board.play(Disk::BLU, 2); + board.play(Disk::RED, 1); + board.play(Disk::RED, 1); + board.play(Disk::BLU, 1); + board.play(Disk::RED, 0); + board.play(Disk::RED, 0); + board.play(Disk::RED, 0); + board.play(Disk::BLU, 0); + dbg!(&board.columns.as_columns()); + assert_eq!(4, scan(&board.columns, &(0, 3), Direction::UPLEFT, 4)); + assert_eq!(4, scan(&board.columns, &(3, 0), Direction::DOWNRIGHT, 4)); +} +#[test] +fn variant_eq_test() { + assert!(score_checkers::variant_eq(&Disk::RED, &Disk::RED)); + assert!(matches!(Disk::RED, Disk::RED)); + assert!(matches!(&Disk::BLU, &Disk::BLU)); + assert!(!score_checkers::variant_eq(&Disk::BLU, &Disk::RED)); + assert!(!matches!(Disk::BLU, Disk::RED)); +} +#[test] +fn game_over_test() { + let mut board = Board::default(); + assert!(!board.game_over()); + board.columns = Array2D::filled_with(Disk::BLU, 7, 6); + assert!(board.game_over()); + board.columns.set(0, 0, Disk::EMPTY).expect("balls"); + assert!(!board.game_over()); } diff --git a/src/main.rs b/src/main.rs index 3eb4a0a..6d200cf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,10 +2,18 @@ use raylib::prelude::*; fn main() { let (mut rl, thread) = raylib::init().size(640, 480).title("Hello, World").build(); - while !rl.window_should_close() { - let mut d = rl.begin_drawing(&thread); + let _rust_orange = Color::new(222, 165, 132, 255); + let _ray_white = Color::new(255, 255, 255, 255); + rl.set_target_fps(60); + while !rl.window_should_close() { + let pressed_key = rl.get_key_pressed(); + let mut d = rl.begin_drawing(&thread); d.clear_background(Color::WHITE); - d.draw_text("Hello, world!", 12, 12, 20, Color::BLACK); + if let Some(pressed_key) = pressed_key { + // Certain keyboards may have keys raylib does not expect. Uncomment this line if so. + // let pressed_key: u32 = unsafe { std::mem::transmute(pressed_key) }; + d.draw_text(&format!("{:?}", pressed_key), 100, 12, 10, Color::BLACK); + } } }