string implode(const vecstr & vec, const string & sep){ string ret; if(vec.size() == 0) return ret; ret += vec[0]; for(unsigned int i = 1; i < vec.size(); i++){ ret += sep; ret += vec[i]; } return ret; }
GTPResponse GTPCommon::gtp_time(vecstr args){ if(args.size() == 0) return GTPResponse(true, string("\n") + "Update the time settings, eg: time -s 2.5 -m 10 -g 600 -f 1\n" + "Method for distributing remaining time, current: " + time_control.method_name() + " " + to_str(time_control.param) + "\n" + " -p --percent Percentage of the remaining time every move [10.0]\n" + " -e --even Multiple of even split of the maximum remaining moves [2.0]\n" + " -s --stats Multiple of even split of the expected remaining moves [2.0]\n" + "Time allocation\n" + " -m --move Time per move [" + to_str(time_control.move) + "]\n" + " -g --game Time per game [" + to_str(time_control.game) + "]\n" + " -f --flexible Add remaining time per move to remaining time [" + to_str(time_control.flexible) + "]\n" + " -i --maxsims Maximum number of simulations per move [" + to_str(time_control.max_sims) + "]\n" + "Current game\n" + " -r --remain Remaining time for this game [" + to_str(time_control.remain) + "]\n"); for(unsigned int i = 0; i < args.size(); i++) { string arg = args[i]; if(arg == "-p" || arg == "--percent"){ time_control.method = TimeControl::PERCENT; time_control.param = 10; if(i+1 < args.size() && from_str<double>(args[i+1]) > 0) time_control.param = from_str<double>(args[++i]); }else if(arg == "-e" || arg == "--even"){ time_control.method = TimeControl::EVEN; time_control.param = 2; if(i+1 < args.size() && from_str<double>(args[i+1]) > 0) time_control.param = from_str<double>(args[++i]); }else if(arg == "-s" || arg == "--stats"){ time_control.method = TimeControl::STATS; time_control.param = 2; if(i+1 < args.size() && from_str<double>(args[i+1]) > 0) time_control.param = from_str<double>(args[++i]); }else if((arg == "-m" || arg == "--move") && i+1 < args.size()){ time_control.move = from_str<double>(args[++i]); }else if((arg == "-g" || arg == "--game") && i+1 < args.size()){ time_control.game = from_str<float>(args[++i]); // TODO: should this only happen if the game hasn't started yet? time_control.remain = time_control.game; }else if((arg == "-f" || arg == "--flexible") && i+1 < args.size()){ time_control.flexible = from_str<bool>(args[++i]); }else if((arg == "-i" || arg == "--maxsims") && i+1 < args.size()){ time_control.max_sims = from_str<int>(args[++i]); }else if((arg == "-r" || arg == "--remain") && i+1 < args.size()){ time_control.remain = from_str<double>(args[++i]); }else{ return GTPResponse(false, "Missing or unknown parameter"); } } return GTPResponse(true); }
GTPResponse HavannahGTP::gtp_swap(vecstr args){ if(args.size() == 0) return GTPResponse(false, "Wrong number of arguments"); log("swap " + implode(args, " ")); if(args.size() >= 1) allow_swap = from_str<bool>(args[0]); string ret = ""; if(allow_swap) ret += "Swap on"; else ret += "Swap off"; return GTPResponse(true, ret); }
GTPResponse GTP::gtp_colorboard(vecstr args){ if(args.size() >= 1) colorboard = from_str<int>(args[0]); else colorboard = !colorboard; return GTPResponse(true, "Color " + to_str(colorboard)); }
GTPResponse GTP::gtp_extended(vecstr args) { if(args.size() >= 1) genmoveextended = from_str<bool>(args[0]); else genmoveextended = !genmoveextended; return GTPResponse(true, "extended " + to_str(genmoveextended)); }
GTPResponse GTP::gtp_verbose(vecstr args){ if(args.size() >= 1) verbose = from_str<int>(args[0]); else verbose = !verbose; return GTPResponse(true, "Verbose " + to_str(verbose)); }
GTPResponse GTP::gtp_playgame(vecstr args){ GTPResponse ret(true); for(unsigned int i = 0; ret.success && i < args.size(); i++) ret = play(args[i], hist->toplay()); return ret; }
GTPResponse GTP::gtp_play(vecstr args){ if(args.size() != 2) return GTPResponse(false, "Wrong number of arguments"); switch(tolower(args[0][0])){ case 'w': return play(args[1], Side::P1); case 'b': return play(args[1], Side::P2); default: return GTPResponse(false, "Invalid player selection"); } }
GTPResponse GTP::gtp_undo(vecstr args){ int num = (args.size() >= 1 ? from_str<int>(args[0]) : 1); while(num--){ hist.undo(); } set_board(false); if(verbose >= 2) logerr(hist->to_s(colorboard) + "\n"); return GTPResponse(true); }
GTPResponse HavannahGTP::gtp_dists(vecstr args){ Board board = game.getboard(); LBDists dists(&board); int side = 0; if(args.size() >= 1){ switch(tolower(args[0][0])){ case 'w': side = 1; break; case 'b': side = 2; break; default: return GTPResponse(false, "Invalid player selection"); } } int size = board.get_size(); int size_d = board.get_size_d(); string s = "\n"; s += string(size + 3, ' '); for(int i = 0; i < size; i++) s += " " + to_str(i+1); s += "\n"; string white = "O", black = "@"; if(colorboard){ string esc = "\033", reset = esc + "[0m"; white = esc + "[1;33m" + "@" + reset; //yellow black = esc + "[1;34m" + "@" + reset; //blue } for(int y = 0; y < size_d; y++){ s += string(abs(size-1 - y) + 2, ' '); s += char('A' + y); for(int x = board.linestart(y); x < board.lineend(y); x++){ int p = board.get(x, y); s += ' '; if(p == 0){ int d = (side ? dists.get(Move(x, y), side) : dists.get(Move(x, y))); if(d < 10) s += to_str(d); else s += '.'; }else if(p == 1){ s += white; }else if(p == 2){ s += black; } } if(y < size-1) s += " " + to_str(1 + size + y); s += '\n'; } return GTPResponse(true, s); }
GTPResponse GTP::gtp_save_sgf(vecstr args){ int limit = -1; if(args.size() == 0) return GTPResponse(true, "save_sgf <filename> [work limit]"); std::ifstream infile(args[0].c_str()); if(infile) { infile.close(); return GTPResponse(false, "File " + args[0] + " already exists"); } std::ofstream outfile(args[0].c_str()); if(!outfile) return GTPResponse(false, "Opening file " + args[0] + " for writing failed"); if(args.size() > 1) limit = from_str<unsigned int>(args[1]); SGFPrinter<Move> sgf(outfile); sgf.game(Board::name); sgf.program(gtp_name(vecstr()).response, gtp_version(vecstr()).response); sgf.size(hist->get_size()); sgf.end_root(); Side s = Side::P1; for(auto m : hist){ sgf.move(s, m); s = ~s; } agent->gen_sgf(sgf, limit); sgf.end(); outfile.close(); return true; }
GTPResponse GTP::gtp_boardsize(vecstr args) { if(args.size() != 1) return GTPResponse(false, "Current board size: " + to_str(hist->get_size())); int size = from_str<int>(args[0]); if(size < Board::min_size || size > Board::max_size) return GTPResponse(false, "Size " + to_str(size) + " is out of range."); hist = History<Board>(size); set_board(); time_control.new_game(); return GTPResponse(true); }
GTPResponse HavannahGTP::gtp_undo(vecstr args){ int num = 1; if(args.size() >= 1) num = from_str<int>(args[0]); while(num--){ game.undo(); log("undo"); } set_board(false); if(verbose >= 2) logerr(game.getboard().to_s(colorboard) + "\n"); return GTPResponse(true); }
GTPResponse HavannahGTP::gtp_play(vecstr args){ if(args.size() != 2) return GTPResponse(false, "Wrong number of arguments"); char toplay = 0; switch(tolower(args[0][0])){ case 'w': toplay = 1; break; case 'b': toplay = 2; break; default: return GTPResponse(false, "Invalid player selection"); } return play(args[1], toplay); }
GTPResponse HavannahGTP::gtp_boardsize(vecstr args){ if(args.size() != 1) return GTPResponse(false, "Current board size: " + to_str(game.getsize())); log("boardsize " + args[0]); int size = from_str<int>(args[0]); if(size < 3 || size > 10) return GTPResponse(false, "Size " + to_str(size) + " is out of range."); game = HavannahGame(size); set_board(); time_remain = time.game; return GTPResponse(true); }
GTPResponse GTP::gtp_load_sgf(vecstr args){ if(args.size() == 0) return GTPResponse(true, "load_sgf <filename>"); std::ifstream infile(args[0].c_str()); if(!infile) { return GTPResponse(false, "Error opening file " + args[0] + " for reading"); } SGFParser<Move> sgf(infile); if(sgf.game() != Board::name){ infile.close(); return GTPResponse(false, "File is for the wrong game: " + sgf.game()); } int size = sgf.size(); if(size != hist->get_size()){ if(hist.len() == 0){ hist = History(size); set_board(); time_control.new_game(); }else{ infile.close(); return GTPResponse(false, "File has the wrong boardsize to match the existing game"); } } Side s = Side::P1; while(sgf.next_node()){ Move m = sgf.move(); move(m); // push the game forward s = ~s; } if(sgf.has_children()) agent->load_sgf(sgf); assert(sgf.done_child()); infile.close(); return true; }
// list Files in dir 'path' and push to vector 'v' //------------------------------------------------------- bool GetFiles(string path, vecstr& v) { directory_iterator it(path), end_it; if (it == end_it) { cout << "! Empty dir:" << path << endl; //log("Empty dir:" << path); return false; } for (; it != end_it; ++it) { string name = (*it).path().filename().string(); //if (name != "." && name != "..") { bool isDir = is_directory(it->status()); if (!isDir) // file { if (!found(name,".h")) // headers don't have transl v.push_back(path + "/" + name); //cout << name.c_str() << endl; } } } return true; }
GTPResponse GTP::gtp_dists(vecstr args) { using std::string; Board board = *hist; LBDists dists(&board); Side side = Side::NONE; if(args.size() >= 1) { switch(tolower(args[0][0])) { case 'w': side = Side::P1; break; case 'b': side = Side::P2; break; default: return GTPResponse(false, "Invalid player selection"); } } string white = "O", black = "@", empty = ".", coord = "", reset = ""; if(colorboard) { string esc = "\033"; reset = esc + "[0m"; coord = esc + "[1;37m"; empty = reset + "."; white = esc + "[1;33m" + "@"; //yellow black = esc + "[1;34m" + "@"; //blue } int size = board.get_size(); string s = "\n"; for(int i = 0; i < size; i++) s += " " + coord + to_str(i+1); s += "\n"; for(int y = 0; y < size; y++) { s += string(y, ' '); s += coord + char('A' + y); int end = board.lineend(y); for(int x = 0; x < end; x++) { Side p = board.get(x, y); s += ' '; if(p == Side::NONE) { int d = (side == Side::NONE ? dists.get(Move(x, y)) : dists.get(Move(x, y), side)); if(d < 10) s += reset + to_str(d); else s += empty; } else if(p == Side::P1) { s += white; } else if(p == Side::P2) { s += black; } } s += '\n'; } return GTPResponse(true, s); }
GTPResponse HavannahGTP::gtp_print(vecstr args){ Board board = game.getboard(); for(unsigned int i = 0; i < args.size() && board.move(args[i]); i++) ; return GTPResponse(true, "\n" + board.to_s(colorboard, hguicoords)); }
GTPResponse HavannahGTP::gtp_playwhite(vecstr args){ if(args.size() != 1) return GTPResponse(false, "Wrong number of arguments"); return play(args[0], 1); }
GTPResponse GTP::gtp_playblack(vecstr args){ if(args.size() != 1) return GTPResponse(false, "Wrong number of arguments"); return play(args[0], Side::P2); }