feat: refactor AlphaBetaSearch and ClassicalBot for improved evaluation and organization
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
package de.nowchess.bot
|
package de.nowchess.bot
|
||||||
|
|
||||||
|
import de.nowchess.bot.bots.ClassicalBot
|
||||||
|
|
||||||
object BotController {
|
object BotController {
|
||||||
|
|
||||||
private var bots: Map[String, Bot] = Map.empty
|
private var bots: Map[String, Bot] = Map.empty
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package de.nowchess.bot.ai
|
||||||
|
|
||||||
|
import de.nowchess.api.game.GameContext
|
||||||
|
|
||||||
|
trait Weights {
|
||||||
|
|
||||||
|
def CHECKMATE_SCORE: Int
|
||||||
|
def DRAW_SCORE: Int
|
||||||
|
|
||||||
|
def evaluate(context: GameContext): Int
|
||||||
|
|
||||||
|
}
|
||||||
+6
-2
@@ -1,7 +1,11 @@
|
|||||||
package de.nowchess.bot
|
package de.nowchess.bot.bots
|
||||||
|
|
||||||
import de.nowchess.api.game.GameContext
|
import de.nowchess.api.game.GameContext
|
||||||
import de.nowchess.api.move.Move
|
import de.nowchess.api.move.Move
|
||||||
|
import de.nowchess.bot.bots.classic.EvaluationClassic
|
||||||
|
import de.nowchess.bot.logic.AlphaBetaSearch
|
||||||
|
import de.nowchess.bot.util.PolyglotBook
|
||||||
|
import de.nowchess.bot.{Bot, BotDifficulty}
|
||||||
import de.nowchess.rules.RuleSet
|
import de.nowchess.rules.RuleSet
|
||||||
import de.nowchess.rules.sets.DefaultRules
|
import de.nowchess.rules.sets.DefaultRules
|
||||||
|
|
||||||
@@ -11,7 +15,7 @@ final class ClassicalBot(
|
|||||||
book: Option[PolyglotBook] = None
|
book: Option[PolyglotBook] = None
|
||||||
) extends Bot:
|
) extends Bot:
|
||||||
|
|
||||||
private val search: AlphaBetaSearch = AlphaBetaSearch(rules)
|
private val search: AlphaBetaSearch = AlphaBetaSearch(rules, weights = EvaluationClassic)
|
||||||
private val TIME_BUDGET_MS = 1000L
|
private val TIME_BUDGET_MS = 1000L
|
||||||
|
|
||||||
override val name: String = s"ClassicalBot(${difficulty.toString})"
|
override val name: String = s"ClassicalBot(${difficulty.toString})"
|
||||||
+3
-2
@@ -1,9 +1,10 @@
|
|||||||
package de.nowchess.bot
|
package de.nowchess.bot.bots.classic
|
||||||
|
|
||||||
import de.nowchess.api.board.{Color, PieceType, Square}
|
import de.nowchess.api.board.{Color, PieceType, Square}
|
||||||
import de.nowchess.api.game.GameContext
|
import de.nowchess.api.game.GameContext
|
||||||
|
import de.nowchess.bot.ai.Weights
|
||||||
|
|
||||||
object Evaluation:
|
object EvaluationClassic extends Weights:
|
||||||
|
|
||||||
val CHECKMATE_SCORE: Int = 10_000_000
|
val CHECKMATE_SCORE: Int = 10_000_000
|
||||||
val DRAW_SCORE: Int = 0
|
val DRAW_SCORE: Int = 0
|
||||||
+14
-9
@@ -1,18 +1,23 @@
|
|||||||
package de.nowchess.bot
|
package de.nowchess.bot.logic
|
||||||
|
|
||||||
import de.nowchess.api.board.PieceType
|
import de.nowchess.api.board.PieceType
|
||||||
import de.nowchess.api.game.GameContext
|
import de.nowchess.api.game.GameContext
|
||||||
import de.nowchess.api.move.{Move, MoveType}
|
import de.nowchess.api.move.{Move, MoveType}
|
||||||
|
import de.nowchess.bot.ai.Weights
|
||||||
|
import de.nowchess.bot.logic.{MoveOrdering, TTEntry, TTFlag, TranspositionTable}
|
||||||
|
import de.nowchess.bot.util.ZobristHash
|
||||||
import de.nowchess.rules.RuleSet
|
import de.nowchess.rules.RuleSet
|
||||||
import de.nowchess.rules.sets.DefaultRules
|
import de.nowchess.rules.sets.DefaultRules
|
||||||
import scala.concurrent.{ExecutionContext, Future}
|
|
||||||
import scala.concurrent.ExecutionContext.Implicits.global
|
|
||||||
import java.util.concurrent.ForkJoinPool
|
import java.util.concurrent.ForkJoinPool
|
||||||
import java.util.concurrent.atomic.AtomicReference
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
|
import scala.concurrent.ExecutionContext.Implicits.global
|
||||||
|
import scala.concurrent.{ExecutionContext, Future}
|
||||||
|
|
||||||
final class AlphaBetaSearch(
|
final class AlphaBetaSearch(
|
||||||
rules: RuleSet = DefaultRules,
|
rules: RuleSet = DefaultRules,
|
||||||
tt: TranspositionTable = TranspositionTable(),
|
tt: TranspositionTable = TranspositionTable(),
|
||||||
|
weights: Weights,
|
||||||
numThreads: Int = Runtime.getRuntime().availableProcessors()
|
numThreads: Int = Runtime.getRuntime().availableProcessors()
|
||||||
):
|
):
|
||||||
|
|
||||||
@@ -135,7 +140,7 @@ final class AlphaBetaSearch(
|
|||||||
// Periodic time check
|
// Periodic time check
|
||||||
nodeCount += 1
|
nodeCount += 1
|
||||||
if nodeCount % TIME_CHECK_FREQUENCY == 0 && isOutOfTime() then
|
if nodeCount % TIME_CHECK_FREQUENCY == 0 && isOutOfTime() then
|
||||||
return (Evaluation.evaluate(context), None)
|
return (weights.evaluate(context), None)
|
||||||
|
|
||||||
val hash = ZobristHash.hash(context)
|
val hash = ZobristHash.hash(context)
|
||||||
|
|
||||||
@@ -159,13 +164,13 @@ final class AlphaBetaSearch(
|
|||||||
val legalMoves = rules.allLegalMoves(context)
|
val legalMoves = rules.allLegalMoves(context)
|
||||||
if legalMoves.isEmpty then
|
if legalMoves.isEmpty then
|
||||||
val score = if rules.isCheckmate(context) then
|
val score = if rules.isCheckmate(context) then
|
||||||
-(Evaluation.CHECKMATE_SCORE - ply)
|
-(weights.CHECKMATE_SCORE - ply)
|
||||||
else
|
else
|
||||||
Evaluation.DRAW_SCORE
|
weights.DRAW_SCORE
|
||||||
return (score, None)
|
return (score, None)
|
||||||
|
|
||||||
if rules.isInsufficientMaterial(context) || rules.isFiftyMoveRule(context) then
|
if rules.isInsufficientMaterial(context) || rules.isFiftyMoveRule(context) then
|
||||||
return (Evaluation.DRAW_SCORE, None)
|
return (weights.DRAW_SCORE, None)
|
||||||
|
|
||||||
// Leaf node: call quiescence
|
// Leaf node: call quiescence
|
||||||
if depth == 0 then
|
if depth == 0 then
|
||||||
@@ -211,7 +216,7 @@ final class AlphaBetaSearch(
|
|||||||
|
|
||||||
// Futility pruning at frontier nodes: if static eval + margin is still below alpha, skip quiet moves
|
// Futility pruning at frontier nodes: if static eval + margin is still below alpha, skip quiet moves
|
||||||
if depth == 1 && isQuiet && moveNumber > 2 then
|
if depth == 1 && isQuiet && moveNumber > 2 then
|
||||||
val staticEval = Evaluation.evaluate(context)
|
val staticEval = weights.evaluate(context)
|
||||||
if staticEval + FUTILITY_MARGIN < alpha then
|
if staticEval + FUTILITY_MARGIN < alpha then
|
||||||
moveNumber += 1
|
moveNumber += 1
|
||||||
|
|
||||||
@@ -328,7 +333,7 @@ final class AlphaBetaSearch(
|
|||||||
beta: Int
|
beta: Int
|
||||||
): Int =
|
): Int =
|
||||||
// Stand-pat: evaluate current position
|
// Stand-pat: evaluate current position
|
||||||
val standPat = Evaluation.evaluate(context)
|
val standPat = weights.evaluate(context)
|
||||||
if standPat >= beta then
|
if standPat >= beta then
|
||||||
return beta
|
return beta
|
||||||
|
|
||||||
+2
-1
@@ -1,8 +1,9 @@
|
|||||||
package de.nowchess.bot
|
package de.nowchess.bot.logic
|
||||||
|
|
||||||
import de.nowchess.api.board.PieceType
|
import de.nowchess.api.board.PieceType
|
||||||
import de.nowchess.api.game.GameContext
|
import de.nowchess.api.game.GameContext
|
||||||
import de.nowchess.api.move.{Move, MoveType, PromotionPiece}
|
import de.nowchess.api.move.{Move, MoveType, PromotionPiece}
|
||||||
|
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
|
|
||||||
object MoveOrdering:
|
object MoveOrdering:
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package de.nowchess.bot
|
package de.nowchess.bot.logic
|
||||||
|
|
||||||
import de.nowchess.api.move.Move
|
import de.nowchess.api.move.Move
|
||||||
|
|
||||||
+3
-2
@@ -1,8 +1,9 @@
|
|||||||
package de.nowchess.bot
|
package de.nowchess.bot.util
|
||||||
|
|
||||||
import de.nowchess.api.board.{Color, File, PieceType, Rank, Square}
|
import de.nowchess.api.board.*
|
||||||
import de.nowchess.api.game.GameContext
|
import de.nowchess.api.game.GameContext
|
||||||
import de.nowchess.api.move.{Move, MoveType, PromotionPiece}
|
import de.nowchess.api.move.{Move, MoveType, PromotionPiece}
|
||||||
|
|
||||||
import java.io.{DataInputStream, FileInputStream}
|
import java.io.{DataInputStream, FileInputStream}
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
import scala.util.Random
|
import scala.util.Random
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package de.nowchess.bot
|
package de.nowchess.bot.util
|
||||||
|
|
||||||
import de.nowchess.api.board.{Color, Piece, PieceType, Square}
|
import de.nowchess.api.board.{Color, Piece, PieceType, Square}
|
||||||
import de.nowchess.api.game.GameContext
|
import de.nowchess.api.game.GameContext
|
||||||
+2
-1
@@ -1,7 +1,8 @@
|
|||||||
package de.nowchess.bot
|
package de.nowchess.bot.util
|
||||||
|
|
||||||
import de.nowchess.api.board.{Color, File, PieceType, Square}
|
import de.nowchess.api.board.{Color, File, PieceType, Square}
|
||||||
import de.nowchess.api.game.GameContext
|
import de.nowchess.api.game.GameContext
|
||||||
|
|
||||||
import scala.util.Random
|
import scala.util.Random
|
||||||
|
|
||||||
object ZobristHash:
|
object ZobristHash:
|
||||||
@@ -3,6 +3,7 @@ package de.nowchess.bot
|
|||||||
import de.nowchess.api.board.{Board, Color, File, Piece, PieceType, Rank, Square}
|
import de.nowchess.api.board.{Board, Color, File, Piece, PieceType, Rank, Square}
|
||||||
import de.nowchess.api.game.GameContext
|
import de.nowchess.api.game.GameContext
|
||||||
import de.nowchess.api.move.{Move, MoveType}
|
import de.nowchess.api.move.{Move, MoveType}
|
||||||
|
import de.nowchess.bot.logic.AlphaBetaSearch
|
||||||
import de.nowchess.rules.RuleSet
|
import de.nowchess.rules.RuleSet
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
import org.scalatest.funsuite.AnyFunSuite
|
||||||
import org.scalatest.matchers.should.Matchers
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package de.nowchess.bot
|
|||||||
import de.nowchess.api.board.Square
|
import de.nowchess.api.board.Square
|
||||||
import de.nowchess.api.game.GameContext
|
import de.nowchess.api.game.GameContext
|
||||||
import de.nowchess.api.move.Move
|
import de.nowchess.api.move.Move
|
||||||
|
import de.nowchess.bot.bots.ClassicalBot
|
||||||
import de.nowchess.rules.RuleSet
|
import de.nowchess.rules.RuleSet
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
import org.scalatest.funsuite.AnyFunSuite
|
||||||
import org.scalatest.matchers.should.Matchers
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ package de.nowchess.bot
|
|||||||
import de.nowchess.api.board.{Board, Color, File, Piece, PieceType, Rank, Square}
|
import de.nowchess.api.board.{Board, Color, File, Piece, PieceType, Rank, Square}
|
||||||
import de.nowchess.api.game.GameContext
|
import de.nowchess.api.game.GameContext
|
||||||
import de.nowchess.api.board.Board
|
import de.nowchess.api.board.Board
|
||||||
|
import de.nowchess.bot.bots.classic.EvaluationClassic
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
import org.scalatest.funsuite.AnyFunSuite
|
||||||
import org.scalatest.matchers.should.Matchers
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
|
||||||
class EvaluationTest extends AnyFunSuite with Matchers:
|
class EvaluationTest extends AnyFunSuite with Matchers:
|
||||||
|
|
||||||
test("initial position evaluates to tempo bonus"):
|
test("initial position evaluates to tempo bonus"):
|
||||||
val eval = Evaluation.evaluate(GameContext.initial)
|
val eval = EvaluationClassic.evaluate(GameContext.initial)
|
||||||
eval should equal(10) // TEMPO_BONUS only
|
eval should equal(10) // TEMPO_BONUS only
|
||||||
|
|
||||||
test("remove white queen gives negative evaluation"):
|
test("remove white queen gives negative evaluation"):
|
||||||
@@ -18,7 +19,7 @@ class EvaluationTest extends AnyFunSuite with Matchers:
|
|||||||
val emptySquare = Square(File.D, Rank.R1)
|
val emptySquare = Square(File.D, Rank.R1)
|
||||||
val boardWithoutQueen = board.pieces.filter((sq, _) => sq != emptySquare)
|
val boardWithoutQueen = board.pieces.filter((sq, _) => sq != emptySquare)
|
||||||
val newContext = initial.withBoard(Board(boardWithoutQueen))
|
val newContext = initial.withBoard(Board(boardWithoutQueen))
|
||||||
val eval = Evaluation.evaluate(newContext)
|
val eval = EvaluationClassic.evaluate(newContext)
|
||||||
eval should be < 0
|
eval should be < 0
|
||||||
|
|
||||||
test("remove black queen gives positive evaluation"):
|
test("remove black queen gives positive evaluation"):
|
||||||
@@ -27,7 +28,7 @@ class EvaluationTest extends AnyFunSuite with Matchers:
|
|||||||
val emptySquare = Square(File.D, Rank.R8)
|
val emptySquare = Square(File.D, Rank.R8)
|
||||||
val boardWithoutQueen = board.pieces.filter((sq, _) => sq != emptySquare)
|
val boardWithoutQueen = board.pieces.filter((sq, _) => sq != emptySquare)
|
||||||
val newContext = initial.withBoard(Board(boardWithoutQueen))
|
val newContext = initial.withBoard(Board(boardWithoutQueen))
|
||||||
val eval = Evaluation.evaluate(newContext)
|
val eval = EvaluationClassic.evaluate(newContext)
|
||||||
eval should be > 0
|
eval should be > 0
|
||||||
|
|
||||||
test("different piece-square bonuses are applied"):
|
test("different piece-square bonuses are applied"):
|
||||||
@@ -37,27 +38,27 @@ class EvaluationTest extends AnyFunSuite with Matchers:
|
|||||||
val knightD4 = GameContext.initial.withBoard(knightD4Board)
|
val knightD4 = GameContext.initial.withBoard(knightD4Board)
|
||||||
val knightA1 = GameContext.initial.withBoard(knightA1Board)
|
val knightA1 = GameContext.initial.withBoard(knightA1Board)
|
||||||
|
|
||||||
val eval1 = Evaluation.evaluate(knightD4)
|
val eval1 = EvaluationClassic.evaluate(knightD4)
|
||||||
val eval2 = Evaluation.evaluate(knightA1)
|
val eval2 = EvaluationClassic.evaluate(knightA1)
|
||||||
eval1 should be > eval2 // d4 (center) is better than a1 (corner) for knight
|
eval1 should be > eval2 // d4 (center) is better than a1 (corner) for knight
|
||||||
|
|
||||||
test("all piece types are in material map"):
|
test("all piece types are in material map"):
|
||||||
PieceType.values.length should be > 0
|
PieceType.values.length should be > 0
|
||||||
// Just verify evaluate works with all piece types
|
// Just verify evaluate works with all piece types
|
||||||
val eval = Evaluation.evaluate(GameContext.initial)
|
val eval = EvaluationClassic.evaluate(GameContext.initial)
|
||||||
eval should not be (Evaluation.CHECKMATE_SCORE)
|
eval should not be (EvaluationClassic.CHECKMATE_SCORE)
|
||||||
|
|
||||||
test("CHECKMATE_SCORE and DRAW_SCORE are accessible"):
|
test("CHECKMATE_SCORE and DRAW_SCORE are accessible"):
|
||||||
Evaluation.CHECKMATE_SCORE should equal(10_000_000)
|
EvaluationClassic.CHECKMATE_SCORE should equal(10_000_000)
|
||||||
Evaluation.DRAW_SCORE should equal(0)
|
EvaluationClassic.DRAW_SCORE should equal(0)
|
||||||
|
|
||||||
test("active knight (center) scores higher than passive knight (corner)"):
|
test("active knight (center) scores higher than passive knight (corner)"):
|
||||||
val knightD4Board = Board(Map(Square(File.D, Rank.R4) -> Piece.WhiteKnight))
|
val knightD4Board = Board(Map(Square(File.D, Rank.R4) -> Piece.WhiteKnight))
|
||||||
val knightA1Board = Board(Map(Square(File.A, Rank.R1) -> Piece.WhiteKnight))
|
val knightA1Board = Board(Map(Square(File.A, Rank.R1) -> Piece.WhiteKnight))
|
||||||
val knightD4Context = GameContext.initial.withBoard(knightD4Board)
|
val knightD4Context = GameContext.initial.withBoard(knightD4Board)
|
||||||
val knightA1Context = GameContext.initial.withBoard(knightA1Board)
|
val knightA1Context = GameContext.initial.withBoard(knightA1Board)
|
||||||
val evalD4 = Evaluation.evaluate(knightD4Context)
|
val evalD4 = EvaluationClassic.evaluate(knightD4Context)
|
||||||
val evalA1 = Evaluation.evaluate(knightA1Context)
|
val evalA1 = EvaluationClassic.evaluate(knightA1Context)
|
||||||
evalD4 should be > evalA1 // Knight on d4 (center, more mobility) should score higher
|
evalD4 should be > evalA1 // Knight on d4 (center, more mobility) should score higher
|
||||||
|
|
||||||
test("bishop pair scores higher than bishop + knight"):
|
test("bishop pair scores higher than bishop + knight"):
|
||||||
@@ -71,8 +72,8 @@ class EvaluationTest extends AnyFunSuite with Matchers:
|
|||||||
))
|
))
|
||||||
val pairContext = GameContext.initial.withBoard(bishopPairBoard)
|
val pairContext = GameContext.initial.withBoard(bishopPairBoard)
|
||||||
val knightContext = GameContext.initial.withBoard(bishopKnightBoard)
|
val knightContext = GameContext.initial.withBoard(bishopKnightBoard)
|
||||||
val evalPair = Evaluation.evaluate(pairContext)
|
val evalPair = EvaluationClassic.evaluate(pairContext)
|
||||||
val evalKnight = Evaluation.evaluate(knightContext)
|
val evalKnight = EvaluationClassic.evaluate(knightContext)
|
||||||
evalPair should be > evalKnight // Bishop pair should score higher
|
evalPair should be > evalKnight // Bishop pair should score higher
|
||||||
|
|
||||||
test("rook on 7th rank scores higher than rook on 4th rank"):
|
test("rook on 7th rank scores higher than rook on 4th rank"):
|
||||||
@@ -80,6 +81,6 @@ class EvaluationTest extends AnyFunSuite with Matchers:
|
|||||||
val rook4thBoard = Board(Map(Square(File.A, Rank.R4) -> Piece.WhiteRook))
|
val rook4thBoard = Board(Map(Square(File.A, Rank.R4) -> Piece.WhiteRook))
|
||||||
val rook7thContext = GameContext.initial.withBoard(rook7thBoard)
|
val rook7thContext = GameContext.initial.withBoard(rook7thBoard)
|
||||||
val rook4thContext = GameContext.initial.withBoard(rook4thBoard)
|
val rook4thContext = GameContext.initial.withBoard(rook4thBoard)
|
||||||
val eval7th = Evaluation.evaluate(rook7thContext)
|
val eval7th = EvaluationClassic.evaluate(rook7thContext)
|
||||||
val eval4th = Evaluation.evaluate(rook4thContext)
|
val eval4th = EvaluationClassic.evaluate(rook4thContext)
|
||||||
eval7th should be > eval4th // Rook on 7th rank should score higher
|
eval7th should be > eval4th // Rook on 7th rank should score higher
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package de.nowchess.bot
|
|||||||
import de.nowchess.api.board.{Board, Color, File, Piece, PieceType, Rank, Square}
|
import de.nowchess.api.board.{Board, Color, File, Piece, PieceType, Rank, Square}
|
||||||
import de.nowchess.api.game.GameContext
|
import de.nowchess.api.game.GameContext
|
||||||
import de.nowchess.api.move.{Move, MoveType, PromotionPiece}
|
import de.nowchess.api.move.{Move, MoveType, PromotionPiece}
|
||||||
|
import de.nowchess.bot.logic.MoveOrdering
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
import org.scalatest.funsuite.AnyFunSuite
|
||||||
import org.scalatest.matchers.should.Matchers
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,12 @@ package de.nowchess.bot
|
|||||||
import de.nowchess.api.board.{Color, File, Rank, Square}
|
import de.nowchess.api.board.{Color, File, Rank, Square}
|
||||||
import de.nowchess.api.game.GameContext
|
import de.nowchess.api.game.GameContext
|
||||||
import de.nowchess.api.move.{Move, MoveType, PromotionPiece}
|
import de.nowchess.api.move.{Move, MoveType, PromotionPiece}
|
||||||
|
import de.nowchess.bot.bots.ClassicalBot
|
||||||
|
import de.nowchess.bot.util.{PolyglotBook, PolyglotHash}
|
||||||
import de.nowchess.rules.sets.DefaultRules
|
import de.nowchess.rules.sets.DefaultRules
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
import org.scalatest.funsuite.AnyFunSuite
|
||||||
import org.scalatest.matchers.should.Matchers
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
|
||||||
import java.io.{DataOutputStream, FileOutputStream}
|
import java.io.{DataOutputStream, FileOutputStream}
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import scala.util.Using
|
import scala.util.Using
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package de.nowchess.bot
|
|||||||
|
|
||||||
import de.nowchess.api.board.{Color, File, Rank, Square}
|
import de.nowchess.api.board.{Color, File, Rank, Square}
|
||||||
import de.nowchess.api.game.GameContext
|
import de.nowchess.api.game.GameContext
|
||||||
|
import de.nowchess.bot.util.PolyglotHash
|
||||||
import de.nowchess.io.fen.FenParser
|
import de.nowchess.io.fen.FenParser
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
import org.scalatest.funsuite.AnyFunSuite
|
||||||
import org.scalatest.matchers.should.Matchers
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package de.nowchess.bot
|
|||||||
|
|
||||||
import de.nowchess.api.board.{File, Rank, Square}
|
import de.nowchess.api.board.{File, Rank, Square}
|
||||||
import de.nowchess.api.move.{Move, MoveType}
|
import de.nowchess.api.move.{Move, MoveType}
|
||||||
|
import de.nowchess.bot.logic.{TTEntry, TTFlag, TranspositionTable}
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
import org.scalatest.funsuite.AnyFunSuite
|
||||||
import org.scalatest.matchers.should.Matchers
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package de.nowchess.bot
|
package de.nowchess.bot
|
||||||
|
|
||||||
import de.nowchess.api.board.{Board, Color, CastlingRights, File, Piece, Rank, Square}
|
import de.nowchess.api.board.{Board, CastlingRights, Color, File, Piece, Rank, Square}
|
||||||
import de.nowchess.api.game.GameContext
|
import de.nowchess.api.game.GameContext
|
||||||
import de.nowchess.api.move.{Move, MoveType}
|
import de.nowchess.api.move.{Move, MoveType}
|
||||||
|
import de.nowchess.bot.util.ZobristHash
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
import org.scalatest.funsuite.AnyFunSuite
|
||||||
import org.scalatest.matchers.should.Matchers
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ package de.nowchess.chess.engine
|
|||||||
|
|
||||||
import de.nowchess.api.board.Color
|
import de.nowchess.api.board.Color
|
||||||
import de.nowchess.api.game.GameContext
|
import de.nowchess.api.game.GameContext
|
||||||
import de.nowchess.bot.{BotDifficulty, ClassicalBot, BotController}
|
import de.nowchess.bot.bots.ClassicalBot
|
||||||
|
import de.nowchess.bot.{BotDifficulty, BotController}
|
||||||
import de.nowchess.chess.observer.*
|
import de.nowchess.chess.observer.*
|
||||||
import de.nowchess.rules.sets.DefaultRules
|
import de.nowchess.rules.sets.DefaultRules
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
import org.scalatest.funsuite.AnyFunSuite
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package de.nowchess.ui
|
package de.nowchess.ui
|
||||||
|
|
||||||
import de.nowchess.api.board.Color.Black
|
import de.nowchess.api.board.Color.Black
|
||||||
import de.nowchess.bot.{BotDifficulty, ClassicalBot, PolyglotBook}
|
import de.nowchess.bot.util.PolyglotBook
|
||||||
|
import de.nowchess.bot.BotDifficulty
|
||||||
|
import de.nowchess.bot.bots.ClassicalBot
|
||||||
import de.nowchess.chess.engine.GameEngine
|
import de.nowchess.chess.engine.GameEngine
|
||||||
import de.nowchess.ui.terminal.TerminalUI
|
import de.nowchess.ui.terminal.TerminalUI
|
||||||
import de.nowchess.ui.gui.ChessGUILauncher
|
import de.nowchess.ui.gui.ChessGUILauncher
|
||||||
|
|||||||
Reference in New Issue
Block a user