~vcs-imports-ii/gnubg/trunk

1994 by thyssen
Show distribution of rolls (sorry guys: only for GTK+ 2.x).
1
/*
2
 * gtkrolls.c
3
 *
4
 * by Joern Thyssen <jth@gnubg.org>, 2002
5
 *
6
 * This program is free software; you can redistribute it and/or modify
3944 by ace
*** empty log message ***
7
 * it under the terms of version 3 or later of the GNU General Public License as
1994 by thyssen
Show distribution of rolls (sorry guys: only for GTK+ 2.x).
8
 * published by the Free Software Foundation.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 *
6217 by plm
Fix typo
19
 * $Id: gtkrolls.c,v 1.42 2017/05/29 15:33:04 plm Exp $
1994 by thyssen
Show distribution of rolls (sorry guys: only for GTK+ 2.x).
20
 */
21
3940 by c_anthon
replace gtk_signal* with g_signal*
22
#include "config.h"
1994 by thyssen
Show distribution of rolls (sorry guys: only for GTK+ 2.x).
23
4038 by Superfly_Jon
Misc changes
24
#include <string.h>
4513 by c_anthon
minor warnings and inconsistencies
25
#include <stdlib.h>
1994 by thyssen
Show distribution of rolls (sorry guys: only for GTK+ 2.x).
26
6048 by plm
Align neural net output to simd vector size.
27
#include "lib/simd.h"
28
1994 by thyssen
Show distribution of rolls (sorry guys: only for GTK+ 2.x).
29
#include "gtkgame.h"
30
#include "drawboard.h"
2380 by thyssen
move all Output* functions to new file format.c (change all callers)
31
#include "format.h"
3682 by Superfly_Jon
Fixed modal dialog z order problems
32
#include "gtkwindows.h"
4042 by c_anthon
rename sgf.l and sgf.y and fix a bunch of minor compiler warnings
33
#include "gtkrolls.h"
1994 by thyssen
Show distribution of rolls (sorry guys: only for GTK+ 2.x).
34
35
typedef struct _rollswidget {
36
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
37
    GtkWidget *psw;             /* the scrolled window */
38
    GtkWidget *ptv;             /* the tree widget */
39
    GtkWidget *pDialog, *pCancel, *pScale;
40
41
    evalcontext *pec;
42
    matchstate *pms;
43
    int nDepth;                 /* current depth */
6206 by plm
Fix gtk3 warnings.
44
    int closing;
45
1994 by thyssen
Show distribution of rolls (sorry guys: only for GTK+ 2.x).
46
} rollswidget;
47
48
49
static void
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
50
add_level(GtkTreeStore * model, GtkTreeIter * iter,
51
          const int n, const TanBoard anBoard,
52
          evalcontext * pec, cubeinfo * pci, const gboolean fInvert, float arOutput[NUM_ROLLOUT_OUTPUTS])
