QCUGVSRDRUJD5TSKWFWQ7LTAXCXUQICTZ3CIA2LUCWZWJWNJD67QC RKTDDNSGNOB7K27XI6ZBRXHCBOAMAKM667BUQIQSVZ2YJED2YCPQC FPQHLV6PVRI3KCH3ILEZCT5VZHWO7R7B2VOP22RTSU4YVEXGT6SAC U3JHTSEMJLXNKOMAQJQPZKRW6GRPHYLG6DK53XVADIETKVCS2MFQC RSTSRBUU5TMYSKYBYC3APFOPDMCAPUG4ZLJS2TTAH4EBKAPKB5ZQC BYRGC3FM5PQVL2VDTUYOIDOMIVNMUM6DKD5QUQS2CIIIZPZ2VSPAC WN26XTZ7IZN4WNAVXZ4NKD4CXIU7IC6V7BFNVICNMQUVHBZXBNCAC LT2L5OITYEO7I6P5WA35E5FJ5AUGPMLFYYKPVI4WLBIH65AINECQC KN2H7F5CIEAKA5XQ4NQXAZV25VNZ6AV7Q3M2FVOX2JF7JKMDFDCAC 6X6DDDY32EIHOKTZ2PXAE4G7DJGRC46MCQGWNV2EATJUAHHUDSUAC UXWFBRYCNZIYOGP6MGMT5KGY6NFS566QDDJJZIP3YJODQI5QIHDAC FAYXGKV6PUEUYD7BKKV27RKCIJ44WD4L4ZO5ICC5XD5KK5I7X2LQC O325HSUUTHFZ2BM23FLJVHZKYV742BLUWCDYSYDMIEAZRU6RRO7AC if (config.backpropObserver != null) {while (rootNode!.parent != null) {rootNode = rootNode.parent;}config.backpropObserver!(winner, rootNode, currentNode);}
currentNode.visits += 1;currentNode = currentNode.parent;}}rewardBackProp(Map<PlayerType, double> rewards) {Node<MoveType, PlayerType?>? currentNode = this;Node<MoveType, PlayerType?>? rootNode = this;while (currentNode != null) {rewards.forEach((player, reward) {currentNode?.winsByPlayer.update(player, (value) => value + reward, ifAbsent: () => reward);});var currentPlayerReward = rewards[currentPlayer()]!;// Q[s][a] = (N[s][a]*Q[s][a] + v)/(N[s][a]+1)currentNode.q =(currentNode.visits * currentNode.q + currentPlayerReward) /(currentNode.visits + 1.0);
PlayerType? winner = null;if (config.nnpv == null &&config.useRewards == true &&gameState is RewardProvider) {if (currentDepth >= config.useValueAfterDepth!) {var rewards = (gameState as RewardProvider).rewards();var sortedRewards = List.from(rewards.values);sortedRewards.sort();var highestReward = sortedRewards.last;for (var player in rewards.keys) {if (highestReward == rewards[player]) {return player;}}}}