/* CS 51 * Tic Tac Toe game */ // As you read this code, you will see 'Pre:' and 'Post:'. 'Pre:' // refers to the pre-conditions and 'Post:' post-conditions. // Pre-conditions are the conditions that should hold before // the method is executed, whereas post-conditions are the conditions // that should hold after the method has been executed. /** * A board is a 3x3 grid, which you can picture mentally as follows. * The squares of the grid are numbered 1 through 9, as indicated below. * * | | * 1 | 2 | 3 * | | * ---+---+--- * | | * 4 | 5 | 6 * | | * ---+---+--- * | | * 7 | 8 | 9 * | | * * Each square can be empty, can be occupied by an X, or * can be occupied by an O. */ public class Ttt { // The number of empty spaces in the board. private static int spacesLeft; // If square i of the board is empty, variable si = ' '. // If square i of the board contains an X, variable si = 'X'. // If square i of the board contains an O, variable si = 'O'. static TttBoard board; /* These 10 variables (spaceLeft and s1 through s9) are called static variables. They are different from the local variables that we have been using. Local variables are confined within a method/function and their meaning is available only during the time the method is active (remember the large boxes that we have been drawing? So they are active only during the time the box is active). Static variables are non-local. That is, they are shared by all the methods in this class. Any method can access (for read and write accesses) the values of these variables. They can change the values of these variables as well. We will study static variables in more detail later. For now, this should be enough to understand this program. This program also uses the keyword 'private' in front of each variable. You may regard the word 'private' as a decoration for now. For those who can't wait, it means that those variables declared to be private are not accessible outside this class. */ /* Plan for the implementation of the TTT game: 1. Welcome the players 2. Display the board [ draw(), firstDraw() ] 3. Repeat the following - indicate whose turn it is, ask for the next legal move. This will return a square number. [ getLegalMove() ] - update the board by putting a mark in that square and draw the board again. [ move(square, mark) ] - with the updated board displayed, indecate if the player has won or not. If s/he has, finish the game [ is3InRow(mark) ] - Otherwise, if the board is full, then announce a tie game and finish it. [ isBoardFull() ] - Otherwise, game continues with the other player getting the turn. */ public static void main (String[] args) { // Welcome the users, create and draw an empty board, // the first move belongs to X. board = new TttBoard(); System.out.println("Welcome to Tic Tac Toe"); board.initializeBoard(' '); board.draw(); char mark = 'X'; // Until someone wins or the board is filled up, get // a legal move, make the move, and draw the board. // Each time through the loop the turns of X and O // alternate. while (true) { int square = getLegalMove(mark); board.move(square, mark); board.draw(); if (is3InRow(mark)) { System.out.println(mark + " wins!"); break; // break out of the loop } if (isBoardFull()) { System.out.println("Tie game!"); break; } if (mark == 'X') { mark = 'O'; } else { mark = 'X'; } } } // Pre: mark is 'X' or 'O' // The current board contains an empty square // Post: Interacts with the user until the user provides the number // of an empty square in the board. It then returns that number. // public static int getLegalMove (char mark) { java.util.Scanner console = new java.util.Scanner(System.in); while (true) { System.out.println(mark + "'s next move: "); int square = console.nextInt(); if ((square >= 1) && (square <= 9) && (board.isSquareEmpty(square))) { return square; } System.out.println("\nIllegal move, try again\n"); } } // Pre: mark is 'X' or 'O' // Post: Returns true if the board contains three of // the specified mark in a row; returns false // otherwise. public static boolean is3InRow (char mark) { return (s1 == mark && s2 == mark && s3 == mark) || (s4 == mark && s5 == mark && s6 == mark) || (s7 == mark && s8 == mark && s9 == mark) || (s1 == mark && s4 == mark && s7 == mark) || (s2 == mark && s5 == mark && s8 == mark) || (s3 == mark && s6 == mark && s9 == mark) || (s1 == mark && s5 == mark && s9 == mark) || (s3 == mark && s5 == mark && s7 == mark); } // Post: Returns true if the board contains no empty // spaces; returns false otherwise. public static boolean isBoardFull () { return spacesLeft == 0; } }