Many two-player games in computer science can be represented via general trees. Game trees are of interest because they are helpful for finding the best next move or for determining if there is any chance of winning (otherwise one could resign). Given any state of a game, if all next states are winning states (for the other player), this state is a losing state (because no matter what move the current player plays, he/she will end up in a state that the other player can win); and if at least one of the next states are a losing state (for the other player) this state is a winning state because the current player has one move that he/she can play that leads to the ultimate loss of the other player. While not all games can be played only based on game trees, some are simple enough that this approach is attemptable. An example of such simple game is Tic-Tac-Toe.
Tic-Tac-Toe can be represented as a tree where nodes are boards and children of a board are all possible boards that we can get from the current board by playing only one move. The following figure shows a subtree of Tic-Tac-Toe tree rooted at a losing board (O must play and it can't win).
The goal in this assignment is to implement a tree of tic-tac-toe and determining if the player who's to play a given board will win or will lose.
We will assume that X always starts the game and is presented as 1 on the board and O always plays second and is presented as -1 on the board. Therefore, the root of the tree in the above image is represented as "{0,1,0,0,0,1,-1,-1,1}".
g++ -c tttboard.cpp g++ -o test_tttboard.o test_tttboard.cpp tttboard.o ./test_tttboard.o 2 "{0,0,1,-1}" preorder: {0,0,1,-1} {1,0,1,-1} postorder: {1,0,1,-1} {0,0,1,-1} size:2
./test_tttboard_step2.o 3 "{0,0,1,0,0,0,0,0,0}" children of the given board: {-1,0,1,0,0,0,0,0,0} {0,-1,1,0,0,0,0,0,0} {0,0,1,-1,0,0,0,0,0} {0,0,1,0,-1,0,0,0,0} {0,0,1,0,0,-1,0,0,0} {0,0,1,0,0,0,-1,0,0} {0,0,1,0,0,0,0,-1,0} {0,0,1,0,0,0,0,0,-1}
g++ -c tttboard.cpp g++ -o tic_tac_toe.o tic_tac_toe.cpp tttboard.o ./tic_tac_toe.o 2 pre-order: {0,0,0,0} {1,0,0,0} {1,-1,0,0} {1,-1,1,0} {1,-1,1,-1} {1,-1,0,1} {1,-1,-1,1} {1,0,-1,0} {1,1,-1,0} {1,1,-1,-1} {1,0,-1,1} {1,-1,-1,1} {1,0,0,-1} {1,1,0,-1} {1,1,-1,-1} {1,0,1,-1} {1,-1,1,-1} {0,1,0,0} {-1,1,0,0} {-1,1,1,0} {-1,1,1,-1} {-1,1,0,1} {-1,1,-1,1} {0,1,-1,0} {1,1,-1,0} {1,1,-1,-1} {0,1,-1,1} {-1,1,-1,1} {0,1,0,-1} {1,1,0,-1} {1,1,-1,-1} {0,1,1,-1} {-1,1,1,-1} {0,0,1,0} {-1,0,1,0} {-1,1,1,0} {-1,1,1,-1} {-1,0,1,1} {-1,-1,1,1} {0,-1,1,0} {1,-1,1,0} {1,-1,1,-1} {0,-1,1,1} {-1,-1,1,1} {0,0,1,-1} {1,0,1,-1} {1,-1,1,-1} {0,1,1,-1} {-1,1,1,-1} {0,0,0,1} {-1,0,0,1} {-1,1,0,1} {-1,1,-1,1} {-1,0,1,1} {-1,-1,1,1} {0,-1,0,1} {1,-1,0,1} {1,-1,-1,1} {0,-1,1,1} {-1,-1,1,1} {0,0,-1,1} {1,0,-1,1} {1,-1,-1,1} {0,1,-1,1} {-1,1,-1,1} post-order: {1,-1,1,-1} {1,-1,1,0} {1,-1,-1,1} {1,-1,0,1} {1,-1,0,0} {1,1,-1,-1} {1,1,-1,0} {1,-1,-1,1} {1,0,-1,1} {1,0,-1,0} {1,1,-1,-1} {1,1,0,-1} {1,-1,1,-1} {1,0,1,-1} {1,0,0,-1} {1,0,0,0} {-1,1,1,-1} {-1,1,1,0} {-1,1,-1,1} {-1,1,0,1} {-1,1,0,0} {1,1,-1,-1} {1,1,-1,0} {-1,1,-1,1} {0,1,-1,1} {0,1,-1,0} {1,1,-1,-1} {1,1,0,-1} {-1,1,1,-1} {0,1,1,-1} {0,1,0,-1} {0,1,0,0} {-1,1,1,-1} {-1,1,1,0} {-1,-1,1,1} {-1,0,1,1} {-1,0,1,0} {1,-1,1,-1} {1,-1,1,0} {-1,-1,1,1} {0,-1,1,1} {0,-1,1,0} {1,-1,1,-1} {1,0,1,-1} {-1,1,1,-1} {0,1,1,-1} {0,0,1,-1} {0,0,1,0} {-1,1,-1,1} {-1,1,0,1} {-1,-1,1,1} {-1,0,1,1} {-1,0,0,1} {1,-1,-1,1} {1,-1,0,1} {-1,-1,1,1} {0,-1,1,1} {0,-1,0,1} {1,-1,-1,1} {1,0,-1,1} {-1,1,-1,1} {0,1,-1,1} {0,0,-1,1} {0,0,0,1} {0,0,0,0} size: 65Make sure your output exactly matches this one character by character because it might differ and you many not even realize it. And that could potentially lead to losing all the marks for this step AND the next one.
g++ -c tttboard.cpp g++ -o tic_tac_toe.o tic_tac_toe.cpp tttboard.o ./tic_tac_toe.o 2 pre-order: {0,0,0,0} {1,0,0,0} {1,-1,0,0} {1,-1,1,0} {1,-1,1,-1} {1,-1,0,1} {1,-1,-1,1} {1,0,-1,0} {1,1,-1,0} {1,1,-1,-1} {1,0,-1,1} {1,-1,-1,1} {1,0,0,-1} {1,1,0,-1} {1,1,-1,-1} {1,0,1,-1} {1,-1,1,-1} {0,1,0,0} {-1,1,0,0} {-1,1,1,0} {-1,1,1,-1} {-1,1,0,1} {-1,1,-1,1} {0,1,-1,0} {1,1,-1,0} {1,1,-1,-1} {0,1,-1,1} {-1,1,-1,1} {0,1,0,-1} {1,1,0,-1} {1,1,-1,-1} {0,1,1,-1} {-1,1,1,-1} {0,0,1,0} {-1,0,1,0} {-1,1,1,0} {-1,1,1,-1} {-1,0,1,1} {-1,-1,1,1} {0,-1,1,0} {1,-1,1,0} {1,-1,1,-1} {0,-1,1,1} {-1,-1,1,1} {0,0,1,-1} {1,0,1,-1} {1,-1,1,-1} {0,1,1,-1} {-1,1,1,-1} {0,0,0,1} {-1,0,0,1} {-1,1,0,1} {-1,1,-1,1} {-1,0,1,1} {-1,-1,1,1} {0,-1,0,1} {1,-1,0,1} {1,-1,-1,1} {0,-1,1,1} {-1,-1,1,1} {0,0,-1,1} {1,0,-1,1} {1,-1,-1,1} {0,1,-1,1} {-1,1,-1,1} post-order: {1,-1,1,-1} {1,-1,1,0} {1,-1,-1,1} {1,-1,0,1} {1,-1,0,0} {1,1,-1,-1} {1,1,-1,0} {1,-1,-1,1} {1,0,-1,1} {1,0,-1,0} {1,1,-1,-1} {1,1,0,-1} {1,-1,1,-1} {1,0,1,-1} {1,0,0,-1} {1,0,0,0} {-1,1,1,-1} {-1,1,1,0} {-1,1,-1,1} {-1,1,0,1} {-1,1,0,0} {1,1,-1,-1} {1,1,-1,0} {-1,1,-1,1} {0,1,-1,1} {0,1,-1,0} {1,1,-1,-1} {1,1,0,-1} {-1,1,1,-1} {0,1,1,-1} {0,1,0,-1} {0,1,0,0} {-1,1,1,-1} {-1,1,1,0} {-1,-1,1,1} {-1,0,1,1} {-1,0,1,0} {1,-1,1,-1} {1,-1,1,0} {-1,-1,1,1} {0,-1,1,1} {0,-1,1,0} {1,-1,1,-1} {1,0,1,-1} {-1,1,1,-1} {0,1,1,-1} {0,0,1,-1} {0,0,1,0} {-1,1,-1,1} {-1,1,0,1} {-1,-1,1,1} {-1,0,1,1} {-1,0,0,1} {1,-1,-1,1} {1,-1,0,1} {-1,-1,1,1} {0,-1,1,1} {0,-1,0,1} {1,-1,-1,1} {1,0,-1,1} {-1,1,-1,1} {0,1,-1,1} {0,0,-1,1} {0,0,0,1} {0,0,0,0} size: 65 ./tic_tac_toe.o 3 "{0,1,0,0,0,1,-1,-1,1}" losing board ./tic_tac_toe.o 3 "{-1,1,0,0,0,1,-1,-1,1}" winning boardThree more examples:
./tic_tac_toe.o 3 "{0,1,1,-1,0,1,0,0,-1}" winning board ./tic_tac_toe.o 3 "{-1,1,1,-1,0,1,0,0,-1}" losing board ./tic_tac_toe.o 3 "{0,0,0,0,0,0,0,0,0}" not sure
Outputs will be checked based on exact string match. Don't put extra spaces, new lines, etc. or else don't complain if you get a zero.
While it is OK for you to discuss the high-level idea of how to tackle each of these steps among yourselves, I encourage you to try coming up with the idea yourself. Remember, one of the most important goals of the course is to build your problem-solving skills.