calcitem / Sanmill

Sanmill is an open-source, UCI-like Mill/Morris/Merrills/Mühle/Malom (and its variants) program with CUI, Flutter GUI and Qt GUI, sharing and freely distributing the code, tools and data needed to deliver this mill game. We do this because we are convinced that open software and open data are key ingredients to make rapid progress.
https://play.google.com/store/apps/details?id=com.calcitem.sanmill
GNU General Public License v3.0
145 stars 21 forks source link

LateInitializationError: Local 'blurPositionColor' has not been initialized. #766

Open calcitem opened 7 months ago

calcitem commented 7 months ago

An user's feedback.

Alse see:

https://github.com/calcitem/Sanmill/pull/421

https://github.com/calcitem/Sanmill/issues/646

Error:

LateInitializationError: Local 'blurPositionColor' has not been initialized.

Stack trace:

#0 LateError._throwLocalNotInitialized (dart:_internal-patch/internal_patch.dart:189)
#1 PiecePainter.paint (package:sanmill/game_page/widgets/painters/piece_painter.dart:157)
#2 RenderCustomPaint._paintWithPainter (package:flutter/src/rendering/custom_paint.dart:588)
#3 RenderCustomPaint.paint (package:flutter/src/rendering/custom_paint.dart:635)
#4 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#5 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#6 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#7 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#8 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#9 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#10 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#11 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#12 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#13 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#14 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#15 _RenderLayoutBuilder.paint (package:flutter/src/widgets/layout_builder.dart:333)
#16 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#17 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#18 RenderBoxContainerDefaultsMixin.defaultPaint (package:flutter/src/rendering/box.dart:2882)
#19 RenderFlex.paint (package:flutter/src/rendering/flex.dart:1040)
#20 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#21 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#22 _RenderSingleChildViewport.paint.paintContents (package:flutter/src/widgets/single_child_scroll_view.dart:538)
#23 _RenderSingleChildViewport.paint (package:flutter/src/widgets/single_child_scroll_view.dart:552)
#24 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#25 PaintingContext._repaintCompositedChild (package:flutter/src/rendering/object.dart:166)
#26 PaintingContext.repaintCompositedChild (package:flutter/src/rendering/object.dart:109)
#27 PaintingContext._compositeChild (package:flutter/src/rendering/object.dart:261)
#28 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:242)
#29 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#30 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#31 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#32 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#33 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#34 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#35 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#36 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#37 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#38 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#39 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#40 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#41 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#42 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#43 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#44 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#45 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#46 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#47 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#48 RenderTransform.paint (package:flutter/src/rendering/proxy_box.dart:2537)
#49 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#50 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#51 RenderClipRect.paint (package:flutter/src/rendering/proxy_box.dart:1541)
#52 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#53 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#54 RenderShiftedBox.paint (package:flutter/src/rendering/shifted_box.dart:74)
#55 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#56 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#57 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#58 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#59 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#60 _RenderLayoutBuilder.paint (package:flutter/src/widgets/layout_builder.dart:333)
#61 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#62 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#63 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#64 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#65 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#66 _RenderLayoutBuilder.paint (package:flutter/src/widgets/layout_builder.dart:333)
#67 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#68 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#69 RenderShiftedBox.paint (package:flutter/src/rendering/shifted_box.dart:74)
#70 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#71 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#72 RenderShiftedBox.paint (package:flutter/src/rendering/shifted_box.dart:74)
#73 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#74 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#75 RenderBoxContainerDefaultsMixin.defaultPaint (package:flutter/src/rendering/box.dart:2882)
#76 RenderStack.paintStack (package:flutter/src/rendering/stack.dart:640)
#77 RenderStack.paint (package:flutter/src/rendering/stack.dart:656)
#78 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#79 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#80 RenderBoxContainerDefaultsMixin.defaultPaint (package:flutter/src/rendering/box.dart:2882)
#81 RenderCustomMultiChildLayoutBox.paint (package:flutter/src/rendering/custom_layout.dart:408)
#82 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#83 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#84 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#85 _RenderInkFeatures.paint (package:flutter/src/material/material.dart:662)
#86 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#87 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#88 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#89 RenderPhysicalShape.paint.<anonymous closure> (package:flutter/src/rendering/proxy_box.dart:2156)
#90 PaintingContext.pushClipRRect (package:flutter/src/rendering/object.dart:575)
#91 RenderPhysicalModel.paint (package:flutter/src/rendering/proxy_box.dart:2030)
#92 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#93 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#94 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#95 RenderDecoratedBox.paint (package:flutter/src/rendering/proxy_box.dart:2295)
#96 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#97 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#98 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#99 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#100 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#101 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#102 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#103 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#104 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#105 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#106 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#107 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#108 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#109 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#110 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#111 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#112 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#113 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#114 RenderFractionalTranslation.paint (package:flutter/src/rendering/proxy_box.dart:2929)
#115 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#116 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#117 RenderBoxContainerDefaultsMixin.defaultPaint (package:flutter/src/rendering/box.dart:2882)
#118 RenderStack.paintStack (package:flutter/src/rendering/stack.dart:640)
#119 RenderStack.paint (package:flutter/src/rendering/stack.dart:656)
#120 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#121 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#122 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#123 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#124 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#125 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#126 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#127 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250)
#128 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129)
#129 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208)
#130 PaintingContext._repaintCompositedChild (package:flutter/src/rendering/object.dart:166)
#131 PaintingContext.repaintCompositedChild (package:flutter/src/rendering/object.dart:109)
#132 PipelineOwner.flushPaint (package:flutter/src/rendering/object.dart:1156)
#133 PipelineOwner.flushPaint (package:flutter/src/rendering/object.dart:1166)
#134 RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:593)
#135 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:986)
#136 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:457)
#137 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1325)
#138 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1255)
#139 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1113)
#140 _invoke (dart:ui/hooks.dart:312)
#141 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:383)
#142 _drawFrame (dart:ui/hooks.dart:283)

Application parameters:

environment: release
version: 4.0.3
appName: Mill
buildNumber: 3850
packageName: com.calcitem.sanmill

Custom parameters:

SkillLevel: setoption name SkillLevel value 1
MoveTime: setoption name MoveTime value 1
Algorithm: setoption name Algorithm value 2
UsePerfectDatabase: setoption name UsePerfectDatabase value false
PerfectDatabasePath: setoption name PerfectDatabasePath value /storage/emulated/0/Android/data/com.calcitem.sanmill/files/strong
DrawOnHumanExperience: setoption name DrawOnHumanExperience value false
ConsiderMobility: setoption name ConsiderMobility value false
AiIsLazy: setoption name AiIsLazy value false
Shuffling: setoption name Shuffling value false
DeveloperMode: setoption name DeveloperMode value false
PiecesCount: setoption name PiecesCount value 9
HasDiagonalLines: setoption name HasDiagonalLines value false
NMoveRule: setoption name NMoveRule value 100
EndgameNMoveRule: setoption name EndgameNMoveRule value 100
ThreefoldRepetitionRule: setoption name ThreefoldRepetitionRule value true
PiecesAtLeastCount: setoption name PiecesAtLeastCount value 3
HasBannedLocations: setoption name HasBannedLocations value false
BoardFullAction: setoption name BoardFullAction value 0
MayOnlyRemoveUnplacedPieceInPlacingPhase: setoption name MayOnlyRemoveUnplacedPieceInPlacingPhase value false
MayMoveInPlacingPhase: setoption name MayMoveInPlacingPhase value false
IsDefenderMoveFirst: setoption name IsDefenderMoveFirst value false
StalemateAction: setoption name StalemateAction value 0
MayFly: setoption name MayFly value true
FlyPieceCount: setoption name FlyPieceCount value 3
MayRemoveFromMillsAlways: setoption name MayRemoveFromMillsAlways value false
MayRemoveMultiple: setoption name MayRemoveMultiple value false
PositionFen: position fen O@O@O@O@/OOOO***@/****O*** b m s 9 0 5 0 0 0 0 15 moves (2,8)->(2,7) (2,4)->(2,5) 
MoveList: 1. d5 e5 2. e4 e3 3. d3 c3 4. c4 c5 5. d6 d7 6. f6 b6 7. f4 f2 8. g4xd7 d7 9. d2 d1 10. g4-g1 d1-a1 11. g1-d1xd7 a1-a4 12. d1-a1 a4-b4 13. a1-d1xf2 b4-a4 14. d2-f2xa4 b6-b4 15. f2-d2xb4
calcitem commented 7 months ago

错误信息表明在你的 PiecePainter.paint 方法中存在一个 LateInitializationError,具体是变量 blurPositionColor 没有被初始化就被使用了。这个错误发生在你尝试使用 blurPositionColor 来设置画笔颜色时,但是在你实际使用这个变量之前,它从未被赋值。

在你的代码中,blurPositionColor 被声明为 late,这意味着你在声明时没有初始化它,而是承诺在第一次使用前给它赋值。然而,如果在任何绘制逻辑触发之前 blurIndexnull 或者 piecesToDraw 中没有元素使得 blurPositionColor 被正确赋值,就会触发这个错误。

为了解决这个问题,你需要确保在使用 blurPositionColor 之前,它已经被赋予了一个有效的值。一个简单的解决方案是给 blurPositionColor 一个默认值,或者确保在绘制涉及 blurPositionColor 的任何图形之前,blurIndex 对应的逻辑已经成功赋值给了 blurPositionColor。例如,你可以在 for 循环里,当你知道将要用到 blurPositionColor 时,给它赋一个默认值或确保它被初始化:

// 在使用 blurPositionColor 之前提供一个默认值
Color blurPositionColor = Colors.transparent; // 或任何适当的默认颜色

for (final PiecePaintParam piece in piecesToDraw) {
    // 这里保持原有逻辑,当循环开始时,blurPositionColor 已经有了一个安全的值
    blurPositionColor = piece.piece.blurPositionColor;

    // 绘制逻辑保持不变...
}

此外,如果 blurIndex 可能为 null,你应该在尝试使用 blurPositionColor 绘制模糊位置之前,检查它是否已经被正确设置。如果你的逻辑依赖于特定条件(比如 blurIndex 不为 null)来初始化 blurPositionColor,请确保在那些条件未满足时有一个回退方案,比如设置一个默认颜色或跳过使用该变量的代码段。

这种处理方式确保了即使在 blurIndexnull 或者其他情况下没有为 blurPositionColor 赋值的情况下,你的代码也不会因为尝试使用一个未初始化的变量而崩溃。

calcitem commented 7 months ago

Let's break down the error you're encountering and how to fix it.

The Error: LateInitializationError

The error "LateInitializationError: Local 'blurPositionColor' has not been initialized" stems from a fundamental concept in Dart called late variables. Here's the breakdown:

The Problem

The issue arises because you are attempting to use the blurPositionColor variable inside the for loop before giving it a value:

for (final PiecePaintParam piece in piecesToDraw) {
   // ... using blurPositionColor here ...
}

Since the assignment of blurPositionColor (based on piece.piece) takes place within the loop, there's a high chance that you'll run into situations where you try to use the variable before it's been assigned a value.

The Solution

Here are a couple of ways to resolve this error:

1. Initialize blurPositionColor with a Default Value:

Give the blurPositionColor variable an initial value when you declare it. This ensures that it is always initialized before you use it.

   late Color blurPositionColor = Colors.transparent; // Or any sensible default color

2. Provide a Conditional Check:

Before using the blurPositionColor variable, check if it has been assigned a value. If not, either provide a default color or handle the situation differently.

   for (final PiecePaintParam piece in piecesToDraw) {
      // ... 
      if (blurPositionColor == null) { 
          blurPositionColor = Colors.transparent; // Or appropriate handling
      }
      // ... use blurPositionColor ...
   }

Choosing the Approach

The best solution depends on your specific use case:

calcitem commented 7 months ago
Application parameters:

environment: release
version: 4.0.3
appName: Mill
buildNumber: 3850
packageName: com.calcitem.sanmill

Custom parameters:

SkillLevel: setoption name SkillLevel value 4
MoveTime: setoption name MoveTime value 1
Algorithm: setoption name Algorithm value 2
UsePerfectDatabase: setoption name UsePerfectDatabase value true
PerfectDatabasePath: setoption name PerfectDatabasePath value /storage/emulated/0/Android/data/com.calcitem.sanmill/files/strong
DrawOnHumanExperience: setoption name DrawOnHumanExperience value true
ConsiderMobility: setoption name ConsiderMobility value true
AiIsLazy: setoption name AiIsLazy value false
Shuffling: setoption name Shuffling value true
DeveloperMode: setoption name DeveloperMode value false
PiecesCount: setoption name PiecesCount value 9
HasDiagonalLines: setoption name HasDiagonalLines value false
NMoveRule: setoption name NMoveRule value 100
EndgameNMoveRule: setoption name EndgameNMoveRule value 100
ThreefoldRepetitionRule: setoption name ThreefoldRepetitionRule value true
PiecesAtLeastCount: setoption name PiecesAtLeastCount value 3
HasBannedLocations: setoption name HasBannedLocations value false
BoardFullAction: setoption name BoardFullAction value 0
MayOnlyRemoveUnplacedPieceInPlacingPhase: setoption name MayOnlyRemoveUnplacedPieceInPlacingPhase value false
MayMoveInPlacingPhase: setoption name MayMoveInPlacingPhase value false
IsDefenderMoveFirst: setoption name IsDefenderMoveFirst value false
StalemateAction: setoption name StalemateAction value 0
MayFly: setoption name MayFly value true
FlyPieceCount: setoption name FlyPieceCount value 3
MayRemoveFromMillsAlways: setoption name MayRemoveFromMillsAlways value false
MayRemoveMultiple: setoption name MayRemoveMultiple value false
MoveList: 1. f4 d6 2. b4 d2 3. d7 a4 4. d3 g4 5. d1 e4 6. d5 c4 7. b6 b2 8. f2 f6 9. e5 c5 10. d3-c3 g4-g1 11. d1-a1 g1-g4 12. a1-d1 a4-a7 13. d1-a1 a7-a4 14. a1-d1
PositionFen: position fen ********/********/******** w p p 0 9 0 9 0 0 0 1 moves (2,3) (2,1) (2,7) (2,5) (3,1) (3,7) (1,5) (3,3) (3,5) (1,3) (1,1) (1,7) (2,8) (2,6) (2,4) (2,2) (1,2) (1,8) (1,5)->(1,6) (3,3)->(3,4) (3,5)->(3,6) (3,4)->(3,3) (3,6)->(3,5) (3,7)->(3,8) (3,5)->(3,6) (3,8)->(3,7)