53
{
54
55
    int n0, n1;
56
    GtkTreeIter child_iter;
57
    cubeinfo ci;
58
    TanBoard an;
6048 by plm
Align neural net output to simd vector size.
59
    SSE_ALIGN(float ar[NUM_ROLLOUT_OUTPUTS]);
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
60
    int anMove[8];
61
    int i;
62
63
    char szRoll[3], szMove[100], *szEquity;
64
65
    /* cubeinfo for opponent on roll */
66
67
    memcpy(&ci, pci, sizeof(cubeinfo));
68
    ci.fMove = !pci->fMove;
69
70
    for (i = 0; i < NUM_ROLLOUT_OUTPUTS; ++i)
71
        arOutput[i] = 0.0f;
72
73
    for (n0 = 0; n0 < 6; ++n0) {
74
        for (n1 = 0; n1 <= n0; ++n1) {
75
76
            memcpy(an, anBoard, sizeof(an));
77
78
            if (FindBestMove(anMove, n0 + 1, n1 + 1, an, pci, pec, defaultFilters) < 0)
79
                return;
80
81
            SwapSides(an);
82
83
            gtk_tree_store_append(model, &child_iter, iter);
84
85
            if (n) {
86
87
                add_level(model, &child_iter, n - 1, (ConstTanBoard) an, pec, &ci, !fInvert, ar);
88
                if (fInterrupt)
89
                    return;
90
91
            } else {
92
93
                /* evaluate resulting position */
94
95
                ProgressValueAdd(1);
96
97
                if (GeneralEvaluationE(ar, (ConstTanBoard) an, &ci, pec) < 0)
98
                    return;
99
100
            }
101
102
            if (fInvert)
103
                InvertEvaluationR(ar, &ci);
104
105
            sprintf(szRoll, "%d%d", n0 + 1, n1 + 1);
106
            FormatMove(szMove, anBoard, anMove);
107
108
            szEquity = OutputMWC(ar[OUTPUT_CUBEFUL_EQUITY], fInvert ? pci : &ci, TRUE);
109
110
            gtk_tree_store_set(model, &child_iter, 0, szRoll, 1, szMove, 2, szEquity, -1);
111
112
            for (i = 0; i < NUM_ROLLOUT_OUTPUTS; ++i)
113
                arOutput[i] += (n0 == n1) ? ar[i] : 2.0f * ar[i];
114
115
        }
1994 by thyssen
Show distribution of rolls (sorry guys: only for GTK+ 2.x).
116
117
    }
118
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
119
    for (i = 0; i < NUM_ROLLOUT_OUTPUTS; ++i)
120
        arOutput[i] /= 36.0f;
121
122
    /* add average equity */
123
124
    szEquity = OutputMWC(arOutput[OUTPUT_CUBEFUL_EQUITY], fInvert ? pci : &ci, TRUE);
125
126
    gtk_tree_store_append(model, &child_iter, iter);
127
128
    gtk_tree_store_set(model, &child_iter, 0, _("Average equity"), 1, "", 2, szEquity, -1);
129
130
    if (!fInvert)
131
        InvertEvaluationR(arOutput, pci);
132
133
}
134
135
136
static gint
137
sort_func(GtkTreeModel * model, GtkTreeIter * a, GtkTreeIter * b, gpointer UNUSED(data))
138
{
139
    char *sz0, *sz1;
140
    float r0, r1;
141
142
    gtk_tree_model_get(model, a, 2, &sz0, -1);
143
    gtk_tree_model_get(model, b, 2, &sz1, -1);
144
145
    r0 = (float) atof(sz0);
146
    r1 = (float) atof(sz1);
147
148
    if (r0 < r1)
149
        return -1;
150
    else if (r0 > r1)
151
        return +1;
152
    else
153
        return 0;
154
155
}
156
157
158
static GtkTreeModel *
159
create_model(const int n, evalcontext * pec, const matchstate * pms)
160
{
161
    GtkTreeStore *model;
162
    TanBoard anBoard;
163
    cubeinfo ci;
164
    float arOutput[NUM_ROLLOUT_OUTPUTS];
165
    int i, j;
166
167
    memcpy(anBoard, pms->anBoard, sizeof(anBoard));
168
169
    /* create tree store */
170
    model = gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
171
172
    GetMatchStateCubeInfo(&ci, pms);
173
174
    for (i = 0, j = 1; i < n; ++i, j *= 21);
175
176
    ProgressStartValue(_("Calculating equities"), j);
177
178
    add_level(model, NULL, n - 1, (ConstTanBoard) anBoard, pec, &ci, TRUE, arOutput);
179
180
    ProgressEnd();
181
182
    if (!fInterrupt) {
183
        gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model), 2, sort_func, NULL, NULL);
184
        gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), 2, GTK_SORT_DESCENDING);
185
        return GTK_TREE_MODEL(model);
186
    } else
187
        return NULL;
1994 by thyssen
Show distribution of rolls (sorry guys: only for GTK+ 2.x).
188
}
189
190
191
static GtkWidget *
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
192
RollsTree(const int n, evalcontext * pec, const matchstate * pms)
4038 by Superfly_Jon
Misc changes
193
{
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
194
    GtkTreeModel *pm;
195
    GtkWidget *ptv;
196
    int i;
197
    GtkCellRenderer *renderer;
198
    static const char *aszColumn[] = {
199
        N_("Roll"),
200
        N_("Move"),
201
        N_("Equity")
202
    };
203
204
    pm = create_model(n, pec, pms);
205
    if (fInterrupt) {
206
        return NULL;
207
    }
208
    ptv = gtk_tree_view_new_with_model(pm);
209
    g_object_unref(G_OBJECT(pm));
210
211
    /* add columns */
212
213
    for (i = 0; i < 3; ++i) {
214
215
        renderer = gtk_cell_renderer_text_new();
216
        g_object_set(G_OBJECT(renderer), "xalign", 0.0, NULL);
217
218
        gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(ptv),
219
                                                    -1, gettext(aszColumn[i]), renderer, "text", i, NULL);
220
    }
221
222
    if (fInterrupt) {
223
        gtk_widget_destroy(ptv);
224
        return NULL;
225
    }
226
227
    return ptv;
