Browse Source

Further changes for programming challenge environment.

Michał W. Urbańczyk 14 years ago
parent
commit
3fd579a433
6 changed files with 100 additions and 47 deletions
  1. 54 33
      Odpalarka/main.cpp
  2. 5 1
      VCMI_BattleAiHost/main.cpp
  3. 3 3
      lib/CCreatureHandler.cpp
  4. 14 3
      lib/CGameInterface.cpp
  5. 7 2
      server/CGameHandler.cpp
  6. 17 5
      server/CVCMIServer.cpp

+ 54 - 33
Odpalarka/main.cpp

@@ -1,4 +1,4 @@
-#include "../global.h"
+//#include "../global.h"
 #include <boost/thread.hpp>
 #include <boost/bind.hpp>
 #include <boost/program_options.hpp>
@@ -6,7 +6,20 @@ namespace po = boost::program_options;
 
 void prog_help() 
 {
-	throw std::string("The method or operation is not implemented.");
+	std::cout << "If run without args, then StupidAI will be run on b1.json.\n";
+}
+
+void runCommand(const std::string &command, const std::string &name, const std::string &logsDir = "")
+{
+	static std::string commands[100];
+	static int i = 0;
+	std::string &cmd = commands[i++];
+	if(logsDir.size() && name.size())
+		cmd = command + " > " + logsDir + "/" + name + ".txt";
+	else
+		cmd = command;
+
+	boost::thread tt(boost::bind(std::system, cmd.c_str()));
 }
 
 int main(int argc, char **argv)
@@ -15,42 +28,49 @@ int main(int argc, char **argv)
 
 	po::options_description opts("Allowed options");
 	opts.add_options()
-		("help,h", "display help and exit")
-		("aiLeft,l", po::value<std::string>(), "Left AI path")
-		("aiRight,r", po::value<std::string>(), "Right AI path")
-		("battle,b", po::value<std::string>(), "Duel file path")
+		("help,h", "Display help and exit")
+		("aiLeft,l", po::value<std::string>()->default_value("StupidAI"), "Left AI path")
+		("aiRight,r", po::value<std::string>()->default_value("StupidAI"), "Right AI path")
+		("battle,b", po::value<std::string>()->default_value("b1.json"), "Duel file path")
+		("resultsOut,o", po::value<std::string>()->default_value("./results.json"), "Output file when results will be appended")
+		("logsDir,d", po::value<std::string>()->default_value("."), "Directory where log files will be created")
 		("visualization,v", "Runs a client to display a visualization of battle");
 
-	std::string leftAI = "StupidAI", 
-				rightAI = "StupidAI",
-				battle = "b1.json";
+	std::string leftAI, rightAI, battle, results, logsDir;
+	bool withVisualization = false;
 
-	po::variables_map vm;
-	if(argc > 1)
+	try
 	{
-		try
-		{
-			po::store(po::parse_command_line(argc, argv, opts), vm);
-			po::notify(vm);
-			leftAI = vm["aiLeft"].as<std::string>();
-			rightAI = vm["aiRight"].as<std::string>();
-			battle = vm["battle"].as<std::string>();
-		}
-		catch(std::exception &e) 
+		po::variables_map vm;
+		po::store(po::parse_command_line(argc, argv, opts), vm);
+		po::notify(vm);
+
+		if(vm.count("help"))
 		{
-			std::cerr << "Failure during parsing command-line options:\n" << e.what() << std::endl;
-			exit(1);
+			opts.print(std::cout);
+			prog_help();
+			return 0;
 		}
+
+		leftAI = vm["aiLeft"].as<std::string>();
+		rightAI = vm["aiRight"].as<std::string>();
+		battle = vm["battle"].as<std::string>();
+		results = vm["resultsOut"].as<std::string>();
+		logsDir = vm["logsDir"].as<std::string>();
+		withVisualization = vm.count("visualization");
 	}
-	else
+	catch(std::exception &e) 
 	{
-		std::cout << "Default AIs will be used." << std::endl;
+		std::cerr << "Failure during parsing command-line options:\n" << e.what() << std::endl;
+		exit(1);
 	}
 
