Question
In python Your program will take its input via the console, printing no prompts to a user . The intent here is not to write
In python
Your program will take its input via the console, printing no prompts to a user. The intent here is not to write a user-friendly user interface; what you're actually doing is building a tool for testing your game logic, which we'll then be using to automatically test your game logic. So it is vital that your program reads inputs and writes outputs precisely as specified below. You can freely assume that the input will match the specification described; we will not be testing your program on any inputs that don't match the specification.
Your program begins by printing a line of output specifying which of the two sets of Othello rules are supported by your program, by printing FULL
Note that this is not a user option; this is something your program prints, before it does anything else, so we'll know (when we're grading it) how it should behave.
Your program then reads four lines of input, specifying the options that will be used to determine how the game will be played.
The first line specifies the number of rows on the board, which will be an even integer between 4 and 16 (inclusive).
The second line specifies the number of columns on the board, which will be an even integer between 4 and 16 (inclusive) and does not have to be the same as the number of rows.
The third line specifies which of the players will move first: B for black, W for white.
The fourth line selects how the game is won: > means that the player with the most discs on the board at the end of the game wins, < means the player with the fewest.
Next, your program will read the initial contents of the board. To make it simpler to test a variety of scenarios, your game will need to support any initial arrangement of discs, so it will be necessary to read the entire contents of the board from the input. It will be appear in the input in this form:
Each row will occupy a single line of input, with one space separating the cells in that row. Each cell will be specified as either B (if a black disc is in that cell), W (if a white disc is in that cell), or . (if the cell is empty).
The number of rows and columns described in this way will match the number of rows and columns specified in the first two lines of the input.
For example, if there are 8 rows and 8 columns on the board, the initial contents of the board might appear in the input this way:
. . . . . . . .
. . . . . . . .
. . . . . . . .
. B W B W . . .
. . . W B . . .
. . . . B W . .
. . . . . B . .
. . . . . . . .
After the initial arrangement of the board is specified in the input, the game begins, proceeding one move a time until it's complete.Before each turn, the following information is printed to the console:
The character B, followed by a colon and a space, followed by the number of discs on the board that are black. This is followed by two spaces, the character W, a colon and a space, and the number of discs on the board that are white.
The contents of the board, with each row occupying one line of output, and one space separating each pair of cells. Each cell is written either as a B (if a black tile occupies that cell), a W (if a white tile occupies that cell), or a . (if no tile occupies that cell). For example:
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . B W . . .
. . . W B . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
The word TURN (in all-caps), followed by a colon and a space, followed by B if it's the black player's turn, W if it's white's turn.
After printing the information above, the program reads a line of input specifying the current player's move. The move is specified as two integers on a line, separated by a space. The first integer specifies the row number (with 1 being the top row, 2 being the row below that, and so on) and the second integer specifies the column number (with 1 being the leftmost column, 2 being the one to the right of that, and so on).
If the move is valid, print the word VALID alone on a line, apply that move (i.e., make the appropriate changes to the state of the game) and then continue the game..
If the move is invalid (see the rules if you're curious what makes a move invalid), print the word INVALID alone on a line and wait for the user to specify another move.
At the conclusion of the game (i.e., after the last move is made and there are no more legal moves on the board), the final state of the game is printed to the console, quite similarly to how it's printed before each turn:
The character B, followed by a colon and a space, followed by the number of discs on the board that are black. This is followed by two spaces, the character W, a colon and a space, and the number of discs on the board that are white.
The contents of the board, in the same format described above.
The word WINNER (in all-caps), followed by a colon and a space, followed by B if the black player has won, W if the white player has won, and NONE if no player has won (i.e., the final score is tied).
The program ends when the game is over.
A complete example of program execution
The following is an example of the program's execution, if implemented as it should be, including the full Othello rules. Boldfaced, italicized text indicates input, while normal text indicates output.
FULL
4
4
B
>
. . . .
. B W .
. W B .
. . . .
B: 2 W: 2
. . . .
. B W .
. W B .
. . . .
TURN: B
2 4
VALID
B: 4 W: 1
. . . .
. B B B
. W B .
. . . .
TURN: W
1 2
VALID
B: 3 W: 3
. W . .
. W B B
. W B .
. . . .
TURN: B
1 4
INVALID
1 1
VALID
B: 5 W: 2
B W . .
. B B B
. W B .
. . . .
TURN: W
1 4
VALID
B: 4 W: 4
B W . W
. B W B
. W B .
. . . .
TURN: B
1 3
VALID
B: 7 W: 2
B B B W
. B B B
. W B .
. . . .
TURN: W
3 4
VALID
B: 5 W: 5
B B B W
. B B W
. W W W
. . . .
TURN: B
4 2
VALID
B: 7 W: 4
B B B W
. B B W
. B W W
. B . .
TURN: W
2 1
VALID
B: 5 W: 7
B B B W
W W W W
. B W W
. B . .
TURN: B
4 4
VALID
B: 8 W: 5
B B B W
W B W W
. B B W
. B . B
TURN: W
4 1
VALID
B: 7 W: 7
B B B W
W B W W
. W B W
W B . B
TURN: B
3 1
VALID
B: 10 W: 5
B B B W
B B W W
B B B W
W B . B
TURN: W
4 3
VALID
B: 8 W: 8
B B B W
B B W W
B B W W
W W W B
WINNER: NONE
A couple of "gotchas" to be aware of in the game logic
For the most part, Othello games proceed with players moving alternately, and continue until all cells on the grid contain a disc. However, there are a couple of wrinkles that you'll need to be sure you handle:
Sometimes, a player will make a move and, as a result, the opposite player will have no valid moves available (i.e., there is no cell in the grid in which the opposite player can move afterward). In that case, the turn reverts back to the player who just moved, and that player moves again.
Occasionally, neither player will have a valid move on the board, even though there are still empty cells in the grid. (One example is when all of the discs on the board belong to one player, though there are others, as well.) In this case, the game immediately ends and the winner is determined based on the number of discs each player has on the board.
Module design
You are required to keep the code that implements the game logic entirely separate from the code that implements your console-mode user interface. To that end, you will be required to submit at least two modules: one that implements your game logic and another that implements your user interface. You're welcome to break these two modules up further if you find it beneficial, but the requirement is that you keep these two parts of your program the logic and the user interface separate.
Note that this requirement is motivated partly by a desire to build good design habits, but also by the practical reality that maintaining that separation properly will give you a much better chance of being able to reuse your game logic, as-is and without modification, in the next project, when you'll be asked to build a graphical user interface for your game. In a big-picture sense, you can think of the user interface in this project as being a "throwaway"; while we'll be using it to grade your game logic, the true goal here is the complete version of Othello with a graphical user interface. So keeping this "throwaway" code completely separate from your game logic means that it will be easy to leave it out of your completed version, without causing anything else to break.
Module naming
Exactly one of your modules must be executable (i.e., should contain an if __name__ == '__main__': block), namely the one that you would execute if you wanted to launch your console user interface and play your game. No other modules are permitted to have an if __name__ == '__main__': block. (This is so our test automation tools can automatically determine which of your modules to execute.)
Using classes and exceptions to implement your game logic
Your game logic must consist of at least one class whose objects represent the current "state" of an Othello game, with methods that manipulate that state; you can feel free to implement additional classes, if you'd like. Note that this is in stark contrast to the approach used in connectfour.py in Project #2, where we used a namedtuple and a set of functions that returned new states. Classes offer us the ability to mix data together with the operations that safely manipulate that data; they allow us to create kinds of objects that don't just know how to store things, but also to do things.
Some of the methods I found useful in my own implementation of the Othello game state are listed below; this is not an exhaustive list, and you'll probably find a need for additional methods beyond these.
Get the number of rows and/or columns on the board.
Find out whose turn it is.
Determine whether the game is over.
Determine whether a disc is in some cell in the grid; if so, determine its color.
Make a move.
Even if your console user interface does error checking, your game logic must not assume the presence of a particular user interface, so it must check any parameters it's given and raise an exception if the parameters are problematic (e.g., a non-existent row or column, an attempt to make an invalid move, an attempt to make a move after the game is over). Create your own exception class(es) to represent these error conditions.
Testing
One issue that comes up in the implementation of a program like this one is that it's difficult to test some of the corner cases that come up in the game logic by playing your game using your console interface. It can be difficult to duplicate games that end in a tie, situations where the turn skips back to the player who just moved, situations where the game ends with empty cells still on the board, and so on. And yet you need to be sure that these issues, and others like them, are handled correctly by your game logic.
Your ability to specify any initial board configuration when starting the game is one thing that will really help you (and us!) to test these kinds of scenarios, because you won't need to figure out a sequence of moves that lead from a "traditional" initial state to the scenario you want to test.
Another way to do this kind of testing, though, is to load your game logic into the Python interpreter and type Python expressions and statements into the interpreter manually to verify that the behavior is as you expect; if you aren't doing that already, you're missing out on one of the more valuable tools Python offers for testing and understanding the programs you write.
Another approach is to figure out some interesting scenarios and write program input that covers these scenarios, saving each one into a file using your favorite text editor. You can then copy and paste these into your program to test and re-test interesting cases as you work.
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started