~ubuntu-branches/ubuntu/vivid/qgo/vivid-proposed

« back to all changes in this revision

Viewing changes to src/gtp/qgtp.cpp

  • Committer: Package Import Robot
  • Author(s): Yann Dirson
  • Date: 2012-05-19 19:05:05 UTC
  • mfrom: (1.1.12)
  • Revision ID: package-import@ubuntu.com-20120519190505-b23f5tzx7y8cu946
Tags: 2~svn764-1
* The "Raise dead" release (Closes: #673520), new maintainer.
* New upstream snapshot with Qt4 support (Closes: #604589), adjusted
  build-deps.
* Switched to source format "3.0 (quilt)", adjusted build-deps.
* Switched to dh and debhelper compat level 9, adjusted build-deps.
* Build with -fpermissive.
* New build-dep libasound2-dev, remove obsolete build-dep on libxinerama-dev.
* Refreshed patches 01_gnugo and 04_desktop, leaving 20_kfreebsd away
  for this release, and removing the remaining ones, now obsolete.
* Added patch 02_usrgames for FHS-correct install location.
* Adjusted icon names in menu file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
qgtp.cpp  -  description
 
3
-------------------
 
4
begin                : Thu Nov 29 2001
 
5
copyright            : (C) 2001 by PALM Thomas , DINTILHAC Florian, HIVERT Anthony, PIOC Sebastien
 
6
email                : 
 
7
***************************************************************************/
 
8
 
 
9
/***************************************************************************
 
10
*                                                                         *
 
11
*   This program is free software; you can redistribute it and/or modify  *
 
12
*   it under the terms of the GNU General Public License as published by  *
 
13
*   the Free Software Foundation; either version 2 of the License, or     *
 
14
*   (at your option) any later version.                                   *
 
15
*                                                                         *
 
16
***************************************************************************/
 
17
 
 
18
 
 
19
#include <stdio.h>
 
20
//#include <unistd.h>
 
21
#include <stdlib.h>
 
22
//#include <qprocess.h>
 
23
enum CommandType {PROTOCOL, BOARDSIZE, KNOWN_COMMAND, LEVEL, KOMI, PLAY_BLACK, PLAY_WHITE, GENMOVE};
 
24
#include "qgtp.h"
 
25
 
 
26
#ifdef Q_WS_WIN
 
27
#include <Windows.h>
 
28
#endif
 
29
 
 
30
/* Function:  open a session
 
31
* Arguments: name and path of go program
 
32
* Fails:     never
 
33
* Returns:   nothing
 
34
*/
 
35
QGtp::QGtp()
 
36
{
 
37
        /*openGtpSession(filename);*/
 
38
        programProcess = NULL; // This to permit proper ending
 
39
        responseReceived = FALSE;
 
40
        answer = "";
 
41
}
 
42
 
 
43
QGtp::~QGtp()
 
44
{
 
45
        if (programProcess)
 
46
                programProcess->kill();     // not very clean (should use tryTerminate)
 
47
}
 
48
 
 
49
/* Code */
 
50
 
 
51
/* Function:  get the last message from gnugo
 
52
* Arguments: none
 
53
* Fails:     never
 
54
* Returns:   last message from GO
 
55
*/
 
56
 
 
57
 
 
58
QString QGtp::getLastMessage()
 
59
{
 
60
        return _response;
 
61
}
 
62
 
 
63
int QGtp::openGtpSession(QString filename, int size, float komi, int handicap, int /*level*/)
 
64
{
 
65
        _cpt = 1000;
 
66
        
 
67
        programProcess = new QProcess();
 
68
        QStringList arguments;
 
69
        issueCmdNb = FALSE;
 
70
        
 
71
        if(!filename.count())
 
72
        {
 
73
                _response = "No go engine path set";
 
74
                return FAIL;
 
75
        }
 
76
 
 
77
        if (filename.toLower().contains("gnugo"))
 
78
        {
 
79
                arguments << "--mode" << "gtp" << "--quiet" ;
 
80
                issueCmdNb = TRUE;
 
81
        }
 
82
 
 
83
        if (filename.toLower().contains("mogo"))
 
84
        {
 
85
                arguments << "--19" << "--dontDisplay" << "1" ;
 
86
 
 
87
        }
 
88
 
 
89
 
 
90
        connect(programProcess, SIGNAL(readyRead()),
 
91
                this, SLOT(slot_readFromStdout()) );
 
92
        connect(programProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
 
93
                this, SLOT(slot_processExited(int , QProcess::ExitStatus )) );
 
94
        
 
95
        qDebug("starting Go engine : %s %s", filename.toLatin1().constData(), arguments.join(" ").toLatin1().constData());
 
96
 
 
97
        programProcess->start(filename, arguments);
 
98
 
 
99
        
 
100
 
 
101
        if (!programProcess->waitForStarted())
 
102
        {
 
103
                  _response="Could not start "+filename;
 
104
                  return FAIL ;
 
105
        }
 
106
        
 
107
        //?? never know ... otherwise, I get a segfault with sprint ...
 
108
        if ((outFile = (char *)malloc (100)) == NULL)
 
109
        {
 
110
                  _response="Yuck ! Could not allocate 100 bytes !!!"  ;
 
111
                  return FAIL ;
 
112
        }   
 
113
        
 
114
        if (protocolVersion()==OK)
 
115
        {
 
116
                if(getLastMessage().toInt() !=2)
 
117
                {
 
118
                        qDebug("Protocol version problem???");
 
119
                        //                              quit();
 
120
                        _response="Protocol version not supported";
 
121
                        //                              return FAIL;
 
122
                }
 
123
                if(setBoardsize(size)==FAIL)
 
124
                {
 
125
                        return FAIL;
 
126
                }
 
127
                if(clearBoard()==FAIL)
 
128
                {
 
129
                        // removed by frosla -> protocol changes...
 
130
                        // return FAIL;
 
131
                }
 
132
 
 
133
/*
 
134
                if(knownCommand("level")==FAIL)
 
135
                {
 
136
                          return FAIL;
 
137
                }
 
138
        
 
139
                else if (getLastMessage().contains("true"))
 
140
                {
 
141
                        if (setLevel(level)==FAIL)
 
142
                        {
 
143
                                return FAIL;
 
144
                        }
 
145
                }
 
146
*/ 
 
147
      
 
148
                if(setKomi(komi)==FAIL)
 
149
                {
 
150
                        return FAIL;
 
151
                }
 
152
 
 
153
                if(fixedHandicap(handicap)==FAIL)
 
154
                {
 
155
                        return FAIL;
 
156
                }
 
157
        }
 
158
        else
 
159
        {
 
160
                quit();
 
161
                _response="Protocol version error";
 
162
                return FAIL;
 
163
        }
 
164
 
 
165
        return OK;
 
166
}
 
167
 
 
168
// Read from stdout
 
169
void QGtp::slot_readFromStdout()
 
170
{
 
171
        int number;
 
172
        int pos;
 
173
 
 
174
        QString s;
 
175
        do 
 
176
        {
 
177
                s = programProcess->readAllStandardOutput();
 
178
                answer.append(s); 
 
179
        } while (!s.isEmpty());
 
180
        if(answer[answer.length() - 1] != '\n')
 
181
                return;
 
182
        responseReceived = TRUE;
 
183
                
 
184
        answer=answer.trimmed();
 
185
        if (answer.length() != 0)
 
186
                _response = answer;
 
187
        answer = "";
 
188
 
 
189
        buff = _response[0];
 
190
        
 
191
        if(buff != "=" && buff != "?")
 
192
        {
 
193
                responseReceived = FALSE;
 
194
                return;
 
195
        }
 
196
 
 
197
        // do we have any answer after the command number ?
 
198
        pos = _response.indexOf(" ");
 
199
        number = _response.mid(1,pos).toInt();
 
200
 
 
201
        if (pos < 1)
 
202
                _response = "";
 
203
        else
 
204
                _response = _response.right(_response.length() - pos - 1);
 
205
 
 
206
 
 
207
        qDebug("** QGtp::slot_read():  \'%s\'" , _response.toLatin1().constData());
 
208
 
 
209
/*
 
210
        switch (number)
 
211
        {
 
212
                case GENMOVE:
 
213
                        emit signal_computerPlayed( (buff != "?") , _response );
 
214
                        responseReceived = FALSE;
 
215
                default:
 
216
                        ;
 
217
        }
 
218
*/
 
219
}
 
220
 
 
221
// exit
 
222
void QGtp::slot_processExited(int exitCode, QProcess::ExitStatus exitStatus)
 
223
{
 
224
        qDebug("Process Exited with exit code %i and status  %d", exitCode, exitStatus);
 
225
//      sprintf (outFile, "%d quit\n", _cpt);
 
226
//      sprintf (outFile, "quit\n");
 
227
//      fflush(outFile);
 
228
        //      return waitResponse();
 
229
}
 
230
 
 
231
/* Function:  wait for a go response
 
232
* Arguments: none
 
233
* Fails:     never
 
234
* Returns:   nothing
 
235
*/
 
236
int
 
237
QGtp::waitResponse()
 
238
{
 
239
        QString buf = _response;
 
240
        //      QTextStream * inFile;
 
241
        //      char symbole;
 
242
        //int number;
 
243
        //int pos;
 
244
        do //FIXME : we don't nned this, since the process sends the readyRead signal
 
245
        {
 
246
                qApp->processEvents();
 
247
/*#ifdef Q_WS_WIN
 
248
                Sleep(100000);
 
249
#else
 
250
                usleep(100000);
 
251
#endif
 
252
*/
 
253
        } while (!responseReceived/*_response.length() == 0 || _response == buf*/);
 
254
        /*
 
255
        inFile=new QTextStream(programProcess->readStdout(),IO_ReadOnly);
 
256
        do
 
257
        {
 
258
        * inFile>>symbole;
 
259
        * inFile>>number;
 
260
        buff=inFile->readLine();
 
261
        } while(number !=_cpt);
 
262
        */
 
263
        
 
264
        //      _response=buff.stripWhiteSpace();
 
265
        
 
266
        /*      
 
267
        buff=programProcess->readLineStdout();
 
268
        while(!buff.isEmpty())
 
269
        {
 
270
        _response=_response+"\n"+buff;
 
271
        buff=programProcess->readLineStdout();
 
272
        }
 
273
        */
 
274
        /*
 
275
        buff = _response[0];
 
276
        if ((pos = _response.indexOf(" ")) < 1)
 
277
                pos = 1;
 
278
        number = _response.mid(1,pos).toInt();
 
279
        _response = _response.right(_response.length() - pos - 1);
 
280
        */
 
281
        qDebug("** QGtp::waitResponse():  \'%s\'" , _response.toLatin1().constData());
 
282
        responseReceived = FALSE;
 
283
 
 
284
        if (buff == "?") //symbole=='?')
 
285
        {
 
286
                return FAIL;
 
287
        }
 
288
        else
 
289
        {
 
290
                return OK;
 
291
        }
 
292
}
 
293
 
 
294
/****************************
 
295
* Program identity.        *
 
296
****************************/
 
297
 
 
298
/* Function:  Report the name of the program.
 
299
* Arguments: none
 
300
* Fails:     never
 
301
* Returns:   program name
 
302
*/
 
303
int
 
304
QGtp::name ()
 
305
{
 
306
        qDebug("%d name",_cpt);
 
307
        sprintf (outFile, "%d name\n", _cpt);
 
308
        fflush(outFile);
 
309
        return waitResponse();
 
310
}
 
311
 
 
312
/* Function:  Report protocol version.
 
313
* Arguments: none
 
314
* Fails:     never
 
315
* Returns:   protocol version number
 
316
*/
 
317
int
 
318
QGtp::protocolVersion ()
 
319
{
 
320
        qDebug("%d protocol_version",_cpt);
 
321
        if (issueCmdNb)
 
322
                sprintf (outFile, "%d protocol_version\n", /*_cpt*/ PROTOCOL);
 
323
        else
 
324
                sprintf (outFile, "protocol_version\n");
 
325
                
 
326
        fflush(outFile);
 
327
        return waitResponse();
 
328
}
 
329
 
 
330
void QGtp::fflush(char * s)
 
331
{
 
332
/*
 
333
int msglen = strlen(s);
 
334
 
 
335
  QByteArray dat(msglen);
 
336
  for (int j = 0; j < msglen; j++) {
 
337
  dat[j] = s[j];
 
338
  }
 
339
  programProcess->writeToStdin(dat);
 
340
        */
 
341
        _cpt++;
 
342
 
 
343
        qDebug("flush -> %s",s);
 
344
        uint i= programProcess->write(QByteArray(s));
 
345
 
 
346
//      int j= programProcess->waitForBytesWritten ( 100 );
 
347
 
 
348
        if ( i != strlen(s)) 
 
349
                qDebug("Error writing %s",s);
 
350
        
 
351
        
 
352
}
 
353
 
 
354
/****************************
 
355
* Administrative commands. *
 
356
****************************/
 
357
 
 
358
/* Function:  Quit
 
359
* Arguments: none
 
360
* Fails:     never
 
361
* Returns:   nothing
 
362
*/
 
363
int
 
364
QGtp::quit ()
 
365
{
 
366
//      sprintf (outFile, "%d quit\n", _cpt);
 
367
        sprintf (outFile, "quit\n");
 
368
        fflush(outFile);
 
369
        return waitResponse();
 
370
}
 
371
 
 
372
/* Function:  Report the version number of the program.
 
373
* Arguments: none
 
374
* Fails:     never
 
375
* Returns:   version number
 
376
*/
 
377
int
 
378
QGtp::version ()
 
379
{
 
380
//      sprintf (outFile, "%d version\n", _cpt);
 
381
        sprintf (outFile,"version\n");
 
382
        fflush(outFile);
 
383
        return waitResponse();
 
384
}
 
385
 
 
386
 
 
387
/***************************
 
388
* Setting the board size. *
 
389
***************************/
 
390
 
 
391
/* Function:  Set the board size to NxN.
 
392
* Arguments: integer
 
393
* Fails:     board size outside engine's limits
 
394
* Returns:   nothing
 
395
*/
 
396
int
 
397
QGtp::setBoardsize (int size)
 
398
{
 
399
        if (issueCmdNb)
 
400
                sprintf (outFile, "%d boardsize %d\n", BOARDSIZE /*_cpt*/, size);
 
401
        else
 
402
                sprintf (outFile, "boardsize %d\n", size);
 
403
        fflush(outFile);
 
404
        return waitResponse();
 
405
}
 
406
 
 
407
 
 
408
/* Function:  Find the current boardsize
 
409
* Arguments: none
 
410
* Fails:     never
 
411
* Returns:   board_size
 
412
*/
 
413
int
 
414
QGtp::queryBoardsize()
 
415
{
 
416
        sprintf (outFile, "%d query_boardsize\n", _cpt);
 
417
        fflush(outFile);
 
418
        return waitResponse();
 
419
}
 
420
 
 
421
/***********************
 
422
* Clearing the board. *
 
423
***********************/
 
424
 
 
425
/* Function:  Clear the board.
 
426
* Arguments: none
 
427
* Fails:     never
 
428
* Returns:   nothing
 
429
*/
 
430
 
 
431
int
 
432
QGtp::clearBoard ()
 
433
{
 
434
//      if (issueCmdNb)
 
435
//              sprintf (outFile, "%d clear_board\n", _cpt);
 
436
//      else
 
437
                sprintf (outFile,"clear_board\n");
 
438
        fflush(outFile);
 
439
        return waitResponse();
 
440
}
 
441
 
 
442
/***************************
 
443
* Setting.           *
 
444
***************************/
 
445
 
 
446
/* Function:  Set the komi.
 
447
* Arguments: float
 
448
* Fails:     incorrect argument
 
449
* Returns:   nothing
 
450
*/
 
451
int
 
452
QGtp::setKomi(float f)
 
453
{
 
454
        if (issueCmdNb)
 
455
                sprintf (outFile, "%d komi %.2f\n", KOMI /*_cpt*/,f);
 
456
        else
 
457
                sprintf (outFile, "komi %.2f\n", f);
 
458
        fflush(outFile);
 
459
        return waitResponse();
 
460
}
 
461
 
 
462
/* Function:  Set the playing level.
 
463
* Arguments: int
 
464
* Fails:     incorrect argument
 
465
* Returns:   nothing
 
466
*/
 
467
int
 
468
QGtp::setLevel (int level)
 
469
{
 
470
        sprintf (outFile, "%d level %d\n", _cpt,level);
 
471
        fflush(outFile);
 
472
        return waitResponse();
 
473
}
 
474
/******************
 
475
* Playing moves. *
 
476
******************/
 
477
 
 
478
/* Function:  Play a black stone at the given vertex.
 
479
* Arguments: vertex
 
480
* Fails:     invalid vertex, illegal move
 
481
* Returns:   nothing
 
482
*/
 
483
int
 
484
QGtp::playblack (char c , int i)
 
485
{
 
486
        //  sprintf (outFile, "%d play black %c%d\n", _cpt,c,i);
 
487
        if (issueCmdNb)
 
488
                sprintf (outFile, "%d play black %c%d\n", PLAY_BLACK/*_cpt*/,c,i);
 
489
        else
 
490
                sprintf (outFile, "play black %c%d\n", c,i);
 
491
        fflush(outFile);
 
492
        return waitResponse();
 
493
}
 
494
 
 
495
/* Function:  Black pass.
 
496
* Arguments: None
 
497
* Fails:     never
 
498
* Returns:   nothing
 
499
*/
 
500
int
 
501
QGtp::playblackPass ()
 
502
{
 
503
        //  sprintf (outFile, "%d play black pass\n", _cpt);
 
504
        if (issueCmdNb)
 
505
                sprintf (outFile, "%d play black pass\n", PLAY_BLACK /*_cpt*/);
 
506
        else
 
507
                sprintf (outFile, "play black pass\n");
 
508
        fflush(outFile);
 
509
        return waitResponse();
 
510
}
 
511
 
 
512
/* Function:  Play a white stone at the given vertex.
 
513
* Arguments: vertex
 
514
* Fails:     invalid vertex, illegal move
 
515
* Returns:   nothing
 
516
*/
 
517
int
 
518
QGtp::playwhite (char c, int i)
 
519
{
 
520
        //  sprintf (outFile, "%d play white %c%d\n", _cpt,c,i);
 
521
        if (issueCmdNb)
 
522
                sprintf (outFile, "%d play white %c%d\n", PLAY_WHITE /*_cpt*/,c,i);
 
523
        else
 
524
                sprintf (outFile, "play white %c%d\n", c,i);
 
525
        fflush(outFile);
 
526
        return waitResponse();
 
527
}
 
528
 
 
529
/* Function:  White pass.
 
530
* Arguments: none
 
531
* Fails:     never
 
532
* Returns:   nothing
 
533
*/
 
534
int
 
535
QGtp::playwhitePass ()
 
536
{
 
537
        //  sprintf (outFile, "%d play white pass\n", _cpt);
 
538
        if (issueCmdNb)
 
539
                sprintf (outFile, "%d play white pass\n",PLAY_WHITE /*_cpt*/);
 
540
        else
 
541
                sprintf (outFile, "play white pass\n");
 
542
        fflush(outFile);
 
543
        return waitResponse();
 
544
}
 
545
 
 
546
/* Function:  Set up fixed placement handicap stones.
 
547
* Arguments: number of handicap stones
 
548
* Fails:     invalid number of stones for the current boardsize
 
549
* Returns:   list of vertices with handicap stones
 
550
*/
 
551
int
 
552
QGtp::fixedHandicap (int handicap)
 
553
{
 
554
        if (handicap < 2) 
 
555
                return OK;
 
556
 
 
557
        if (issueCmdNb)
 
558
                sprintf (outFile, "%d fixed_handicap %d\n", _cpt,handicap);
 
559
        else
 
560
                sprintf (outFile, "fixed_handicap %d\n",handicap);
 
561
 
 
562
        fflush(outFile);
 
563
        return waitResponse();
 
564
}
 
565
 
 
566
/* Function:  Load an sgf file, possibly up to a move number or the first
 
567
*            occurence of a move.
 
568
* Arguments: filename + move number, vertex, or nothing
 
569
* Fails:     missing filename or failure to open or parse file
 
570
* Returns:   color to play
 
571
*/
 
572
int QGtp::loadsgf (QString filename,int /*movNumber*/,char /*c*/,int /*i*/)
 
573
{
 
574
        //sprintf (outFile, "%d loadsgf %s %d %c%d\n", _cpt,(const char *) filename,movNumber,c,i);
 
575
        qDebug("**QGtp::loadsgf : loading file %s", filename.toLatin1().constData());
 
576
        sprintf (outFile, "%d loadsgf %s\n", _cpt,filename.toLatin1().constData());
 
577
        fflush(outFile);
 
578
        return waitResponse();
 
579
}
 
580
 
 
581
/*****************
 
582
* Board status. *
 
583
*****************/
 
584
 
 
585
/* Function:  Return the color at a vertex.
 
586
* Arguments: vertex
 
587
* Fails:     invalid vertex
 
588
* Returns:   "black", "white", or "empty"
 
589
*/
 
590
int
 
591
QGtp::whatColor (char c, int i)
 
592
{
 
593
        sprintf (outFile, "%d color %c%d\n", _cpt,c,i);
 
594
        fflush(outFile);
 
595
        return waitResponse();
 
596
}
 
597
 
 
598
/* Function:  Count number of liberties for the string at a vertex.
 
599
* Arguments: vertex
 
600
* Fails:     invalid vertex, empty vertex
 
601
* Returns:   Number of liberties.
 
602
*/
 
603
int
 
604
QGtp::countlib (char c, int i)
 
605
{
 
606
        sprintf (outFile, "%d countlib %c%d\n", _cpt,c,i);
 
607
        fflush(outFile);
 
608
        return waitResponse();
 
609
}
 
610
 
 
611
/* Function:  Return the positions of the liberties for the string at a vertex.
 
612
* Arguments: vertex
 
613
* Fails:     invalid vertex, empty vertex
 
614
* Returns:   Sorted space separated list of vertices.
 
615
*/
 
616
int
 
617
QGtp::findlib (char c, int i)
 
618
{
 
619
        sprintf (outFile, "%d findlib %c%d\n", _cpt,c,i);
 
620
        fflush(outFile);
 
621
        return waitResponse();
 
622
}
 
623
 
 
624
/* Function:  Tell whether a move is legal.
 
625
* Arguments: move
 
626
* Fails:     invalid move
 
627
* Returns:   1 if the move is legal, 0 if it is not.
 
628
*/
 
629
int
 
630
QGtp::isLegal (QString color, char c, int i)
 
631
{
 
632
        sprintf (outFile, "%d is_legal %s %c%d\n", _cpt,color.toLatin1().constData(),c,i);
 
633
        fflush(outFile);
 
634
        return waitResponse();
 
635
}
 
636
 
 
637
/* Function:  List all legal moves for either color.
 
638
* Arguments: color
 
639
* Fails:     invalid color
 
640
* Returns:   Sorted space separated list of vertices.
 
641
*/
 
642
int
 
643
QGtp::allLegal (QString color)
 
644
{
 
645
        sprintf (outFile, "%d all_legal %s\n", _cpt,color.toLatin1().constData());
 
646
        fflush(outFile);
 
647
        return waitResponse();
 
648
}
 
649
 
 
650
/* Function:  List the number of captures taken by either color.
 
651
* Arguments: color
 
652
* Fails:     invalid color
 
653
* Returns:   Number of captures.
 
654
*/
 
655
int
 
656
QGtp::captures (QString color)
 
657
{
 
658
        sprintf (outFile, "%d captures %s\n", _cpt,color.toLatin1().constData());
 
659
        fflush(outFile);
 
660
        return waitResponse();
 
661
}
 
662
 
 
663
/**********************
 
664
* Retractable moves. *
 
665
**********************/
 
666
 
 
667
/* Function:  Play a stone of the given color at the given vertex.
 
668
* Arguments: move (color + vertex)
 
669
* Fails:     invalid color, invalid vertex, illegal move
 
670
* Returns:   nothing
 
671
*/
 
672
int
 
673
QGtp::trymove (QString color, char c, int i)
 
674
{
 
675
        sprintf (outFile, "%d trymove %s %c%d\n", _cpt,color.toLatin1().constData(),c,i);
 
676
        fflush(outFile);
 
677
        return waitResponse();
 
678
}
 
679
 
 
680
/* Function:  Undo a trymove.
 
681
* Arguments: none
 
682
* Fails:     stack empty
 
683
* Returns:   nothing
 
684
*/
 
685
int
 
686
QGtp::popgo ()
 
687
{
 
688
        sprintf (outFile, "%d popgo\n", _cpt);
 
689
        fflush(outFile);
 
690
        return waitResponse();
 
691
}
 
692
 
 
693
/*********************
 
694
* Tactical reading. *
 
695
*********************/
 
696
 
 
697
/* Function:  Try to attack a string.
 
698
* Arguments: vertex
 
699
* Fails:     invalid vertex, empty vertex
 
700
* Returns:   attack code followed by attack point if attack code nonzero.
 
701
*/
 
702
int
 
703
QGtp::attack (char c, int i)
 
704
{
 
705
        sprintf (outFile, "%d attack %c%d\n", _cpt,c,i);
 
706
        fflush(outFile);
 
707
        return waitResponse();
 
708
}
 
709
 
 
710
/* Function:  Try to defend a string.
 
711
* Arguments: vertex
 
712
* Fails:     invalid vertex, empty vertex
 
713
* Returns:   defense code followed by defense point if defense code nonzero.
 
714
*/
 
715
int
 
716
QGtp::defend (char c, int i)
 
717
{
 
718
        sprintf (outFile, "%d defend %c%d\n", _cpt,c,i);
 
719
        fflush(outFile);
 
720
        return waitResponse();
 
721
}
 
722
 
 
723
/* Function:  Increase depth values by one.
 
724
* Arguments: none
 
725
* Fails:     never
 
726
* Returns:   nothing
 
727
*/
 
728
int
 
729
QGtp::increaseDepths ()
 
730
{
 
731
        sprintf (outFile, "%d increase_depths\n", _cpt);
 
732
        fflush(outFile);
 
733
        return waitResponse();
 
734
}
 
735
 
 
736
/* Function:  Decrease depth values by one.
 
737
* Arguments: none
 
738
* Fails:     never
 
739
* Returns:   nothing
 
740
*/
 
741
int
 
742
QGtp::decreaseDepths ()
 
743
{
 
744
        sprintf (outFile, "%d decrease_depths\n", _cpt);
 
745
        fflush(outFile);
 
746
        return waitResponse();
 
747
}
 
748
 
 
749
/******************
 
750
* owl reading. *
 
751
******************/
 
752
 
 
753
/* Function:  Try to attack a dragon.
 
754
* Arguments: vertex
 
755
* Fails:     invalid vertex, empty vertex
 
756
* Returns:   attack code followed by attack point if attack code nonzero.
 
757
*/
 
758
int
 
759
QGtp::owlAttack (char c, int i)
 
760
{
 
761
        sprintf (outFile, "%d owl_attack %c%d\n", _cpt,c,i);
 
762
        fflush(outFile);
 
763
        return waitResponse();
 
764
}
 
765
 
 
766
/* Function:  Try to defend a dragon.
 
767
* Arguments: vertex
 
768
* Fails:     invalid vertex, empty vertex
 
769
* Returns:   defense code followed by defense point if defense code nonzero.
 
770
*/
 
771
int
 
772
QGtp::owlDefend (char c, int i)
 
773
{
 
774
        sprintf (outFile, "%d owl_defend %c%d\n", _cpt,c,i);
 
775
        fflush(outFile);
 
776
        return waitResponse();
 
777
}
 
778
 
 
779
/********
 
780
* eyes *
 
781
********/
 
782
 
 
783
/* Function:  Evaluate an eye space
 
784
* Arguments: vertex
 
785
* Fails:     invalid vertex
 
786
* Returns:   Minimum and maximum number of eyes. If these differ an
 
787
*            attack and a defense point are additionally returned.
 
788
*            If the vertex is not an eye space or not of unique color,
 
789
*            a single -1 is returned.
 
790
*/
 
791
 
 
792
int
 
793
QGtp::evalEye (char c, int i)
 
794
{
 
795
        sprintf (outFile, "%d eval_eye %c%d\n", _cpt,c,i);
 
796
        fflush(outFile);
 
797
        return waitResponse();
 
798
}
 
799
 
 
800
/*****************
 
801
* dragon status *
 
802
*****************/
 
803
 
 
804
/* Function:  Determine status of a dragon.
 
805
* Arguments: vertex
 
806
* Fails:     invalid vertex, empty vertex
 
807
* Returns:   status ("alive", "critical", "dead", or "unknown"),
 
808
*            attack point, defense point. Points of attack and
 
809
*            defense are only given if the status is critical and the
 
810
*            owl code is enabled.
 
811
*
 
812
* FIXME: Should be able to distinguish between life in seki
 
813
*        and life with territory. Should also be able to identify ko.
 
814
*/
 
815
 
 
816
int
 
817
QGtp::dragonStatus (char c, int i)
 
818
{
 
819
        sprintf (outFile, "%d dragon_status %c%d\n", _cpt,c,i);
 
820
        fflush(outFile);
 
821
        return waitResponse();
 
822
}
 
823
 
 
824
/* Function:  Determine whether two stones belong to the same dragon.
 
825
* Arguments: vertex, vertex
 
826
* Fails:     invalid vertex, empty vertex
 
827
* Returns:   1 if the vertices belong to the same dragon, 0 otherwise
 
828
*/
 
829
 
 
830
int
 
831
QGtp::sameDragon (char c1, int i1, char c2, int i2)
 
832
{
 
833
        sprintf (outFile, "%d same_dragon %c%d %c%d\n", _cpt,c1,i1,c2,i2);
 
834
        fflush(outFile);
 
835
        return waitResponse();
 
836
}
 
837
 
 
838
/* Function:  Return the information in the dragon data structure.
 
839
* Arguments: nothing
 
840
* Fails:     never
 
841
* Returns:   Dragon data formatted in the corresponding way to gtp_worm__
 
842
*/
 
843
int
 
844
QGtp::dragonData ()
 
845
{
 
846
        sprintf (outFile, "%d dragon_data \n", _cpt);
 
847
        fflush(outFile);
 
848
        return waitResponse();
 
849
}
 
850
 
 
851
/* Function:  Return the information in the dragon data structure.
 
852
* Arguments: intersection
 
853
* Fails:     invalid coordinate
 
854
* Returns:   Dragon data formatted in the corresponding way to gtp_worm__
 
855
*/
 
856
int
 
857
QGtp::dragonData (char c,int i)
 
858
{
 
859
        sprintf (outFile, "%d dragon_data %c%d\n", _cpt,c,i);
 
860
        fflush(outFile);
 
861
        return waitResponse();
 
862
}
 
863
 
 
864
/***********************
 
865
* combination attacks *
 
866
***********************/
 
867
 
 
868
/* Function:  Find a move by color capturing something through a
 
869
*            combination attack.
 
870
* Arguments: color
 
871
* Fails:     invalid color
 
872
* Returns:   Recommended move, PASS if no move found
 
873
*/
 
874
 
 
875
int
 
876
QGtp::combinationAttack (QString color)
 
877
{
 
878
        sprintf (outFile, "%d combination_attack %s\n", _cpt,color.toLatin1().constData());
 
879
        fflush(outFile);
 
880
        return waitResponse();
 
881
}
 
882
 
 
883
/********************
 
884
* generating moves *
 
885
********************/
 
886
 
 
887
/* Function:  Generate and play the supposedly best black move.
 
888
* Arguments: none
 
889
* Fails:     never
 
890
* Returns:   a move coordinate (or "PASS")
 
891
*/
 
892
int
 
893
QGtp::genmoveBlack ()
 
894
{
 
895
        if (issueCmdNb)
 
896
                sprintf (outFile, "%d genmove black\n", GENMOVE);
 
897
        else
 
898
                sprintf (outFile, "genmove black\n");
 
899
        fflush(outFile);
 
900
        waitResponse();
 
901
 
 
902
        emit signal_computerPlayed( (buff != "?") , _response );
 
903
//      responseReceived = FALSE;
 
904
 
 
905
        return OK;
 
906
}
 
907
 
 
908
/* Function:  Generate and play the supposedly best white move.
 
909
* Arguments: none
 
910
* Fails:     never
 
911
* Returns:   a move coordinate (or "PASS")
 
912
*/
 
913
int
 
914
QGtp::genmoveWhite ()
 
915
{
 
916
        if (issueCmdNb)
 
917
                sprintf (outFile, "%d genmove white\n", GENMOVE);
 
918
        else
 
919
                sprintf (outFile, "genmove white\n");
 
920
        fflush(outFile);
 
921
        waitResponse();
 
922
 
 
923
        emit signal_computerPlayed( (buff != "?") , _response );
 
924
//      responseReceived = FALSE;
 
925
 
 
926
        return OK;
 
927
}
 
928
 
 
929
/* Function:  Generate the supposedly best move for either color.
 
930
* Arguments: color to move, optionally a random seed
 
931
* Fails:     invalid color
 
932
* Returns:   a move coordinate (or "PASS")
 
933
*/
 
934
int
 
935
QGtp::genmove (QString color,int seed)
 
936
{
 
937
        sprintf (outFile, "%d gg_genmove %s %d\n", _cpt,color.toLatin1().constData(),seed);
 
938
        fflush(outFile);
 
939
        return waitResponse();
 
940
}
 
941
 
 
942
/* Function : Generate a list of the best moves for White with weights
 
943
* Arguments: none
 
944
* Fails:   : never
 
945
* Returns  : list of moves with weights
 
946
*/
 
947
 
 
948
int
 
949
QGtp::topMovesWhite ()
 
950
{
 
951
        sprintf (outFile, "%d top_moves_white\n", _cpt);
 
952
        fflush(outFile);
 
953
        return waitResponse();
 
954
}
 
955
 
 
956
/* Function : Generate a list of the best moves for Black with weights
 
957
* Arguments: none
 
958
* Fails:   : never
 
959
* Returns  : list of moves with weights
 
960
*/
 
961
 
 
962
int
 
963
QGtp::topMovesBlack ()
 
964
{
 
965
        sprintf (outFile, "%d top_moves_black\n", _cpt);
 
966
        fflush(outFile);
 
967
        return waitResponse();
 
968
}
 
969
 
 
970
/* Function:  Undo last move
 
971
* Arguments: int
 
972
* Fails:     If move pointer is 0
 
973
* Returns:   nothing
 
974
*/
 
975
int
 
976
QGtp::undo (int i)
 
977
{
 
978
        sprintf (outFile, "%d undo %d\n", _cpt,i);
 
979
        fflush(outFile);
 
980
        return waitResponse();
 
981
}
 
982
 
 
983
/* Function:  Report the final status of a vertex in a finished game.
 
984
* Arguments: Vertex, optional random seed
 
985
* Fails:     invalid vertex
 
986
* Returns:   Status in the form of one of the strings "alive", "dead",
 
987
*            "seki", "white_territory", "black_territory", or "dame".
 
988
*/
 
989
int
 
990
QGtp::finalStatus (char c, int i, int seed)     
 
991
{
 
992
        sprintf (outFile, "%d final_status %c%d %d\n", _cpt,c,i,seed);
 
993
        fflush(outFile);
 
994
        return waitResponse();
 
995
}
 
996
 
 
997
/* Function:  Report vertices with a specific final status in a finished game.
 
998
* Arguments: Status in the form of one of the strings "alive", "dead",
 
999
*            "seki", "white_territory", "black_territory", or "dame".
 
1000
*            An optional random seed can be added.
 
1001
* Fails:     missing or invalid status string
 
1002
* Returns:   Vertices having the specified status. These are split with
 
1003
*            one string on each line if the vertices are nonempty (i.e.
 
1004
*            for "alive", "dead", and "seki").
 
1005
*/
 
1006
int
 
1007
QGtp::finalStatusList (QString status, int seed)
 
1008
{
 
1009
        sprintf (outFile, "%d final_status_list %s %d\n", _cpt,status.toLatin1().constData(),seed);
 
1010
        fflush(outFile);
 
1011
        return waitResponse();
 
1012
}
 
1013
 
 
1014
/**************
 
1015
* score *
 
1016
**************/
 
1017
 
 
1018
/* Function:  Compute the score of a finished game.
 
1019
* Arguments: Optional random seed
 
1020
* Fails:     never
 
1021
* Returns:   Score in SGF format (RE property).
 
1022
*/
 
1023
int
 
1024
QGtp::finalScore (int seed)
 
1025
{
 
1026
        sprintf (outFile, "%d final_score %d\n", _cpt,seed);
 
1027
        fflush(outFile);
 
1028
        return waitResponse();
 
1029
}
 
1030
 
 
1031
int
 
1032
QGtp::estimateScore ()
 
1033
{
 
1034
        sprintf (outFile, "%d estimate_score\n", _cpt);
 
1035
        fflush(outFile);
 
1036
        return waitResponse();
 
1037
}
 
1038
 
 
1039
int
 
1040
QGtp::newScore ()
 
1041
{
 
1042
        sprintf (outFile, "%d new_score \n", _cpt);
 
1043
        fflush(outFile);
 
1044
        return waitResponse();
 
1045
}
 
1046
 
 
1047
/**************
 
1048
* statistics *
 
1049
**************/
 
1050
 
 
1051
/* Function:  Reset the count of life nodes.
 
1052
* Arguments: none
 
1053
* Fails:     never
 
1054
* Returns:   nothing
 
1055
*/
 
1056
int
 
1057
QGtp::resetLifeNodeCounter ()
 
1058
{
 
1059
        sprintf (outFile, "%d reset_life_node_counter\n", _cpt);
 
1060
        fflush(outFile);
 
1061
        return waitResponse();
 
1062
}
 
1063
 
 
1064
/* Function:  Retrieve the count of life nodes.
 
1065
* Arguments: none
 
1066
* Fails:     never
 
1067
* Returns:   number of life nodes
 
1068
*/
 
1069
int
 
1070
QGtp::getLifeNodeCounter ()
 
1071
{
 
1072
        sprintf (outFile, "%d get_life_node_counter\n", _cpt);
 
1073
        fflush(outFile);
 
1074
        return waitResponse();
 
1075
}
 
1076
 
 
1077
/* Function:  Reset the count of owl nodes.
 
1078
* Arguments: none
 
1079
* Fails:     never
 
1080
* Returns:   nothing
 
1081
*/
 
1082
int
 
1083
QGtp::resetOwlNodeCounter ()
 
1084
{
 
1085
        sprintf (outFile, "%d reset_owl_node_counter\n", _cpt);
 
1086
        fflush(outFile);
 
1087
        return waitResponse();
 
1088
}
 
1089
 
 
1090
/* Function:  Retrieve the count of owl nodes.
 
1091
* Arguments: none
 
1092
* Fails:     never
 
1093
* Returns:   number of owl nodes
 
1094
*/
 
1095
int
 
1096
QGtp::getOwlNodeCounter ()
 
1097
{
 
1098
        sprintf (outFile, "%d get_owl_node_counter\n", _cpt);
 
1099
        fflush(outFile);
 
1100
        return waitResponse();
 
1101
}
 
1102
 
 
1103
/* Function:  Reset the count of reading nodes.
 
1104
* Arguments: none
 
1105
* Fails:     never
 
1106
* Returns:   nothing
 
1107
*/
 
1108
int
 
1109
QGtp::resetReadingNodeCounter ()
 
1110
{
 
1111
        sprintf (outFile, "%d reset_reading_node_counter\n", _cpt);
 
1112
        fflush(outFile);
 
1113
        return waitResponse();
 
1114
}
 
1115
 
 
1116
/* Function:  Retrieve the count of reading nodes.
 
1117
* Arguments: none
 
1118
* Fails:     never
 
1119
* Returns:   number of reading nodes
 
1120
*/
 
1121
int
 
1122
QGtp::getReadingNodeCounter ()
 
1123
{
 
1124
        sprintf (outFile, "%d get_reading_node_counter\n", _cpt);
 
1125
        fflush(outFile);
 
1126
        return waitResponse();
 
1127
}
 
1128
 
 
1129
/* Function:  Reset the count of trymoves/trykos.
 
1130
* Arguments: none
 
1131
* Fails:     never
 
1132
* Returns:   nothing
 
1133
*/
 
1134
int
 
1135
QGtp::resetTrymoveCounter ()
 
1136
{
 
1137
        sprintf (outFile, "%d reset_trymove_counter\n", _cpt);
 
1138
        fflush(outFile);
 
1139
        return waitResponse();
 
1140
}
 
1141
 
 
1142
/* Function:  Retrieve the count of trymoves/trykos.
 
1143
* Arguments: none
 
1144
* Fails:     never
 
1145
* Returns:   number of trymoves/trykos
 
1146
*/
 
1147
int
 
1148
QGtp::getTrymoveCounter ()
 
1149
{
 
1150
        sprintf (outFile, "%d get_trymove_counter\n", _cpt);
 
1151
        fflush(outFile);
 
1152
        return waitResponse();
 
1153
}
 
1154
 
 
1155
/*********
 
1156
* debug *
 
1157
*********/
 
1158
 
 
1159
/* Function:  Write the position to stderr.
 
1160
* Arguments: none
 
1161
* Fails:     never
 
1162
* Returns:   nothing
 
1163
*/
 
1164
int
 
1165
QGtp::showboard ()
 
1166
{
 
1167
        sprintf (outFile, "%d showboard\n", _cpt);
 
1168
        fflush(outFile);
 
1169
        return waitResponse();
 
1170
}
 
1171
 
 
1172
/* Function:  Dump stack to stderr.
 
1173
* Arguments: none
 
1174
* Fails:     never
 
1175
* Returns:   nothing
 
1176
*/
 
1177
int
 
1178
QGtp::dumpStack ()
 
1179
{
 
1180
        sprintf (outFile, "%d dump_stack\n", _cpt);
 
1181
        fflush(outFile);
 
1182
        return waitResponse();
 
1183
}
 
1184
 
 
1185
/* Function:  Write information about the influence function to stderr.
 
1186
* Arguments: color to move, optionally a list of what to show
 
1187
* Fails:     invalid color
 
1188
* Returns:   nothing
 
1189
*/
 
1190
int
 
1191
QGtp::debugInfluence (QString color,QString list)
 
1192
{
 
1193
        sprintf (outFile, "%d debug_influence %s %s\n", _cpt,color.toLatin1().constData(),list.toLatin1().constData());
 
1194
        fflush(outFile);
 
1195
        return waitResponse();
 
1196
}
 
1197
 
 
1198
/* Function:  Write information about the influence function after making
 
1199
*            a move to stderr.
 
1200
* Arguments: move, optionally a list of what to show
 
1201
* Fails:     never
 
1202
* Returns:   nothing
 
1203
*/
 
1204
int
 
1205
QGtp::debugMoveInfluence (QString color, char c, int i,QString list)
 
1206
{
 
1207
        sprintf (outFile, "%d debug_move_influence %s %c%d %s\n", _cpt,color.toLatin1().constData(),c,i,list.toLatin1().constData());
 
1208
        fflush(outFile);
 
1209
        return waitResponse();
 
1210
}
 
1211
 
 
1212
/* Function:  Return information about the influence function.
 
1213
* Arguments: color to move
 
1214
* Fails:     never
 
1215
* Returns:   Influence data formatted
 
1216
*/
 
1217
int
 
1218
QGtp::influence (QString color)
 
1219
{
 
1220
        sprintf (outFile, "%d influence %s\n", _cpt,color.toLatin1().constData());
 
1221
        fflush(outFile);
 
1222
        return waitResponse();
 
1223
}
 
1224
 
 
1225
/* Function:  Return information about the influence function after a move
 
1226
* Arguments: move
 
1227
* Fails:     never
 
1228
* Returns:   Influence data formatted in the same way as for gtp_influence.
 
1229
*/
 
1230
int
 
1231
QGtp::moveInfluence (QString color, char c, int i)
 
1232
{
 
1233
        sprintf (outFile, "%d move_influence %s %c%d\n", _cpt,color.toLatin1().constData(),c,i);
 
1234
        fflush(outFile);
 
1235
        return waitResponse();
 
1236
}
 
1237
 
 
1238
/* Function:  Return the information in the worm data structure.
 
1239
* Arguments: none
 
1240
* Fails:     never
 
1241
* Returns:   Worm data formatted
 
1242
*/
 
1243
int
 
1244
QGtp::wormData ()
 
1245
{
 
1246
        sprintf (outFile, "%d worm_data\n", _cpt);
 
1247
        fflush(outFile);
 
1248
        return waitResponse();
 
1249
}
 
1250
 
 
1251
/* Function:  Return the information in the worm data structure.
 
1252
* Arguments: vertex
 
1253
* Fails:     never
 
1254
* Returns:   Worm data formatted
 
1255
*/
 
1256
int
 
1257
QGtp::wormData (char c, int i)
 
1258
{
 
1259
        sprintf (outFile, "%d worm_data %c%d\n", _cpt,c,i);
 
1260
        fflush(outFile);
 
1261
        return waitResponse();
 
1262
}
 
1263
 
 
1264
/* Function:  Return the cutstone field in the worm data structure.
 
1265
* Arguments: non-empty vertex
 
1266
* Fails:     never
 
1267
* Returns:   cutstone
 
1268
*/
 
1269
int
 
1270
QGtp::wormCutstone (char c, int i)
 
1271
{
 
1272
        sprintf (outFile, "%d worm_cutstone %c%d\n", _cpt,c,i);
 
1273
        fflush(outFile);
 
1274
        return waitResponse();
 
1275
}
 
1276
 
 
1277
/* Function:  Tune the parameters for the move ordering in the tactical
 
1278
*            reading.
 
1279
* Arguments: MOVE_ORDERING_PARAMETERS integers
 
1280
* Fails:     incorrect arguments
 
1281
* Returns:   nothing
 
1282
*/
 
1283
int
 
1284
QGtp::tuneMoveOrdering (int MOVE_ORDERING_PARAMETERS)
 
1285
{
 
1286
        sprintf (outFile, "%d tune_move_ordering %d\n", _cpt,MOVE_ORDERING_PARAMETERS);
 
1287
        fflush(outFile);
 
1288
        return waitResponse();
 
1289
}
 
1290
 
 
1291
/* Function:  Echo the parameter
 
1292
* Arguments: string
 
1293
* Fails:     never
 
1294
* Returns:   nothing
 
1295
*/
 
1296
int
 
1297
QGtp::echo (QString param)
 
1298
{
 
1299
        sprintf (outFile, "%d echo %s\n", _cpt,param.toLatin1().constData());
 
1300
        fflush(outFile);
 
1301
        return waitResponse();
 
1302
}
 
1303
 
 
1304
/* Function:  List all known commands
 
1305
* Arguments: none
 
1306
* Fails:     never
 
1307
* Returns:   list of known commands, one per line
 
1308
*/
 
1309
int
 
1310
QGtp::help ()
 
1311
{
 
1312
        sprintf (outFile, "%d help\n", _cpt);
 
1313
        fflush(outFile);
 
1314
        return waitResponse();
 
1315
}
 
1316
 
 
1317
/* Function:  evaluate wether a command is known
 
1318
* Arguments: command word
 
1319
* Fails:     never
 
1320
* Returns:   true or false
 
1321
*/
 
1322
int
 
1323
QGtp::knownCommand (QString s)
 
1324
{
 
1325
        sprintf (outFile, "%d known_command %s\n", _cpt,s.toLatin1().constData());
 
1326
        fflush(outFile);
 
1327
        return waitResponse();
 
1328
}
 
1329
 
 
1330
/* Function:  Turn uncertainty reports from owl_attack
 
1331
*            and owl_defend on or off.
 
1332
* Arguments: "on" or "off"
 
1333
* Fails:     invalid argument
 
1334
* Returns:   nothing
 
1335
*/
 
1336
int
 
1337
QGtp::reportUncertainty (QString s)
 
1338
{
 
1339
        sprintf (outFile, "%d report_uncertainty %s\n", _cpt,s.toLatin1().constData());
 
1340
        fflush(outFile);
 
1341
        return waitResponse();
 
1342
}
 
1343
 
 
1344
/* Function:  List the stones of a worm
 
1345
* Arguments: the location
 
1346
* Fails:     if called on an empty or off-board location
 
1347
* Returns:   list of stones
 
1348
*/
 
1349
int
 
1350
QGtp::wormStones()
 
1351
{
 
1352
        sprintf (outFile, "%d worm_stones\n", _cpt);
 
1353
        fflush(outFile);
 
1354
        return waitResponse();
 
1355
}
 
1356
 
 
1357
int
 
1358
QGtp::shell(QString s)
 
1359
{
 
1360
        sprintf (outFile, "%d %s\n", _cpt, s.toLatin1().constData());
 
1361
        fflush(outFile);
 
1362
        return waitResponse();
 
1363
}
 
1364