|
| 1 | +# Submissions |
| 2 | + |
| 3 | +## File Specification |
| 4 | +A valid Othello submission consists of a Python 3.x file, with a class called |
| 5 | +`Strategy` and a method called `best_strategy`. A minimal example is shown below: |
| 6 | +```py |
| 7 | +def choose_move(board: str, player: str, still_running, time_limit: float): |
| 8 | + # Implement this method |
| 9 | + return 0 |
| 10 | + |
| 11 | + |
| 12 | +class Strategy: |
| 13 | + # Uncomment the below flags as needed |
| 14 | + # logging = True |
| 15 | + # uses_10x10_board = True |
| 16 | + # uses_10x10_moves = True |
| 17 | + |
| 18 | + def best_strategy(self, board: str, player: str, best_move, still_running, time_limit: float): |
| 19 | + move = choose_move(board, player, still_running, time_limit) |
| 20 | + best_move.value = move |
| 21 | + |
| 22 | +``` |
| 23 | + |
| 24 | +## Method Specification |
| 25 | +The `best_strategy` method must accept at least 4 parameters: |
| 26 | + |
| 27 | +- `board`: a string of length 64, containing the characters `#!python {'.', 'x', 'o'}` |
| 28 | + The `.` represents an empty space, `x` represents black, and `o` represents white. |
| 29 | +- `player`: a character in `#!python {'x', 'o'}` that represents who your script is playing |
| 30 | + as. |
| 31 | +- `best_move`: A `multiprocessing.Value` object of type `int` |
| 32 | +- `still_running`: A `multiprocessing.Value` object of type `int` |
| 33 | + |
| 34 | +Once you have determined your move, set `best_move.value` to the index of the board at which |
| 35 | +to place your token. |
| 36 | + |
| 37 | +!!! note |
| 38 | + |
| 39 | + You do *NOT* need to import `multiprocessing` to use the `multiprocessing.Value` objects. |
| 40 | + |
| 41 | +## Time Management |
| 42 | +To know when you run out of time, you can use `still_running.value`, which starts as 1 but changes to 0 when |
| 43 | +you near the time limit. Alternatively, `best_strategy` can accept an optional 5th argument, `time_limit`. |
| 44 | +If included in your method header, it will be set to an integer representing the amount of time (in seconds) |
| 45 | +that your script has to determine the best move. |
| 46 | + |
| 47 | +!!! tip "Time Hoarding" |
| 48 | + |
| 49 | + If your game supports "Good Citizen" timing, exiting the `best_strategy` method before the time limit will give you extra time on the next turn. |
| 50 | + |
| 51 | + |
| 52 | +!!! warning |
| 53 | + |
| 54 | + All user code will be run in a daemonized `multiprocessing.Process`. This means your script cannot spawn any Processes of its own. |
| 55 | + If your code does spawn any `multiprocessing.Process` instances, it will error out. |
| 56 | + |
| 57 | +## Logging |
| 58 | +In addition to the specifications listed above, your `Strategy` class may contain a `logging` variable. |
| 59 | +This variable, if used, must be an attribute of the `Strategy` class. |
| 60 | +Therefore it should be defined within `Strategy`'s constructor (as `self.logging`) or inside the class but outside a class method (just `logging`). |
| 61 | +For instance, `logging` cannot be defined in the `best_strategy` method of your `Strategy` class or in a helper method defined outside of `Strategy`. |
| 62 | + |
| 63 | +If set to `True`, you will see the output of any `#!python print` statements on either side of the board when playing your script. |
| 64 | +Output for scripts that are playing as black will appear on the left-hand side of the Othello board while the output for scripts that are |
| 65 | +playing as white will appear on the right-hand side of the Othello board. |
| 66 | + |
| 67 | +If you omit the `logging` variable in your `Strategy` class, it will be assumed that you do not wish to output any `#!python print` |
| 68 | +statements. |
| 69 | + |
| 70 | +!!! info |
| 71 | + |
| 72 | + If you set `logging = True` in your `Strategy` class, you will only be able to view script logs if you are |
| 73 | + currently logged in and own the running script. |
| 74 | + |
| 75 | + |
| 76 | +## Customizing Board Representation |
| 77 | +If you would like to be provided with a 10x10 board instead of the default 8x8 board, you can add a `uses_10x10_board` variable to your strategy class. |
| 78 | +This will surround the 8x8 board with an additional layer of `'?'` characters, as shown below. |
| 79 | +Similar to the `logging` variable, `uses_10x10_board` must be an attribute of the `Strategy` class and will default to `False` if omitted. |
| 80 | + |
| 81 | +You can also use the `uses_10x10_moves` variable to signify that your submitted `best_move.value` refers to indices in this 10x10 board representation. |
| 82 | +If not used, the server will assume that your `best_move.value` refers to indices in the default 8x8 board, irrespective of whether or not `uses_10x10_board` is enabled. |
| 83 | + |
| 84 | +``` |
| 85 | + ? ? ? ? ? ? ? ? ? ? |
| 86 | + . . . . . . . . ? . . . . . . . . ? |
| 87 | + . . . . . . . . ? . . . . . . . . ? |
| 88 | + . . . . . . . . ? . . . . . . . . ? |
| 89 | + . . . o x . . . ? . . . o x . . . ? |
| 90 | + . . . x o . . . => ? . . . x o . . . ? |
| 91 | + . . . . . . . . ? . . . . . . . . ? |
| 92 | + . . . . . . . . ? . . . . . . . . ? |
| 93 | + . . . . . . . . ? . . . . . . . . ? |
| 94 | + ? ? ? ? ? ? ? ? ? ? |
| 95 | +
|
| 96 | +``` |
| 97 | +## Upload Errors |
| 98 | +When uploading code to the server you may encounter one of the following errors. |
| 99 | + |
| 100 | +- File has invalid syntax |
| 101 | + * The Othello server was unable to validate your code because there was a syntax error somewhere in the file. |
| 102 | + Go back through your code and revise any syntax issues then upload again. |
| 103 | +- Cannot find attribute `Strategy.best_strategy` in file |
| 104 | + * Your code does not follow the specifications listed above. |
| 105 | + Reread the specifications and revise your code before submitting again. |
| 106 | +- Attribute `Strategy.best_strategy` has an invalid amount of parameters |
| 107 | + * Your code does not follow the specifications listed above. |
| 108 | + Specifically regarding the amount of parameters `Strategy.best_strategy` should take. |
| 109 | + Reread the specifications and revise your code before submitting again. |
| 110 | +- Code takes too long to validate! |
| 111 | + * Your file has some code that is outside a function or outside an `#!python if __name__ == '__main__'` block. |
| 112 | + Any code that is outside such block must terminate after 1s. |
| 113 | + Go back through your file and ensure that code that runs on import terminates quickly. |
| 114 | + |
| 115 | +If you encounter another error message that you cannot interpret, email othello@tjhsst.edu |
| 116 | +a screenshot of the error message as well as your code. |
| 117 | + |
| 118 | +## Playing Games and Errors |
| 119 | + |
| 120 | +To play a game, go to the Games->Play page and select two players. |
| 121 | +To watch a game, go to the Games->Watch page and select one of the listed games. |
| 122 | +If there are no games currently being played, no games will be listed. |
| 123 | + |
| 124 | + |
| 125 | +When playing games, if your script behaves incorrectly, the server will interpret this as an `UserError`. |
| 126 | +When the server encounters an `UserError`, your script will automatically forfeit the game and your opponent will be awarded the win. |
| 127 | +The `UserError` will be reported in either log area, regardless if the playing script set the `logging` variable. |
| 128 | +The following are the possible `UserError` codes and their meanings: |
| 129 | + |
| 130 | +- An error code of `#!python -1` is a `NO_MOVE_ERROR`, meaning your script did not submit any move before the time limit |
| 131 | +- An error code of `#!python -2` is a `READ_INVALID` error, meaning your script submitted something to |
| 132 | + the `best_move` variable but it was not an integer in the range 0-63, inclusive. |
| 133 | +- An error code of `#!python -3` is an `INVALID_MOVE` error, meaning your script submitted an integer |
| 134 | + in the range 0-63, inclusive, but it was not a valid move given the current board state. |
| 135 | + |
| 136 | +If any other error code is outputted, namely an error code within `#!python {-4,-5,-6, -7, -8}`, this means the server has |
| 137 | +encountered an error while running your game. In this case, the game will be marked as a tie between both players, but |
| 138 | +you should email othello@tjhsst.edu a screenshot of the game along with your code |
| 139 | +so we can investigate and fix this error. |
| 140 | + |
| 141 | +Finally, when running a non-tournament game, the server continuously checks if the browser which initiated the game is |
| 142 | +still watching the game. If not, the game will be terminated and the game will end in a tie. Meaning, if you start |
| 143 | +a game but then close the window with the game still running, the game will be terminated and end in a tie. |
| 144 | + |
| 145 | + |
| 146 | +## Multiple Submissions |
| 147 | +You may submit code any amount of times, and the Othello server will record and store all your submissions. If you wish, you may retrieve any |
| 148 | +previously submitted script from the upload page. However, the Othello Server will only run your most recent submission. |
| 149 | + |
| 150 | +All your code submissions will persist on the Othello server, and you can retrieve previous submissions through the Games->Upload page. |
| 151 | +The Othello server will always use your most recent code submission when running your AI against other players. |
| 152 | +(If you were to submit twice, your second submission would be used to play against other users) |
| 153 | + |
| 154 | +!!! note "Labeling Scripts" |
| 155 | + |
| 156 | + When uploading a script, you will be given an option to attach a "name" or "label" to that script. |
| 157 | + Adding a "name" to your script will make it easier to identify previous submissions if you wish to retrieve them later. |
| 158 | + If omitted, your script's "name" will default to the time it was submitted. |
| 159 | + |
| 160 | + |
| 161 | +## Running Multiple Files |
| 162 | + |
| 163 | +As of now the Othello server will only run the most recently uploaded script. |
| 164 | +You should try to put all your code in a single file and upload that file. |
| 165 | +Any files created by your code will persist between runs and games. |
| 166 | +If you do in fact need other files for your code to work, and it is infeasible to include it in one file, |
| 167 | +contact othello@tjhsst.edu or your AI teacher about your situation. |
| 168 | + |
| 169 | +!!! warning |
| 170 | + |
| 171 | + When your code is uploaded, it is stored under a different, randomly-generated filename. Submitting two Python files and expecting to be |
| 172 | + able to import the other file by name is infeasible. |
| 173 | + |
| 174 | + |
| 175 | +## Replaying Past Games |
| 176 | + |
| 177 | + |
| 178 | +After either playing or watching a game, you may download a text-formatted version of the game using the "Download Game" button below the game board. |
| 179 | +You may choose to download the game in a format that is pretty-printed and easy to interpret visually or in a format that is more easily parsed programmatically. |
| 180 | +The exact specifications for both formats, and a preview, are shown when downloading a game. |
| 181 | + |
| 182 | +In addition to downloading games, you can upload this file to the Games->Replay page and more closely interact with the downloaded game file. |
| 183 | +After uploading the game file, you will be able to step forward and step back through all the turns played in that game. |
| 184 | + |
| 185 | +!!! warning |
| 186 | + |
| 187 | + Logging data is not saved in game files and will not be displayed during replays |
| 188 | + |
| 189 | + |
| 190 | +## Other Info |
| 191 | + |
| 192 | +If your code fails to return a move, returns an invalid move, or errors for whatever reason, it will be treated as a forfeit. |
| 193 | +As such, make sure you code works on your computer before using this website to test against other AIs. |
| 194 | +Just as a reminder, if your code is caught cheating during the tournament in any way, you **will** be given an integrity violation, so just don't do it. |
| 195 | + |
0 commit comments