@@ -12,7 +12,6 @@ const (
1212 DefaultMovesToGo = 30
1313 MoveOverhead = 200 * time .Millisecond
1414 MaxTime = 30000 * time .Millisecond
15- MinTimeLeft = 3000 * time .Millisecond
1615)
1716
1817type UciTimingInfo struct {
@@ -49,6 +48,32 @@ func NewTimingInfo(messageParts []string) (timingInfo *UciTimingInfo) {
4948}
5049
5150func (timingInfo * UciTimingInfo ) calculateTimeoutContext (ctx context.Context , g * game.Game , options []UciOption ) (context.Context , func ()) {
51+ if timingInfo .MoveTime > 0 {
52+ return context .WithDeadline (ctx , timingInfo .StartTimestamp .Add (time .Duration (timingInfo .MoveTime )))
53+ }
54+
55+ maxTime := MaxTime
56+ for _ , option := range options {
57+ if option .name == "Max Time" {
58+ optionsMT , err := strconv .Atoi (option .value )
59+ if err == nil {
60+ maxTime = time .Duration (optionsMT ) * time .Second
61+ }
62+ }
63+ }
64+
65+ if timingInfo .MovesToGo > 0 && timingInfo .IncrementWhite <= 0 && timingInfo .IncrementBlack <= 0 && timingInfo .TimeWhite > 0 && timingInfo .TimeBlack > 0 {
66+ return timingInfo .calculateTimeoutContextMPSTC (ctx , g , options )
67+ }
68+
69+ if timingInfo .MovesToGo <= 0 && timingInfo .IncrementWhite > 0 && timingInfo .IncrementBlack > 0 && timingInfo .TimeWhite > 0 && timingInfo .TimeBlack > 0 {
70+ return timingInfo .calculateTimeoutContextFisherTC (ctx , g , options )
71+ }
72+
73+ return context .WithDeadline (ctx , timingInfo .StartTimestamp .Add (maxTime ))
74+ }
75+
76+ func (timingInfo * UciTimingInfo ) calculateTimeoutContextFisherTC (ctx context.Context , g * game.Game , options []UciOption ) (context.Context , func ()) {
5277 moveOverhead := MoveOverhead
5378 maxTime := MaxTime
5479 for _ , option := range options {
@@ -66,10 +91,6 @@ func (timingInfo *UciTimingInfo) calculateTimeoutContext(ctx context.Context, g
6691 }
6792 }
6893
69- if timingInfo .MovesToGo <= 0 && timingInfo .TimeWhite <= 0 && timingInfo .TimeBlack <= 0 {
70- return context .WithDeadline (ctx , timingInfo .StartTimestamp .Add (maxTime ))
71- }
72-
7394 if timingInfo .MovesToGo <= 0 {
7495 timingInfo .MovesToGo = DefaultMovesToGo
7596 }
@@ -84,12 +105,46 @@ func (timingInfo *UciTimingInfo) calculateTimeoutContext(ctx context.Context, g
84105 timeLeft = 0
85106 }
86107
87- total := float64 (timeLeft ) + float64 (timingInfo .MovesToGo - 1 )* float64 (increment )
88- limit := time .Duration (total / float64 (timingInfo .MovesToGo - 1 ))
108+ total := float64 (timeLeft ) + float64 (timingInfo .MovesToGo )* float64 (increment )
109+ limit := time .Duration (total / float64 (timingInfo .MovesToGo ))
110+
111+ if limit > maxTime {
112+ limit = maxTime
113+ }
114+
115+ return context .WithDeadline (ctx , timingInfo .StartTimestamp .Add (limit ))
116+ }
117+
118+ func (timingInfo * UciTimingInfo ) calculateTimeoutContextMPSTC (ctx context.Context , g * game.Game , options []UciOption ) (context.Context , func ()) {
119+ moveOverhead := MoveOverhead
120+ maxTime := MaxTime
121+ for _ , option := range options {
122+ if option .name == "Move Overhead" {
123+ optionsMO , err := strconv .Atoi (option .value )
124+ if err == nil {
125+ moveOverhead = time .Duration (optionsMO ) * time .Millisecond
126+ }
127+ }
128+ if option .name == "Max Time" {
129+ optionsMT , err := strconv .Atoi (option .value )
130+ if err == nil {
131+ maxTime = time .Duration (optionsMT ) * time .Second
132+ }
133+ }
134+ }
135+
136+ timeLeft := time .Duration (timingInfo .TimeWhite ) * time .Millisecond
137+ if ! g .Position .Wtomove {
138+ timeLeft = time .Duration (timingInfo .TimeBlack ) * time .Millisecond
139+ }
89140
90- if limit > timeLeft - MinTimeLeft {
91- limit = timeLeft - MinTimeLeft
141+ timeLeft -= moveOverhead
142+ if timeLeft <= 0 {
143+ timeLeft = 0
92144 }
145+
146+ limit := time .Duration (float64 (timeLeft ) / float64 (timingInfo .MovesToGo + 1 ))
147+
93148 if limit > maxTime {
94149 limit = maxTime
95150 }
0 commit comments