1994 by thyssen
Show distribution of rolls (sorry guys: only for GTK+ 2.x).
228
}
229
5051 by mdpetch
gtk_range_set_update_policy deprecated. Replace using events
230
static gboolean fScrollComplete = FALSE;
231
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
232
static void
233
DepthChanged(GtkRange * pr, rollswidget * prw)
234
{
235
    GtkWidget *pNewRolls;
236
    int n;
237
238
    if (!fScrollComplete)
239
        return;
240
241
    if (fInterrupt) {           /* Stop recursion on cancel */
242
        fInterrupt = FALSE;
243
        return;
244
    }
245
246
    n = (int) gtk_range_get_value(pr);
247
    if (n == prw->nDepth)
248
        return;
249
250
    pwOldGrab = pwGrab;
251
    pwGrab = prw->pDialog;
252
253
    gtk_widget_set_sensitive(DialogArea(prw->pDialog, DA_BUTTONS), FALSE);
254
    gtk_widget_set_sensitive(prw->pScale, FALSE);
255
    gtk_widget_set_sensitive(prw->pCancel, TRUE);
256
257
    pNewRolls = RollsTree(n, prw->pec, prw->pms);
258
259
    if (pNewRolls) {
260
        if (prw->ptv) {
261
            gtk_widget_destroy(GTK_WIDGET(prw->ptv));
262
            prw->ptv = NULL;
263
        }
264
        prw->ptv = pNewRolls;
265
266
        gtk_container_add(GTK_CONTAINER(prw->psw), prw->ptv);
267
        prw->nDepth = n;
268
    } else {
269
        if (!prw->closing)
270
            gtk_range_set_value(GTK_RANGE(prw->pScale), (double) prw->nDepth);
271
    }
272
273
    pwGrab = pwOldGrab;
274
    if (!prw->closing) {
275
        gtk_widget_set_sensitive(DialogArea(prw->pDialog, DA_BUTTONS), TRUE);
276
        gtk_widget_set_sensitive(prw->pScale, TRUE);
277
        gtk_widget_set_sensitive(prw->pCancel, FALSE);
278
279
        gtk_widget_show_all(GTK_WIDGET(prw->psw));
280
    } else {                    /* dialog is waiting to close */
281
        gtk_widget_destroy(prw->pDialog);
282
    }
283
}
284
285
static void
286
CancelRolls(GtkWidget * pButton)
287
{
288
    fInterrupt = TRUE;
289
    gtk_widget_set_sensitive(pButton, FALSE);
290
}
291
292
static gint
293
RollsClose(GtkWidget * UNUSED(widget), GdkEvent * UNUSED(eventDetails), rollswidget * prw)
294
{
295
    if (pwOldGrab != pwGrab) {  /* Mid-depth change - wait for it to cancel */
296
        gtk_widget_set_sensitive(prw->pCancel, FALSE);
297
        prw->closing = TRUE;
298
        fInterrupt = TRUE;
299
        return TRUE;
300
    } else
301
        return FALSE;
302
}
303
304
static gboolean
305
DepthEvent(GtkWidget * UNUSED(widget), GdkEvent * event, rollswidget * prw)
306
{
307
    switch (event->type) {
308
    case GDK_BUTTON_PRESS:
309
        fScrollComplete = FALSE;
310
        break;
311
    case GDK_BUTTON_RELEASE:
312
        fScrollComplete = TRUE;
313
        g_signal_emit_by_name(G_OBJECT(prw->pScale), "value-changed", prw);
314
        break;
315
    default:
316
        ;
317
    }
318
319
    return FALSE;
320
}
321
1994 by thyssen
Show distribution of rolls (sorry guys: only for GTK+ 2.x).
322
extern void
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
323
GTKShowRolls(const gint nDepth, evalcontext * pec, matchstate * pms)
324
{
325
326
327
    GtkWidget *vbox, *hbox, *vb2;
328
    GtkAdjustment *padj;
329
    int n;
330
331
    rollswidget *prw = (rollswidget *) g_malloc(sizeof(rollswidget));
332
333
    prw->closing = FALSE;
334
    prw->pDialog = GTKCreateDialog(_("Distribution of rolls"), DT_INFO, NULL, DIALOG_FLAG_MODAL, NULL, NULL);
335
336
    n = (nDepth < 1) ? 1 : nDepth;
337
338
    prw->pms = pms;
339
    prw->pec = pec;
340
    prw->nDepth = -1;           /* not yet calculated */
341
342
    /* vbox to hold tree widget and buttons */
343
6206 by plm
Fix gtk3 warnings.
344
#if GTK_CHECK_VERSION(3,0,0)
345
    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
346
#else
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
347
    vbox = gtk_vbox_new(FALSE, 8);
6206 by plm
Fix gtk3 warnings.
348
#endif
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
349
    gtk_container_set_border_width(GTK_CONTAINER(vbox), 8);
350
    gtk_container_add(GTK_CONTAINER(DialogArea(prw->pDialog, DA_MAIN)), vbox);
351
352
    /* hook to free rollswidget on widget destruction */
353
    g_object_set_data_full(G_OBJECT(vbox), "rollswidget", prw, g_free);
354
355
    /* scrolled window to hold tree widget */
356
357
    prw->psw = gtk_scrolled_window_new(NULL, NULL);
6216 by plm
Fix tree widget width issue with gtk3
358
#if GTK_CHECK_VERSION(3,0,0)
359
/* This is apparently needed in 3.18.9 (Ubuntu 16.04)
360
   but no longer in 3.22.15 (Fedora 25 / FreeBSD) */
6217 by plm
Fix typo
361
    g_object_set(G_OBJECT(prw->psw), "expand", TRUE, NULL);
6216 by plm
Fix tree widget width issue with gtk3
362
#endif
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
363
    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(prw->psw), GTK_SHADOW_ETCHED_IN);
