1
1
using System ;
2
2
using System . Collections . Generic ;
3
3
using System . Diagnostics ;
4
+ using System . IO ;
5
+ using System . Security . Cryptography ;
6
+ using System . Text ;
4
7
using Cosette . Arbiter . Settings ;
5
8
6
9
namespace Cosette . Arbiter . Engine
7
10
{
8
11
public class EngineOperator
9
12
{
10
- private string _name ;
13
+ public Lazy < string > ExecutableHash ;
14
+
11
15
private string _enginePath ;
16
+ private string _engineArguments ;
12
17
private Process _engineProcess ;
13
18
14
- public EngineOperator ( string name , string path )
19
+ public EngineOperator ( string path , string arguments )
15
20
{
16
- _name = name ;
17
21
_enginePath = path ;
22
+ _engineArguments = arguments ;
23
+
24
+ ExecutableHash = new Lazy < string > ( GetExecutableHash ) ;
18
25
}
19
26
20
27
public void Init ( )
21
28
{
22
29
_engineProcess = Process . Start ( new ProcessStartInfo
23
30
{
24
31
FileName = _enginePath ,
32
+ Arguments = _engineArguments ,
25
33
CreateNoWindow = true ,
26
34
RedirectStandardInput = true ,
27
35
RedirectStandardOutput = true
@@ -30,20 +38,36 @@ public void Init()
30
38
Write ( "uci" ) ;
31
39
WaitForMessage ( "uciok" ) ;
32
40
33
- SettingsLoader . Data . Options . ForEach ( Write ) ;
41
+ ApplyOptions ( ) ;
34
42
35
43
Write ( "isready" ) ;
36
44
WaitForMessage ( "readyok" ) ;
37
45
}
38
46
47
+ public void Restart ( )
48
+ {
49
+ if ( ! _engineProcess . HasExited )
50
+ {
51
+ _engineProcess . Close ( ) ;
52
+ }
53
+
54
+ Init ( ) ;
55
+ ApplyOptions ( ) ;
56
+ }
57
+
39
58
public void InitNewGame ( )
40
59
{
41
60
Write ( "ucinewgame" ) ;
42
61
Write ( "isready" ) ;
43
62
WaitForMessage ( "readyok" ) ;
44
63
}
45
64
46
- public BestMoveData Go ( List < string > moves )
65
+ public void ApplyOptions ( )
66
+ {
67
+ SettingsLoader . Data . Options . ForEach ( Write ) ;
68
+ }
69
+
70
+ public BestMoveData Go ( List < string > moves , int whiteClock , int blackClock )
47
71
{
48
72
var bestMoveData = new BestMoveData ( ) ;
49
73
var movesJoined = string . Join ( ' ' , moves ) ;
@@ -53,26 +77,22 @@ public BestMoveData Go(List<string> moves)
53
77
Write ( $ "position startpos moves { movesJoined } ") ;
54
78
}
55
79
56
- Write ( $ "go movetime { SettingsLoader . Data . MillisecondsPerMove } ") ;
80
+ Write ( $ "go wtime { whiteClock } btime { blackClock } winc { SettingsLoader . Data . IncTime } binc { SettingsLoader . Data . IncTime } ") ;
57
81
58
82
while ( true )
59
83
{
60
- try
84
+ var response = Read ( ) ;
85
+ if ( response . StartsWith ( "info depth" ) )
61
86
{
62
- var response = Read ( ) ;
63
- if ( response . StartsWith ( "info depth" ) )
64
- {
65
- bestMoveData . LastInfoData = InfoData . FromString ( response ) ;
66
- }
67
- else if ( response . StartsWith ( "bestmove" ) )
68
- {
69
- bestMoveData . BestMove = response . Split ( ' ' ) [ 1 ] ;
70
- break ;
71
- }
87
+ bestMoveData . LastInfoData = InfoData . FromString ( response ) ;
72
88
}
73
- catch
89
+ else if ( response . StartsWith ( "bestmove" ) )
90
+ {
91
+ bestMoveData . BestMove = response . Split ( ' ' ) [ 1 ] ;
92
+ break ;
93
+ }
94
+ else if ( response . StartsWith ( "error" ) )
74
95
{
75
- Init ( ) ;
76
96
return null ;
77
97
}
78
98
}
@@ -94,5 +114,24 @@ public void WaitForMessage(string message)
94
114
{
95
115
while ( Read ( ) != message ) ;
96
116
}
117
+
118
+ private string GetExecutableHash ( )
119
+ {
120
+ var md5 = new MD5CryptoServiceProvider ( ) ;
121
+ var path = _enginePath == "dotnet" ? _engineArguments : _enginePath ;
122
+
123
+ using ( var streamReader = new StreamReader ( path ) )
124
+ {
125
+ md5 . ComputeHash ( streamReader . BaseStream ) ;
126
+ }
127
+
128
+ var hashBuilder = new StringBuilder ( ) ;
129
+ foreach ( var b in md5 . Hash )
130
+ {
131
+ hashBuilder . Append ( b . ToString ( "x2" ) ) ;
132
+ }
133
+
134
+ return hashBuilder . ToString ( ) ;
135
+ }
97
136
}
98
137
}
0 commit comments