working version with json analysis engine
This commit is contained in:
1 parent
ff1db55a97
commit
da5d99194b
9 files changed
+68
-703
No files matched your search
@@ -1,305 +0,0 @@
|
||||
# Example config for C++ (non-python) gtp bot
|
||||
|
||||
# RUNNING ON AN ONLINE SERVER OR IN A REAL TOURNAMENT OR MATCH:
|
||||
# If you plan to do so, you may want to read through the "Rules" section
|
||||
# below carefully for proper handling of komi and handicap games and end-of-game cleanup
|
||||
# and various other details.
|
||||
|
||||
# NOTES ABOUT PERFORMANCE AND MEMORY USAGE:
|
||||
# You will likely want to tune one or more the following:
|
||||
#
|
||||
# numSearchThreads:
|
||||
# The number of CPU threads to use. If your GPU is powerful, it can actually be much higher than
|
||||
# the number of cores on your processor because you will need many threads to feed large enough
|
||||
# batches to make good use of the GPU.
|
||||
#
|
||||
# The "./katago benchmark" command can help you tune this parameter, as well as to test out the effect
|
||||
# of changes to any of the other parameters below!
|
||||
#
|
||||
# nnMaxBatchSize:
|
||||
# The maximum GPU batch size. Should often be at least as large as numSearchThreads.
|
||||
# Larger won't do anything, but also won't hurt except use a little bit more GPU memory.
|
||||
# Smaller can be fine if you have more than one GPU, since the GPUs will be sharing the work
|
||||
# of servicing the CPU threads.
|
||||
#
|
||||
# cudaUseFP16 and cudaUseNHWC:
|
||||
# These have a good chance of improving peformance at larger threads/batch sizes if
|
||||
# you are using the CUDA implementation with an NVIDIA GPU with FP16 tensor cores.
|
||||
#
|
||||
# nnCacheSizePowerOfTwo:
|
||||
# This controls the NN Cache size, which is the primary RAM/memory use.
|
||||
# Increase this if you don't mind the memory use and want better performance for searches with
|
||||
# tens of thousands of visits or more. Decrease this if you want to limit memory usage.
|
||||
#
|
||||
# If you're someone who is happy to do a bit of math - each neural net entry takes very
|
||||
# approximately 1.5KB, except when using whole-board ownership/territory visualizations, each
|
||||
# entry will take very approximately 3KB. The number of entries is (2 ** nnCacheSizePowerOfTwo),
|
||||
# for example 2 ** 18 = 262144.
|
||||
#
|
||||
# OTHER NOTES:
|
||||
# If you have more than one GPU, take a look at "OpenCL GPU settings" or "CUDA GPU settings" below.
|
||||
#
|
||||
# If using OpenCL, you will want to verify that KataGo is picking up the correct device!
|
||||
# (e.g. some systems may have both an Intel CPU OpenCL and GPU OpenCL, if KataGo appears to pick
|
||||
# the wrong one, you correct this by specifying "openclGpuToUse" below).
|
||||
#
|
||||
# You may also want to adjust "maxVisits", "ponderingEnabled", "resignThreshold", and possibly
|
||||
# other parameters depending on your intended usage.
|
||||
|
||||
|
||||
# Logs------------------------------------------------------------------------------------
|
||||
|
||||
# Where to output log?
|
||||
logFile = gtp.log
|
||||
# Logging options
|
||||
logAllGTPCommunication = true
|
||||
logSearchInfo = true
|
||||
logToStderr = false
|
||||
|
||||
# KataGo will display some info to stderr on GTP startup
|
||||
# Uncomment this to suppress that and remain silent
|
||||
# startupPrintMessageToStderr = false
|
||||
|
||||
# Chat some stuff to stderr, for use in things like malkovich chat to OGS.
|
||||
# ogsChatToStderr = true
|
||||
|
||||
# Configure the maximum length of analysis printed out by lz-analyze and other places.
|
||||
# Controls the number of moves after the first move in a variation.
|
||||
# analysisPVLen = 9
|
||||
|
||||
# Report winrates for chat and analysis as (BLACK|WHITE|SIDETOMOVE).
|
||||
# Default is SIDETOMOVE, which is what tools that use LZ probably also expect
|
||||
# reportAnalysisWinratesAs = SIDETOMOVE
|
||||
|
||||
# Default rules------------------------------------------------------------------------------------
|
||||
# See https://lightvector.github.io/KataGo/rules.html for a description of the rules.
|
||||
# These rules are defaults and can be changed mid-run by several custom GTP commands.
|
||||
# See https://github.com/lightvector/KataGo/blob/master/docs/GTP_Extensions.md for those commands.
|
||||
|
||||
# koRule = SIMPLE # Simple ko rules (triple ko = no result)
|
||||
koRule = POSITIONAL # Positional superko
|
||||
# koRule = SITUATIONAL # Situational superko
|
||||
|
||||
scoringRule = AREA # Area scoring
|
||||
# scoringRule = TERRITORY # Territory scoring (uses a sort of special computer-friendly territory ruleset)
|
||||
|
||||
taxRule = NONE # All surrounded empty points are scored
|
||||
# taxRule = SEKI # Eyes in seki do NOT count as points
|
||||
# taxRule = ALL # All groups are taxed up to 2 points for the two eyes needed to live
|
||||
|
||||
multiStoneSuicideLegal = true #Is multiple-stone suicide legal? (Single-stone suicide is always illegal).
|
||||
|
||||
hasButton = false # Set to true when area scoring to award 0.5 points to the first pass.
|
||||
|
||||
whiteHandicapBonus = 0 # In handicap games, give white no compensation for black's handicap stones (Tromp-taylor, NZ, JP)
|
||||
# whiteHandicapBonus = N-1 # In handicap games, give white N-1 points for black's handicap stones (AGA)
|
||||
# whiteHandicapBonus = N # In handicap games, give white N points for black's handicap stones (Chinese)
|
||||
|
||||
# Bot behavior---------------------------------------------------------------------------------------
|
||||
|
||||
# Resignation -------------
|
||||
|
||||
# Resignation occurs if for at least resignConsecTurns in a row,
|
||||
# the winLossUtility (which is on a [-1,1] scale) is below resignThreshold.
|
||||
allowResignation = true
|
||||
resignThreshold = -0.98
|
||||
resignConsecTurns = 3
|
||||
|
||||
# Handicap -------------
|
||||
|
||||
# Assume that if black makes many moves in a row right at the start of the game, then the game is a handicap game.
|
||||
# This is necessary on some servers and for some GUIs and also when initializing from many SGF files, which may
|
||||
# set up a handicap games using repeated GTP "play" commands for black rather than GTP "place_free_handicap" commands.
|
||||
# However, it may also lead to incorrect understanding of komi if whiteHandicapBonus is used and a server does NOT
|
||||
# have such a practice.
|
||||
# Defaults to true! Uncomment and set to false to disable this behavior.
|
||||
# assumeMultipleStartingBlackMovesAreHandicap = true
|
||||
|
||||
# Makes katago dynamically adjust to play more aggressively in handicap games based on the handicap and the current state of the game.
|
||||
# Comment to disable this and make KataGo play the same always.
|
||||
dynamicPlayoutDoublingAdvantageCapPerOppLead = 0.04
|
||||
# Instead of setting dynamicPlayoutDoublingAdvantageCapPerOppLead, you can uncomment these and set this to a value from -2.0 to 2.0
|
||||
# to set KataGo's aggression to a FIXED level.
|
||||
# Negative makes KataGo behave as if it is much weaker than the opponent, preferring to play defensively
|
||||
# Positive makes KataGo behave as if it is much stronger than the opponent, prefering to play aggressively or even overplay slightly.
|
||||
# playoutDoublingAdvantage = 0.0
|
||||
|
||||
# Controls which side dynamicPlayoutDoublingAdvantageCapPerOppLead or playoutDoublingAdvantage applies to.
|
||||
playoutDoublingAdvantagePla = WHITE
|
||||
|
||||
# Passing and cleanup -------------
|
||||
|
||||
# Make the bot never assume that its pass will end the game, even if passing would end and "win" under Tromp-Taylor rules.
|
||||
# Usually this is a good idea when using it for analysis or playing on servers where scoring may be implemented non-tromp-taylorly.
|
||||
# Defaults to true! Uncomment and set to false to disable this.
|
||||
# conservativePass = true
|
||||
|
||||
# When playing under territory scoring, encourage the bot to fill dame before passing.
|
||||
# This is NOT absolutely guaranteed to work, and possibly in some rare pathological situations will make the bot
|
||||
# play a bad move, losing points. However, it also acts as a safeguard against things like a situation when the opponent must
|
||||
# eventually make a protective move and lose 1 point, where the bot might otherwise assume that the score would be counted as such,
|
||||
# yet without filling the dame to force the opponent to actually make the move.
|
||||
# Defaults to true! Uncomment and set to false to disable this.
|
||||
# fillDameBeforePass = true
|
||||
|
||||
# When using territory scoring, self-play games continue beyond two passes with special cleanup
|
||||
# rules that may be confusing for human players. This option prevents the special cleanup phases from being
|
||||
# reachable when using the bot for GTP play.
|
||||
# Defaults to true! Uncomment and set to false if you want KataGo to be able to enter special cleanup.
|
||||
# For example, if you are testing it against itself, or against another bot that has precisely implemented the rules
|
||||
# documented at https://lightvector.github.io/KataGo/rules.html
|
||||
# preventCleanupPhase = true
|
||||
|
||||
|
||||
# Search limits-----------------------------------------------------------------------------------
|
||||
|
||||
# If provided, limit maximum number of root visits per search to this much. (With tree reuse, visits do count earlier search)
|
||||
maxVisits = 500
|
||||
# If provided, limit maximum number of new playouts per search to this much. (With tree reuse, playouts do not count earlier search)
|
||||
# maxPlayouts = 300
|
||||
# If provided, cap search time at this many seconds (search will still try to follow GTP time controls)
|
||||
# maxTime = 60
|
||||
|
||||
# Ponder on the opponent's turn?
|
||||
ponderingEnabled = false
|
||||
|
||||
# Same limits but for ponder searches if pondering is enabled
|
||||
# maxVisitsPondering = 1000
|
||||
# maxPlayoutsPondering = 1000
|
||||
# maxTimePondering = 60
|
||||
|
||||
# Number of seconds to buffer for lag for GTP time controls
|
||||
lagBuffer = 1.0
|
||||
|
||||
# Number of threads to use in search
|
||||
numSearchThreads = 1
|
||||
|
||||
# Play a little faster if the opponent is passing, for friendliness
|
||||
searchFactorAfterOnePass = 0.50
|
||||
searchFactorAfterTwoPass = 0.25
|
||||
# Play a little faster if super-winning, for friendliess
|
||||
searchFactorWhenWinning = 0.40
|
||||
searchFactorWhenWinningThreshold = 0.95
|
||||
|
||||
# GPU Settings-------------------------------------------------------------------------------
|
||||
|
||||
# Maximum number of positions to send to GPU at once. Note that you will also need to increase numSearchThreads
|
||||
# to make use of this, as every thread in KataGo is synchronous, so with 1 thread max batch will only be 1 anyways.
|
||||
nnMaxBatchSize = 16
|
||||
# Cache up to 2 ** this many neural net evaluations in case of transpositions in the tree.
|
||||
nnCacheSizePowerOfTwo = 19
|
||||
# Size of mutex pool for nnCache is 2 ** this
|
||||
nnMutexPoolSizePowerOfTwo = 15
|
||||
# Randomize board orientation when running neural net evals?
|
||||
nnRandomize = true
|
||||
# If provided, force usage of a specific seed for nnRandomize instead of randomizing
|
||||
# nnRandSeed = abcdefg
|
||||
|
||||
# How many threads should there be to feed positions to the neural net?
|
||||
# Server threads are indexed 0,1,...(n-1) for the purposes of the below GPU settings arguments
|
||||
# that specify which threads should use which GPUs.
|
||||
# NOTE: This parameter is probably ONLY useful if you have multiple GPUs, since each GPU will need a thread.
|
||||
# If you're tuning single-GPU performance, use numSearchThreads instead.
|
||||
numNNServerThreadsPerModel = 1
|
||||
|
||||
# CUDA GPU settings--------------------------------------
|
||||
# These only apply when using CUDA as the backend for inference.
|
||||
# (For GTP, we only ever have one model, when playing matches, we might have more than one, see match_example.cfg)
|
||||
|
||||
# Default behavior tries to guess the 'best' GPU or device
|
||||
# You will want to uncomment and adjust one or more of these lines to take advantage of a multi-gpu machine
|
||||
# cudaDeviceToUse = 0 #use device 0 for all server threads (numNNServerThreadsPerModel) unless otherwise specified per-model or per-thread-per-model
|
||||
# cudaDeviceToUseModel0 = 3 #use device 3 for model 0 for all threads unless otherwise specified per-thread for this model
|
||||
# cudaDeviceToUseModel1 = 2 #use device 2 for model 1 for all threads unless otherwise specified per-thread for this model
|
||||
# cudaDeviceToUseModel0Thread0 = 3 #use device 3 for model 0, server thread 0
|
||||
# cudaDeviceToUseModel0Thread1 = 2 #use device 2 for model 0, server thread 1
|
||||
|
||||
# Uncomment these on NVIDIA devices with FP16 tensor cores for probably a speedup, at the cost of introducing some precision loss in the nn calculation.
|
||||
# cudaUseFP16 = true
|
||||
# cudaUseNHWC = true
|
||||
|
||||
# OpenCL GPU settings--------------------------------------
|
||||
# These only apply when using OpenCL as the backend for inference.
|
||||
# (For GTP, we only ever have one model, when playing matches, we might have more than one, see match_example.cfg)
|
||||
|
||||
# Default behavior tries to guess the 'best' GPU or device
|
||||
# You will want to uncomment and adjust one or more of these lines to take advantage of a multi-gpu machine
|
||||
# openclDeviceToUse = 0 #use device 0 for all server threads (numNNServerThreadsPerModel) unless otherwise specified per-model or per-thread-per-model
|
||||
# openclDeviceToUseModel0 = 3 #use device 3 for model 0 for all threads unless otherwise specified per-thread for this model
|
||||
# openclDeviceToUseModel1 = 2 #use device 2 for model 1 for all threads unless otherwise specified per-thread for this model
|
||||
# openclDeviceToUseModel0Thread0 = 3 #use device 3 for model 0, server thread 0
|
||||
# openclDeviceToUseModel0Thread1 = 2 #use device 2 for model 0, server thread 1
|
||||
|
||||
# Uncomment to tune OpenCL for every board size separately, rather than only the largest possible size
|
||||
# openclReTunePerBoardSize = true
|
||||
|
||||
# Root move selection and biases------------------------------------------------------------------------------
|
||||
|
||||
# If provided, force usage of a specific seed for various things in the search instead of randomizing
|
||||
# searchRandSeed = hijklmn
|
||||
|
||||
# Temperature for the early game, randomize between chosen moves with this temperature
|
||||
chosenMoveTemperatureEarly = 0.5
|
||||
# Decay temperature for the early game by 0.5 every this many moves, scaled with board size.
|
||||
chosenMoveTemperatureHalflife = 19
|
||||
# At the end of search after the early game, randomize between chosen moves with this temperature
|
||||
chosenMoveTemperature = 0.10
|
||||
# Subtract this many visits from each move prior to applying chosenMoveTemperature
|
||||
# (unless all moves have too few visits) to downweight unlikely moves
|
||||
chosenMoveSubtract = 0
|
||||
# The same as chosenMoveSubtract but only prunes moves that fall below the threshold, does not affect moves above
|
||||
chosenMovePrune = 1
|
||||
|
||||
# Use dirichlet noise for the root node policy?
|
||||
rootNoiseEnabled = false
|
||||
# Dirichlet noise alpha is set to this divided by number of legal moves. 10.83 produces an alpha of 0.03 on an empty 19x19 board.
|
||||
rootDirichletNoiseTotalConcentration = 10.83
|
||||
# Proportion of root policy that is noise
|
||||
rootDirichletNoiseWeight = 0.25
|
||||
|
||||
# Number of symmetries to sample (WITH replacement) and average at the root
|
||||
rootNumSymmetriesToSample = 1
|
||||
|
||||
# Using LCB for move selection?
|
||||
useLcbForSelection = true
|
||||
# How many stdevs a move needs to be better than another for LCB selection
|
||||
lcbStdevs = 5.0
|
||||
# Only use LCB override when a move has this proportion of visits as the top move
|
||||
minVisitPropForLCB = 0.15
|
||||
|
||||
# Internal params------------------------------------------------------------------------------
|
||||
|
||||
# Scales the utility of winning/losing
|
||||
winLossUtilityFactor = 1.0
|
||||
# Scales the utility for trying to maximize score
|
||||
staticScoreUtilityFactor = 0.10
|
||||
dynamicScoreUtilityFactor = 0.30
|
||||
# Adjust dynamic score center this proportion of the way towards zero, capped at a reasonable amount.
|
||||
dynamicScoreCenterZeroWeight = 0.20
|
||||
dynamicScoreCenterScale = 0.75
|
||||
# The utility of getting a "no result" due to triple ko or other long cycle in non-superko rulesets (-1 to 1)
|
||||
noResultUtilityForWhite = 0.0
|
||||
# The number of wins that a draw counts as, for white. (0 to 1)
|
||||
drawEquivalentWinsForWhite = 0.5
|
||||
|
||||
# Exploration constant for mcts
|
||||
cpuctExploration = 0.9
|
||||
cpuctExplorationLog = 0.6
|
||||
# FPU reduction constant for mcts
|
||||
fpuReductionMax = 0.2
|
||||
rootFpuReductionMax = 0.1
|
||||
# Use parent average value for fpu base point instead of point value net estimate
|
||||
fpuUseParentAverage = true
|
||||
# Amount to apply a downweighting of children with very bad values relative to good ones
|
||||
valueWeightExponent = 0.5
|
||||
# Slight incentive for the bot to behave human-like with regard to passing at the end, filling the dame,
|
||||
# not wasting time playing in its own territory, etc, and not play moves that are equivalent in terms of
|
||||
# points but a bit more unfriendly to humans.
|
||||
rootEndingBonusPoints = 0.5
|
||||
# Make the bot prune useless moves that are just prolonging the game to avoid losing yet
|
||||
rootPruneUselessMoves = true
|
||||
|
||||
# How big to make the mutex pool for search synchronization
|
||||
mutexPoolSize = 8192
|
||||
# How many virtual losses to add when a thread descends through a node
|
||||
numVirtualLossesPerThread = 1
|
||||
@@ -1,305 +0,0 @@
|
||||
# Example config for C++ (non-python) gtp bot
|
||||
|
||||
# RUNNING ON AN ONLINE SERVER OR IN A REAL TOURNAMENT OR MATCH:
|
||||
# If you plan to do so, you may want to read through the "Rules" section
|
||||
# below carefully for proper handling of komi and handicap games and end-of-game cleanup
|
||||
# and various other details.
|
||||
|
||||
# NOTES ABOUT PERFORMANCE AND MEMORY USAGE:
|
||||
# You will likely want to tune one or more the following:
|
||||
#
|
||||
# numSearchThreads:
|
||||
# The number of CPU threads to use. If your GPU is powerful, it can actually be much higher than
|
||||
# the number of cores on your processor because you will need many threads to feed large enough
|
||||
# batches to make good use of the GPU.
|
||||
#
|
||||
# The "./katago benchmark" command can help you tune this parameter, as well as to test out the effect
|
||||
# of changes to any of the other parameters below!
|
||||
#
|
||||
# nnMaxBatchSize:
|
||||
# The maximum GPU batch size. Should often be at least as large as numSearchThreads.
|
||||
# Larger won't do anything, but also won't hurt except use a little bit more GPU memory.
|
||||
# Smaller can be fine if you have more than one GPU, since the GPUs will be sharing the work
|
||||
# of servicing the CPU threads.
|
||||
#
|
||||
# cudaUseFP16 and cudaUseNHWC:
|
||||
# These have a good chance of improving peformance at larger threads/batch sizes if
|
||||
# you are using the CUDA implementation with an NVIDIA GPU with FP16 tensor cores.
|
||||
#
|
||||
# nnCacheSizePowerOfTwo:
|
||||
# This controls the NN Cache size, which is the primary RAM/memory use.
|
||||
# Increase this if you don't mind the memory use and want better performance for searches with
|
||||
# tens of thousands of visits or more. Decrease this if you want to limit memory usage.
|
||||
#
|
||||
# If you're someone who is happy to do a bit of math - each neural net entry takes very
|
||||
# approximately 1.5KB, except when using whole-board ownership/territory visualizations, each
|
||||
# entry will take very approximately 3KB. The number of entries is (2 ** nnCacheSizePowerOfTwo),
|
||||
# for example 2 ** 18 = 262144.
|
||||
#
|
||||
# OTHER NOTES:
|
||||
# If you have more than one GPU, take a look at "OpenCL GPU settings" or "CUDA GPU settings" below.
|
||||
#
|
||||
# If using OpenCL, you will want to verify that KataGo is picking up the correct device!
|
||||
# (e.g. some systems may have both an Intel CPU OpenCL and GPU OpenCL, if KataGo appears to pick
|
||||
# the wrong one, you correct this by specifying "openclGpuToUse" below).
|
||||
#
|
||||
# You may also want to adjust "maxVisits", "ponderingEnabled", "resignThreshold", and possibly
|
||||
# other parameters depending on your intended usage.
|
||||
|
||||
|
||||
# Logs------------------------------------------------------------------------------------
|
||||
|
||||
# Where to output log?
|
||||
logFile = gtp.log
|
||||
# Logging options
|
||||
logAllGTPCommunication = true
|
||||
logSearchInfo = true
|
||||
logToStderr = false
|
||||
|
||||
# KataGo will display some info to stderr on GTP startup
|
||||
# Uncomment this to suppress that and remain silent
|
||||
# startupPrintMessageToStderr = false
|
||||
|
||||
# Chat some stuff to stderr, for use in things like malkovich chat to OGS.
|
||||
# ogsChatToStderr = true
|
||||
|
||||
# Configure the maximum length of analysis printed out by lz-analyze and other places.
|
||||
# Controls the number of moves after the first move in a variation.
|
||||
# analysisPVLen = 9
|
||||
|
||||
# Report winrates for chat and analysis as (BLACK|WHITE|SIDETOMOVE).
|
||||
# Default is SIDETOMOVE, which is what tools that use LZ probably also expect
|
||||
# reportAnalysisWinratesAs = SIDETOMOVE
|
||||
|
||||
# Default rules------------------------------------------------------------------------------------
|
||||
# See https://lightvector.github.io/KataGo/rules.html for a description of the rules.
|
||||
# These rules are defaults and can be changed mid-run by several custom GTP commands.
|
||||
# See https://github.com/lightvector/KataGo/blob/master/docs/GTP_Extensions.md for those commands.
|
||||
|
||||
koRule = SIMPLE # Simple ko rules (triple ko = no result)
|
||||
# koRule = POSITIONAL # Positional superko
|
||||
# koRule = SITUATIONAL # Situational superko
|
||||
|
||||
# scoringRule = AREA # Area scoring
|
||||
scoringRule = TERRITORY # Territory scoring (uses a sort of special computer-friendly territory ruleset)
|
||||
|
||||
# taxRule = NONE # All surrounded empty points are scored
|
||||
taxRule = SEKI # Eyes in seki do NOT count as points
|
||||
# taxRule = ALL # All groups are taxed up to 2 points for the two eyes needed to live
|
||||
|
||||
multiStoneSuicideLegal = false #Is multiple-stone suicide legal? (Single-stone suicide is always illegal).
|
||||
|
||||
hasButton = false # Set to true when area scoring to award 0.5 points to the first pass.
|
||||
|
||||
whiteHandicapBonus = 0 # In handicap games, give white no compensation for black's handicap stones (Tromp-taylor, NZ, JP)
|
||||
# whiteHandicapBonus = N-1 # In handicap games, give white N-1 points for black's handicap stones (AGA)
|
||||
# whiteHandicapBonus = N # In handicap games, give white N points for black's handicap stones (Chinese)
|
||||
|
||||
# Bot behavior---------------------------------------------------------------------------------------
|
||||
|
||||
# Resignation -------------
|
||||
|
||||
# Resignation occurs if for at least resignConsecTurns in a row,
|
||||
# the winLossUtility (which is on a [-1,1] scale) is below resignThreshold.
|
||||
allowResignation = true
|
||||
resignThreshold = -0.999
|
||||
resignConsecTurns = 3
|
||||
|
||||
# Handicap -------------
|
||||
|
||||
# Assume that if black makes many moves in a row right at the start of the game, then the game is a handicap game.
|
||||
# This is necessary on some servers and for some GUIs and also when initializing from many SGF files, which may
|
||||
# set up a handicap games using repeated GTP "play" commands for black rather than GTP "place_free_handicap" commands.
|
||||
# However, it may also lead to incorrect understanding of komi if whiteHandicapBonus is used and a server does NOT
|
||||
# have such a practice.
|
||||
# Defaults to true! Uncomment and set to false to disable this behavior.
|
||||
# assumeMultipleStartingBlackMovesAreHandicap = true
|
||||
|
||||
# Makes katago dynamically adjust to play more aggressively in handicap games based on the handicap and the current state of the game.
|
||||
# Comment to disable this and make KataGo play the same always.
|
||||
dynamicPlayoutDoublingAdvantageCapPerOppLead = 0.04
|
||||
# Instead of setting dynamicPlayoutDoublingAdvantageCapPerOppLead, you can uncomment these and set this to a value from -2.0 to 2.0
|
||||
# to set KataGo's aggression to a FIXED level.
|
||||
# Negative makes KataGo behave as if it is much weaker than the opponent, preferring to play defensively
|
||||
# Positive makes KataGo behave as if it is much stronger than the opponent, prefering to play aggressively or even overplay slightly.
|
||||
# playoutDoublingAdvantage = 0.0
|
||||
|
||||
# Controls which side dynamicPlayoutDoublingAdvantageCapPerOppLead or playoutDoublingAdvantage applies to.
|
||||
playoutDoublingAdvantagePla = WHITE
|
||||
|
||||
# Passing and cleanup -------------
|
||||
|
||||
# Make the bot never assume that its pass will end the game, even if passing would end and "win" under Tromp-Taylor rules.
|
||||
# Usually this is a good idea when using it for analysis or playing on servers where scoring may be implemented non-tromp-taylorly.
|
||||
# Defaults to true! Uncomment and set to false to disable this.
|
||||
conservativePass = true
|
||||
|
||||
# When playing under territory scoring, encourage the bot to fill dame before passing.
|
||||
# This is NOT absolutely guaranteed to work, and possibly in some rare pathological situations will make the bot
|
||||
# play a bad move, losing points. However, it also acts as a safeguard against things like a situation when the opponent must
|
||||
# eventually make a protective move and lose 1 point, where the bot might otherwise assume that the score would be counted as such,
|
||||
# yet without filling the dame to force the opponent to actually make the move.
|
||||
# Defaults to true! Uncomment and set to false to disable this.
|
||||
# fillDameBeforePass = true
|
||||
|
||||
# When using territory scoring, self-play games continue beyond two passes with special cleanup
|
||||
# rules that may be confusing for human players. This option prevents the special cleanup phases from being
|
||||
# reachable when using the bot for GTP play.
|
||||
# Defaults to true! Uncomment and set to false if you want KataGo to be able to enter special cleanup.
|
||||
# For example, if you are testing it against itself, or against another bot that has precisely implemented the rules
|
||||
# documented at https://lightvector.github.io/KataGo/rules.html
|
||||
# preventCleanupPhase = true
|
||||
|
||||
|
||||
# Search limits-----------------------------------------------------------------------------------
|
||||
|
||||
# If provided, limit maximum number of root visits per search to this much. (With tree reuse, visits do count earlier search)
|
||||
maxVisits = 2500
|
||||
# If provided, limit maximum number of new playouts per search to this much. (With tree reuse, playouts do not count earlier search)
|
||||
# maxPlayouts = 300
|
||||
# If provided, cap search time at this many seconds (search will still try to follow GTP time controls)
|
||||
# maxTime = 60
|
||||
|
||||
# Ponder on the opponent's turn?
|
||||
ponderingEnabled = false
|
||||
|
||||
# Same limits but for ponder searches if pondering is enabled
|
||||
# maxVisitsPondering = 1000
|
||||
# maxPlayoutsPondering = 1000
|
||||
# maxTimePondering = 60
|
||||
|
||||
# Number of seconds to buffer for lag for GTP time controls
|
||||
lagBuffer = 1.0
|
||||
|
||||
# Number of threads to use in search
|
||||
numSearchThreads = 4
|
||||
|
||||
# Play a little faster if the opponent is passing, for friendliness
|
||||
searchFactorAfterOnePass = 0.50
|
||||
searchFactorAfterTwoPass = 0.25
|
||||
# Play a little faster if super-winning, for friendliess
|
||||
searchFactorWhenWinning = 0.40
|
||||
searchFactorWhenWinningThreshold = 0.95
|
||||
|
||||
# GPU Settings-------------------------------------------------------------------------------
|
||||
|
||||
# Maximum number of positions to send to GPU at once. Note that you will also need to increase numSearchThreads
|
||||
# to make use of this, as every thread in KataGo is synchronous, so with 1 thread max batch will only be 1 anyways.
|
||||
nnMaxBatchSize = 16
|
||||
# Cache up to 2 ** this many neural net evaluations in case of transpositions in the tree.
|
||||
nnCacheSizePowerOfTwo = 20
|
||||
# Size of mutex pool for nnCache is 2 ** this
|
||||
nnMutexPoolSizePowerOfTwo = 16
|
||||
# Randomize board orientation when running neural net evals?
|
||||
nnRandomize = true
|
||||
# If provided, force usage of a specific seed for nnRandomize instead of randomizing
|
||||
# nnRandSeed = abcdefg
|
||||
|
||||
# How many threads should there be to feed positions to the neural net?
|
||||
# Server threads are indexed 0,1,...(n-1) for the purposes of the below GPU settings arguments
|
||||
# that specify which threads should use which GPUs.
|
||||
# NOTE: This parameter is probably ONLY useful if you have multiple GPUs, since each GPU will need a thread.
|
||||
# If you're tuning single-GPU performance, use numSearchThreads instead.
|
||||
numNNServerThreadsPerModel = 1
|
||||
|
||||
# CUDA GPU settings--------------------------------------
|
||||
# These only apply when using CUDA as the backend for inference.
|
||||
# (For GTP, we only ever have one model, when playing matches, we might have more than one, see match_example.cfg)
|
||||
|
||||
# Default behavior tries to guess the 'best' GPU or device
|
||||
# You will want to uncomment and adjust one or more of these lines to take advantage of a multi-gpu machine
|
||||
# cudaDeviceToUse = 0 #use device 0 for all server threads (numNNServerThreadsPerModel) unless otherwise specified per-model or per-thread-per-model
|
||||
# cudaDeviceToUseModel0 = 3 #use device 3 for model 0 for all threads unless otherwise specified per-thread for this model
|
||||
# cudaDeviceToUseModel1 = 2 #use device 2 for model 1 for all threads unless otherwise specified per-thread for this model
|
||||
# cudaDeviceToUseModel0Thread0 = 3 #use device 3 for model 0, server thread 0
|
||||
# cudaDeviceToUseModel0Thread1 = 2 #use device 2 for model 0, server thread 1
|
||||
|
||||
# Uncomment these on NVIDIA devices with FP16 tensor cores for probably a speedup, at the cost of introducing some precision loss in the nn calculation.
|
||||
# cudaUseFP16 = true
|
||||
# cudaUseNHWC = true
|
||||
|
||||
# OpenCL GPU settings--------------------------------------
|
||||
# These only apply when using OpenCL as the backend for inference.
|
||||
# (For GTP, we only ever have one model, when playing matches, we might have more than one, see match_example.cfg)
|
||||
|
||||
# Default behavior tries to guess the 'best' GPU or device
|
||||
# You will want to uncomment and adjust one or more of these lines to take advantage of a multi-gpu machine
|
||||
# openclDeviceToUse = 0 #use device 0 for all server threads (numNNServerThreadsPerModel) unless otherwise specified per-model or per-thread-per-model
|
||||
# openclDeviceToUseModel0 = 3 #use device 3 for model 0 for all threads unless otherwise specified per-thread for this model
|
||||
# openclDeviceToUseModel1 = 2 #use device 2 for model 1 for all threads unless otherwise specified per-thread for this model
|
||||
# openclDeviceToUseModel0Thread0 = 3 #use device 3 for model 0, server thread 0
|
||||
# openclDeviceToUseModel0Thread1 = 2 #use device 2 for model 0, server thread 1
|
||||
|
||||
# Uncomment to tune OpenCL for every board size separately, rather than only the largest possible size
|
||||
# openclReTunePerBoardSize = true
|
||||
|
||||
# Root move selection and biases------------------------------------------------------------------------------
|
||||
|
||||
# If provided, force usage of a specific seed for various things in the search instead of randomizing
|
||||
# searchRandSeed = hijklmn
|
||||
|
||||
# Temperature for the early game, randomize between chosen moves with this temperature
|
||||
chosenMoveTemperatureEarly = 0.5
|
||||
# Decay temperature for the early game by 0.5 every this many moves, scaled with board size.
|
||||
chosenMoveTemperatureHalflife = 19
|
||||
# At the end of search after the early game, randomize between chosen moves with this temperature
|
||||
chosenMoveTemperature = 0.10
|
||||
# Subtract this many visits from each move prior to applying chosenMoveTemperature
|
||||
# (unless all moves have too few visits) to downweight unlikely moves
|
||||
chosenMoveSubtract = 0
|
||||
# The same as chosenMoveSubtract but only prunes moves that fall below the threshold, does not affect moves above
|
||||
chosenMovePrune = 1
|
||||
|
||||
# Use dirichlet noise for the root node policy?
|
||||
rootNoiseEnabled = false
|
||||
# Dirichlet noise alpha is set to this divided by number of legal moves. 10.83 produces an alpha of 0.03 on an empty 19x19 board.
|
||||
rootDirichletNoiseTotalConcentration = 10.83
|
||||
# Proportion of root policy that is noise
|
||||
rootDirichletNoiseWeight = 0.25
|
||||
|
||||
# Number of symmetries to sample (WITH replacement) and average at the root
|
||||
rootNumSymmetriesToSample = 1
|
||||
|
||||
# Using LCB for move selection?
|
||||
useLcbForSelection = true
|
||||
# How many stdevs a move needs to be better than another for LCB selection
|
||||
lcbStdevs = 5.0
|
||||
# Only use LCB override when a move has this proportion of visits as the top move
|
||||
minVisitPropForLCB = 0.15
|
||||
|
||||
# Internal params------------------------------------------------------------------------------
|
||||
|
||||
# Scales the utility of winning/losing
|
||||
winLossUtilityFactor = 0.4
|
||||
# Scales the utility for trying to maximize score
|
||||
staticScoreUtilityFactor = 0.2
|
||||
dynamicScoreUtilityFactor = 0.4
|
||||
# Adjust dynamic score center this proportion of the way towards zero, capped at a reasonable amount.
|
||||
dynamicScoreCenterZeroWeight = 0.20
|
||||
dynamicScoreCenterScale = 0.75
|
||||
# The utility of getting a "no result" due to triple ko or other long cycle in non-superko rulesets (-1 to 1)
|
||||
noResultUtilityForWhite = 0.0
|
||||
# The number of wins that a draw counts as, for white. (0 to 1)
|
||||
drawEquivalentWinsForWhite = 0.5
|
||||
|
||||
# Exploration constant for mcts
|
||||
cpuctExploration = 2.0
|
||||
cpuctExplorationLog = 0.8
|
||||
# FPU reduction constant for mcts
|
||||
fpuReductionMax = 0.2
|
||||
rootFpuReductionMax = 0.1
|
||||
# Use parent average value for fpu base point instead of point value net estimate
|
||||
fpuUseParentAverage = true
|
||||
# Amount to apply a downweighting of children with very bad values relative to good ones
|
||||
valueWeightExponent = 0.5
|
||||
# Slight incentive for the bot to behave human-like with regard to passing at the end, filling the dame,
|
||||
# not wasting time playing in its own territory, etc, and not play moves that are equivalent in terms of
|
||||
# points but a bit more unfriendly to humans.
|
||||
rootEndingBonusPoints = 0.5
|
||||
# Make the bot prune useless moves that are just prolonging the game to avoid losing yet
|
||||
rootPruneUselessMoves = true
|
||||
|
||||
# How big to make the mutex pool for search synchronization
|
||||
mutexPoolSize = 8192
|
||||
# How many virtual losses to add when a thread descends through a node
|
||||
numVirtualLossesPerThread = 1
|
||||
Binary file not shown.
@@ -4,36 +4,38 @@ Manual
|
||||
Installation
|
||||
------------
|
||||
* pip install kivy
|
||||
* change the `engine.command` field in `config.json` to your kata installation (for example, to `path/to/lizzie/katago/katago.exe`)
|
||||
* start the app by running `python katrain.py` (or `python3` if needed)
|
||||
* On linux, change the `engine.command` field in `config.json` to your kata v1.3+ installation.
|
||||
* start the app by running `python katrain.py`
|
||||
|
||||
Options
|
||||
-------
|
||||
* Top row options
|
||||
* Check box options
|
||||
* Eval: show the coloured dots on the moves for this player.
|
||||
* Hints: show suggested moves for this player.
|
||||
* Undo: automatically undo poor moves for this player and make them try again.
|
||||
* Lock AI: disallow extra undos, changing hints options, changing auto move, or AI move.
|
||||
* AI: let the AI control this player. Check both for self-play.
|
||||
* Show owner: show expected control of territory.
|
||||
* Lock AI: disallow extra undos, changing hints options, changing auto move, or AI move.
|
||||
* Fast: use a lower number of max visits for evaluation/AI move.
|
||||
* Balance score: Deliberately make sub-optimal moves as the AI in an attempt to balance the score towawrds a slight win.
|
||||
|
||||
* Temperature/Evaluation/Score: Not that these fields can be hidden by clicking on the text.
|
||||
* Temperature is the point difference between passing and the best move.
|
||||
* Evaluation is where on this scale the last move was, from 0% (equivalent to a pass) to 100% (best move).
|
||||
This can be < 0% in case of suicidal moves, or >100% when Kata did not consider the move before, or further analysis shows it to be better than the best one considered.
|
||||
* Score: Expected score.
|
||||
* Score: How far one player is ahead.
|
||||
|
||||
Play
|
||||
----
|
||||
|
||||
* Play against the AI
|
||||
* Turn on auto move.
|
||||
* Turn on AI for the chosen player.
|
||||
* Choose whether to turn on `balance score` to make the AI play slack moves.
|
||||
* Choose whether to turn on `undo` for your colour to be prompted to re-try poor moves.
|
||||
* Choose whether or not to turn on `fast` to make the AI play faster but read less deeply (NB: with balance score, faster AI can be a stronger opponent, as there are fewer mediocre moves considered).
|
||||
* Possibly lock AI to prevent yourself from peeking at hints, etc.
|
||||
* Possibly hide score or temperature.
|
||||
* Possibly hide evaluation for the AI player.
|
||||
* Play by playing a move or clicking AI move if you want white.
|
||||
* If you chose AI to play black, click AI move for the first move.
|
||||
|
||||
* Engine-assisted play
|
||||
* Turn off auto move.
|
||||
@@ -43,7 +45,7 @@ Play
|
||||
* Play with a friend with instant feedback and/or undos for both, or see how many stones stronger you are with one undo. (But please play unranked and be honest to your opponent on what you're doing)
|
||||
|
||||
* Analysis
|
||||
* Copy the SGF into the text box
|
||||
* Copy the SGF into the text box. Note that branches are not supported and will lead to strange results.
|
||||
* Choose whether or not to turn on `fast` to make the AI weaker but analyze faster.
|
||||
* Click `Analyze`
|
||||
|
||||
@@ -61,9 +63,7 @@ The `trainer` block has the following options to tweak:
|
||||
* `balance_play_min_eval`: when needing to balance score, the AI will pick a move which is at least this good.
|
||||
* `balance_play_min_visits`: never pick a move with fewer playouts than this.
|
||||
* `undo_eval_threshold`, `undo_point_threshold`: prompt player to undo if move is worse than this in terms of points AND evaluation.
|
||||
* `undo_outdated_eval_threshold`: don't prompt undo if last move's evaluation is >= `undo_eval_threshold` and the NEW evaluation is greater than this. (this decreases frustration when hints are on, or when kata over-estimates the best move).
|
||||
* `num_undo_prompts`: automatically undo bad moves when `undo` is on at most this many times.
|
||||
* `show_ai_options`: show which moves the AI considered.
|
||||
|
||||
The cfg file has additional configuration for kata. In particular, it changes the default to being more exploratory and score-based (and therefore nicer as an opponent, but weaker as analysis tool).
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ class Move:
|
||||
self.analysis = None
|
||||
self.pass_analysis = None
|
||||
self.ownership = None
|
||||
self.x_comment = ""
|
||||
self.auto_undid = False
|
||||
self.move_number = 0
|
||||
|
||||
def __repr__(self):
|
||||
@@ -61,11 +63,13 @@ class Move:
|
||||
score = score or self.score
|
||||
return f"{'B' if score >= 0 else 'W'}+{abs(score):.1f}"
|
||||
|
||||
@property
|
||||
def comment(self,sgf=False):
|
||||
def comment(self,sgf=False, eval=False, hints=False):
|
||||
if not self.parent: # root
|
||||
return ""
|
||||
text = f"Move {self.move_number}: {self.bw_player()} @ {self.gtp()} {'(AI Move)' if self.robot else ''}\n"
|
||||
text = f"Move {self.move_number}: {self.bw_player()} {self.gtp()} {'(AI Move)' if self.robot else ''}\n"
|
||||
text += self.x_comment
|
||||
text += "".join(f"Auto undid move {m.gtp()} ({m.evaluation*100:.1f}% efficient)\n" for m in self.children if m.auto_undid)
|
||||
|
||||
if self.analysis_ready:
|
||||
score, _, temperature = self.temperature_stats
|
||||
if sgf:
|
||||
@@ -73,13 +77,14 @@ class Move:
|
||||
text += f"Temperature: {temperature:.1f}\n"
|
||||
if self.parent and self.parent.analysis_ready:
|
||||
prev_best_score, prev_worst_score, prev_temperature = self.parent.temperature_stats
|
||||
text += f"Top move was {self.format_score(prev_best_score)} @ {self.parent.analysis[0]['move']}\n"
|
||||
if sgf or hints:
|
||||
text += f"Top move was {self.parent.analysis[0]['move']} ({self.format_score(prev_best_score)})\n"
|
||||
text += f"Pass score was {self.format_score(prev_worst_score)}\n"
|
||||
if prev_temperature < 0.5:
|
||||
text += f"Previous temperature ({prev_temperature}) too low for evaluation\n"
|
||||
else:
|
||||
if eval:
|
||||
text += f"Evaluation: {100*self.evaluation:.1f}%\n"
|
||||
if sgf or eval:
|
||||
text += f"Evaluation: {100*self.evaluation:.1f}% efficient\n"
|
||||
outdated_evaluation = self.outdated_evaluation
|
||||
if outdated_evaluation and outdated_evaluation > self.evaluation and outdated_evaluation > self.evaluation + 0.01:
|
||||
text += f"(Was considered last move as: {100 * outdated_evaluation :.1f}%)\n"
|
||||
@@ -94,7 +99,7 @@ class Move:
|
||||
@property
|
||||
def evaluation_info(self):
|
||||
if self.parent and self.parent.analysis_ready and self.analysis_ready:
|
||||
return self.evaluation,self.parent.temperature_stats[2]
|
||||
return self.evaluation, self.parent.temperature_stats[2]
|
||||
else:
|
||||
return None,None
|
||||
|
||||
@@ -264,7 +269,7 @@ class Board:
|
||||
def moves(self) -> list: # flat list of moves to current
|
||||
moves = []
|
||||
p = self.current_move
|
||||
while p != self.root:
|
||||
while p is not self.root: # NB == is wrong here
|
||||
moves.append(p)
|
||||
p = p.parent
|
||||
return moves[::-1]
|
||||
|
||||
+2
-4
@@ -3,12 +3,11 @@
|
||||
"pass_visits": 200,
|
||||
"pass_visits_fast": 50,
|
||||
"visits": 3500,
|
||||
"visits_fast": 1500,
|
||||
"nopass_visits": 10
|
||||
"visits_fast": 1500
|
||||
},
|
||||
"board": {
|
||||
"size": 19,
|
||||
"komi": 7.5
|
||||
"komi": 6.5
|
||||
},
|
||||
"ui": {
|
||||
"size_min": 1,
|
||||
@@ -35,7 +34,6 @@
|
||||
"balance_play_min_eval": 0.875,
|
||||
"balance_play_min_visits": 20,
|
||||
"undo_eval_threshold": 0.875,
|
||||
"undo_outdated_eval_threshold": 0.8,
|
||||
"undo_point_threshold": 1,
|
||||
"num_undo_prompts": 1
|
||||
},
|
||||
|
||||
+24
-58
@@ -26,7 +26,6 @@ class EngineControls(GridLayout):
|
||||
[analysis_settings["pass_visits"], analysis_settings["visits"]],
|
||||
[analysis_settings["pass_visits_fast"], analysis_settings["visits_fast"]],
|
||||
]
|
||||
self.min_nopass_visits = analysis_settings["nopass_visits"]
|
||||
self.train_settings = Config.get("trainer")
|
||||
self.debug = Config.get("debug")["level"]
|
||||
self.board_size = Config.get("board")["size"]
|
||||
@@ -78,13 +77,11 @@ class EngineControls(GridLayout):
|
||||
print(str(e))
|
||||
self.info.text = f"Illegal move: {str(e)}"
|
||||
return
|
||||
print("PLAYED", move, self.board.stones)
|
||||
self._request_analysis(mr)
|
||||
return mr
|
||||
|
||||
# engine action functions
|
||||
def _do_play(self, *args):
|
||||
print("CURRENT PLAYER", self.board.current_player)
|
||||
move = Move(player=self.board.current_player, coords=args[0])
|
||||
self.play(move)
|
||||
# mr.waiting_for_analysis
|
||||
@@ -93,66 +90,34 @@ class EngineControls(GridLayout):
|
||||
def update_evaluation(self):
|
||||
current_move = self.board.current_move
|
||||
if self.eval.active(current_move.player):
|
||||
self.info.text = current_move.comment
|
||||
self.info.text = current_move.comment(eval=self.eval.active(current_move.player), hints=self.hints.active(current_move.player))
|
||||
self.evaluation.text = ''
|
||||
if current_move.analysis_ready:
|
||||
if current_move.analysis_ready and self.eval.active(current_move.player):
|
||||
self.score.text = current_move.format_score().replace("-", "\u2013")
|
||||
self.temperature.text = f"{current_move.temperature_stats[2]:.1f}"
|
||||
if current_move.parent and current_move.parent.analysis_ready:
|
||||
self.evaluation.text = f"{100 * current_move.evaluation:.1f}%"
|
||||
|
||||
# when to trigger auto undo?
|
||||
# self.undo.disabled = True # undo while waiting for this does weird things
|
||||
# undid = False
|
||||
# self.info.text = ""
|
||||
# if self.auto_undo.active(1 - self.board.current_player):
|
||||
# undid = self._auto_undo(move)
|
||||
# if self.ai_auto.active and not undid:
|
||||
# self._do_aimove(move, True)
|
||||
# self.undo.disabled = False
|
||||
|
||||
def _auto_undo(self, move):
|
||||
if current_move.analysis_ready and current_move.parent and current_move.parent.analysis_ready and not current_move.children:
|
||||
# handle automatic undo
|
||||
if self.auto_undo.active(current_move.player) and not self.ai_auto.active(current_move.player) and not current_move.auto_undid:
|
||||
ts = self.train_settings
|
||||
self.info.text = "Evaluating..."
|
||||
if (
|
||||
move.evaluation
|
||||
and move.evaluation < ts["undo_eval_threshold"]
|
||||
and move.points_lost >= ts["undo_point_threshold"]
|
||||
and ts["num_undo_prompts"] > 0
|
||||
):
|
||||
if move.outdated_evaluation:
|
||||
outdated_points_lost = (1 - move.outdated_evaluation) * move.points_lost / (1 - move.evaluation)
|
||||
# so if the move was not that far off (>undo_outdated_eval_threshold) and according to last move's analysis it was fine, don't undo.
|
||||
if (
|
||||
move.outdated_evaluation
|
||||
and (
|
||||
move.outdated_evaluation >= ts["undo_eval_threshold"]
|
||||
or outdated_points_lost < ts["undo_point_threshold"]
|
||||
)
|
||||
and (
|
||||
move.evaluation > ts["undo_outdated_eval_threshold"]
|
||||
or outdated_points_lost < ts["undo_point_threshold"]
|
||||
)
|
||||
):
|
||||
self.info.text += f"\nBut according to my previous evaluation it was {move.outdated_evaluation*100:.1f}% effective and lost {outdated_points_lost:.1f} point(s), so let's continue anyway.\n"
|
||||
else:
|
||||
if len(self.board.current_move.parent.children) <= ts["num_undo_prompts"]:
|
||||
self.info.text += f"\nLet's try again.\n"
|
||||
# TODO: is this overly generous wrt low visit outdated evaluations?
|
||||
eval = max(current_move.evaluation, current_move.outdated_evaluation or 0)
|
||||
points_lost = (current_move.parent or current_move).temperature_stats[2] * (1 - eval)
|
||||
if eval < ts["undo_eval_threshold"] and points_lost >= ts["undo_point_threshold"]:
|
||||
current_move.auto_undid = True
|
||||
self.board.undo()
|
||||
return True
|
||||
else:
|
||||
evaled_moves = sorted(
|
||||
[m for m in self.board.current_move.parent.children if m.evaluation],
|
||||
key=lambda m: -m.evaluation,
|
||||
)
|
||||
if evaled_moves and evaled_moves[0].coords != move.coords:
|
||||
self.board.undo()
|
||||
self.board.play(evaled_moves[0])
|
||||
summary = "\n".join(f"{m.gtp()}: {100*m.evaluation:.1f}% effective" for m in evaled_moves)
|
||||
self.info.text += f"\nYour moves:\n{summary}.\nLet's continue with {evaled_moves[0].gtp()}.\n"
|
||||
return False
|
||||
if len(current_move.parent.children) >= ts["num_undo_prompts"] + 1:
|
||||
best_move = sorted([m for m in current_move.parent.children], key=lambda m: -(m.evaluation_info[0] or 0) )[0]
|
||||
best_move.x_comment = f"Automatically played as best option after max. {ts['num_undo_prompts']} undo(s).\n"
|
||||
self.board.play(best_move)
|
||||
self.update_evaluation()
|
||||
# ai player doesn't technically need parent ready, but don't want to override waiting for undo
|
||||
elif self.ai_auto.active(1 - current_move.player) and not current_move.children:
|
||||
self._do_aimove()
|
||||
|
||||
def _do_aimove(self, auto=False):
|
||||
def _do_aimove(self):
|
||||
ts = self.train_settings
|
||||
while not self.board.current_move.analysis_ready:
|
||||
self.info.text = "Thinking..."
|
||||
@@ -204,9 +169,9 @@ class EngineControls(GridLayout):
|
||||
sgfmoves = re.findall(r"([BW])\[([a-z]{2})\]", sgf)
|
||||
moves = [Move(player=Move.PLAYERS.index(p.upper()), sgfcoords=(mv, self.board_size)) for p, mv in sgfmoves]
|
||||
for move in moves:
|
||||
self.board.play(move)
|
||||
self.play(move)
|
||||
while not all(m.analysis for m in moves):
|
||||
time.sleep(0.01)
|
||||
time.sleep(0.05)
|
||||
self.info.text = f"{sum([1 if m.analysis else 0 for m in moves])}/{len(moves)} analyzed"
|
||||
|
||||
# analysis thread
|
||||
@@ -215,6 +180,7 @@ class EngineControls(GridLayout):
|
||||
while self.outstanding_analysis_queries:
|
||||
self._send_analysis_query(self.outstanding_analysis_queries.pop(0))
|
||||
line = self.kata.stdout.readline()
|
||||
if self.debug:
|
||||
print("KATA ANALYSIS RECEIVED:", line[:50])
|
||||
self.board.store_analysis(json.loads(line))
|
||||
self.update_evaluation()
|
||||
@@ -242,14 +208,14 @@ class EngineControls(GridLayout):
|
||||
"includeOwnership": True,
|
||||
"maxVisits": self.visits[fast][1],
|
||||
}
|
||||
if self.debug:
|
||||
print("query", query)
|
||||
self._send_analysis_query(query)
|
||||
query.update(
|
||||
{"id": f"PASS_{move_id}", "maxVisits": self.visits[fast][0], "includeOwnership": False}
|
||||
) # TODO: merge?
|
||||
)
|
||||
query["moves"] += [[move.bw_player(next_move=True), "pass"]]
|
||||
query["analyzeTurns"][0] += 1
|
||||
print("pass-query", query)
|
||||
self._send_analysis_query(query)
|
||||
|
||||
|
||||
|
||||
+12
-12
@@ -168,11 +168,11 @@
|
||||
id: auto_undo
|
||||
text: 'undo'
|
||||
on_active: root.parent.board.redraw()
|
||||
CheckBoxHint:
|
||||
size_hint: 0.2, 0.5
|
||||
text: 'lock\nai'
|
||||
id: ai_lock
|
||||
on_active: self.checkbox.disabled = hints.black.disabled = hints.white.disabled = ai_move.disabled = auto_undo.black.disabled = auto_undo.white.disabled = ai_auto.checkbox.disabled = True
|
||||
BWCheckBoxHint:
|
||||
size_hint: 0.166, 0.5
|
||||
text: 'ai'
|
||||
id: ai_auto
|
||||
default_active: False
|
||||
CheckBoxHint:
|
||||
size_hint: 0.2, 0.5
|
||||
id: ownership
|
||||
@@ -189,19 +189,19 @@
|
||||
on_press: root.action("aimove")
|
||||
CheckBoxHint:
|
||||
size_hint: 0.166, 0.5
|
||||
text: 'auto\nmove'
|
||||
id: ai_auto
|
||||
default_active: False
|
||||
text: 'fast'
|
||||
id: ai_fast
|
||||
default_active: True
|
||||
CheckBoxHint:
|
||||
size_hint: 0.166, 0.5
|
||||
text: 'balance\nscore'
|
||||
id: ai_balance
|
||||
default_active: False
|
||||
CheckBoxHint:
|
||||
size_hint: 0.166, 0.5
|
||||
text: 'fast'
|
||||
id: ai_fast
|
||||
default_active: True
|
||||
size_hint: 0.2, 0.5
|
||||
text: 'lock\nai'
|
||||
id: ai_lock
|
||||
on_active: self.checkbox.disabled = hints.black.disabled = hints.white.disabled = ai_move.disabled = auto_undo.black.disabled = auto_undo.white.disabled = ai_auto.checkbox.disabled = True
|
||||
GridLayout:
|
||||
cols: 2
|
||||
rows: 1
|
||||
|
||||
@@ -47,6 +47,12 @@ class BadukPanWidget(Widget):
|
||||
def on_touch_up(self, touch):
|
||||
if self.ghost_stone:
|
||||
self.engine.action("play", self.ghost_stone)
|
||||
else:
|
||||
xd, xp = self._find_closest(touch.x)
|
||||
yd, yp = self._find_closest(touch.y)
|
||||
stones_here = [m for m in self.engine.board.stones if m.coords == (xp,yp)]
|
||||
if stones_here and max(yd, xd) < self.grid_size / 2: # load old comment
|
||||
self.engine.info.text = stones_here[-1].comment(sgf=True)
|
||||
self.ghost_stone = None
|
||||
self.redraw() # remove ghost
|
||||
|
||||
|
||||
Reference in new issue
Block a user