364
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(prw->psw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
365
    gtk_box_pack_start(GTK_BOX(vbox), prw->psw, TRUE, TRUE, 0);
366
367
    /* buttons */
368
6206 by plm
Fix gtk3 warnings.
369
#if GTK_CHECK_VERSION(3,0,0)
370
    gtk_box_pack_start(GTK_BOX(vbox), gtk_separator_new(GTK_ORIENTATION_HORIZONTAL), FALSE, FALSE, 0);
371
#else
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
372
    gtk_box_pack_start(GTK_BOX(vbox), gtk_hseparator_new(), FALSE, FALSE, 0);
6206 by plm
Fix gtk3 warnings.
373
#endif
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
374
6206 by plm
Fix gtk3 warnings.
375
#if GTK_CHECK_VERSION(3,0,0)
376
    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
377
#else
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
378
    hbox = gtk_hbox_new(FALSE, 0);
6206 by plm
Fix gtk3 warnings.
379
#endif
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
380
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 4);
381
382
    gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_("Depth")), FALSE, FALSE, 4);
383
384
    /* Set page size to 1 */
6212 by plm
Limit depth of rolls analysis to 4
385
    padj = GTK_ADJUSTMENT(gtk_adjustment_new(1., 1., 4., 1., 1., 0.));
6206 by plm
Fix gtk3 warnings.
386
#if GTK_CHECK_VERSION(3,0,0)
387
    prw->pScale = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, padj);
388
#else
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
389
    prw->pScale = gtk_hscale_new(padj);
6206 by plm
Fix gtk3 warnings.
390
#endif
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
391
    gtk_widget_set_size_request(prw->pScale, 100, -1);
392
    gtk_box_pack_start(GTK_BOX(hbox), prw->pScale, FALSE, FALSE, 4);
393
    gtk_scale_set_digits(GTK_SCALE(prw->pScale), 0);
394
    gtk_scale_set_draw_value(GTK_SCALE(prw->pScale), TRUE);
395
396
    /* Separate vbox to make button height correct */
6206 by plm
Fix gtk3 warnings.
397
#if GTK_CHECK_VERSION(3,0,0)
398
    vb2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
399
#else
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
400
    vb2 = gtk_vbox_new(FALSE, 0);
6206 by plm
Fix gtk3 warnings.
401
#endif
5379 by mdpetch
Standardized the code formatting with indent -kr -l120 -fc1 -sc -nut -psl
402
    gtk_box_pack_start(GTK_BOX(hbox), vb2, FALSE, FALSE, 4);
403
    prw->pCancel = gtk_button_new_with_label(_("Cancel"));
404
    gtk_widget_set_size_request(prw->pCancel, -1, 27);
405
    gtk_widget_set_sensitive(prw->pCancel, FALSE);
406
    g_signal_connect(G_OBJECT(prw->pCancel), "clicked", G_CALLBACK(CancelRolls), NULL);
407
    gtk_box_pack_start(GTK_BOX(vb2), prw->pCancel, FALSE, FALSE, 4);
408
409
    g_signal_connect(G_OBJECT(prw->pScale), "button-press-event", G_CALLBACK(DepthEvent), prw);
410
    g_signal_connect(G_OBJECT(prw->pScale), "button-release-event", G_CALLBACK(DepthEvent), prw);
411
    g_signal_connect(G_OBJECT(prw->pScale), "value-changed", G_CALLBACK(DepthChanged), prw);
412
413
    /* tree  */
414
415
    if ((prw->ptv = RollsTree(n, pec, pms)) != 0) {
416
        gtk_container_add(GTK_CONTAINER(prw->psw), prw->ptv);
417
        prw->nDepth = n;
418
    }
419
420
    gtk_window_set_default_size(GTK_WINDOW(prw->pDialog), 560, 400);
421
    g_signal_connect(G_OBJECT(prw->pDialog), "delete_event", G_CALLBACK(RollsClose), prw);      /* In case closed mid calculation */
422
423
    GTKRunDialog(prw->pDialog);
1994 by thyssen
Show distribution of rolls (sorry guys: only for GTK+ 2.x).
424
}