This lab will help you practice with 2D vectors.
Write a program to play Tic-Tac-Toe with the user. Well, sort-of.
Let's first get rid of that graphical interface mess. Let's just have a simple console interface like this:
1 | 2 | 3 -----+-----+----- 4 | 5 | 6 -----+-----+----- 7 | 8 | 9 Your move? 3 1 | 2 | X -----+-----+----- 4 | 5 | 6 -----+-----+----- 7 | 8 | 9 Your move? 4 1 | 2 | X -----+-----+----- O | 5 | 6 -----+-----+----- 7 | 8 | 9 Your move?
But don't forget to check for invalid input (taken squares, squares that aren't there, etc.).
What kind of vector can store both digits and X or O?
How can you translate a numeric position (1-9) into a [0-based] 2D coordinate? (Hint: Search might work; or, even better, integer arithmetic tricks?)
How do you determine a winner? (Rule: 3 of a single player's pieces in a row either horizontally, vertically, or diagonally.) Will loops be of use here? Perhaps one that starts at the placed piece location and looks out from there...relatively to the extent of the 'in-a-row' count? (Hint: How can you accumulate a boolean value like true or false? After all, they'll only win if this one and this one and that one are theirs, right?)
This assignment is (Level 3.5).
Add (Level 2) to allow for a computer opponent. The computer should move randomly, albeit legally. If you opt for a more intelligent player, discuss how many extra levels your computer player's intelligence is worth.
Add (Level 1) to allow for a 'demo mode' where two computer players battle it out for Tic-Tac Supremacy. Of course, both of these totally random computer players should be processed by the same code that currently processes your human players. (I.E. no cheating but also no extra code for processing and determining a win...)
Add (Level 2.5) to allow the players to choose either a 3x3 grid or a 4x4 grid. Should winning on the larger grid be 3 in a row or 4 in a row?
Add (Level 1) to allow the players to play on any [reasonably-sized] rectangular board. The 'in-a-row' length (for winning) should be the smaller of the width and height of the board (but also should not probably exceed 5 for the sake of playability).
The height can be anything up to 20 — after which even the ugliest of boards will begin to scroll. The width can be anything up to 20 (any larger and printing it nicely gets difficult). (You may shrink these if you wish to make the board print even nicer than minimally readable, of course.) The minimum for both dimensions should be 3. Let the user enter their desired height and width within these ranges.
(Note: This option assumes you've done the previous one as well. If not, this one is worth (Level 3) and the 4x4 option is then worth only (Level 0.5) if you decide to 'add' it later.)
Add (Level 1) to detect that the user is trying to enter 2D coordinates instead of your displayed position numbers. The clue would be that more input followed the number they entered or — in bizarre situations — that they've entered a leading '(' before the number. If either of these situations occurs, you should take in their 2D coordinate instead of their position number. Allow the second coordinate to follow after either a space or a comma.
At least you won't have to translate it ...as much... You know, the 0-based thing? What, you thought they'd enter 0-based 2D coordinates? *snicker* Not likely...
Add (Level 2) to allow winning to wrap from one side of the board to another. For instance, on a 3x3 board, not only the standard placements would win, but also:
X - - - X - - X - - - X - - X X - - - - X X - - - X - - - X X - - - X -
Aren't diagonals fun? But on a 4x8 board, things such as these would win, in additional to any standard length 4 runs:
- - - - - - - - - - - X - - - - - - - - - - - - - - - - X - - - X X - - - - X X - X - - - - - - - - - - - - - - - - X - - - - -
Notice how the wrap-around effect doesn't affect vertical wins in any configuration. (Unless, of course, the height is greater than 5, which was the suggested upper-bound for the 'in-a-row' count.) Only diagonal and possibly horizontal. Hmm...