Commit 85cfed04 authored by Sam Moore's avatar Sam Moore

[RULE CHANGE] "NO_MOVE" is no longer a legal

Previously AIs could respond with "NO_MOVE" whenever they felt like.
Officially, now they can only respond with "NO_MOVE" when they have no mobile pieces left.
(That is, only Bombs and the Flag are left).

However the game should end by a VICTORY_ATTRITION condition as soon as either player loses its last mobile piece.
So technically, "NO_MOVE" can't ever be legally printed, because the game should have ended. If it doesn't, there is a bug.

Updated webpage, updated manual, updated README

Going to email the list later today.

Goodluck!

PS: The rule change is due to a mean initial setup, for example:

**********
**********
**********
BB**BB**BB
..++..++..
..++..++..
etc

Here, Red has placed Bombs in all three "lanes". Red is unable to move.
However, as long as Red can use "NO_MOVE", an unsuspecting Blue will lose most of its pieces on the Bombs.
(Unless Blue puts a miner up the front...) But anyway, being able to not move is silly and not allowed in the real game.
parent e1153eeb
......@@ -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
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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
......
......@@ -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() {}
......
......@@ -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")
......
......@@ -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
......@@ -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 [email protected] 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 [email protected] </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 [email protected] </p>
<p> <b>Last webpage update: 22/12/11</b></p>
<p> <b>Last webpage update: 06/01/12</b></p>
</body>
</html>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment