From f863fe7485dea3c85081df96edcc66442b4fb1a7 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Mon, 1 May 2023 00:26:44 +0300 Subject: [PATCH 01/45] tests :D --- src/gamedata/tests.rs | 71 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index 92190be..48dc54d 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -1,17 +1,68 @@ -use crate::gamedata::Board; +use crate::gamedata::{ + score_checkers::{one_direction, Direction}, + Board, +}; use super::Disk; -#[test] -fn board_default() { - assert_eq!(7, Board::default().columns.len()) -} +// #[test] +// fn board_default() { +// unimplemented!() +// } + #[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::BLUE, 0)); + assert!(board.play(Disk::BLUE, 0)); + assert!(board.play(Disk::BLUE, 0)); + assert!(board.play(Disk::BLUE, 0)); + assert!(board.play(Disk::BLUE, 0)); + assert!(board.play(Disk::BLUE, 0)); + assert!(board.play(Disk::BLUE, 0)); + assert!(!board.play(Disk::BLUE, 0)); + + assert!(board.play(Disk::BLUE, 1)); + assert!(board.play(Disk::BLUE, 1)); + assert!(board.play(Disk::BLUE, 1)); + assert!(board.play(Disk::BLUE, 1)); + assert!(board.play(Disk::BLUE, 1)); + assert!(board.play(Disk::BLUE, 1)); + assert!(board.play(Disk::BLUE, 1)); + assert!(!board.play(Disk::BLUE, 1)); + + assert!(board.play(Disk::BLUE, 2)); + assert!(board.play(Disk::BLUE, 2)); + assert!(board.play(Disk::BLUE, 2)); + assert!(board.play(Disk::BLUE, 2)); + assert!(board.play(Disk::BLUE, 2)); + assert!(board.play(Disk::BLUE, 2)); + assert!(board.play(Disk::BLUE, 2)); + assert!(!board.play(Disk::BLUE, 2)); + + assert!(board.play(Disk::BLUE, 3)); + assert!(board.play(Disk::BLUE, 3)); + assert!(board.play(Disk::BLUE, 3)); + assert!(board.play(Disk::BLUE, 3)); + assert!(board.play(Disk::BLUE, 3)); + assert!(board.play(Disk::BLUE, 3)); + assert!(board.play(Disk::BLUE, 3)); + assert!(!board.play(Disk::BLUE, 3)); +} +#[test] +fn one_direction_test() { + let mut board_true = Board::default(); + let board_false = Board::default(); + board_true.play(Disk::BLUE, 0); + board_true.play(Disk::BLUE, 0); + board_true.play(Disk::BLUE, 0); + board_true.play(Disk::BLUE, 0); + assert_eq!( + 1, + one_direction(&board_true.columns, &(3, 0), Direction::BACKWARD) + ); + assert_eq!( + 0, + one_direction(&board_false.columns, &(3, 0), Direction::BACKWARD) + ); } From c5a49aa3d4779825d7cd9b6923adfbd0b82b89a1 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Mon, 1 May 2023 22:27:08 +0300 Subject: [PATCH 02/45] score checkers work (made a function for variant checking) --- src/gamedata/score_checkers.rs | 66 ++++++++++++++++++++++++++++++---- src/gamedata/tests.rs | 53 ++++++++++++++++++++++----- 2 files changed, 104 insertions(+), 15 deletions(-) diff --git a/src/gamedata/score_checkers.rs b/src/gamedata/score_checkers.rs index 8956f7b..c96c18f 100644 --- a/src/gamedata/score_checkers.rs +++ b/src/gamedata/score_checkers.rs @@ -3,30 +3,76 @@ use array2d::Array2D; use super::Disk; pub fn one_direction(board: &Array2D, index: &(usize, usize), direction: Direction) -> i32 { - let current_disk = board.get(index.0, index.1); + 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); match board.get(current_index.0, current_index.1) { Some(_disk) => { - if matches!(current_disk, _disk) && !matches!(_disk, Disk::EMPTY) { + if variant_eq(current_disk, _disk) && !matches!(_disk, Disk::EMPTY) { + dbg!(current_index, in_a_row, current_disk, _disk); // add in a row by 1 in_a_row += 1; //go to next element match direction { - Direction::BACKWARD => { + Direction::DOWN => { if current_index.0 == 0 { break; } current_index.0 -= 1; } - Direction::FORWARD => { - if current_index.0 == board.num_rows() - 1 { + Direction::UP => { + if current_index.0 == board.num_columns() - 1 { break; } current_index.0 += 1; } + Direction::BACKWARD => { + if current_index.1 == 0 { + break; + } + current_index.1 -= 1; + } + Direction::FORWARD => { + if current_index.1 == board.num_rows() - 1 { + break; + } + current_index.1 += 1; + } + Direction::UPFORW => { + if current_index.0 == board.num_columns() - 1 + || current_index.1 == board.num_rows() - 1 + { + break; + } + current_index.1 += 1; + current_index.0 += 1; + } + Direction::UPBACK => { + if current_index.0 == 0 || current_index.1 == board.num_rows() - 1 { + break; + } + current_index.1 -= 1; + current_index.0 += 1; + } + Direction::DOWNFORW => { + if current_index.1 == 0 || current_index.0 == board.num_columns() - 1 { + break; + } + current_index.1 += 1; + current_index.0 -= 1; + } + Direction::DOWNBACK => { + if current_index.1 == 0 || current_index.0 == 0 { + break; + } + current_index.1 -= 1; + current_index.0 -= 1; + } } } else { break; @@ -36,6 +82,7 @@ pub fn one_direction(board: &Array2D, index: &(usize, usize), direction: D None => break, } } + dbg!(in_a_row); if in_a_row == 4 { //score added return 1; @@ -63,5 +110,12 @@ pub enum Direction { DOWN, FORWARD, BACKWARD, + UPFORW, + UPBACK, + DOWNFORW, + DOWNBACK, //TODO add more directions for diagonals } +fn variant_eq(a: &T, b: &T) -> bool { + std::mem::discriminant(a) == std::mem::discriminant(b) +} diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index 48dc54d..1686e2b 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -50,19 +50,54 @@ fn play() { assert!(!board.play(Disk::BLUE, 3)); } #[test] -fn one_direction_test() { - let mut board_true = Board::default(); - let board_false = Board::default(); - board_true.play(Disk::BLUE, 0); - board_true.play(Disk::BLUE, 0); - board_true.play(Disk::BLUE, 0); - board_true.play(Disk::BLUE, 0); +fn one_direction_updown() { + let mut board = Board::default(); + board.play(Disk::BLUE, 0); + board.play(Disk::BLUE, 0); + board.play(Disk::BLUE, 0); + board.play(Disk::BLUE, 0); + assert_eq!(1, one_direction(&board.columns, &(3, 0), Direction::DOWN)); +} +#[test] +fn one_direction_updown2() { + let mut board = Board::default(); + board.play(Disk::BLUE, 0); + board.play(Disk::RED, 0); + board.play(Disk::BLUE, 0); + board.play(Disk::BLUE, 0); + assert_eq!(0, one_direction(&board.columns, &(3, 0), Direction::DOWN)); +} +#[test] +fn one_direction_forwardback() { + let mut board = Board::default(); + board.play(Disk::BLUE, 0); + board.play(Disk::BLUE, 1); + board.play(Disk::BLUE, 2); + board.play(Disk::BLUE, 3); + + assert!(!matches!(Disk::RED, Disk::BLUE)); assert_eq!( 1, - one_direction(&board_true.columns, &(3, 0), Direction::BACKWARD) + one_direction(&board.columns, &(0, 0), Direction::FORWARD) + ); + assert_eq!( + 1, + one_direction(&board.columns, &(0, 3), Direction::BACKWARD) + ); +} +#[test] +fn one_direction_forwardback2() { + let mut board = Board::default(); + board.play(Disk::BLUE, 0); + board.play(Disk::BLUE, 1); + board.play(Disk::BLUE, 3); + board.play(Disk::RED, 2); + assert_eq!( + 0, + one_direction(&board.columns, &(0, 0), Direction::FORWARD) ); assert_eq!( 0, - one_direction(&board_false.columns, &(3, 0), Direction::BACKWARD) + one_direction(&board.columns, &(0, 3), Direction::BACKWARD) ); } From fbcf6c81e76e9cadac893eaac2b2d892cb6ac790 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Mon, 1 May 2023 22:27:24 +0300 Subject: [PATCH 03/45] derive debug for Disks because I was losing my sanity --- src/gamedata/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gamedata/mod.rs b/src/gamedata/mod.rs index 444ea2f..83f8bcf 100644 --- a/src/gamedata/mod.rs +++ b/src/gamedata/mod.rs @@ -43,11 +43,9 @@ impl Board { } } -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum Disk { RED, BLUE, EMPTY, } - - From 23fc7aa872af4ef3c5de8c5fca99620a8e7be476 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Mon, 1 May 2023 23:18:32 +0300 Subject: [PATCH 04/45] renamed BLUE to BLU for consistency --- src/gamedata/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gamedata/mod.rs b/src/gamedata/mod.rs index 83f8bcf..89250a3 100644 --- a/src/gamedata/mod.rs +++ b/src/gamedata/mod.rs @@ -46,6 +46,6 @@ impl Board { #[derive(Clone, Debug)] pub enum Disk { RED, - BLUE, + BLU, EMPTY, } From f992f2331fd4897275182e50a02001213219b51c Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Mon, 1 May 2023 23:19:31 +0300 Subject: [PATCH 05/45] removed dbgs and hint comments --- src/gamedata/score_checkers.rs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/gamedata/score_checkers.rs b/src/gamedata/score_checkers.rs index c96c18f..4b07f6e 100644 --- a/src/gamedata/score_checkers.rs +++ b/src/gamedata/score_checkers.rs @@ -14,7 +14,6 @@ pub fn one_direction(board: &Array2D, index: &(usize, usize), direction: D match board.get(current_index.0, current_index.1) { Some(_disk) => { if variant_eq(current_disk, _disk) && !matches!(_disk, Disk::EMPTY) { - dbg!(current_index, in_a_row, current_disk, _disk); // add in a row by 1 in_a_row += 1; //go to next element @@ -53,21 +52,21 @@ pub fn one_direction(board: &Array2D, index: &(usize, usize), direction: D current_index.0 += 1; } Direction::UPBACK => { - if current_index.0 == 0 || current_index.1 == board.num_rows() - 1 { + if current_index.0 == board.num_columns() - 1 || current_index.1 == 0 { break; } current_index.1 -= 1; current_index.0 += 1; } Direction::DOWNFORW => { - if current_index.1 == 0 || current_index.0 == board.num_columns() - 1 { + if current_index.0 == 0 || current_index.1 == board.num_columns() - 1 { break; } current_index.1 += 1; current_index.0 -= 1; } Direction::DOWNBACK => { - if current_index.1 == 0 || current_index.0 == 0 { + if current_index.0 == 0 || current_index.1 == 0 { break; } current_index.1 -= 1; @@ -82,7 +81,6 @@ pub fn one_direction(board: &Array2D, index: &(usize, usize), direction: D None => break, } } - dbg!(in_a_row); if in_a_row == 4 { //score added return 1; @@ -98,13 +96,6 @@ pub fn two_direction(board: &Array2D, index: &(usize, usize)) -> i32 { unimplemented!() //+-1 -+2 } -//1 == number -//dbg!() -//println!() -//matches!() -//assert!() - -// for _num 0..n {} pub enum Direction { UP, DOWN, @@ -116,6 +107,7 @@ pub enum Direction { DOWNBACK, //TODO add more directions for diagonals } +// serves nothing except do what matches!() should have done all along fn variant_eq(a: &T, b: &T) -> bool { std::mem::discriminant(a) == std::mem::discriminant(b) } From 733745ef30497886097d0fb55b5588ac25de69aa Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Mon, 1 May 2023 23:19:39 +0300 Subject: [PATCH 06/45] all tests for possible scores --- src/gamedata/tests.rs | 133 +++++++++++++++++++++++++++--------------- 1 file changed, 86 insertions(+), 47 deletions(-) diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index 1686e2b..5118891 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -13,69 +13,69 @@ use super::Disk; #[test] fn play() { let mut board = Board::default(); - assert!(board.play(Disk::BLUE, 0)); - assert!(board.play(Disk::BLUE, 0)); - assert!(board.play(Disk::BLUE, 0)); - assert!(board.play(Disk::BLUE, 0)); - assert!(board.play(Disk::BLUE, 0)); - assert!(board.play(Disk::BLUE, 0)); - assert!(board.play(Disk::BLUE, 0)); - assert!(!board.play(Disk::BLUE, 0)); + 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!(board.play(Disk::BLU, 0)); + assert!(board.play(Disk::BLU, 0)); + assert!(board.play(Disk::BLU, 0)); + assert!(!board.play(Disk::BLU, 0)); - assert!(board.play(Disk::BLUE, 1)); - assert!(board.play(Disk::BLUE, 1)); - assert!(board.play(Disk::BLUE, 1)); - assert!(board.play(Disk::BLUE, 1)); - assert!(board.play(Disk::BLUE, 1)); - assert!(board.play(Disk::BLUE, 1)); - assert!(board.play(Disk::BLUE, 1)); - assert!(!board.play(Disk::BLUE, 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, 1)); + assert!(!board.play(Disk::BLU, 1)); - assert!(board.play(Disk::BLUE, 2)); - assert!(board.play(Disk::BLUE, 2)); - assert!(board.play(Disk::BLUE, 2)); - assert!(board.play(Disk::BLUE, 2)); - assert!(board.play(Disk::BLUE, 2)); - assert!(board.play(Disk::BLUE, 2)); - assert!(board.play(Disk::BLUE, 2)); - assert!(!board.play(Disk::BLUE, 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, 2)); + assert!(!board.play(Disk::BLU, 2)); - assert!(board.play(Disk::BLUE, 3)); - assert!(board.play(Disk::BLUE, 3)); - assert!(board.play(Disk::BLUE, 3)); - assert!(board.play(Disk::BLUE, 3)); - assert!(board.play(Disk::BLUE, 3)); - assert!(board.play(Disk::BLUE, 3)); - assert!(board.play(Disk::BLUE, 3)); - assert!(!board.play(Disk::BLUE, 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)); + assert!(board.play(Disk::BLU, 3)); + assert!(!board.play(Disk::BLU, 3)); } #[test] fn one_direction_updown() { let mut board = Board::default(); - board.play(Disk::BLUE, 0); - board.play(Disk::BLUE, 0); - board.play(Disk::BLUE, 0); - board.play(Disk::BLUE, 0); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 0); assert_eq!(1, one_direction(&board.columns, &(3, 0), Direction::DOWN)); } #[test] fn one_direction_updown2() { let mut board = Board::default(); - board.play(Disk::BLUE, 0); + board.play(Disk::BLU, 0); board.play(Disk::RED, 0); - board.play(Disk::BLUE, 0); - board.play(Disk::BLUE, 0); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 0); assert_eq!(0, one_direction(&board.columns, &(3, 0), Direction::DOWN)); } #[test] fn one_direction_forwardback() { let mut board = Board::default(); - board.play(Disk::BLUE, 0); - board.play(Disk::BLUE, 1); - board.play(Disk::BLUE, 2); - board.play(Disk::BLUE, 3); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 1); + board.play(Disk::BLU, 2); + board.play(Disk::BLU, 3); - assert!(!matches!(Disk::RED, Disk::BLUE)); + assert!(!matches!(Disk::RED, Disk::BLU)); assert_eq!( 1, one_direction(&board.columns, &(0, 0), Direction::FORWARD) @@ -88,9 +88,9 @@ fn one_direction_forwardback() { #[test] fn one_direction_forwardback2() { let mut board = Board::default(); - board.play(Disk::BLUE, 0); - board.play(Disk::BLUE, 1); - board.play(Disk::BLUE, 3); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 1); + board.play(Disk::BLU, 3); board.play(Disk::RED, 2); assert_eq!( 0, @@ -101,3 +101,42 @@ fn one_direction_forwardback2() { one_direction(&board.columns, &(0, 3), Direction::BACKWARD) ); } +#[test] +fn one_direction_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!(1, one_direction(&board.columns, &(0, 0), Direction::UPFORW)); + assert_eq!( + 1, + one_direction(&board.columns, &(3, 3), Direction::DOWNBACK) + ); +} +#[test] +fn one_direction_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!(1, one_direction(&board.columns, &(0, 3), Direction::UPBACK)); + assert_eq!( + 1, + one_direction(&board.columns, &(3, 0), Direction::DOWNFORW) + ); +} From 5def7bdaced85181d28245a27cd5f21de3c25bf2 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Mon, 1 May 2023 23:19:54 +0300 Subject: [PATCH 07/45] why do these even show up here? --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 6985cf1..3f367e5 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ Cargo.lock # MSVC Windows builds of rustc generate these, which store debugging information *.pdb +src/gamedata/.tests.rs.swp +src/gamedata/.score_checkers.rs.swp From 70c08272058f5cfcf5c10c7c5d5bb46e11a99042 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 02:20:13 +0300 Subject: [PATCH 08/45] functional programming --- src/gamedata/mod.rs | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/gamedata/mod.rs b/src/gamedata/mod.rs index 89250a3..7c2b05b 100644 --- a/src/gamedata/mod.rs +++ b/src/gamedata/mod.rs @@ -42,8 +42,46 @@ impl Board { unimplemented!() } } +pub fn get_indices( + index: &(usize, usize), + op: fn(&(usize, usize), usize) -> (usize, usize), + values: Vec, +) -> Vec<(usize, usize)> { + let mut indices: Vec<(usize, usize)> = Vec::with_capacity(3); + for num in values { + indices.push(op(index, num)); + } + indices +} -#[derive(Clone, Debug)] +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) +} + +#[derive(Copy, Clone, Debug)] pub enum Disk { RED, BLU, From 21f8976e5ea8d92436e5167982a51a7204feda14 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 02:20:18 +0300 Subject: [PATCH 09/45] uncommented hardwork :( --- src/gamedata/score_checkers.rs | 212 +++++++++++++++++++-------------- 1 file changed, 121 insertions(+), 91 deletions(-) diff --git a/src/gamedata/score_checkers.rs b/src/gamedata/score_checkers.rs index 4b07f6e..53c4bc5 100644 --- a/src/gamedata/score_checkers.rs +++ b/src/gamedata/score_checkers.rs @@ -1,111 +1,141 @@ use array2d::Array2D; -use super::Disk; +use super::{dec_col, get_indices, inc_col, Disk}; pub fn one_direction(board: &Array2D, index: &(usize, usize), direction: Direction) -> 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; + // for _num in 0..4 { + // match board.get(current_index.0, current_index.1) { + // Some(_disk) => { + // if variant_eq(current_disk, _disk) && !matches!(_disk, Disk::EMPTY) { + // // add in a row by 1 + // in_a_row += 1; + // //go to next element + // match direction { + // Direction::DOWN => { + // if current_index.0 == 0 { + // break; + // } + // current_index.0 -= 1; + // } + // Direction::UP => { + // if current_index.0 == board.num_columns() - 1 { + // break; + // } + // current_index.0 += 1; + // } + // Direction::BACKWARD => { + // if current_index.1 == 0 { + // break; + // } + // current_index.1 -= 1; + // } + // Direction::FORWARD => { + // if current_index.1 == board.num_rows() - 1 { + // break; + // } + // current_index.1 += 1; + // } + // Direction::UPFORW => { + // if current_index.0 == board.num_columns() - 1 + // || current_index.1 == board.num_rows() - 1 + // { + // break; + // } + // current_index.1 += 1; + // current_index.0 += 1; + // } + // Direction::UPBACK => { + // if current_index.0 == board.num_columns() - 1 || current_index.1 == 0 { + // break; + // } + // current_index.1 -= 1; + // current_index.0 += 1; + // } + // Direction::DOWNFORW => { + // if current_index.0 == 0 || current_index.1 == board.num_columns() - 1 { + // break; + // } + // current_index.1 += 1; + // current_index.0 -= 1; + // } + // Direction::DOWNBACK => { + // if current_index.0 == 0 || current_index.1 == 0 { + // break; + // } + // current_index.1 -= 1; + // current_index.0 -= 1; + // } + // } + // } else { + // break; + // } + // } + // + // None => break, + // } + // } + // if in_a_row == 4 { + // //score added + // return 1; + // } else { + // return 0; + // } + // //+-3 + todo!() +} +// board[(2,3)]; + +pub fn two_direction(board: &Array2D, index: &(usize, usize), direction: Direction) -> i32 { + let mut added_score = 0; 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 { - match board.get(current_index.0, current_index.1) { - Some(_disk) => { - if variant_eq(current_disk, _disk) && !matches!(_disk, Disk::EMPTY) { - // add in a row by 1 - in_a_row += 1; - //go to next element - match direction { - Direction::DOWN => { - if current_index.0 == 0 { - break; - } - current_index.0 -= 1; - } - Direction::UP => { - if current_index.0 == board.num_columns() - 1 { - break; - } - current_index.0 += 1; - } - Direction::BACKWARD => { - if current_index.1 == 0 { - break; - } - current_index.1 -= 1; - } - Direction::FORWARD => { - if current_index.1 == board.num_rows() - 1 { - break; - } - current_index.1 += 1; - } - Direction::UPFORW => { - if current_index.0 == board.num_columns() - 1 - || current_index.1 == board.num_rows() - 1 - { - break; - } - current_index.1 += 1; - current_index.0 += 1; - } - Direction::UPBACK => { - if current_index.0 == board.num_columns() - 1 || current_index.1 == 0 { - break; - } - current_index.1 -= 1; - current_index.0 += 1; - } - Direction::DOWNFORW => { - if current_index.0 == 0 || current_index.1 == board.num_columns() - 1 { - break; - } - current_index.1 += 1; - current_index.0 -= 1; - } - Direction::DOWNBACK => { - if current_index.0 == 0 || current_index.1 == 0 { - break; - } - current_index.1 -= 1; - current_index.0 -= 1; - } - } - } else { - break; + match direction { + Direction::HORIZONTAL => { + //get values to increase/decrease by + let two = vec![1, 2]; + let one = vec![1]; + //get surrounding indices + let mut indices: Vec<(usize, usize)> = vec![]; + indices.append(&mut get_indices(index, inc_col, two)); + indices.append(&mut get_indices(index, dec_col, one)); + dbg!(indices.clone()); + let mut neighbours: Vec = vec![]; + //get neighbours + for index in indices { + match board.get(index.0, index.1) { + Some(disk) => neighbours.push(*disk), + None => break, } } + let in_a_row = neighbours + .iter() + .filter(|&a| variant_eq(a, current_disk)) + .count(); + if in_a_row == 3 { + added_score += 1; + } - None => break, + added_score } + Direction::VERTICAL => todo!(), + Direction::DIAGONAL => todo!(), } - if in_a_row == 4 { - //score added - return 1; - } else { - return 0; - } - //+-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 enum Direction { - UP, - DOWN, - FORWARD, - BACKWARD, - UPFORW, - UPBACK, - DOWNFORW, - DOWNBACK, - //TODO add more directions for diagonals + HORIZONTAL, + VERTICAL, + DIAGONAL, } // serves nothing except do what matches!() should have done all along fn variant_eq(a: &T, b: &T) -> bool { From 5225821adc66e014cadaf1f97c1915e42aa7b16a Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 02:20:22 +0300 Subject: [PATCH 10/45] tests that work...gone --- src/gamedata/tests.rs | 92 +++++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 35 deletions(-) diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index 5118891..2fba6ad 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -1,9 +1,6 @@ -use crate::gamedata::{ - score_checkers::{one_direction, Direction}, - Board, -}; +use crate::gamedata::{dec_col, score_checkers::Direction, Board}; -use super::Disk; +use super::{get_indices, inc_col, score_checkers::two_direction, Disk}; // #[test] // fn board_default() { @@ -56,7 +53,11 @@ fn one_direction_updown() { board.play(Disk::BLU, 0); board.play(Disk::BLU, 0); board.play(Disk::BLU, 0); - assert_eq!(1, one_direction(&board.columns, &(3, 0), Direction::DOWN)); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 0); + board.play(Disk::BLU, 0); + // assert_eq!(1, one_direction(&board.columns, &(4, 0), Direction::DOWN)); + // assert_eq!(1, one_direction(&board.columns, &(3, 0), Direction::DOWN)); } #[test] fn one_direction_updown2() { @@ -65,7 +66,7 @@ fn one_direction_updown2() { board.play(Disk::RED, 0); board.play(Disk::BLU, 0); board.play(Disk::BLU, 0); - assert_eq!(0, one_direction(&board.columns, &(3, 0), Direction::DOWN)); + // assert_eq!(0, one_direction(&board.columns, &(3, 0), Direction::DOWN)); } #[test] fn one_direction_forwardback() { @@ -75,31 +76,31 @@ fn one_direction_forwardback() { board.play(Disk::BLU, 2); board.play(Disk::BLU, 3); - assert!(!matches!(Disk::RED, Disk::BLU)); - assert_eq!( - 1, - one_direction(&board.columns, &(0, 0), Direction::FORWARD) - ); - assert_eq!( - 1, - one_direction(&board.columns, &(0, 3), Direction::BACKWARD) - ); + // assert!(!matches!(Disk::RED, Disk::BLU)); + // assert_eq!( + // 1, + // one_direction(&board.columns, &(0, 0), Direction::FORWARD) + // ); + // assert_eq!( + // 1, + // one_direction(&board.columns, &(0, 3), Direction::BACKWARD) + // ); } #[test] fn one_direction_forwardback2() { let mut board = Board::default(); board.play(Disk::BLU, 0); board.play(Disk::BLU, 1); - board.play(Disk::BLU, 3); board.play(Disk::RED, 2); - assert_eq!( - 0, - one_direction(&board.columns, &(0, 0), Direction::FORWARD) - ); - assert_eq!( - 0, - one_direction(&board.columns, &(0, 3), Direction::BACKWARD) - ); + board.play(Disk::BLU, 3); + // assert_eq!( + // 0, + // one_direction(&board.columns, &(0, 0), Direction::FORWARD) + // ); + // assert_eq!( + // 0, + // one_direction(&board.columns, &(0, 3), Direction::BACKWARD) + // ); } #[test] fn one_direction_diag1() { @@ -114,11 +115,11 @@ fn one_direction_diag1() { board.play(Disk::RED, 3); board.play(Disk::RED, 3); board.play(Disk::BLU, 3); - assert_eq!(1, one_direction(&board.columns, &(0, 0), Direction::UPFORW)); - assert_eq!( - 1, - one_direction(&board.columns, &(3, 3), Direction::DOWNBACK) - ); + // assert_eq!(1, one_direction(&board.columns, &(0, 0), Direction::UPFORW)); + // assert_eq!( + // 1, + // one_direction(&board.columns, &(3, 3), Direction::DOWNBACK) + // ); } #[test] fn one_direction_diag2() { @@ -134,9 +135,30 @@ fn one_direction_diag2() { board.play(Disk::RED, 0); board.play(Disk::BLU, 0); dbg!(&board.columns.as_columns()); - assert_eq!(1, one_direction(&board.columns, &(0, 3), Direction::UPBACK)); - assert_eq!( - 1, - one_direction(&board.columns, &(3, 0), Direction::DOWNFORW) - ); + // assert_eq!(1, one_direction(&board.columns, &(0, 3), Direction::UPBACK)); + // assert_eq!( + // 1, + // one_direction(&board.columns, &(3, 0), Direction::DOWNFORW) + // ); +} +#[test] +fn get_indices_test() { + let values: Vec = vec![1, 2]; + let indices = get_indices(&(2, 1), inc_col, values); + assert_eq!(vec![(2, 2), (2, 3)], indices); + let indices = get_indices(&(2, 1), dec_col, vec![1]); + assert_eq!(vec![(2, 0)], indices); +} + +#[test] +fn two_direction_test() { + 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); + board.play(Disk::BLU, 4); + board.play(Disk::BLU, 5); + let added = two_direction(&board.columns, &(0, 3), Direction::HORIZONTAL); + assert_eq!(1, added) } From 1c44006ff418f5d68ec982993f0177b8c68c5e04 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 14:38:15 +0300 Subject: [PATCH 11/45] pls help --- src/gamedata/mod.rs | 24 ++-- src/gamedata/score_checkers.rs | 245 +++++++++++++++++---------------- src/gamedata/tests.rs | 82 ++++------- 3 files changed, 160 insertions(+), 191 deletions(-) diff --git a/src/gamedata/mod.rs b/src/gamedata/mod.rs index 7c2b05b..8900012 100644 --- a/src/gamedata/mod.rs +++ b/src/gamedata/mod.rs @@ -4,7 +4,7 @@ mod tests; use array2d::Array2D; -use self::score_checkers::{one_direction, two_direction}; +use self::score_checkers::scan; #[derive(Clone)] pub struct Board { p1_score: i32, @@ -42,17 +42,17 @@ impl Board { unimplemented!() } } -pub fn get_indices( - index: &(usize, usize), - op: fn(&(usize, usize), usize) -> (usize, usize), - values: Vec, -) -> Vec<(usize, usize)> { - let mut indices: Vec<(usize, usize)> = Vec::with_capacity(3); - for num in values { - indices.push(op(index, num)); - } - indices -} +// pub fn get_indices( +// index: &(usize, usize), +// op: fn(&(usize, usize), usize) -> (usize, usize), +// values: Vec, +// ) -> Vec<(usize, usize)> { +// let mut indices: Vec<(usize, usize)> = Vec::with_capacity(3); +// for num in values { +// indices.push(op(index, num)); +// } +// indices +// } pub fn inc_row((row, col): &(usize, usize), value: usize) -> (usize, usize) { (row + value as usize, *col) diff --git a/src/gamedata/score_checkers.rs b/src/gamedata/score_checkers.rs index 53c4bc5..bb51580 100644 --- a/src/gamedata/score_checkers.rs +++ b/src/gamedata/score_checkers.rs @@ -1,143 +1,144 @@ use array2d::Array2D; -use super::{dec_col, get_indices, inc_col, 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: &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; - // for _num in 0..4 { - // match board.get(current_index.0, current_index.1) { - // Some(_disk) => { - // if variant_eq(current_disk, _disk) && !matches!(_disk, Disk::EMPTY) { - // // add in a row by 1 - // in_a_row += 1; - // //go to next element - // match direction { - // Direction::DOWN => { - // if current_index.0 == 0 { - // break; - // } - // current_index.0 -= 1; - // } - // Direction::UP => { - // if current_index.0 == board.num_columns() - 1 { - // break; - // } - // current_index.0 += 1; - // } - // Direction::BACKWARD => { - // if current_index.1 == 0 { - // break; - // } - // current_index.1 -= 1; - // } - // Direction::FORWARD => { - // if current_index.1 == board.num_rows() - 1 { - // break; - // } - // current_index.1 += 1; - // } - // Direction::UPFORW => { - // if current_index.0 == board.num_columns() - 1 - // || current_index.1 == board.num_rows() - 1 - // { - // break; - // } - // current_index.1 += 1; - // current_index.0 += 1; - // } - // Direction::UPBACK => { - // if current_index.0 == board.num_columns() - 1 || current_index.1 == 0 { - // break; - // } - // current_index.1 -= 1; - // current_index.0 += 1; - // } - // Direction::DOWNFORW => { - // if current_index.0 == 0 || current_index.1 == board.num_columns() - 1 { - // break; - // } - // current_index.1 += 1; - // current_index.0 -= 1; - // } - // Direction::DOWNBACK => { - // if current_index.0 == 0 || current_index.1 == 0 { - // break; - // } - // current_index.1 -= 1; - // current_index.0 -= 1; - // } - // } - // } else { - // break; - // } - // } - // - // None => break, - // } - // } - // if in_a_row == 4 { - // //score added - // return 1; - // } else { - // return 0; - // } - // //+-3 - todo!() -} -// board[(2,3)]; +use super::{dec_col, inc_col, Disk}; -pub fn two_direction(board: &Array2D, index: &(usize, usize), direction: Direction) -> i32 { - let mut added_score = 0; +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, }; - match direction { - Direction::HORIZONTAL => { - //get values to increase/decrease by - let two = vec![1, 2]; - let one = vec![1]; - //get surrounding indices - let mut indices: Vec<(usize, usize)> = vec![]; - indices.append(&mut get_indices(index, inc_col, two)); - indices.append(&mut get_indices(index, dec_col, one)); - dbg!(indices.clone()); - let mut neighbours: Vec = vec![]; - //get neighbours - for index in indices { - match board.get(index.0, index.1) { - Some(disk) => neighbours.push(*disk), - None => break, + let mut current_index = *index; + let mut in_a_row = 0; + for _num in 0..depth { + match board.get(current_index.0, current_index.1) { + Some(_disk) => { + dbg!(_disk, current_disk); + 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::DOWN => { + if current_index.0 == 0 { + break; + } + current_index = dec_row(¤t_index, 1); + //current_index.0 -= 1; + } + Direction::UP => { + if current_index.0 == board.num_rows() - 1 { + break; + } + current_index = inc_row(¤t_index, 1); + // current_index.0 += 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 { + break; } } - let in_a_row = neighbours - .iter() - .filter(|&a| variant_eq(a, current_disk)) - .count(); - if in_a_row == 3 { - added_score += 1; - } - added_score + None => break, } - Direction::VERTICAL => todo!(), - Direction::DIAGONAL => todo!(), } + in_a_row + // //+-3 +} +// board[(2,3)]; +pub fn get_legal_moves( + (row, col): &(usize, usize), + direction: Direction, + (nrow, ncol): (usize, usize), +) -> Vec { + let max_col = nrow - 1; + let max_row = ncol - 1; + let mut moves: Vec = vec![]; + match *row { + 0 => moves.push(Direction::UP), + max_row => moves.push(Direction::DOWN), + _ => { + moves.push(Direction::UP); + moves.push(Direction::DOWN); + } + }; + match *col { + 0 => moves.push(Direction::RIGHT), + max_row => moves.push(Direction::LEFT), + _ => { + moves.push(Direction::LEFT); + moves.push(Direction::RIGHT) + } + }; + moves } pub enum Direction { - HORIZONTAL, - VERTICAL, - DIAGONAL, + UP, + DOWN, + LEFT, + RIGHT, + UPLEFT, + UPRIGHT, + DOWNLEFT, + DOWNRIGHT, } // serves nothing except do what matches!() should have done all along -fn variant_eq(a: &T, b: &T) -> bool { +pub fn variant_eq(a: &T, b: &T) -> bool { std::mem::discriminant(a) == std::mem::discriminant(b) } diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index 2fba6ad..fc4a15e 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -1,6 +1,6 @@ -use crate::gamedata::{dec_col, score_checkers::Direction, Board}; +use crate::gamedata::score_checkers::Direction; -use super::{get_indices, inc_col, score_checkers::two_direction, Disk}; +use super::*; // #[test] // fn board_default() { @@ -47,7 +47,7 @@ fn play() { assert!(!board.play(Disk::BLU, 3)); } #[test] -fn one_direction_updown() { +fn scan_updown() { let mut board = Board::default(); board.play(Disk::BLU, 0); board.play(Disk::BLU, 0); @@ -56,54 +56,42 @@ fn one_direction_updown() { board.play(Disk::BLU, 0); board.play(Disk::BLU, 0); board.play(Disk::BLU, 0); - // assert_eq!(1, one_direction(&board.columns, &(4, 0), Direction::DOWN)); - // assert_eq!(1, one_direction(&board.columns, &(3, 0), Direction::DOWN)); + assert_eq!(3, scan(&board.columns, &(4, 0), Direction::DOWN, 3)); + assert_eq!(3, scan(&board.columns, &(3, 0), Direction::DOWN, 3)); } #[test] -fn one_direction_updown2() { +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!(0, one_direction(&board.columns, &(3, 0), Direction::DOWN)); + assert_eq!(0, scan(&board.columns, &(0, 0), Direction::UP, 3)); } #[test] -fn one_direction_forwardback() { +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!(!matches!(Disk::RED, Disk::BLU)); - // assert_eq!( - // 1, - // one_direction(&board.columns, &(0, 0), Direction::FORWARD) - // ); - // assert_eq!( - // 1, - // one_direction(&board.columns, &(0, 3), Direction::BACKWARD) - // ); + assert!(!matches!(Disk::RED, Disk::BLU)); + assert_eq!(1, scan(&board.columns, &(0, 0), Direction::RIGHT, 3)); + assert_eq!(1, scan(&board.columns, &(0, 3), Direction::LEFT, 3)); } #[test] -fn one_direction_forwardback2() { +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!( - // 0, - // one_direction(&board.columns, &(0, 0), Direction::FORWARD) - // ); - // assert_eq!( - // 0, - // one_direction(&board.columns, &(0, 3), Direction::BACKWARD) - // ); + assert_eq!(0, scan(&board.columns, &(0, 0), Direction::RIGHT, 3)); + assert_eq!(0, scan(&board.columns, &(0, 3), Direction::LEFT, 3)); } #[test] -fn one_direction_diag1() { +fn scan_diag1() { let mut board = Board::default(); board.play(Disk::BLU, 0); board.play(Disk::RED, 1); @@ -115,14 +103,11 @@ fn one_direction_diag1() { board.play(Disk::RED, 3); board.play(Disk::RED, 3); board.play(Disk::BLU, 3); - // assert_eq!(1, one_direction(&board.columns, &(0, 0), Direction::UPFORW)); - // assert_eq!( - // 1, - // one_direction(&board.columns, &(3, 3), Direction::DOWNBACK) - // ); + assert_eq!(1, scan(&board.columns, &(0, 0), Direction::UPRIGHT, 3)); + assert_eq!(1, scan(&board.columns, &(3, 3), Direction::DOWNLEFT, 3)); } #[test] -fn one_direction_diag2() { +fn scan_diag2() { let mut board = Board::default(); board.play(Disk::BLU, 3); board.play(Disk::RED, 2); @@ -135,30 +120,13 @@ fn one_direction_diag2() { board.play(Disk::RED, 0); board.play(Disk::BLU, 0); dbg!(&board.columns.as_columns()); - // assert_eq!(1, one_direction(&board.columns, &(0, 3), Direction::UPBACK)); - // assert_eq!( - // 1, - // one_direction(&board.columns, &(3, 0), Direction::DOWNFORW) - // ); + assert_eq!(1, scan(&board.columns, &(0, 3), Direction::UPLEFT, 3)); + assert_eq!(1, scan(&board.columns, &(3, 0), Direction::DOWNRIGHT, 3)); } #[test] -fn get_indices_test() { - let values: Vec = vec![1, 2]; - let indices = get_indices(&(2, 1), inc_col, values); - assert_eq!(vec![(2, 2), (2, 3)], indices); - let indices = get_indices(&(2, 1), dec_col, vec![1]); - assert_eq!(vec![(2, 0)], indices); -} - -#[test] -fn two_direction_test() { - 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); - board.play(Disk::BLU, 4); - board.play(Disk::BLU, 5); - let added = two_direction(&board.columns, &(0, 3), Direction::HORIZONTAL); - assert_eq!(1, added) +fn variant_eq_test() { + assert!(score_checkers::variant_eq(&Disk::RED, &Disk::RED)); + assert!(matches!(Disk::RED, Disk::RED)); + assert!(!score_checkers::variant_eq(&Disk::BLU, &Disk::RED)); + assert!(!matches!(Disk::BLU, Disk::RED)); } From dd22d7f63a9ed2e1387d13c3b23865698805dbc6 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 17:35:00 +0300 Subject: [PATCH 12/45] more debugging in case --- src/gamedata/score_checkers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gamedata/score_checkers.rs b/src/gamedata/score_checkers.rs index bb51580..909613b 100644 --- a/src/gamedata/score_checkers.rs +++ b/src/gamedata/score_checkers.rs @@ -20,7 +20,7 @@ pub fn scan( for _num in 0..depth { match board.get(current_index.0, current_index.1) { Some(_disk) => { - dbg!(_disk, current_disk); + 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; From 3d3d6fb3f9baa802a64944e20782644797365514 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 17:35:03 +0300 Subject: [PATCH 13/45] all tests passed :D --- src/gamedata/tests.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index fc4a15e..d7a825d 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -56,8 +56,8 @@ fn scan_updown() { board.play(Disk::BLU, 0); board.play(Disk::BLU, 0); board.play(Disk::BLU, 0); - assert_eq!(3, scan(&board.columns, &(4, 0), Direction::DOWN, 3)); - assert_eq!(3, scan(&board.columns, &(3, 0), Direction::DOWN, 3)); + 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() { @@ -66,7 +66,7 @@ fn scan_updown2() { board.play(Disk::RED, 0); board.play(Disk::BLU, 0); board.play(Disk::BLU, 0); - assert_eq!(0, scan(&board.columns, &(0, 0), Direction::UP, 3)); + assert_eq!(1, scan(&board.columns, &(0, 0), Direction::UP, 4)); } #[test] fn scan_forwardback() { @@ -76,9 +76,8 @@ fn scan_forwardback() { board.play(Disk::BLU, 2); board.play(Disk::BLU, 3); - assert!(!matches!(Disk::RED, Disk::BLU)); - assert_eq!(1, scan(&board.columns, &(0, 0), Direction::RIGHT, 3)); - assert_eq!(1, scan(&board.columns, &(0, 3), Direction::LEFT, 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() { @@ -87,8 +86,8 @@ fn scan_forwardback2() { board.play(Disk::BLU, 1); board.play(Disk::RED, 2); board.play(Disk::BLU, 3); - assert_eq!(0, scan(&board.columns, &(0, 0), Direction::RIGHT, 3)); - assert_eq!(0, scan(&board.columns, &(0, 3), Direction::LEFT, 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() { @@ -103,8 +102,8 @@ fn scan_diag1() { board.play(Disk::RED, 3); board.play(Disk::RED, 3); board.play(Disk::BLU, 3); - assert_eq!(1, scan(&board.columns, &(0, 0), Direction::UPRIGHT, 3)); - assert_eq!(1, scan(&board.columns, &(3, 3), Direction::DOWNLEFT, 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() { @@ -120,8 +119,8 @@ fn scan_diag2() { board.play(Disk::RED, 0); board.play(Disk::BLU, 0); dbg!(&board.columns.as_columns()); - assert_eq!(1, scan(&board.columns, &(0, 3), Direction::UPLEFT, 3)); - assert_eq!(1, scan(&board.columns, &(3, 0), Direction::DOWNRIGHT, 3)); + 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() { From 9deef3ba5b3500c15aa0eb2e0255abcf47d924a3 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 17:55:41 +0300 Subject: [PATCH 14/45] migrated index manipulation functions to a new file --- src/gamedata/indices.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/gamedata/indices.rs 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) +} From 5bc294388f2edf641c6ca8819d8dbae4e5cea1f6 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 17:55:53 +0300 Subject: [PATCH 15/45] public use for indices for the module :D --- src/gamedata/mod.rs | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/src/gamedata/mod.rs b/src/gamedata/mod.rs index 8900012..6451efd 100644 --- a/src/gamedata/mod.rs +++ b/src/gamedata/mod.rs @@ -1,8 +1,10 @@ +mod indices; mod score_checkers; #[cfg(test)] mod tests; use array2d::Array2D; +pub use indices::*; use self::score_checkers::scan; #[derive(Clone)] @@ -41,6 +43,14 @@ impl Board { fn score_check(&mut self, index: (usize, usize)) { unimplemented!() } + fn game_over(&self) -> bool { + self.columns + .as_row_major() + .iter() + .filter(|&d| matches!(d, &Disk::EMPTY)) + .count() + == 0 + } } // pub fn get_indices( // index: &(usize, usize), @@ -54,33 +64,6 @@ impl Board { // indices // } -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) -} - #[derive(Copy, Clone, Debug)] pub enum Disk { RED, From 32592e45474c44d04b71cbb1daecad1731def93c Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 17:56:14 +0300 Subject: [PATCH 16/45] game over test and one more variant assertion --- src/gamedata/tests.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index d7a825d..5b6b133 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -126,6 +126,16 @@ fn scan_diag2() { 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()); +} From a8f0ed948f3909902f094b79156deb564d605ed0 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 17:56:23 +0300 Subject: [PATCH 17/45] ignore this --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 3f367e5..ee86488 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ Cargo.lock *.pdb src/gamedata/.tests.rs.swp src/gamedata/.score_checkers.rs.swp +src/gamedata/.indices.rs.swp +src/gamedata/.mod.rs.swp From f9f150ef5fa358818d6f2c743e00a30f61bef0a5 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 17:59:59 +0300 Subject: [PATCH 18/45] funny comment --- src/gamedata/score_checkers.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gamedata/score_checkers.rs b/src/gamedata/score_checkers.rs index 909613b..da5085e 100644 --- a/src/gamedata/score_checkers.rs +++ b/src/gamedata/score_checkers.rs @@ -139,6 +139,7 @@ pub enum Direction { 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) } From 09899d5a824f74858ce2d08f488b3ae60833ba84 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 18:37:14 +0300 Subject: [PATCH 19/45] accidentally switched up indices --- src/gamedata/score_checkers.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/gamedata/score_checkers.rs b/src/gamedata/score_checkers.rs index da5085e..11f0653 100644 --- a/src/gamedata/score_checkers.rs +++ b/src/gamedata/score_checkers.rs @@ -17,6 +17,7 @@ pub fn scan( }; let mut current_index = *index; let mut in_a_row = 0; + dbg!("Starting new thing", &direction); for _num in 0..depth { match board.get(current_index.0, current_index.1) { Some(_disk) => { @@ -103,13 +104,12 @@ pub fn scan( // board[(2,3)]; pub fn get_legal_moves( (row, col): &(usize, usize), - direction: Direction, (nrow, ncol): (usize, usize), ) -> Vec { let max_col = nrow - 1; let max_row = ncol - 1; let mut moves: Vec = vec![]; - match *row { + match *col { 0 => moves.push(Direction::UP), max_row => moves.push(Direction::DOWN), _ => { @@ -117,7 +117,7 @@ pub fn get_legal_moves( moves.push(Direction::DOWN); } }; - match *col { + match *row { 0 => moves.push(Direction::RIGHT), max_row => moves.push(Direction::LEFT), _ => { @@ -128,6 +128,7 @@ pub fn get_legal_moves( moves } +#[derive(Clone, Debug)] pub enum Direction { UP, DOWN, @@ -143,3 +144,15 @@ pub enum Direction { 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, + } +} From 769d40af39bde9e5b2c5d9e7ded02e3dcdbbed4c Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 18:37:24 +0300 Subject: [PATCH 20/45] refactored scores to make sense and check on each insertion :D --- src/gamedata/mod.rs | 61 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/src/gamedata/mod.rs b/src/gamedata/mod.rs index 6451efd..58f44f8 100644 --- a/src/gamedata/mod.rs +++ b/src/gamedata/mod.rs @@ -9,8 +9,8 @@ pub use indices::*; use self::score_checkers::scan; #[derive(Clone)] pub struct Board { - p1_score: i32, - p2_score: i32, + red_score: i32, + blu_score: i32, columns: Array2D, } @@ -19,8 +19,8 @@ impl Default for Board { let columns = Array2D::filled_with(Disk::EMPTY, 7, 6); Self { - p1_score: 0, - p2_score: 0, + red_score: 0, + blu_score: 0, columns, } } @@ -28,20 +28,65 @@ 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 From ace98c4e3ff1034b4b89633ef4baf569483aeb0f Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 18:37:32 +0300 Subject: [PATCH 21/45] one test for the one test --- src/gamedata/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index 5b6b133..7b56817 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -14,6 +14,7 @@ fn play() { 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)); From dc6cdff3783b449dbb15bc25792c0ff4850d1194 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 19:08:05 +0300 Subject: [PATCH 22/45] diagonal added to legal moves --- src/gamedata/score_checkers.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/gamedata/score_checkers.rs b/src/gamedata/score_checkers.rs index 11f0653..33b3b16 100644 --- a/src/gamedata/score_checkers.rs +++ b/src/gamedata/score_checkers.rs @@ -125,10 +125,22 @@ pub fn get_legal_moves( 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 } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum Direction { UP, DOWN, From e4bd4ae90342668f563fc329e8df37b525507250 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 19:08:12 +0300 Subject: [PATCH 23/45] test to ensure that diagonal scores are ensured --- src/gamedata/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index 7b56817..50c7711 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -122,6 +122,7 @@ fn scan_diag2() { 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)); + assert_eq!(1, board.blu_score); } #[test] fn variant_eq_test() { From 5af58857467abc60f04e227dd589e2232864a163 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 19:13:19 +0300 Subject: [PATCH 24/45] comment out dbgs --- src/gamedata/score_checkers.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gamedata/score_checkers.rs b/src/gamedata/score_checkers.rs index 33b3b16..05fdd89 100644 --- a/src/gamedata/score_checkers.rs +++ b/src/gamedata/score_checkers.rs @@ -17,15 +17,15 @@ pub fn scan( }; let mut current_index = *index; let mut in_a_row = 0; - dbg!("Starting new thing", &direction); + // 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); + // 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); + // dbg!(current_index); //go to next element match direction { Direction::DOWN => { From ead76cef1a357c5e93e73ee32b83523853faf255 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 20:35:04 +0300 Subject: [PATCH 25/45] heuristic file oh boy --- src/gamedata/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gamedata/mod.rs b/src/gamedata/mod.rs index 58f44f8..1ef384b 100644 --- a/src/gamedata/mod.rs +++ b/src/gamedata/mod.rs @@ -1,5 +1,7 @@ +mod heuristic; mod indices; mod score_checkers; + #[cfg(test)] mod tests; From f41b868752fee3814da44582ba4d6e2c15157e7e Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 21:35:15 +0300 Subject: [PATCH 26/45] death to indices --- src/gamedata/mod.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/gamedata/mod.rs b/src/gamedata/mod.rs index 1ef384b..9f3e473 100644 --- a/src/gamedata/mod.rs +++ b/src/gamedata/mod.rs @@ -1,7 +1,6 @@ mod heuristic; mod indices; mod score_checkers; - #[cfg(test)] mod tests; @@ -99,17 +98,6 @@ impl Board { == 0 } } -// pub fn get_indices( -// index: &(usize, usize), -// op: fn(&(usize, usize), usize) -> (usize, usize), -// values: Vec, -// ) -> Vec<(usize, usize)> { -// let mut indices: Vec<(usize, usize)> = Vec::with_capacity(3); -// for num in values { -// indices.push(op(index, num)); -// } -// indices -// } #[derive(Copy, Clone, Debug)] pub enum Disk { From 8d07cbb51dd4e3f831134ca187e2e0db8db3ec75 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Tue, 2 May 2023 21:35:22 +0300 Subject: [PATCH 27/45] idkmanpls --- src/gamedata/tests.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index 50c7711..7b56817 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -122,7 +122,6 @@ fn scan_diag2() { 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)); - assert_eq!(1, board.blu_score); } #[test] fn variant_eq_test() { From e016d5f358a8559e4180db5abbedc8bc89e6646e Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Wed, 3 May 2023 00:11:50 +0300 Subject: [PATCH 28/45] heuristic scan (needs tests) and constants --- src/gamedata/heuristic.rs | 113 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/gamedata/heuristic.rs diff --git a/src/gamedata/heuristic.rs b/src/gamedata/heuristic.rs new file mode 100644 index 0000000..25805c2 --- /dev/null +++ b/src/gamedata/heuristic.rs @@ -0,0 +1,113 @@ +use array2d::Array2D; + +use super::{ + dec_both, dec_col, dec_inc, dec_row, inc_both, inc_col, inc_dec, inc_row, + score_checkers::{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) -> i32 { + //this should be summing up a bunch of functions defined below this one + todo!() +} +pub fn potential_wins(board: &Array2D) -> i32 { + //3 of same kind and 4th EMPTY + todo!() +} +pub fn potential_streaks(board: &Array2D) -> i32 { + //This should grab potential streaks (Disk::EMPTY) + todo!() +} +fn heur_scan( + board: &Array2D, + index: &(usize, usize), + direction: Direction, + depth: i32, +) -> Vec { + let current_disk: &Disk; + match board.get(index.0, index.1) { + Some(disk) => current_disk = disk, + 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(current_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 +} From 6e8fed68fd130150ac76d81891fe50e1410bcf50 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Wed, 3 May 2023 00:11:56 +0300 Subject: [PATCH 29/45] removed silly comments --- src/gamedata/score_checkers.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gamedata/score_checkers.rs b/src/gamedata/score_checkers.rs index 05fdd89..9dd25bc 100644 --- a/src/gamedata/score_checkers.rs +++ b/src/gamedata/score_checkers.rs @@ -33,14 +33,12 @@ pub fn scan( break; } current_index = dec_row(¤t_index, 1); - //current_index.0 -= 1; } Direction::UP => { if current_index.0 == board.num_rows() - 1 { break; } current_index = inc_row(¤t_index, 1); - // current_index.0 += 1; } Direction::LEFT => { if current_index.1 == 0 { From 1e45e93a68f90470195cd3ccbb3686e3a5c91b9f Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Wed, 3 May 2023 00:12:11 +0300 Subject: [PATCH 30/45] swapped one raylib sample for another --- src/main.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) 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); + } } } From 9146f5be0b305755a9699e0640f72bea2e011ad9 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Thu, 4 May 2023 14:08:44 +0300 Subject: [PATCH 31/45] feat: heuristic calculations (need tests) --- src/gamedata/heuristic.rs | 56 +++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/src/gamedata/heuristic.rs b/src/gamedata/heuristic.rs index 25805c2..4d7ba37 100644 --- a/src/gamedata/heuristic.rs +++ b/src/gamedata/heuristic.rs @@ -2,7 +2,7 @@ use array2d::Array2D; use super::{ dec_both, dec_col, dec_inc, dec_row, inc_both, inc_col, inc_dec, inc_row, - score_checkers::{variant_eq, Direction}, + score_checkers::{get_legal_moves, variant_eq, Direction}, Board, Disk, }; //multipliers @@ -13,18 +13,58 @@ const POT_WINS: i32 = 8; const SCORE_DIFF: i32 = 6; const MAX_WINS: i32 = 17; -pub fn get_score(board: &Board) -> i32 { +pub fn get_score(board: &Board, disk: Disk) -> i32 { //this should be summing up a bunch of functions defined below this one - todo!() + 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(&board.columns, &disk) + + potential_wins(&board.columns, &disk) + + score * SCORE_DIFF } -pub fn potential_wins(board: &Array2D) -> i32 { - //3 of same kind and 4th EMPTY - todo!() +pub fn potential_wins(board: &Array2D, disk: &Disk) -> i32 { + let pot_wins = get_dups(board, disk); + match pot_wins { + 1 => POT_WIN, + _ => POT_WINS * pot_wins, + } } -pub fn potential_streaks(board: &Array2D) -> i32 { +pub fn potential_streaks(board: &Array2D, disk: &Disk) -> i32 { //This should grab potential streaks (Disk::EMPTY) - todo!() + // get all middle indexes + let streaks = get_dups(board, disk); + match streaks { + 1 => POT_STREAK, + _ => POT_STREAKS * streaks, + } } +fn get_dups(board: &Array2D, _target_disk: &Disk) -> i32 { + let mid_col = (board.num_rows() - 1) / 2; + let mid_indices: Vec<(usize, usize)> = board + .indices_row_major() + .filter(|&index| index.1.eq(&mid_col)) + .collect(); + let mut dups = 0; + for index in mid_indices { + let moves = get_legal_moves(&index, (board.num_rows(), board.num_columns())); + for direction in moves { + let poopy = heur_scan(&board, &index, direction, 4); + match poopy + .iter() + .filter(|&disk| matches!(&disk, _target_disk)) + .count() + { + 3 => dups += 1, + 2 => dups += 1, + _ => {} + } + } + } + dups +} + fn heur_scan( board: &Array2D, index: &(usize, usize), From ef5a6f7ee31b9caa16affe0d9d25032f2573daf5 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Thu, 4 May 2023 17:04:50 +0300 Subject: [PATCH 32/45] started the testing :D --- src/gamedata/tests.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index 7b56817..e975823 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -1,4 +1,4 @@ -use crate::gamedata::score_checkers::Direction; +use crate::gamedata::{heuristic::potential_wins, score_checkers::Direction}; use super::*; @@ -140,3 +140,14 @@ fn game_over_test() { board.columns.set(0, 0, Disk::EMPTY).expect("balls"); assert!(!board.game_over()); } + +#[test] +fn heuristic_pot_wins() { + 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); + assert_eq!(16, potential_wins(&board.columns, &Disk::BLU)); +} From 6b4aa377a0c2e60d99aa5741c29ed17d3b546592 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Thu, 4 May 2023 18:47:07 +0300 Subject: [PATCH 33/45] partial eq for disk --- src/gamedata/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gamedata/mod.rs b/src/gamedata/mod.rs index 9f3e473..2253daa 100644 --- a/src/gamedata/mod.rs +++ b/src/gamedata/mod.rs @@ -99,7 +99,7 @@ impl Board { } } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Disk { RED, BLU, From fef292c69d1fe8b99940a97667e7d1fa4884a1b1 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Thu, 4 May 2023 18:47:18 +0300 Subject: [PATCH 34/45] heuristic potential wins pass :D --- src/gamedata/heuristic.rs | 44 ++++++++++++++++++++++++++------------- src/gamedata/tests.rs | 7 +++++++ 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/gamedata/heuristic.rs b/src/gamedata/heuristic.rs index 4d7ba37..98155f8 100644 --- a/src/gamedata/heuristic.rs +++ b/src/gamedata/heuristic.rs @@ -26,38 +26,52 @@ pub fn get_score(board: &Board, disk: Disk) -> i32 { } pub fn potential_wins(board: &Array2D, disk: &Disk) -> i32 { let pot_wins = get_dups(board, disk); - match pot_wins { + dbg!(&pot_wins); + let mut count: i32 = 0; + for win in pot_wins { + if win + .iter() + .filter(|&_disk| variant_eq(_disk, &Disk::EMPTY)) + .count() + == 1 + && win.len() == 4 + { + count += 1; + } + } + match count { 1 => POT_WIN, - _ => POT_WINS * pot_wins, + _ => POT_WINS * count, } } pub fn potential_streaks(board: &Array2D, disk: &Disk) -> i32 { //This should grab potential streaks (Disk::EMPTY) // get all middle indexes let streaks = get_dups(board, disk); - match streaks { + match streaks.iter().count() { 1 => POT_STREAK, - _ => POT_STREAKS * streaks, + _ => POT_STREAKS * streaks.iter().count() as i32, } } -fn get_dups(board: &Array2D, _target_disk: &Disk) -> i32 { - let mid_col = (board.num_rows() - 1) / 2; +fn get_dups(board: &Array2D, player_disk: &Disk) -> Vec> { + let edge_col = board.num_columns() - 1; + let mid_col = edge_col / 2; let mid_indices: Vec<(usize, usize)> = board .indices_row_major() - .filter(|&index| index.1.eq(&mid_col)) + .filter(|&index| variant_eq(board.get(index.0, index.1).expect(""), &Disk::EMPTY)) .collect(); - let mut dups = 0; + let mut dups: Vec> = vec![]; for index in mid_indices { let moves = get_legal_moves(&index, (board.num_rows(), board.num_columns())); for direction in moves { - let poopy = heur_scan(&board, &index, direction, 4); + let poopy = heur_scan(&board, &index, direction.clone(), 4, *player_disk); + //dbg!(&index, &direction, &poopy); match poopy .iter() - .filter(|&disk| matches!(&disk, _target_disk)) + .filter(|&disk| variant_eq(disk, player_disk)) .count() { - 3 => dups += 1, - 2 => dups += 1, + 3 | 2 => dups.push(poopy), _ => {} } } @@ -70,10 +84,10 @@ fn heur_scan( index: &(usize, usize), direction: Direction, depth: i32, + player_disk: Disk, ) -> Vec { - let current_disk: &Disk; match board.get(index.0, index.1) { - Some(disk) => current_disk = disk, + Some(_) => {} None => return vec![], }; let mut current_index = *index; @@ -83,7 +97,7 @@ fn heur_scan( match board.get(current_index.0, current_index.1) { Some(_disk) => { // dbg!(_disk, current_disk, in_a_row); - if variant_eq(current_disk, _disk) || variant_eq(_disk, &Disk::EMPTY) { + 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); diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index e975823..84027b6 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -150,4 +150,11 @@ fn heuristic_pot_wins() { board.play(Disk::BLU, 2); board.play(Disk::BLU, 1); assert_eq!(16, potential_wins(&board.columns, &Disk::BLU)); + board.play(Disk::BLU, 0); + assert_eq!(5, potential_wins(&board.columns, &Disk::BLU)); + board.play(Disk::BLU, 3); + board.play(Disk::BLU, 3); + board.play(Disk::BLU, 3); + board.play(Disk::BLU, 3); + assert_eq!(0, potential_wins(&board.columns, &Disk::BLU)); } From ced0fd48a0fd0599b4e1ace25dc0cd645580b7e2 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Thu, 4 May 2023 20:17:42 +0300 Subject: [PATCH 35/45] why do these keep pooping up pls --- .gitignore | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index ee86488..57a1303 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,5 @@ Cargo.lock # MSVC Windows builds of rustc generate these, which store debugging information *.pdb -src/gamedata/.tests.rs.swp -src/gamedata/.score_checkers.rs.swp -src/gamedata/.indices.rs.swp -src/gamedata/.mod.rs.swp +# Silly swap thingies +*.swp From 63242e1bce3ef2e02f517191c10642a8ef969a64 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Thu, 4 May 2023 21:15:26 +0300 Subject: [PATCH 36/45] moved heuristic test to its own file --- src/gamedata/tests.rs | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index 84027b6..1e41c8f 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -140,21 +140,3 @@ fn game_over_test() { board.columns.set(0, 0, Disk::EMPTY).expect("balls"); assert!(!board.game_over()); } - -#[test] -fn heuristic_pot_wins() { - 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); - assert_eq!(16, potential_wins(&board.columns, &Disk::BLU)); - board.play(Disk::BLU, 0); - assert_eq!(5, potential_wins(&board.columns, &Disk::BLU)); - board.play(Disk::BLU, 3); - board.play(Disk::BLU, 3); - board.play(Disk::BLU, 3); - board.play(Disk::BLU, 3); - assert_eq!(0, potential_wins(&board.columns, &Disk::BLU)); -} From c1eac620fe2b0864844cbc0a509c929f5c83924e Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Thu, 4 May 2023 21:16:06 +0300 Subject: [PATCH 37/45] Sequences and Win tests passed :D --- src/gamedata/heuristic.rs | 54 +++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/src/gamedata/heuristic.rs b/src/gamedata/heuristic.rs index 98155f8..204664b 100644 --- a/src/gamedata/heuristic.rs +++ b/src/gamedata/heuristic.rs @@ -15,20 +15,17 @@ 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_dups(&board.columns, &Disk::BLU); 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(&board.columns, &disk) - + potential_wins(&board.columns, &disk) - + score * SCORE_DIFF + potential_streaks(&sequences, &disk) + potential_wins(&sequences, &disk) + score * SCORE_DIFF } -pub fn potential_wins(board: &Array2D, disk: &Disk) -> i32 { - let pot_wins = get_dups(board, disk); - dbg!(&pot_wins); +pub fn potential_wins(sequences: &Vec>, disk: &Disk) -> i32 { let mut count: i32 = 0; - for win in pot_wins { + for win in sequences { if win .iter() .filter(|&_disk| variant_eq(_disk, &Disk::EMPTY)) @@ -44,13 +41,23 @@ pub fn potential_wins(board: &Array2D, disk: &Disk) -> i32 { _ => POT_WINS * count, } } -pub fn potential_streaks(board: &Array2D, disk: &Disk) -> i32 { +pub fn potential_streaks(sequences: &Vec>, _disk: &Disk) -> i32 { //This should grab potential streaks (Disk::EMPTY) // get all middle indexes - let streaks = get_dups(board, disk); - match streaks.iter().count() { + 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.iter().count() as i32, + _ => POT_STREAKS * streaks as i32, } } fn get_dups(board: &Array2D, player_disk: &Disk) -> Vec> { @@ -165,3 +172,28 @@ fn heur_scan( } in_a_row } + +//Tests because I am making everything public +//TODO separate module here +#[test] +fn heuristic_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_dups(&board.columns, &Disk::BLU); + assert_eq!(16, potential_wins(&sequences, &Disk::BLU)); + assert_eq!(18, potential_streaks(&sequences, &Disk::BLU)); + board.play(Disk::BLU, 0); + let sequences = get_dups(&board.columns, &Disk::BLU); + assert_eq!(5, potential_wins(&sequences, &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_dups(&board.columns, &Disk::BLU); + assert_eq!(0, potential_wins(&sequences, &Disk::BLU)); + assert_eq!(12, potential_streaks(&sequences, &Disk::BLU)); +} From 0959ff00e603fb5726d3b2cb55a125d0ed89e8ff Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Thu, 4 May 2023 22:51:53 +0300 Subject: [PATCH 38/45] not hardcoded oop --- src/gamedata/heuristic.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/gamedata/heuristic.rs b/src/gamedata/heuristic.rs index 204664b..45f7946 100644 --- a/src/gamedata/heuristic.rs +++ b/src/gamedata/heuristic.rs @@ -15,7 +15,7 @@ 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_dups(&board.columns, &Disk::BLU); + let sequences = get_dups(&board.columns, &disk); let score: i32 = match disk { Disk::RED => board.red_score - board.blu_score, Disk::BLU => board.blu_score - board.red_score, @@ -23,7 +23,7 @@ pub fn get_score(board: &Board, disk: Disk) -> i32 { }; potential_streaks(&sequences, &disk) + potential_wins(&sequences, &disk) + score * SCORE_DIFF } -pub fn potential_wins(sequences: &Vec>, disk: &Disk) -> i32 { +fn potential_wins(sequences: &Vec>, _disk: &Disk) -> i32 { let mut count: i32 = 0; for win in sequences { if win @@ -41,9 +41,9 @@ pub fn potential_wins(sequences: &Vec>, disk: &Disk) -> i32 { _ => POT_WINS * count, } } -pub fn potential_streaks(sequences: &Vec>, _disk: &Disk) -> i32 { +fn potential_streaks(sequences: &Vec>, _disk: &Disk) -> i32 { //This should grab potential streaks (Disk::EMPTY) - // get all middle indexes + // get all "EMPTY" indexes let streaks = sequences .iter() .filter(|&seq| { @@ -61,8 +61,6 @@ pub fn potential_streaks(sequences: &Vec>, _disk: &Disk) -> i32 { } } fn get_dups(board: &Array2D, player_disk: &Disk) -> Vec> { - let edge_col = board.num_columns() - 1; - let mid_col = edge_col / 2; let mid_indices: Vec<(usize, usize)> = board .indices_row_major() .filter(|&index| variant_eq(board.get(index.0, index.1).expect(""), &Disk::EMPTY)) From 85e022f0fb665d13ed5591cfda3fb95afca800d2 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Thu, 4 May 2023 22:52:02 +0300 Subject: [PATCH 39/45] moved to the tests file --- src/gamedata/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gamedata/mod.rs b/src/gamedata/mod.rs index 2253daa..74874be 100644 --- a/src/gamedata/mod.rs +++ b/src/gamedata/mod.rs @@ -7,7 +7,6 @@ mod tests; use array2d::Array2D; pub use indices::*; -use self::score_checkers::scan; #[derive(Clone)] pub struct Board { red_score: i32, From b16b95a5c73f0d62633f65aca9d158c8f8f6aa01 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Thu, 4 May 2023 22:52:09 +0300 Subject: [PATCH 40/45] imports needed --- src/gamedata/tests.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index 1e41c8f..25d8601 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -1,4 +1,5 @@ -use crate::gamedata::{heuristic::potential_wins, score_checkers::Direction}; +use self::score_checkers::scan; +use crate::gamedata::score_checkers::Direction; use super::*; From 9f6f97cc70222060cf4993362023ba297fbd80a5 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Thu, 4 May 2023 22:52:19 +0300 Subject: [PATCH 41/45] _ makes the thing not yell at me --- src/gamedata/score_checkers.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gamedata/score_checkers.rs b/src/gamedata/score_checkers.rs index 9dd25bc..387f344 100644 --- a/src/gamedata/score_checkers.rs +++ b/src/gamedata/score_checkers.rs @@ -104,12 +104,12 @@ 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 _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), + _max_row => moves.push(Direction::DOWN), _ => { moves.push(Direction::UP); moves.push(Direction::DOWN); @@ -117,7 +117,7 @@ pub fn get_legal_moves( }; match *row { 0 => moves.push(Direction::RIGHT), - max_row => moves.push(Direction::LEFT), + _max_row => moves.push(Direction::LEFT), _ => { moves.push(Direction::LEFT); moves.push(Direction::RIGHT) From c3f53436a91dab4fe156031666558be4b441f1b8 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Fri, 5 May 2023 15:45:36 +0300 Subject: [PATCH 42/45] flipped column and row numbers (i forgor) --- src/gamedata/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gamedata/mod.rs b/src/gamedata/mod.rs index 74874be..8694444 100644 --- a/src/gamedata/mod.rs +++ b/src/gamedata/mod.rs @@ -1,3 +1,4 @@ +mod algorithms; mod heuristic; mod indices; mod score_checkers; @@ -16,7 +17,7 @@ pub struct Board { 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 { red_score: 0, From 3a6829b5b65799cc5ce8191818563c5468699dc9 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Fri, 5 May 2023 15:45:47 +0300 Subject: [PATCH 43/45] adjusted the tests to new column and rows :DDDD --- src/gamedata/tests.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/gamedata/tests.rs b/src/gamedata/tests.rs index 25d8601..b003439 100644 --- a/src/gamedata/tests.rs +++ b/src/gamedata/tests.rs @@ -18,7 +18,6 @@ fn play() { 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, 0)); assert!(board.play(Disk::BLU, 1)); @@ -27,7 +26,6 @@ fn play() { 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)); @@ -36,7 +34,6 @@ fn play() { 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)); @@ -45,7 +42,6 @@ fn play() { 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] From f23e147a201400a0781e21effd6b2299d39f1802 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Fri, 5 May 2023 15:45:58 +0300 Subject: [PATCH 44/45] skeleton for minimax (pls help) --- src/gamedata/algorithms.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/gamedata/algorithms.rs 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!() +} From 75e946d9eea79f76cc1332f3e3bcb5d14cb6c398 Mon Sep 17 00:00:00 2001 From: LinlyBoi Date: Fri, 5 May 2023 15:56:43 +0300 Subject: [PATCH 45/45] Cleaned up commented code, get_wins and get_streaks are now separate :D --- src/gamedata/heuristic.rs | 129 +++++++++++++++++++++++++++++--------- 1 file changed, 100 insertions(+), 29 deletions(-) diff --git a/src/gamedata/heuristic.rs b/src/gamedata/heuristic.rs index 45f7946..a16b44c 100644 --- a/src/gamedata/heuristic.rs +++ b/src/gamedata/heuristic.rs @@ -2,7 +2,7 @@ use array2d::Array2D; use super::{ dec_both, dec_col, dec_inc, dec_row, inc_both, inc_col, inc_dec, inc_row, - score_checkers::{get_legal_moves, variant_eq, Direction}, + score_checkers::{flip_direction, get_legal_moves, variant_eq, Direction}, Board, Disk, }; //multipliers @@ -15,7 +15,7 @@ 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_dups(&board.columns, &disk); + 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, @@ -24,18 +24,18 @@ pub fn get_score(board: &Board, disk: Disk) -> i32 { potential_streaks(&sequences, &disk) + potential_wins(&sequences, &disk) + score * SCORE_DIFF } fn potential_wins(sequences: &Vec>, _disk: &Disk) -> i32 { - let mut count: i32 = 0; - for win in sequences { - if win - .iter() - .filter(|&_disk| variant_eq(_disk, &Disk::EMPTY)) - .count() - == 1 - && win.len() == 4 - { - count += 1; - } - } + 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, @@ -60,28 +60,77 @@ fn potential_streaks(sequences: &Vec>, _disk: &Disk) -> i32 { _ => POT_STREAKS * streaks as i32, } } -fn get_dups(board: &Array2D, player_disk: &Disk) -> Vec> { - let mid_indices: Vec<(usize, usize)> = board +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(); - let mut dups: Vec> = vec![]; - for index in mid_indices { + //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 poopy = heur_scan(&board, &index, direction.clone(), 4, *player_disk); + let mut sequence = heur_scan(&board, &index, direction.clone(), 4, *player_disk); //dbg!(&index, &direction, &poopy); - match poopy + match sequence .iter() .filter(|&disk| variant_eq(disk, player_disk)) .count() { - 3 | 2 => dups.push(poopy), + 2 => streaks.push(sequence), _ => {} } } } - dups + 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( @@ -174,24 +223,46 @@ fn heur_scan( //Tests because I am making everything public //TODO separate module here #[test] -fn heuristic_test_1() { +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_dups(&board.columns, &Disk::BLU); - assert_eq!(16, potential_wins(&sequences, &Disk::BLU)); + let sequences = get_streaks(&board.columns, &Disk::BLU); assert_eq!(18, potential_streaks(&sequences, &Disk::BLU)); board.play(Disk::BLU, 0); - let sequences = get_dups(&board.columns, &Disk::BLU); - assert_eq!(5, potential_wins(&sequences, &Disk::BLU)); + 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_dups(&board.columns, &Disk::BLU); - assert_eq!(0, potential_wins(&sequences, &Disk::BLU)); + 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)); +}