00001 //---------------------------------------------------------------------------- 00002 /** @file FuegoMain.cpp 00003 Main function for Fuego 00004 */ 00005 //---------------------------------------------------------------------------- 00006 00007 #include "SgSystem.h" 00008 00009 #include <iostream> 00010 #include <boost/filesystem/path.hpp> 00011 #include "FuegoMainEngine.h" 00012 #include "FuegoMainUtil.h" 00013 #include "GoInit.h" 00014 #include "SgDebug.h" 00015 #include "SgException.h" 00016 #include "SgInit.h" 00017 00018 #include <boost/utility.hpp> 00019 #include <boost/program_options/options_description.hpp> 00020 #include <boost/program_options/cmdline.hpp> 00021 #include <boost/program_options/variables_map.hpp> 00022 #include <boost/program_options/parsers.hpp> 00023 00024 using namespace std; 00025 using boost::filesystem::path; 00026 namespace po = boost::program_options; 00027 00028 //---------------------------------------------------------------------------- 00029 00030 namespace { 00031 00032 /** @name Settings from command line options */ 00033 // @{ 00034 00035 bool g_noHandicap = false; 00036 00037 bool g_noBook = false; 00038 00039 bool g_quiet = false; 00040 00041 int g_fixedBoardSize; 00042 00043 int g_maxGames; 00044 00045 string g_config; 00046 00047 path g_programDir; 00048 00049 const char* g_programPath; 00050 00051 int g_srand; 00052 00053 // @} // @name 00054 00055 /** Get program directory from program path. 00056 @param programPath Program path taken from @c argv[0] in 00057 @c main. According to ANSI C, this can be @c 0. 00058 */ 00059 path GetProgramDir(const char* programPath) 00060 { 00061 if (programPath == 0) 00062 return ""; 00063 return path(programPath, boost::filesystem::native).branch_path(); 00064 } 00065 00066 void MainLoop() 00067 { 00068 GtpInputStream gtpIn(cin); 00069 GtpOutputStream gtpOut(cout); 00070 FuegoMainEngine engine(gtpIn, gtpOut, g_fixedBoardSize, g_programPath, 00071 g_noHandicap); 00072 GoGtpAssertionHandler assertionHandler(engine); 00073 if (g_maxGames >= 0) 00074 engine.SetMaxClearBoard(g_maxGames); 00075 if (! g_noBook) 00076 FuegoMainUtil::LoadBook(engine.Book(), g_programDir); 00077 if (g_config != "") 00078 engine.ExecuteFile(g_config); 00079 engine.MainLoop(); 00080 } 00081 00082 void Help(po::options_description& desc) 00083 { 00084 cout << "Options:\n" << desc << "\n"; 00085 exit(0); 00086 } 00087 00088 void ParseOptions(int argc, char** argv) 00089 { 00090 po::options_description options_desc; 00091 options_desc.add_options() 00092 ("config", 00093 po::value<std::string>(&g_config)->default_value(""), 00094 "execuate GTP commands from file before starting main command loop") 00095 ("help", "Displays this help and exit") 00096 ("maxgames", 00097 po::value<int>(&g_maxGames)->default_value(-1), 00098 "make clear_board fail after n invocations") 00099 ("nobook", "don't automatically load opening book") 00100 ("nohandicap", "don't support handicap commands") 00101 ("quiet", "don't print debug messages") 00102 ("srand", 00103 po::value<int>(&g_srand)->default_value(0), 00104 "set random seed (-1:none, 0:time(0))") 00105 ("size", 00106 po::value<int>(&g_fixedBoardSize)->default_value(0), 00107 "initial (and fixed) board size"); 00108 po::variables_map vm; 00109 try { 00110 po::store(po::parse_command_line(argc, argv, options_desc), vm); 00111 po::notify(vm); 00112 } 00113 catch(...) { 00114 Help(options_desc); 00115 } 00116 if (vm.count("help")) 00117 Help(options_desc); 00118 if (vm.count("nobook")) 00119 g_noBook = true; 00120 if (vm.count("nohandicap")) 00121 g_noHandicap = true; 00122 if (vm.count("quiet")) 00123 g_quiet = true; 00124 } 00125 00126 void PrintStartupMessage() 00127 { 00128 SgDebug() << 00129 "Fuego " << FuegoMainUtil::Version() << "\n" 00130 "Copyright (C) 2009-10 by the authors of the Fuego project.\n" 00131 "This program comes with ABSOLUTELY NO WARRANTY. This is\n" 00132 "free software and you are welcome to redistribute it under\n" 00133 "certain conditions. Type `fuego-license' for details.\n\n"; 00134 } 00135 00136 } // namespace 00137 00138 //---------------------------------------------------------------------------- 00139 00140 int main(int argc, char** argv) 00141 { 00142 if (argc > 0 && argv != 0) 00143 { 00144 g_programPath = argv[0]; 00145 g_programDir = GetProgramDir(argv[0]); 00146 try 00147 { 00148 ParseOptions(argc, argv); 00149 } 00150 catch (const SgException& e) 00151 { 00152 SgDebug() << e.what() << "\n"; 00153 return 1; 00154 } 00155 } 00156 if (g_quiet) 00157 SgDebugToNull(); 00158 try 00159 { 00160 SgInit(); 00161 GoInit(); 00162 PrintStartupMessage(); 00163 SgRandom::SetSeed(g_srand); 00164 MainLoop(); 00165 GoFini(); 00166 SgFini(); 00167 } 00168 catch (const GtpFailure& e) 00169 { 00170 SgDebug() << e.Response() << '\n'; 00171 return 1; 00172 } 00173 catch (const std::exception& e) 00174 { 00175 SgDebug() << e.what() << '\n'; 00176 return 1; 00177 } 00178 return 0; 00179 } 00180 00181 //---------------------------------------------------------------------------- 00182