Full java version of tic tac toe, with AI.
compliments of me.
TicTacToe.java
Code: Select all
import java.util.Random;
/**
*
* @Author : Andre van-Schalkwyk
* @Version : 8.19.05-19:18
*
*/
public class TicTacToe
{
private int spacesLeft; // int that hold the amount of spaces left on board.
private Random r; // random number generator.
private String game = ""; // string that displays game state.
private char[] board = new char[15]; // array that holds the char of specified space.
private char whosTurn = 'x'; // char detirmening whos turn it is.
private char[] winCon = new char[5];
private int[][] con = new int[9][4];
public TicTacToe(){ // TicTacToe constructor.
r = new Random();
spacesLeft = 9;
for(int a = 0;a < 15;a++){
board[a] = ' '; // inits the blank array.
}
winCon[0] = 'x';
winCon[1] = 'o';
con[0][0] = 0;
con[0][1] = 1;
con[0][2] = 2;
con[1][0] = 3;
con[1][1] = 4;
con[1][2] = 5;
con[2][0] = 6;
con[2][1] = 7;
con[2][2] = 8;
con[3][0] = 0;
con[3][1] = 3;
con[3][2] = 6;
con[4][0] = 1;
con[4][1] = 4;
con[4][2] = 7;
con[5][0] = 2;
con[5][1] = 5;
con[5][2] = 8;
con[6][0] = 0;
con[6][1] = 4;
con[6][2] = 8;
con[7][0] = 2;
con[7][1] = 4;
con[7][2] = 6;
} // end of constructor.
public String getMessage(){ // returns game state.
return game; // game is string containing game state.
} // end of function.
public void runAI(){ // AI function.
int temp = 0; // temp for position
int winO = 0; // position for victory execution.
int winX = 0; // position for victory prevention.
winX = isPlayerAboutToWin('x'); // assign prevention spot if one.
winO = isPlayerAboutToWin('o'); // assign execution spot if one.
boolean gameOver = false; // boolean to state of game is over.
gameOver = gameOver(); // see if game is over.
if(gameOver != true){ // check if game is over.
if(winO != 0 && spacesLeft >= 1){ // check if victory is possible
System.out.println("AI chooses: " + winO); // print chosen spot in console.
board[winO-1] = 'o'; // enter spot into array to win.
spacesLeft--; // decrease the number of open spaces.
nextTurn(); // go on and give human player back control.
}else if(winX != 0 && spacesLeft >= 1){ // check if defeat is possible
System.out.println("AI chooses: " + winX); // print chosen spot in console.
board[winX-1] = 'o'; // enter spot into array to foil defeat.
spacesLeft--; // check if mouse is on bottom of screen.
nextTurn(); // go on and give human player back control.
}else if(spacesLeft >= 1){ // see if spaces are available, happens when neither players can win.
temp = getRandomSlot(); // get a random spot to choose.
board[temp-1] = 'o'; // enter spot into array.
spacesLeft--; // decreast number of spots available.
nextTurn(); // go on and give human player back control.
}
}
gameOver = gameOver(); // get game state.
}
/**
* return x or o at certain spot
*
* @param : int whichOne
*
*
*/
public char getMark(int whichOne){ // returns the char value that is stored in array
return board[whichOne-1]; // return array value at certain spot.
} // end function.
private void nextTurn(){ // switches player control.
if(whosTurn == 'x'){ // basic switch around.
whosTurn = 'o'; // O's turn.
}else{
whosTurn = 'x'; // X's turn.
}
} // end function.
/**
*
* @param : int slot
*
* puts a x at slot.
*
*/
public boolean setMark(int slot){ // to assign 'x' to certain spot in array.
if(whosTurn == 'o'){ // make sure it is human players turn.
System.out.println("O's turn"); // if not display cause of denile.
}else if(board[slot] == ' ' && spacesLeft != 0){ // check if space is empty.
board[slot] = 'x'; // assign spot to array.
spacesLeft--; // decrease number of spots.
nextTurn(); // switch players.
runAI(); // execute AI.
return true; // return true.
}else{
System.out.println("Space is not vacant"); // else print that the space is taken.
return false; // return false;
}
return false;
} // end function.
/**
*
* starts a new game and resets variables.
*
*/
public void startNewGame(){ // new game function, resets critical game data.
spacesLeft = 9; // make all spaces available.
whosTurn = 'x'; // assign turn to human player.
for(int a = 0;a < 15;a++){
board[a] = ' '; // clear array.
}
game = ""; // make game message nothing.
} // end function.
/**
*
* to check if game if over,
* either by victory, defeat, or draw.
*
*/
public boolean gameOver(){ // function start.
char[] array = new char[15];
for(int a = 0;a < 15;a++){
array[a] = board[a]; // copy array over to temp array.
}
for(int a = 0;a <= 1;a++){ // loop for checking x and o
for(int b = 0;b <= 7;b++){ // loop for checking 8 possible win conditions.
// check if X won.
if(array[con[b][0]] == winCon[a] && array[con[b][1]] == winCon[a] && array[con[b][2]] == winCon[a]){
//System.out.println("X won"); // print "X won" to console.
game = winCon[a] + "X is the Winner!"; // make game state message "X won".
spacesLeft = 0; // make spaces 0.
return true; // return true.
}
}
}
if(spacesLeft == 0){ // check if the are not spaces left.
game = "Draw."; // assing "Draw" to game state string.
return true; // return true.
}
return false; // return false.
} // end function.
/**
* This method chooses a random slot for the computer to take.
*
* @return The number of the slot for the computer to take
*/
private int getRandomSlot(){
int go = r.nextInt(9) + 1; // get random int.
char[] array = new char[15];// create temp array.
for(int a = 0;a < 15;a++){
array[a] = board[a]; // copy array over.
}
if(array[go-1] != ' '){ // check if space was unavailable.
System.out.println("AI chooses: " + (go)); // display what spot was chosen.
System.out.println("that space was taken"); // display that it was not available.
} // end if.
while(array[go-1] != ' '){ // wile loop till open spot is chosen.
go = r.nextInt(9) + 1; // generate random int.
if(array[go-1] != ' '){ // check if space was unavailable.
System.out.println("AI chooses: " + (go)); // display what spot was chosen.
System.out.println("that space was taken"); // display that it was not available.
}
}
System.out.println("AI chooses: " + (go)); // display that it was available.
return go; // return chosen spot.
} // end function.
/**
* This method determines if the player is about to win
* @param mark Which player we are inquiring about (x or o)
* @return The space in which the player would win if they took
*/
private int isPlayerAboutToWin(char mark){
if(findOpen(0,1,2,mark) != 0)
return findOpen(0,1,2,mark); // return if victory is possible.
if(findOpen(3,4,5,mark) != 0)
return findOpen(3,4,5,mark); // return if victory is possible.
if(findOpen(6,7,8,mark) != 0)
return findOpen(6,7,8,mark); // return if victory is possible.
if(findOpen(0,3,6,mark) != 0)
return findOpen(0,3,6,mark); // return if victory is possible.
if(findOpen(1,4,7,mark) != 0)
return findOpen(1,4,7,mark); // return if victory is possible.
if(findOpen(2,5,8,mark) != 0)
return findOpen(2,5,8,mark); // return if victory is possible.
if(findOpen(0,4,8,mark) != 0)
return findOpen(0,4,8,mark); // return if victory is possible.
if(findOpen(2,4,6,mark) != 0)
return findOpen(2,4,6,mark); // return if victory is possible.
return 0; // return 0 is victory not possible.
} // end function.
/**
* This method finds the open space that if taken the given player would
* be the winner.
*
* @param one The first slot we are checking
* @param two The second slot we are checking
* @param three The third slot we are checking
* @param mark The player we are inquiring about (x or o)
*
* @return The open spot
*/
private int findOpen(int one, int two, int three, char mark){
char[] array = new char[15]; // create temp array.
for(int a = 0;a < 15;a++){
array[a] = board[a]; // store temp array.
}
if(array[one] == mark && array[two] == mark && array[three] == ' ') // check if victory is possible.
return three+1; // return slot for victory if possible.
if(array[one] == mark && array[two] == ' ' && array[three] == mark) // check if victory is possible.
return two+1; // return slot for victory if possible.
if(array[one] == ' ' && array[two] == mark && array[three] == mark) // check if victory is possible.
return one+1; // return slot for victory if possible.
return 0; // return 0 if victory not possible.
} // end function,
} // end class.
TicTacToeGUI.java
Code: Select all
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/**
* TicTacToeGUI.java
*
* This class creates a JFrame for the game to be viewed in
* and creates a TicTacToePanel object, which is added to
* the frame's container. JButtons for starting a new game
* and quitting are also created and given to the TicTacToePanel.
*
* This file DOES NOT need to be modified.
*
* @Author : Andre van-Schalkwyk
* @Version : 8.19.05-16:15
* @Program : TicTacToe
*
*/
public class TicTacToeGUI extends JFrame // the GUI
{
/** The textfield that shows the end of game message */
private JTextField message;
/** The button that will start a new game */
private JButton newGame;
/** The button that will exit the program */
private JButton quit;
/**
* This is the constructor, which initializes all
* intance variables and sets up the GUI
*/
public TicTacToeGUI(){ // constructor.
super("Tic-Tac-Toe"); // super name.
setSize(600,700); // setting the size.
setLocation(100,0); //nsetting the location.
setDefaultCloseOperation(EXIT_ON_CLOSE); // default close opperation.
Container c = getContentPane(); // container for objects.
message = new JTextField("", 20); // our text field.
newGame = new JButton("Start New Game"); // button to start new game.
quit = new JButton("Quit"); // button to quit program.
JPanel btnPanel = new JPanel(); // new panel.
btnPanel.setLayout(new GridLayout(1,2)); // set the layout.
btnPanel.add(newGame); // add the new game button.
btnPanel.add(quit); // add the quit game button.
JPanel bottom = new JPanel(); // bottom panel.
bottom.setLayout(new GridLayout(2,1)); // set layout.
bottom.add(btnPanel); // add the panel containing the buttons.
bottom.add(message); // add the message box to lower panel.
c.add(new TicTacToePanel(message, quit, newGame), BorderLayout.CENTER); // create the TicTacToe panel.
c.add(bottom, BorderLayout.SOUTH); // south border layout.
setVisible(true); // make it visible.
} // end of constructor.
/**
* This method starts the program.
* @param args Command Line arguments (not used)
*/
public static void main(String args[]){ // main of entire program
new TicTacToeGUI(); // new gui.
} // ends entire program.
} // ends the TicTacToeGUI class.
TicTacToePanel.java
Code: Select all
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/**
*
* @Description : The TicTacToePanel class contains all the listeners
* and event handlers. Also contains the graphical aspect of the
* program. Does minimal computation, just determains which block
* was chosen depending on what location the mouse was clicked at.
*
* @File : TicTacToePanel.java
* @Author : Andre van-Schalkwyk
* @Version : 8.19.05-18:12
*
* @Param m : JTextField for the game messages.
* @Param q : JButton for quit game.
* @Param n : JButton for new game.
*
*/
public class TicTacToePanel extends JPanel implements ActionListener, MouseListener // implements 2 listeners
{
public TicTacToe ttt = new TicTacToe(); // ttt contains all the functions to run the tic tac toe program
public JButton quitGame; // button reference for quit game.
public JButton newGame; // button reference fot new game.
public JTextField text; // text reference for messages.
public TicTacToePanel(JTextField m, JButton q, JButton n){ // starts TicTacToePanel object.
addMouseListener(this); // adds a listener for the mouse.
repaint(); // function to repaint the screen(panel).
quitGame = q; // reference to the quit game button.
newGame = n; // reference to the new game button.
text = m; // reference to the message text field.
q.addActionListener(this); // action listener for quit game button.
n.addActionListener(this); // action listener for new game button.
}
/**
* This method paints the graphics in the window
* @param g The graphics object that does the painting
*/
public void paint(Graphics g){
super.paint(g);
paintBoard(g);
paintMark(g,ttt.getMark(1), 1);
paintMark(g,ttt.getMark(2), 2);
paintMark(g,ttt.getMark(3), 3);
paintMark(g,ttt.getMark(4), 4);
paintMark(g,ttt.getMark(5), 5);
paintMark(g,ttt.getMark(6), 6);
paintMark(g,ttt.getMark(7), 7);
paintMark(g,ttt.getMark(8), 8);
paintMark(g,ttt.getMark(9), 9);
}
/**
* This method paints all the marks on the board
* @param g The graphics object that does the painting
* @param c The character to paint (x or o)
* @param slot The slot in which to paint the mark
*/
public void paintMark(Graphics g, char c, int slot){
slot--;
int x = (slot % 3);
int y = slot / 3;
if(c == 'x')
{
g.drawLine(x*200,y*200,x*200+200, y*200+200);
g.drawLine(x*200+200,y*200,x*200, y*200+200);
}
else if(c == 'o')
{
g.drawOval(x*200,y*200,200,200);
}
}
/**
* This method paints the lines that make up the board.
* @param g The graphics object that does the painting
*/
public void paintBoard(Graphics g){
g.drawLine(200,0,200,600);
g.drawLine(400,0,400,600);
g.drawLine(0,200,600,200);
g.drawLine(0,400,600,400);
}
/**
*
* @Param e : action event.
* @Description : to translate the event and to proceed acoordingly.
*
*/
public void actionPerformed(ActionEvent e){
Object source = e.getSource(); // take event and convert to understandible object.
if (source == quitGame){ // check if quitGame button was pressed.
System.out.println("Program Ended"); // print "Program Ended" in console.
System.exit(0); // end program.
} // end if.
if (source == newGame){ // check if newGame button was pressed.
System.out.println("New Game"); // print "New Game" in consloe.
ttt.startNewGame(); // start a new game.
text.setText(ttt.getMessage()); // display game state message.
repaint(); // repaint the screen.
} // end if.
repaint(); // repaint the screen.
}
public void mouseClicked(MouseEvent e){
int x = 0; // create int x variable for holding mouse x coordinate.
int y = 0; // create int y variable for holding mouse y coordinate.
int block = 0; // create int block to store sector of mouse.
x = e.getX(); // assign mouse x coordinate to x.
y = e.getY(); // assing mouse y coordinate to y.
if(x < 200){ // check if mouse is on left of screen.
if(y < 200){ // check if mouse is on top of screen.
block = 1; // assing sector 1.
}
if(y > 200 && y < 400){ // check if mouse is in middle vertically on screen.
block = 4; // assign sector 4.
}
if(y > 400){ // check if mouse is on bottom of screen.
block = 7; // assign sector 7.
}
}
if(x > 200 && x < 400){ // check if mouse is in the middle, horizontally on screen.
if(y < 200){ // check if mouse is on top of screen.
block = 2; // assing sector 2.
}
if(y > 200 && y < 400){ // check if mouse is in middle vertically on screen.
block = 5; // assing sector 5.
}
if(y > 400){ // check if mouse is on bottom of screen.
block = 8; // assing sector 8.
}
}
if(x > 400){ // check if mouse is right on screen.
if(y < 200){ // check if mouse is on top of screen.
block = 3; // assing sector 3.
}
if(y > 200 && y < 400){ // check if mouse is in middle vertically on screen.
block = 6; // assing sector 6.
}
if(y > 400){ // check if mouse is on bottom of screen.
block = 9; // assing sector 9.
}
}
boolean gameOver = false; // create boolean gameOver.
gameOver = ttt.gameOver(); // get the game state and assign it to gameOver.
if(gameOver != true){ // checks if the game is over, continues if false
ttt.setMark(block-1); // sets a 'x' at the location clicked.
// (-1 there because arrays start at zero [0]).
}
text.setText(ttt.getMessage()); // display the game state message in the text field.
repaint(); // repaint the screen(Panel).
}
public void mouseEntered(MouseEvent e)
{
// not used
//repaint();
}
public void mouseExited(MouseEvent e)
{
// not used
}
public void mousePressed(MouseEvent e)
{
// not used
}
public void mouseReleased(MouseEvent e)
{
// not used
}
}