diff --git a/README b/README index 042882bf4e4ebd619871d3baae20aa1021ca0539..9cdb4d128e9325940f2eeff1b7400dbd228b493e 100644 --- a/README +++ b/README @@ -51,10 +51,6 @@ description Please do not allow paths such as "../../" etc - but that is common sense! -=== TODO === -Add a user for each submission for extra security -Web upload? - [SZM] (matches) 22/12/2011 diff --git a/judge/manager/controller.cpp b/judge/manager/controller.cpp index f5c99ce262c45402b7936ef55eb2089eb3ce24a3..56914061c2131f32298a899b9173b2e2fedf64f0 100644 --- a/judge/manager/controller.cpp +++ b/judge/manager/controller.cpp @@ -80,6 +80,8 @@ MovementResult Controller::MakeMove(string & buffer) if (query != MovementResult::OK) return query; + /* + //Removed 3/01/12 NO_MOVE now not allowed, SURRENDER is undocumented and not necessary if (buffer == "NO_MOVE") { buffer += " OK"; @@ -90,6 +92,7 @@ MovementResult Controller::MakeMove(string & buffer) buffer += " OK"; return MovementResult::SURRENDER; } + */ int x; int y; string direction=""; stringstream s(buffer); diff --git a/judge/manager/game.cpp b/judge/manager/game.cpp index 3df968cc9dad319282197be3d522b19788d35cf0..486920d3acaadb35f55d235939b1a77b8f6c4811 100644 --- a/judge/manager/game.cpp +++ b/judge/manager/game.cpp @@ -442,9 +442,24 @@ void Game::PrintEndMessage(const MovementResult & result) } } +/** Checks for victory by attrition (destroying all mobile pieces) + * + * @returns OK for no victory, + * DRAW if both players have no pieces, or + * VICTORY_ATTRITION if the current player has won by attrition + */ +MovementResult Game::CheckVictoryAttrition() +{ + if (theBoard.MobilePieces(Piece::OppositeColour(turn)) == 0) + { + if (theBoard.MobilePieces(turn) == 0) + return MovementResult::DRAW; + else + return MovementResult::VICTORY_ATTRITION; + } + return MovementResult::OK; - - +} MovementResult Game::Play() { @@ -483,22 +498,26 @@ MovementResult Game::Play() #endif //BUILD_GRAPHICS turn = Piece::RED; + + if (!Board::HaltResult(result)) + { + result = CheckVictoryAttrition(); + } + if (Board::HaltResult(result)) + break; + logMessage( "%d RED: ", turnCount); result = red->MakeMove(buffer); red->Message(buffer); blue->Message(buffer); logMessage( "%s\n", buffer.c_str()); - if (Board::HaltResult(result)) - break; - if (theBoard.MobilePieces(Piece::BLUE) == 0) + if (!Board::HaltResult(result)) { - if (theBoard.MobilePieces(Piece::RED) == 0) - result = MovementResult::DRAW; - else - result = MovementResult::VICTORY_ATTRITION; - break; + result = CheckVictoryAttrition(); } + if (Board::HaltResult(result)) + break; if (stallTime >= 0) Wait(stallTime); @@ -523,12 +542,24 @@ MovementResult Game::Play() turn = Piece::BLUE; + + if (!Board::HaltResult(result)) + { + result = CheckVictoryAttrition(); + } + if (Board::HaltResult(result)) + break; + logMessage( "%d BLU: ", turnCount); result = blue->MakeMove(buffer); blue->Message(buffer); red->Message(buffer); logMessage( "%s\n", buffer.c_str()); + if (!Board::HaltResult(result)) + { + result = CheckVictoryAttrition(); + } if (Board::HaltResult(result)) break; diff --git a/judge/manager/game.h b/judge/manager/game.h index aebda9dfba671ec5f445ee2c1a6c9365fbb59044..2ed35f6b593ce1d05f357370fb532ea993c1eef7 100644 --- a/judge/manager/game.h +++ b/judge/manager/game.h @@ -23,6 +23,7 @@ class Game void Wait(double wait); Piece::Colour Setup(const char * redName, const char * blueName); + MovementResult CheckVictoryAttrition(); MovementResult Play(); void PrintEndMessage(const MovementResult & result); diff --git a/judge/manager/stratego.cpp b/judge/manager/stratego.cpp index 5acfaa38250b07152732069bda41c636894eb230..e142a4bd67cc3e39e51cff3d3b2e82a20476e1b2 100644 --- a/judge/manager/stratego.cpp +++ b/judge/manager/stratego.cpp @@ -57,6 +57,27 @@ Piece::Type Piece::GetType(char fromToken) return Piece::BOULDER; } +/** + * Gets the opposite to the indicated colour + */ +Piece::Colour Piece::OppositeColour(const Colour & colour) +{ + switch (colour) + { + case Piece::RED: + return Piece::BLUE; + break; + case Piece::BLUE: + return Piece::RED; + break; + case Piece::BOTH: + return Piece::BOTH; + break; + case Piece::NONE: + return Piece::NONE; + } +} + /** * Construct a new, empty board * @param newWidth - the width of the board diff --git a/judge/manager/stratego.h b/judge/manager/stratego.h index d2e667ff072897a1252c22133b141a7f8f5f5add..098540c9f0f8db365dc0ca8cf942135ac11f7bc0 100644 --- a/judge/manager/stratego.h +++ b/judge/manager/stratego.h @@ -28,6 +28,9 @@ class Piece typedef enum {RED=0, BLUE=1, NONE=2, BOTH=3} Colour; //Used for the allegiance of the pieces - terrain counts as NONE. + static Colour OppositeColour(const Colour & compare); + + Piece(const Type & newType, const Colour & newColour) : type(newType), colour(newColour), beenRevealed(false) {} virtual ~Piece() {} diff --git a/judge/simulator/simulate.py b/judge/simulator/simulate.py index b44012b0397952591f017c6bba41cae8f9c1df3f..5daafb7dde7182899d54eb6462fdeb075485930d 100755 --- a/judge/simulator/simulate.py +++ b/judge/simulator/simulate.py @@ -328,10 +328,10 @@ for roundNumber in range(totalRounds, totalRounds + nRounds): print "RESULTS FOR ROUND " + str(roundNumber) #totalFile = open(resultsDirectory+"total.scores", "w") #Recreate the file - for agent in agents: + #for agent in agents: #totalFile.write(agent["name"] + " " + str(agent["totalScore"]) +"\n") #Write the total scores in descending order #if verbose: - print "Agent: " + str(agent) + # print "Agent: " + str(agent) if verbose: @@ -356,9 +356,9 @@ for roundNumber in range(totalRounds, totalRounds + nRounds): for index in range(0, len(agent["ALL"])): if agent["ALL"][index][4] == "RED": - logFile = logDirectory + "round"+str(roundNumber) + "/"+agent["name"]+".vs."+agent["ALL"][index][0]+"."+str(agent["ALL"][index][1]) + logFile = "log/round"+str(roundNumber) + "/"+agent["name"]+".vs."+agent["ALL"][index][0]+"."+str(agent["ALL"][index][1]) else: - logFile = logDirectory + "round"+str(roundNumber) + "/"+agent["ALL"][index][0]+".vs."+agent["name"]+"."+str(agent["ALL"][index][1]) + logFile = "log/round"+str(roundNumber) + "/"+agent["ALL"][index][0]+".vs."+agent["name"]+"."+str(agent["ALL"][index][1]) agentFile.write("<tr> <td> <a href="+logFile+">" + str(agent["ALL"][index][1]) + " </a> </td> <td> <a href="+agent["ALL"][index][0]+".html>"+agent["ALL"][index][0] + " </a> </td> <td> " + agent["ALL"][index][4] + " </td> <td> " + agent["ALL"][index][3] + " </td> <td> " + str(agent["ALL"][index][2]) + "</td> <td> " + str(agent["score"][len(agent["score"])-index -2]) + " </td> </tr> </th>\n") agentFile.write("</table>\n") diff --git a/web/doc/manager_manual.txt b/web/doc/manager_manual.txt index bd9f0e16849b03f3d8b1a0b7c66cf6ed589c27bc..d8b7a68a05351c8bcbce05115caacb13e29b51a2 100644 --- a/web/doc/manager_manual.txt +++ b/web/doc/manager_manual.txt @@ -157,16 +157,14 @@ PROTOCOL as described in the GAME_RULES section. Each line ends with the newline character. - RESPONSE: X Y DIRECTION [MULTIPLIER=1] | NO_MOVE + RESPONSE: X Y DIRECTION [MULTIPLIER=1] X and Y are the coords (starting from 0) of the piece to move DIRECTION is either UP, DOWN, LEFT or RIGHT MULTIPLIER is optional and only valid for units of type Scout. Scouts may move through any number of unblocked squares in one direction. - The AI program should print "NO_MOVE" if it is unable to determine a move. - This will typically occur when the only pieces belonging to the AI program are Bombs and the Flag. - CONFIRMATION: X Y DIRECTION [MULTIPLIER=1] OUTCOME | NO_MOVE {OK | ILLEGAL} | QUIT [RESULT] + CONFIRMATION: X Y DIRECTION [MULTIPLIER=1] OUTCOME | QUIT [RESULT] OUTCOME may be either OK, ILLEGAL, KILLS or DIES OK - Move was successful @@ -174,14 +172,7 @@ PROTOCOL KILLS ATTACKER_RANK DEFENDER_RANK - The piece moved into an occupied square and killed the defender. DIES ATTACKER_RANK DEFENDER_RANK - The piece moved into an occupied square and was killed by the defender. - Most turns will be confirmed with: "X Y DIRECTION [MULTIPLIER=1] OUTCOME" - - A confirmation of "NO_MOVE OK" occurs when the AI program made no move for a legitimate reason. - "NO_MOVE ILLEGAL" is printed if the AI program made no move for an illegitimate reason. - - If both AI programs successively make a "NO_MOVE" response, then the game will end. - The player with the highest piece value will win, or a draw will be declared if the values are equal. - + QUIT will only be sent when the game is about to end. 3. END GAME If the CONFIRMATION line is of the form: QUIT [RESULT] @@ -277,5 +268,5 @@ NOTES irc://irc.ucc.asn.au #progcomp THIS PAGE LAST UPDATED - 23/12/11 by Sam Moore + 3/01/12 by Sam Moore diff --git a/web/index.html b/web/index.html index 8563b14a5db87338b4257676f159e7c1a453b4cb..9cf4c0f147b5c00f547aca3f4783e8bad244d826 100644 --- a/web/index.html +++ b/web/index.html @@ -39,42 +39,31 @@ <h3> Protocol </h3> <p> For the sake of simplicity and keeping things in one place, the protocol is now entirely described in the <a href="doc/manager_manual.txt"/>manual page</a> of the manager program. All updates to the protocol will be reflected in that file. </p> +<p> Major updates to the manager program or protocol will be accompanied by an email to the mailing list. However, it is probably a good idea to clone the git repository, and regularly pull from it. </p> -<p> <b> Warning:</b> The accuracy of the above file depends on how recently I pulled it from git. To ensure you get the latest version, find it under "web/doc/manager_manual.txt" in the <a href="http://git.ucc.asn.au/?p=progcomp2012.git;a=summary"/>git repository</a> </p> +<p> <b> Warning:</b> AI programs <b>must</b> unbuffer stdin and stdout themselves. This is explained in the manual page, but I figured no one would read it. It is fairly simple to unbuffer stdin/stdout in C/C++ and python, I have not investigated other languages yet. </p> -<p> <b> Another Warning:</b> AI programs <b>must</b> unbuffer stdin and stdout themselves. This is explained in the manual page, but I figured no one would read it. It is fairly simple to unbuffer stdin/stdout in C/C++ and python, I have not investigated other languages yet. </p> +<h2> Scoring and Results </h2> +<p> The competition will be a round robin, with every AI playing three (3) games against each possible opponent. A points system is used to score each AI, 3 points for a Win, 2 for a Draw, 1 for a Loss or -1 for an Illegal response (counts as a Win for the opponent). Scores accumulate between rounds. </p> +<p> The winning AI will be the AI with the highest score after all games have been played. In the event of a tied score, the two highest scoring AI's will play one more round consisting of three games. If the scores are still tied, the official outcome will be a Draw. </p> +<p> When the competition officially runs, results will appear <a href="results"/>here</a>. There may (or may not) be test results there now. </p> <p> -<h2> Long Term Scoring </h2> -<p> Several rounds will be played (depending on the number of entries), with contestants given time to improve their entries between rounds. </p> -<p> Each round is a round robin, with every AI playing several games against each possible opponent. A points system is used to score each AI, 3 points for a Win, 2 for a Draw, 1 for a Loss or -1 for an Illegal response (counts as a Win for the opponent). Scores accumulate between rounds. </p> -<p> The winning AI will be the AI with the highest score after all rounds have been played. In the event of a tied score, the two highest scoring AI's will play one more round consisting of three games. If the scores are still tied, the official outcome will be a Draw. </p> -<p> When the competition officially runs, results will appear <a href="results"/>here</a>. Preliminary test results might occasionally appear there for the next few weeks. </p> <p> - -<h2> Sample AI Programs </h2>> -<p> The following sample programs are currently available (and in a semi-working state - refer to the git repository): </p> -<table border="0"> -<tr> <th>Name</th> <th>Language</th> <th> Moves </th> <th> Considers... </th> </tr> -<tr> <td>basic_python</td> <td>Python</td> <td>Randomised</td> </tr> -<tr> <td>basic_cpp</td> <td>C++</td> <td>Randomised</td> </tr> -<tr> <td>asmodeus</td> <td>Python</td> <td>Scored</td> <td>Path finding, known combat results, piece values</td> </th> -<tr> <td>vixen</td> <td>Python</td> <td>Scored</td> <td>Asmodeus + Probabilities for unknown combat results </td> </th> -</table> -<p> It is planned to implement the equivelants of these samples in C++ and Python at least, possibly other languages later. </p> +<h2> Sample AI Programs </h2> +<p> Several sample AI programs are currently available. No guarantees are provided about the functioning of these programs. The sample programs can be downloaded from the <a href="http://git.ucc.asn.au/?p=progcomp2012.git;a=summary"/>git repository </a> <h2> Submissions </h2> <p> You must submit the full source code, and build instructions or makefile(s) for your program. </p> <p> Also include the name of the executable or script, the name of the AI, your name, and optionally a description of your AI and its tactics. </p> <p> Please email matches@ if you have a submission. </p> -<p> <b> Code which attempts to comprimise the host machine, or interfere directly with the functioning of other programs will be disqualified. </b> </p> +<p> <b> Code which attempts to comprimise the host machine, or interfere interfere either directly or indirectly with the functioning of other programs will be disqualified. </b> </p> <h2> Dates </h2> -<p> The competition will run in 2012. The exact dates have not been determined. An email will be sent to the list and messages sent to the irc channel. </p> - -<h2> Involvement </h2> -<p> If you want to help set up the competition, email matches@ </p> +<p> The competition is now officially open. Submissions will be accepted until midday, Saturday the 10th of March, 2012. Results will be announced as soon as they are available (depending on the number of entries it may take several days to simulate the competition). </p> +<h2> FAQ </h2> +<p> No one has asked any questions yet. If there is anything not covered or vague on this page, please email matches@ </p> -<p> <b>Last webpage update: 22/12/11</b></p> +<p> <b>Last webpage update: 06/01/12</b></p> </body> </html>