###TicTacToe package tictactoe.peter;
TicTacToe
package tictactoe.peter;
/** Manages basic operations for a Tic Tac Toe game
*
* @author Buffy, Peter
*
*/
public class TicTacToe {
private TicTacToeBoard board = new TicTacToeBoard();
private int turnNumber = 0;
private boolean gameWon = false;
/** Determine whether another move is possible
* @return true if a move can be made
*/
public boolean moveAvailable() {
return !(turnNumber >= 9 || gameWon);
}
/** A player attempts to make a move
* @param player the player trying to move
* @param location the board location of the move
* @return true if the move is successful
*/
public boolean makeMove(ArrayPlayer player, ArrayLocation location) {
boolean success = validateMove(location);
if (success) {
board.play(player, location);
turnNumber++;
}
return success;
}
/** Print a representation of the board to standard output.
*
*/
public void printBoard() {
board.printGrid();
}
/** Check to see if the game has been won and remember the result.
*
*/
public void checkIfWon() {
if (turnNumber >= 5) {
gameWon = board.haveWinner();
}
}
/** Print what happened in the game
* @param player the last player that moved.
*/
public void printFinalStatus(ArrayPlayer player) {
if (gameWon) {
System.out.println(player.symbol() + " is the champion");
} else {
System.out.println("Draw");
}
}
/** Determine if a location represents a valid move
* @param location the location to be checked
* @return true if the location is on the board and empty
*/
private boolean validateMove(ArrayLocation location) {
return board.isValidAndFree(location);
}
}
#TicTacToeGame package tictactoe.peter;
TicTacToeGame
package tictactoe.peter;
import java.util.*;
/** Play a standard game of tic tac toe.
*
* @author Buffy
*
*/
public class TicTacToeGame {
public static void main(String args[]) {
TicTacToe game = new TicTacToe();
Scanner readIn = new Scanner(System.in);
ArrayPlayer xPlayer = new ArrayPlayer('X', readIn);
ArrayPlayer oPlayer = new ArrayPlayer('O', readIn);
ArrayPlayer player = xPlayer;
ArrayPlayer other = oPlayer;
while (game.moveAvailable()) {
ArrayLocation where = player.getMove();
boolean success = game.makeMove(player, where);
game.printBoard();
game.checkIfWon();
if (success) {
// swap the players for next round
ArrayPlayer temp = other;
other = player;
player = temp;
}
}
game.printFinalStatus(other); // already swapped
readIn.close();
}
}
###TicTacToe package tictactoe.peter;
/** Manages basic operations for a Tic Tac Toe game
*
* @author Buffy, Peter
*
*/
public class TicTacToe {
private TicTacToeBoard board = new TicTacToeBoard();
private int turnNumber = 0;
private boolean gameWon = false;
/** Determine whether another move is possible
* @return true if a move can be made
*/
public boolean moveAvailable() {
return !(turnNumber >= 9 || gameWon);
}
/** A player attempts to make a move
* @param player the player trying to move
* @param location the board location of the move
* @return true if the move is successful
*/
public boolean makeMove(ArrayPlayer player, ArrayLocation location) {
boolean success = validateMove(location);
if (success) {
board.play(player, location);
turnNumber++;
}
return success;
}
/** Print a representation of the board to standard output.
*
*/
public void printBoard() {
board.printGrid();
}
/** Check to see if the game has been won and remember the result.
*
*/
public void checkIfWon() {
if (turnNumber >= 5) {
gameWon = board.haveWinner();
}
}
/** Print what happened in the game
* @param player the last player that moved.
*/
public void printFinalStatus(ArrayPlayer player) {
if (gameWon) {
System.out.println(player.symbol() + " is the champion");
} else {
System.out.println("Draw");
}
}
/** Determine if a location represents a valid move
* @param location the location to be checked
* @return true if the location is on the board and empty
*/
private boolean validateMove(ArrayLocation location) {
return board.isValidAndFree(location);
}
}
#TicTacToeGame package tictactoe.peter;
import java.util.*;
/** Play a standard game of tic tac toe.
*
* @author Buffy
*
*/
public class TicTacToeGame {
public static void main(String args[]) {
TicTacToe game = new TicTacToe();
Scanner readIn = new Scanner(System.in);
ArrayPlayer xPlayer = new ArrayPlayer('X', readIn);
ArrayPlayer oPlayer = new ArrayPlayer('O', readIn);
ArrayPlayer player = xPlayer;
ArrayPlayer other = oPlayer;
while (game.moveAvailable()) {
ArrayLocation where = player.getMove();
boolean success = game.makeMove(player, where);
game.printBoard();
game.checkIfWon();
if (success) {
// swap the players for next round
ArrayPlayer temp = other;
other = player;
player = temp;
}
}
game.printFinalStatus(other); // already swapped
readIn.close();
}
}
TicTacToe
package tictactoe.peter;
/** Manages basic operations for a Tic Tac Toe game
*
* @author Buffy, Peter
*
*/
public class TicTacToe {
private TicTacToeBoard board = new TicTacToeBoard();
private int turnNumber = 0;
private boolean gameWon = false;
/** Determine whether another move is possible
* @return true if a move can be made
*/
public boolean moveAvailable() {
return !(turnNumber >= 9 || gameWon);
}
/** A player attempts to make a move
* @param player the player trying to move
* @param location the board location of the move
* @return true if the move is successful
*/
public boolean makeMove(ArrayPlayer player, ArrayLocation location) {
boolean success = validateMove(location);
if (success) {
board.play(player, location);
turnNumber++;
}
return success;
}
/** Print a representation of the board to standard output.
*
*/
public void printBoard() {
board.printGrid();
}
/** Check to see if the game has been won and remember the result.
*
*/
public void checkIfWon() {
if (turnNumber >= 5) {
gameWon = board.haveWinner();
}
}
/** Print what happened in the game
* @param player the last player that moved.
*/
public void printFinalStatus(ArrayPlayer player) {
if (gameWon) {
System.out.println(player.symbol() + " is the champion");
} else {
System.out.println("Draw");
}
}
/** Determine if a location represents a valid move
* @param location the location to be checked
* @return true if the location is on the board and empty
*/
private boolean validateMove(ArrayLocation location) {
return board.isValidAndFree(location);
}
}
TicTacToeGame
package tictactoe.peter;
import java.util.*;
/** Play a standard game of tic tac toe.
*
* @author Buffy
*
*/
public class TicTacToeGame {
public static void main(String args[]) {
TicTacToe game = new TicTacToe();
Scanner readIn = new Scanner(System.in);
ArrayPlayer xPlayer = new ArrayPlayer('X', readIn);
ArrayPlayer oPlayer = new ArrayPlayer('O', readIn);
ArrayPlayer player = xPlayer;
ArrayPlayer other = oPlayer;
while (game.moveAvailable()) {
ArrayLocation where = player.getMove();
boolean success = game.makeMove(player, where);
game.printBoard();
game.checkIfWon();
if (success) {
// swap the players for next round
ArrayPlayer temp = other;
other = player;
player = temp;
}
}
game.printFinalStatus(other); // already swapped
readIn.close();
}
}
I've added a package and javadocs (which should always be present) and changed the position of initial braces to a more common standard - that you may love or hate.
I've added a package and javadocs (which should always be present and changed the position of initial braces to a more common standard - that you may love or hate.
I've added a package and javadocs (which should always be present) and changed the position of initial braces to a more common standard - that you may love or hate.
Here is a somewhat different factorization of @Peter's code. It has five abstractions.
ArrayLocation: the row and column numbers captured in an object.
ArrayPlayer: an object that can play a symbol in an array based game.
TicTacToeBoard: manages the array aspects of the game and allows ArrayPlayers to play at ArrayLocations.
TicTacToe: manages the basic operations of the game.
TicTacToeGame: main - runs a single game
There are a few things that might be made better on a future edit. Some are noted in comments.
Note that I changed the user input rows and columns to be 1..3 based, which is a more common way of thinking about the game for most players. Internally usual array indices are used.
ArrayLocation
package tictactoe.peter;
/**
* Represents a location in a two dimensional array. It is immutable. The
* upper left corner has (0, 0) coordinates.
* No check for validity is done.
*
* @author Buffy
*
*/
public class ArrayLocation {
private int row;
private int column;
public ArrayLocation(int row, int column) {
this.row = row;
this.column = column;
}
/** A row in the array with 0 as the first row
* @return the row number - zero based
*/
public int row() {
return this.row;
}
/** A column in the array with 0 as the first column
* @return the column number - zero based
*/
public int column() {
return this.column;
}
}
ArrayPlayer
package tictactoe.peter;
import java.util.Scanner;
/** A player in an array based interactive game. The player can read a
* location in which to play and has a symbol that it can utilize
* at that location. It reads from aScanner for the location.
* It does not, however, remember the location.
*
* @author Buffy, Peter
*/
public class ArrayPlayer {
private char symbol;
private Scanner input;
public ArrayPlayer(char symbol, Scanner input) {
this.symbol = symbol;
this.input = input;
}
/** The symbol that the player uses
* @return the symbol of this player
*/
public char symbol() {
return this.symbol;
}
/** Prompt a user for a row to play (1..n) and a column (1..n).
* The validity is not checked here.
*
* @return an ArrayLocation object with (0..n-1) coordinates.
*/
public ArrayLocation getMove() {
System.out.print("Row: ");
int row = input.nextInt();
System.out.print("Column: ");
int column = input.nextInt();
return new ArrayLocation(row - 1, column - 1);
}
}
TicTacToeBoard
package tictactoe.peter;
import java.util.Arrays;
/** Represents a 3 by 3 board for a tic tac toe game.
*
* @author Buffy, Peter
*
*/
public class TicTacToeBoard {
private int size = 3;
private char[][] grid = new char[size][size];
/** Create a 3 by 3 Tic Tac Toe board
*
*/
public TicTacToeBoard() {
for (char[] row : grid) {
Arrays.fill(row, ' ');
}
}
private boolean validLocation(ArrayLocation location) {
return location.row() >= 0 &&
location.row() < size &&
location.column() >= 0 &&
location.column() < size;
}
/** Marks the board with the player's symbol if the location is valid.
* Otherwise a no-op.
* @param player the current player
* @param location the location to play
*/
public void play(ArrayPlayer player, ArrayLocation location) {
if (validLocation(location)) {
grid[location.row()][location.column()] = player.symbol();
}
}
/** Does the board show a winner?
* @return whether the board has a winner.
*/
public boolean haveWinner() {
// Assumes the size is 3. Could use a fixup.
boolean result = false;
for (int i = 0; i < size; i++) {
if (grid[0][i] != ' ' && grid[0][i] == grid[1][i] && grid[1][i] == grid[2][i]) {
result = true;
}
if (grid[i][0] != ' ' && grid[i][0] == grid[i][1] && grid[i][1] == grid[i][2]) {
result = true;
}
}
if (grid[1][1] != ' ' && ((grid[0][0] == grid[1][1] && grid[1][1] == grid[2][2])
|| (grid[0][2] == grid[1][1] && grid[1][1] == grid[2][0]))) {
result = true;
}
return result;
}
/** Is the location a valid place for a move
* @param location a location that may be on the board or not
* @return whether the location is on the board and has not been
* played
*/
public boolean isValidAndFree(ArrayLocation location) {
boolean validMove = true;
int row = location.row();
int col = location.column();
if (row < 0 || col < 0 || row >= size || col >= size) {
System.out.println("ERROR: Invalid location.\nTry again.");
validMove = false;
} else if (!(grid[row][col] == ' ')) {
System.out.println("ERROR: Spot taken.\nTry again.");
validMove = false;
}
return validMove;
}
/** Print a representation of the board to standard output.
*
*/
public void printGrid() {
// assumes size = 3. Fixup?
for (int row = 0; row < grid.length; row++) {
for (int column = 0; column < grid[row].length; column++) {
switch (column) {
case 0:
System.out.print(" " + grid[row][column] + " | ");
break;
case 1:
System.out.print(grid[row][column] + " | ");
break;
case 2:
System.out.println(grid[row][column]);
break;
}
}
if (row < grid.length - 1) {
System.out.println("-----------");
}
}
}
}
###TicTacToe package tictactoe.peter;
/** Manages basic operations for a Tic Tac Toe game
*
* @author Buffy, Peter
*
*/
public class TicTacToe {
private TicTacToeBoard board = new TicTacToeBoard();
private int turnNumber = 0;
private boolean gameWon = false;
/** Determine whether another move is possible
* @return true if a move can be made
*/
public boolean moveAvailable() {
return !(turnNumber >= 9 || gameWon);
}
/** A player attempts to make a move
* @param player the player trying to move
* @param location the board location of the move
* @return true if the move is successful
*/
public boolean makeMove(ArrayPlayer player, ArrayLocation location) {
boolean success = validateMove(location);
if (success) {
board.play(player, location);
turnNumber++;
}
return success;
}
/** Print a representation of the board to standard output.
*
*/
public void printBoard() {
board.printGrid();
}
/** Check to see if the game has been won and remember the result.
*
*/
public void checkIfWon() {
if (turnNumber >= 5) {
gameWon = board.haveWinner();
}
}
/** Print what happened in the game
* @param player the last player that moved.
*/
public void printFinalStatus(ArrayPlayer player) {
if (gameWon) {
System.out.println(player.symbol() + " is the champion");
} else {
System.out.println("Draw");
}
}
/** Determine if a location represents a valid move
* @param location the location to be checked
* @return true if the location is on the board and empty
*/
private boolean validateMove(ArrayLocation location) {
return board.isValidAndFree(location);
}
}
#TicTacToeGame package tictactoe.peter;
import java.util.*;
/** Play a standard game of tic tac toe.
*
* @author Buffy
*
*/
public class TicTacToeGame {
public static void main(String args[]) {
TicTacToe game = new TicTacToe();
Scanner readIn = new Scanner(System.in);
ArrayPlayer xPlayer = new ArrayPlayer('X', readIn);
ArrayPlayer oPlayer = new ArrayPlayer('O', readIn);
ArrayPlayer player = xPlayer;
ArrayPlayer other = oPlayer;
while (game.moveAvailable()) {
ArrayLocation where = player.getMove();
boolean success = game.makeMove(player, where);
game.printBoard();
game.checkIfWon();
if (success) {
// swap the players for next round
ArrayPlayer temp = other;
other = player;
player = temp;
}
}
game.printFinalStatus(other); // already swapped
readIn.close();
}
}
Note that it would be fairly easy to remove variable turnNumber
from TicTacToe
leaving almost all manipulation of primitives of Java in class TicTacToeBoard. Nearly everything else is a higher level abstraction.
I've added a package and javadocs (which should always be present and changed the position of initial braces to a more common standard - that you may love or hate.