Commit 5b100d94 authored by Stefano Cobelli's avatar Stefano Cobelli

Init commit

parents
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>hw02</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
import javax.swing.JOptionPane;
import model.Game;
import view.TTTMainView;
import controller.TTTController;
/**
* CSCI 205 -Software Design and Engineering
* Name(s) Stefano Cobelli
*
* Work: Lab15
* Created: Oct 26, 2014, 9:18:57 PM
*/
/**
* The main class the runs the game. Prompts to enter a size.
*
* @author sjc032
*
*/
public class TTTMainGame {
/**
* the maximum size I'll allow for a board to be. the actual max is around
* 42 for a lab linux machine, it just doesn't show up. Anything above 25 is
* stupid anyway
*/
private final static int MAXSIZE = 25;
/**
* main method that runs the gui and controller
*
* @param args
*/
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
int size;
String sizeStr;
// handles the size of the board
while (true) {
try {
sizeStr = JOptionPane
.showInputDialog(
null,
"Pick a board size length:\n(Enter nothing for 3)",
"Tic Tac Toe!",
JOptionPane.QUESTION_MESSAGE);
// if cancel or xed out
if (sizeStr == null) {
return;
}
size = Integer.parseInt(sizeStr);
if (size <= 0) {
JOptionPane
.showMessageDialog(null,
"It's gotta be bigger than zero, come on, try again");
continue;
}
if (size > MAXSIZE) {
JOptionPane.showMessageDialog(null,
"Little too big, try again");
continue;
}
break;
// if okay is hit without a value
} catch (NumberFormatException e) {
size = 3;
break;
}
}
TTTMainView frame = new TTTMainView(size);
Game game = new Game(size);
@SuppressWarnings("unused")
TTTController ctrl = new TTTController(game, frame);
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
/**
* CSCI 205 -Software Design and Engineering
* Name(s) Stefano Cobelli
*
* Work: Lab15
* Created: Oct 27, 2014, 1:38:34 AM
*/
package controller;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
import model.Board.State;
import model.Game;
import view.TTTBoardPanel;
import view.TTTMainView;
import view.TTTStatsPanel;
/**
* The controller that combines the GUI and the game
*
* @author sjc032
*/
public class TTTController implements ActionListener {
/** a game instance */
private Game theGame;
/** an instance of the main view */
private TTTMainView theView;
/** an instance of the stats panel from the main veiw */
private TTTStatsPanel statsPanel;
/** an instance of the board panel from the main veiw */
private TTTBoardPanel boardPanel;
/**
* Constructor that sets up the gui buttons as this's actionListener
*
* @param theGame
* - a Game instance
* @param theView
* - a TTTMainView veiw instance
*/
public TTTController(Game theGame, TTTMainView theView) {
this.theGame = theGame;
this.theView = theView;
statsPanel = this.theView.getStatsPanel();
boardPanel = this.theView.getBoardPanel();
for (int i = 0; i < boardPanel.getButtonBoard().length; i++) {
for (int j = 0; j < boardPanel.getButtonBoard().length; j++) {
boardPanel.getButtonBoard()[i][j].addActionListener(this);
}
}
}
/*
* (non-Javadoc)
*
* @see
* java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
@Override
public void actionPerformed(ActionEvent e) {
// checks all the buttons if it's the source
for (int row = 0; row < boardPanel.getButtonBoard().length; row++) {
for (int col = 0; col < boardPanel.getButtonBoard().length; col++) {
if (e.getSource() == boardPanel.getButtonBoard()[row][col]) {
if (theGame.getCurPlayer().move(row, col)) {
// sets text on button if marked
boardPanel.getButtonBoard()[row][col].setText(theGame
.getPlayerTurn());
if (!theGame.isPlayable()) {
// performs relative actions if game is over
if (theGame.getState() == State.WIN) {
JOptionPane.showMessageDialog(null,
theGame.getPlayerTurn() + " wins!");
if (theGame.getPlayerTurn() == "X")
statsPanel.getXWins().setText(
incrementString(statsPanel
.getXWins().getText()));
else if (theGame.getPlayerTurn() == "O")
statsPanel.getOWins().setText(
incrementString(statsPanel
.getOWins().getText()));
theGame.newGame();
clearGUI();
} else if (theGame.getState() == State.DRAW) {
JOptionPane.showMessageDialog(null,
"The game's a draw!");
statsPanel.getDraws().setText(
incrementString(statsPanel.getDraws()
.getText()));
theGame.newGame();
clearGUI();
}
} else {
// if the game is playable, switch the turn
theGame.switchTurn();
statsPanel.getPlayerTurn().setText(
theGame.getPlayerTurn());
}
}
}
}
}
}
/**
* clears the GUI to all ""
*/
public void clearGUI() {
for (int row = 0; row < boardPanel.getButtonBoard().length; row++) {
for (int col = 0; col < boardPanel.getButtonBoard().length; col++) {
boardPanel.getButtonBoard()[row][col].setText("");
}
}
statsPanel.getPlayerTurn().setText("X");
}
/**
* increments a String representation of an int
*
* @param num
* @return
*/
public String incrementString(String num) {
return String.valueOf(Integer.parseInt(num) + 1);
}
}
/**
* CSCI 205 -Software Design and Engineering
* Name(s) Stefano Cobelli
*
* Work: Lab15
* Created: Oct 26, 2014, 7:01:52 PM
*/
package model;
/**
* Board for the Tic Tac Toe
*
* @author sjc032
*
*/
public class Board {
/**
* states the board can be in
*
* @author sjc032
*
*/
public static enum State {
NEW, PLAYING, WIN, DRAW;
}
/** the board in a mark representation */
private Mark[][] board;
/** the current state of the board */
private State state;
/** the size of a board (a single dimention) */
private int size;
/**
* constructor that initiallizes the board
*
* @param size
* -size of the board
*/
public Board(int size) {
this.size = size;
board = new Mark[size][size];
clear();
}
/**
* clears the whole board. Sets states to NONE
*
*/
public void clear() {
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
board[row][col] = Mark.NONE;
}
}
state = State.NEW;
}
/**
* sets the mark at the coordinates row and collumn to a specific mark.
* Returns true if successful. Updates the boards state regardless.
*
* @param row
* - row
* @param col
* - column
* @param mark
* - player's mark to be set
* @return success in placing mark
*/
public boolean setMark(int row, int col, Mark mark) {
if (isEmpty(row, col) && isPlayable() && row < size && col < size) {
board[row][col] = mark;
updateBoardState();
return true;
}
return false;
}
/**
* gets the mark at the coordinates
*
* Mark, someone's asking for you
*
* @param row
* @param col
* @return mark at row,col
*/
public Mark getMark(int row, int col) {
return board[row][col];
}
/**
* @return the state
*/
public State getState() {
return state;
}
/**
* prints boring string of the board. Example:
*
*
* return string representation of board
*/
@Override
public String toString() {
String result = "";
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
result += board[row][col].getSign();
}
result += "\n";
}
return result;
}
/**
*
* @return whether the game is in a playable state
*/
public boolean isPlayable() {
return (getState() == State.NEW || getState() == State.PLAYING);
}
/**
* @param row
* @param col
* @return whether the spot at row,col is empty
*/
public boolean isEmpty(int row, int col) {
return getMark(row, col) == Mark.NONE;
}
/**
* checks if the row, given by an int has won
*
* @param row
* - row number
* @return mark of the winner, or none if not
*/
public Mark checkRow(int row) {
Mark start = board[row][0];
for (int col = 0; col < size; col++) {
if (board[row][col] != start) {
return Mark.NONE;
}
}
return start;
}
/**
* checks if the col, given by an int has won
*
* @param col
* - col number
* @return mark of the winner, or none if not
*/
public Mark checkCol(int col) {
Mark start = board[0][col];
for (int row = 0; row < size; row++) {
if (board[row][col] != start) {
return Mark.NONE;
}
}
return start;
}
/**
* checks if game is won by the North West diagonal
*
* @return mark of the winner, or none if not
*/
public Mark checkDiagNW() {
Mark start = board[0][0];
for (int rowCol = 0; rowCol < size; rowCol++) {
if (board[rowCol][rowCol] != start)
return Mark.NONE;
}
return start;
}
/**
* checks if game is won by the North East diagonal
*
* @return mark of the winner, or none if not
*/
public Mark checkDiagNE() {
Mark start = board[0][size - 1];
for (int rowCol = 0; rowCol < size; rowCol++) {
if (board[rowCol][(size - 1) - rowCol] != start)
return Mark.NONE;
}
return start;
}
/**
* @return if board is full
*/
public boolean isBoardFull() {
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
if (isEmpty(row, col))
return false;
}
}
return true;
}
/**
* @return if board is empty
*/
public boolean isBoardEmpty() {
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
if (!isEmpty(row, col))
return false;
}
}
return true;
}
/**
* updates the board state by first checking if the game is empty, making it
* a new game. Then it checks for wins. if not, and the game is not done,
* then the game is playing. if the board is full, then it's a tie.
*
* @return the winner if game is WIN. returns Mark.None otherwise.
*/
private Mark updateBoardState() {
if (isBoardEmpty()) {
state = State.NEW;
return Mark.NONE;
}
for (int i = 0; i < size; i++) {
if (checkRow(i) != Mark.NONE) {
state = State.WIN;
return checkRow(i);
}
if (checkCol(i) != Mark.NONE) {
state = State.WIN;
return checkCol(i);
}
}
if (checkDiagNE() != Mark.NONE) {
state = State.WIN;
return checkDiagNE();
}
if (checkDiagNW() != Mark.NONE) {
state = State.WIN;
return checkDiagNW();
}
// not a win
if (isBoardFull()) {
state = State.DRAW;
return Mark.NONE;
}
state = State.PLAYING;
return Mark.NONE;
}
/**
* checks if the specified player has won
*
* @param player
* @return
*/
public boolean isWinFor(Player player) {
return (updateBoardState() == player.getMark());
}
}
/**
* CSCI 205 -Software Design and Engineering
* Name(s) Stefano Cobelli
*
* Work: Lab15
* Created: Oct 26, 2014, 9:29:32 PM
*/
package model;
import java.util.Scanner;
import model.Board.State;
/**
* The actual game class
*
* @author sjc032
*
*/
public class Game {
/** the board instance the game uses */
private Board theBoard;
/** array of two players */
private Player[] players;
/** index of the current player */
private int currentPlayer;
/** size of the board */
private int size;
/**
* initalizes the board and players
*/
public Game(int size) {
theBoard = new Board(size);
players = new Player[2];
players[0] = new Player(theBoard, Mark.X);
players[1] = new Player(theBoard, Mark.O);
currentPlayer = 0;
this.size = size;
}
/**
* plays a console game of TTT with 3x3
*/
public void playGame() {
Scanner sc = new Scanner(System.in);
String input = "";
String[] rowCol;
while (true) {
System.out.println(theBoard);
System.out.println(players[currentPlayer] + "\'s turn");
System.out
.println("Where should a mark be placed? (In \"row col\" fashion, space seperated, inclusive)");
input = sc.nextLine();
System.out.println();
// parsing
rowCol = input.split(" ");
if (input != "" && rowCol != null && rowCol.length == 2) {
try {
if (Integer.parseInt(rowCol[0]) < size
&& Integer.parseInt(rowCol[1]) < size) {
// game moves
if (players[currentPlayer].move(
Integer.parseInt(rowCol[0]),
Integer.parseInt(rowCol[1]))) {
if (!isPlayable()) {
if (getState() == State.DRAW) {
System.out.println("The game is a draw");
System.out.println(theBoard);
break;
} else if (isWinFor(players[currentPlayer])) {
System.out.println("The winner is "
+ players[currentPlayer]);
System.out.println(theBoard);
break;
}
} else
switchTurn();
}
else {
System.out.println("Spot seems taken, try again");
}
}
} catch (Exception e) {
System.out
.println("Coordinates couldn't be parsed, try again");
}
} else {
System.out.println("Coordinates didn't split right, try again");
}
}
sc.close();
}
/**
* main method
*/
public static void main(String[] args) {
Game game = new Game(3);
game.playGame();
}
/**
* @return the board
*/
public Board getBoard() {
return theBoard;
}
/**
* @return the size
*/
public int getSize() {
return size;
}
/**
* @return the current players turn as a string
*/
public String getPlayerTurn() {
return players[currentPlayer].toString();
}
/**
* @return the current player
*/
public Player getCurPlayer() {
return players[currentPlayer];
}
/**
* @return if playable
*/
public boolean isPlayable() {
return theBoard.isPlayable();
}
/**
* switches the turn; x goes to O, O goes to X
*/
public void switchTurn() {
if (currentPlayer == 0)
currentPlayer = 1;
else
currentPlayer = 0;
}
/**
* returns if the winner is the given player
*
* @param player
* @return if winner
*/
public boolean isWinFor(Player player) {
return theBoard.isWinFor(player);
}
/**
* returns the state of the board
*
* @return
*/
public State getState() {
return theBoard.getState();
}
/**
* clears the board and sets the player to X
*/
public void newGame() {
theBoard.clear();
currentPlayer = 0;
}
}
/**
* CSCI 205 -Software Design and Engineering
* Name(s) Stefano Cobelli
*
* Work: Lab15
* Created: Oct 26, 2014, 7:01:17 PM
*/
package model;
/**
* Mark of an x, o or an empty mark
*
* @author sjc032
*/
public enum Mark {
NONE("-"), X("X"), O("O");
/**
* String representation of the mark
*/
private String sign = "";
/**
* initializes the mark with a string representation
*
* @param sign
*/
private Mark(String sign) {
this.sign = sign;
}
/**
* gets the string representation of the mark
*/
public String getSign() {