-	if(vm.count("help"))
+	std::cout << "Config:\n" << leftAI << " vs " << rightAI << " on " << battle << std::endl;
+
+	if(leftAI.empty() || rightAI.empty() || battle.empty())
 	{
-		prog_help();
-		return 0;
+		std::cerr << "I wasn't able to retreive names of AI or battles. Ending.\n";
+		return 1;
 	}
 
 
@@ -70,13 +90,14 @@ int main(int argc, char **argv)
 #endif
 	;
 
-	bool withVisualization = vm.count("visualization");
-	std::string serverCommand = servername + " " + battle + " " + leftAI + " " + rightAI + (withVisualization ? " v" : "");
-	std::string runnerCommand = runnername;
+	std::string serverCommand = servername + " " + battle + " " + leftAI + " " + rightAI + " " + results + " " + logsDir + " " + (withVisualization ? " v" : "");
+	std::string runnerCommand = runnername + " " + logsDir;
+	std::cout <<"Server command: " << serverCommand << std::endl << "Runner command: " << runnername << std::endl;
+
 	boost::thread t(boost::bind(std::system, serverCommand.c_str()));
-	boost::thread tt(boost::bind(std::system, runnerCommand.c_str()));
-	boost::thread ttt(boost::bind(std::system, runnerCommand.c_str()));
-	boost::thread tttt(boost::bind(std::system, runnername.c_str()));
+	runCommand(runnerCommand, "first_runner", logsDir);
+	runCommand(runnerCommand, "second_runner", logsDir);
+	runCommand(runnerCommand, "third_runner", logsDir);
 	if(withVisualization)
 	{
 		//boost::this_thread::sleep(boost::posix_time::millisec(500)); //FIXME

+ 5 - 1
VCMI_BattleAiHost/main.cpp

@@ -30,12 +30,16 @@ std::string NAME = NAME_VER + std::string(" DLL runner");
 
 int main(int argc, char** argv)
 {
+	std::string logDir = ".";
+	if(argc >= 2)
+		logDir = argv[1];
+
 	int pid = getMyPid();
 
 
 	initDLL(console,logfile);
 
-	logfile = new std::ofstream(("VCMI_Runner_log_" + boost::lexical_cast<std::string>(pid) + ".txt").c_str());
+	logfile = new std::ofstream((logDir + "/" + "VCMI_Runner_log_" + boost::lexical_cast<std::string>(pid) + ".txt").c_str());
 
 	try
 	{

+ 3 - 3
lib/CCreatureHandler.cpp

@@ -780,7 +780,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, std::string & src
 			case 'U':
 				b.type = Bonus::UNDEAD; break;
 			default:
-			tlog3 << "Not parsed bonus " << buf << mod << "\n";
+			//tlog3 << "Not parsed bonus " << buf << mod << "\n";
 				return;
 				break;
 		}
@@ -879,7 +879,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, std::string & src
 				b.type = Bonus::RECEPTIVE;
 				break;
 			default:
-				tlog3 << "Not parsed bonus " << buf << mod << "\n";
+				//tlog3 << "Not parsed bonus " << buf << mod << "\n";
 				return;
 		}
 		break;
@@ -908,7 +908,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, std::string & src
 		b.additionalInfo = 3; //always expert?
 		break;
 	default:
-		tlog3 << "Not parsed bonus " << buf << mod << "\n";
+		//tlog3 << "Not parsed bonus " << buf << mod << "\n";
 		return;
 		break;
 	}

+ 14 - 3
lib/CGameInterface.cpp

@@ -75,9 +75,20 @@ std::string getAIFileName(std::string input)
 template<typename rett>
 rett * createAnyAI(std::string dllname, std::string methodName)
 {
-	tlog1<<"Opening "<<dllname<<"\n";
-	std::string filename = getAIFileName(dllname);
-	rett* ret = createAny<rett>(LIB_DIR "/AI/" + filename, methodName);
+	tlog1 << "Opening " << dllname<<"\n";
+
+	if(vstd::contains(dllname, '/'))
+	{
+		tlog1 << "Assuming that AI is an absolute path.\n";
+	}
+	else
+	{
+		std::string filename = getAIFileName(dllname);
+		dllname = LIB_DIR "/AI/" + filename;
+		tlog1 << "The AI path will be " << dllname << std::endl;
+	}
+
+	rett* ret = createAny<rett>(dllname, methodName);
 	ret->dllName = dllname;
 	return ret;
 }

