File: Output.cpp

package info (click to toggle)
pentobi 29.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,892 kB
  • sloc: cpp: 25,719; javascript: 875; xml: 40; makefile: 13; sh: 6
file content (139 lines) | stat: -rw-r--r-- 4,054 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//-----------------------------------------------------------------------------
/** @file twogtp/Output.cpp
    @author Markus Enzenberger
    @copyright GNU General Public License version 3 or later */
//-----------------------------------------------------------------------------

#include "Output.h"

#include <cstdio>
#include <fstream>
#include <iomanip>
#include <fcntl.h>
#include <unistd.h>
#include <sys/file.h>
#include "libboardgame_base/StringUtil.h"

using libboardgame_base::from_string;
using libboardgame_base::split;
using libboardgame_base::trim;

//-----------------------------------------------------------------------------

Output::Output(Variant variant, const string& prefix, bool create_tree)
    : m_create_tree(create_tree),
      m_prefix(prefix),
      m_output_tree(variant)
{
    m_lock_fd = creat((prefix + ".lock").c_str(), 0644);
    if (m_lock_fd == -1)
        throw runtime_error("Output: could not create lock file");
    if (flock(m_lock_fd, LOCK_EX | LOCK_NB) == -1)
        throw runtime_error("Output: twogtp already running");
    m_timer.reset(m_time_source);
    ifstream in(prefix + ".dat");
    if (! in)
        return;
    string line;
    while (getline(in, line))
    {
        line = trim(line);
        if (! line.empty() && line[0] == '#')
            continue;
        auto columns = split(line, '\t');
        if (columns.empty())
            continue;
        unsigned game_number;
        if (! from_string(columns[0], game_number))
            throw runtime_error("Output: expected game number");
        m_games.insert({game_number, line});
    }
    while (m_games.count(m_next) != 0)
        ++m_next;
    if (check_sentinel())
        remove((prefix + ".stop").c_str());
    if (m_create_tree && m_next > 0)
        m_output_tree.load(prefix + "-tree.blksgf");
}

Output::~Output()
{
    save();
    flock(m_lock_fd, LOCK_UN);
    close(m_lock_fd);
    remove((m_prefix + ".lock").c_str());
}

void Output::add_result(unsigned n, float result, const Board& bd,
                        unsigned player_black, double cpu_black,
                        double cpu_white, const string& sgf,
                        const array<bool, Board::max_moves>& is_real_move)
{
    {
        lock_guard lock(m_mutex);
        unsigned nu_fast_open = 0;
        for (unsigned i = 0; i < bd.get_nu_moves(); ++i)
            if (! is_real_move[i])
                ++nu_fast_open;
        ostringstream line;
        line << n << '\t'
             << setprecision(4) << result << '\t'
             << bd.get_nu_moves() << '\t'
             << player_black << '\t'
             << setprecision(5) << cpu_black << '\t'
             << cpu_white << '\t'
             << nu_fast_open;
        m_games.insert({n, line.str()});
        m_sgf_buffer << sgf;
        if (m_create_tree)
            m_output_tree.add_game(bd, player_black, result, is_real_move);
    }
    if (m_timer() > m_save_interval)
    {
        save();
        m_timer.reset();
    }
}

bool Output::check_sentinel()
{
    return ! ifstream(m_prefix + ".stop").fail();
}

bool Output::generate_fast_open_move(bool is_player_black, const Board& bd,
                                     Color to_play, Move& mv)
{
    lock_guard lock(m_mutex);
    m_output_tree.generate_move(is_player_black, bd, to_play, mv);
    return ! mv.is_null();
}

unsigned Output::get_next()
{
    lock_guard lock(m_mutex);
    unsigned n = m_next;
    do
       ++m_next;
    while (m_games.count(m_next) != 0);
    return n;
}

void Output::save()
{
    lock_guard lock(m_mutex);
    {
        ofstream out(m_prefix + ".dat");
        out << "# Game\tResult\tLength\tPlayerB\tCpuB\tCpuW\tFast\n";
        for (auto& i : m_games)
            out << i.second << '\n';
    }
    {
        ofstream out(m_prefix + ".blksgf", ios::app);
        out << m_sgf_buffer.str();
        m_sgf_buffer.str("");
    }
    if (m_create_tree)
        m_output_tree.save(m_prefix + "-tree.blksgf");
}

//-----------------------------------------------------------------------------