Skip to content

Commit

Permalink
Fix findLast, add last function for Bitboard
Browse files Browse the repository at this point in the history
Also add tests
  • Loading branch information
lenguyenthanh committed Nov 5, 2023
1 parent 76fd6e7 commit 5f4cc41
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/main/scala/bitboard/Bitboard.scala
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ object Bitboard:
inline def isDisjoint(o: Bitboard): Boolean =
(a & o).isEmpty

// return list of square that sorted ascendingly
def squares: List[Square] =
var b = a
val builder = List.newBuilder[Square]
Expand All @@ -129,6 +130,15 @@ object Bitboard:
b &= (b - 1L)
result

def last[B](f: Square => Option[B]): Option[B] =
var b = a
var result: Option[B] = None
while b != 0L && result.isEmpty
do
result = f(b.msb)
b &= ~b.msb.bl
result

def find(f: Square => Boolean): Option[Square] =
var b = a
var result: Option[Square] = None
Expand All @@ -138,14 +148,13 @@ object Bitboard:
b &= (b - 1L)
result

// tests
def findLast(f: Square => Boolean): Option[Square] =
var b = a
var result: Option[Square] = None
while b != 0L && result.isEmpty
do
if f(b.msb) then result = Some(b.msb)
b &= (b - 1L)
b &= ~b.msb.bl
result

def fold[B](init: B)(f: (B, Square) => B): B =
Expand Down
25 changes: 25 additions & 0 deletions test-kit/src/test/scala/bitboard/BitboardTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,27 @@ class BitboardTest extends ScalaCheckSuite:
def f = (p: Square) => if p == x then Some(p) else None
Bitboard(xs + x).first(f) == Some(x)

test("last with a function that always return None should return None"):
forAll: (bb: Bitboard) =>
assertEquals(bb.last(_ => None), None)

test("last with a function that always return Some should return the last square"):
forAll: (bb: Bitboard) =>
assertEquals(bb.last(Some(_)), bb.last)

test("last returns the correct square"):
forAll: (xs: Set[Square], x: Square) =>
def f = (p: Square) => if p == x then Some(p) else None
Bitboard(xs + x).last(f) == Some(x)

test("find"):
forAll: (bb: Bitboard, f: Square => Boolean) =>
bb.find(f) == bb.squares.find(f)

test("findLast"):
forAll: (bb: Bitboard, f: Square => Boolean) =>
bb.findLast(f) == bb.squares.reverse.find(f)

test("bitboard created by set of square should contains and only contains those square"):
forAll: (xs: Set[Square]) =>
val bb = Bitboard(xs)
Expand Down Expand Up @@ -147,6 +168,10 @@ class BitboardTest extends ScalaCheckSuite:
forAll: (b: Bitboard, f: Square => Option[Int]) =>
b.first(f) == b.squares.map(f).find(_.isDefined).flatten

property("last"):
forAll: (b: Bitboard, f: Square => Option[Int]) =>
b.last(f) == b.squares.map(f).findLast(_.isDefined).flatten

property("foreach"):
forAll: (b: Bitboard, f: Square => Int) =>
var s1 = 0L
Expand Down

0 comments on commit 5f4cc41

Please sign in to comment.