+ 7 - 2
server/CGameHandler.cpp

@@ -60,6 +60,8 @@ CondSh<BattleResult *> battleResult(NULL);
 std::ptrdiff_t randomizer (ptrdiff_t i) {return rand();}
 std::ptrdiff_t (*p_myrandom)(std::ptrdiff_t) = randomizer;
 
+extern std::string RESULTS_PATH;
+
 template <typename T> class CApplyOnGH;
 
 class CBaseForGHApply
@@ -476,8 +478,11 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 		time_t czas;
 		time(&czas);
 		std::string resultTypes[] = {"SIDE_DEFEATED", "SIDE_RETREATED", "SIDE_SURRENDERED", "SIDE_DISQUALIFIED"};
-		std::ofstream resultsList("results.txt", std::fstream::out | std::fstream::app);
-		resultsList << boost::format("%s\t%s\t%s\t%d\t%d\t%s\t%s") % gs->scenarioOps->mapname % ais[0] % ais[1] % (int)battleResult.data->winner % casualtiesPoints % resultTypes[battleResult.data->result] % asctime(localtime(&czas));
+		std::ofstream resultsList(RESULTS_PATH, std::fstream::out | std::fstream::app);
+		if(resultsList)
+			resultsList << boost::format("%s\t%s\t%s\t%d\t%d\t%s\t%s") % gs->scenarioOps->mapname % ais[0] % ais[1] % (int)battleResult.data->winner % casualtiesPoints % resultTypes[battleResult.data->result] % asctime(localtime(&czas));
+		else
+			tlog2 << "Failed to open to write " << resultsList << std::endl;
 	}
 
 	sendAndApply(&resultsApplied);

+ 17 - 5
server/CVCMIServer.cpp

@@ -25,6 +25,8 @@
 #include "../lib/CMapInfo.h"
 #include "../lib/CondSh.h"
 
+std::string RESULTS_PATH = "./results.txt",
+	LOGS_DIR = ".";
 std::string NAME_AFFIX = "server";
 std::string NAME = NAME_VER + std::string(" (") + NAME_AFFIX + ')'; //application name
 using namespace boost;
@@ -519,7 +521,8 @@ bool memViolated(const int pid, const int refpid, const int limit) {
 	//return 0 != ::system(call);
 }
 
-void memoryMonitor(int lAIpid, int rAIpid, int refPid) {
+void memoryMonitor(int lAIpid, int rAIpid, int refPid) 
+{
 	const int MAX_MEM = 20000; //in blocks (of, I hope, 4096 B)
 	monitringRes = 2;
 	tlog0 << "Monitor is activated\n";
@@ -534,7 +537,8 @@ void memoryMonitor(int lAIpid, int rAIpid, int refPid) {
 				monitringRes = 1;
 				break;
 			}
-			sleep(3);
+			//sleep(3);
+			boost::this_thread::sleep(boost::posix_time::seconds(3));
 			tlog0 << "Monitor is active 34\n";
 		}
 	}
@@ -673,7 +677,10 @@ int _tmain(int argc, _TCHAR* argv[])
 int main(int argc, char** argv)
 #endif
 {
-	logfile = new std::ofstream("VCMI_Server_log.txt");
+	if(argc >= 6)
+		LOGS_DIR = argv[5];
+
+	logfile = new std::ofstream(LOGS_DIR + "/" + "VCMI_Server_log.txt");
 	console = new CConsoleHandler;
 	//boost::thread t(boost::bind(&CConsoleHandler::run,::console));
 
@@ -684,8 +691,13 @@ int main(int argc, char** argv)
 	{
 		io_service io_service;
 		CVCMIServer server;
-		if(argc == 4 || argc == 5)
-			server.startDuel(argv[1], argv[2], argv[3], argc-1);
+		if(argc == 6 || argc == 7)
+		{
+			RESULTS_PATH = argv[4];
+			tlog1 << "Results path: " << RESULTS_PATH << std::endl;
+			tlog1 << "Logs path: " << RESULTS_PATH << std::endl;
+			server.startDuel(argv[1], argv[2], argv[3], argc-3);
+		}
 		else
 			server.startDuel("b1.json", "StupidAI", "StupidAI", 2);