Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Main.java
- import javax.swing.JFrame; // for creating windows
- public class Main {
- public static void main(String[] args) {
- JFrame window= new JFrame();
- window.setSize(800, 600);
- window.setTitle("Tic-tac-toe");
- window.setVisible(true);
- window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- Board board= new Board();
- window.add(board);
- }
- }
- //Board.java
- import javax.swing.*;
- import javax.swing.event.MouseInputListener;
- import java.awt.*; // wildcard first level only
- import java.awt.event.MouseEvent;
- import java.awt.event.MouseListener;
- import java.awt.geom.*; // drawing
- //import java.awt.event.*;
- public class Board extends JComponent implements MouseListener, MouseInputListener{
- // the board contains the 9 cells which need drawn
- public Cell[] cells = new Cell[9];
- // status is the message on the bottom of the window
- public String status= "Player X's move";
- // move determines whose turn it is
- public String move="X";
- public Board()
- {
- int x,y, xlower, xupper, ylower, yupper;
- for (int i=0; i<3; i++)
- {
- for (int j=0; j<3; j++)
- {
- x=276+i*100; // where the marker is to be put
- y=224+j*100;
- xlower= 250+i*100; // top left corner of area
- ylower= 150+j*100;
- xupper= 350+i*100; // bottom right corner of area
- yupper= 250+j*100;
- // Cells need to be created now to allow for screen refreshes
- this.cells[i+j*3]=new Cell(x,y,xlower,ylower,xupper,yupper,"");
- }
- }
- addMouseListener(this); // adds listener to cover the entire board (screen)
- }
- /* method paintConponent
- * inherited from JComponent
- * non-Javadoc)
- * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
- */
- public void paintComponent(Graphics g)
- {
- Graphics2D g2= (Graphics2D) g;
- // create background
- g2.setColor(Color.BLUE);
- g2.fillRect(0, 0, this.getWidth(), this.getHeight());
- g2.setColor(Color.WHITE);
- // first vertical line of board
- Line2D.Double v1=new Line2D.Double(350, 150, 350, 450);
- g2.draw(v1);
- // second vertical line of board
- Line2D.Double v2=new Line2D.Double(450, 150, 450, 450);
- g2.draw(v2);
- // first horizontal line of board
- Line2D.Double h1=new Line2D.Double(250, 250, 550, 250);
- g2.draw(h1);
- // second horizontal line of board
- Line2D.Double h2=new Line2D.Double(250, 350, 550, 350);
- g2.draw(h2);
- // creating the content for the 9 cells;
- Font text= new Font("serif", Font.BOLD, 72);
- g2.setFont(text);
- for (int i=0; i<9; i++)
- {
- // type-casting required as drawstring required ints while x and y in cells are doubles
- g2.drawString(this.cells[i].getContent(), (int)this.cells[i].getx(), (int)this.cells[i].gety());
- }
- // change font for bottom text
- Font textstatus= new Font("serif", Font.PLAIN, 16);
- g2.setFont(textstatus);
- g2.drawString(status, 350, 550);
- }
- /*
- * function ValidMove
- * paramters: id (int)
- * determines if the selected move is legal
- * returns boolean
- */
- public boolean ValidMove(int id)
- {
- // check if id is out of range, which would otherwise cause out of bounds error (shouldn't ever be the case)
- if (id>8 || id<0) return false;
- // make sure the selected cell hasn't already been taken
- if (this.cells[id].getContent()!="") return false;
- // if neither of these tests fail, the move is valid
- return true;
- }
- /*
- * function GameState
- * parameters: none
- * determines the current state of the game
- * returns int (0=ongoing, 1=X wins, 2=O wins, 3=drawn)
- */
- public int GameState()
- {
- // standard iterator
- int i=0;
- // WinCombos is a 2D array showing the 8 possible ways of winning
- int[][] WinCombos= {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,3,8},{0,4,8},{2,4,6}};
- // iterate through the above array
- for (i=0; i<8; i++)
- {
- // these 2 if statements should be combined, but this way leads to shorter lines
- if (this.cells[WinCombos[i][0]].getContent()==this.cells[WinCombos[i][1]].getContent())
- {
- if (this.cells[WinCombos[i][0]].getContent()==this.cells[WinCombos[i][2]].getContent())
- {
- // if it's got in here, then one of the winning combos has happened, check who won
- if (this.cells[WinCombos[i][0]].getContent()=="X") return 1; // player X wins
- if (this.cells[WinCombos[i][0]].getContent()=="O") return 2; // player O wins
- }
- }
- }
- // if no-one has won, is the game still ongoing?
- for (i=0; i<9; i++)
- {
- if (this.cells[i].getContent()=="") return 0; // game still in progress
- }
- return 3; // game drawn
- }
- // required by interface, but not used
- @Override
- public void mouseDragged(MouseEvent arg0) {
- // TODO Auto-generated method stub
- }
- // required by interface, but not used
- @Override
- public void mouseMoved(MouseEvent arg0) {
- // TODO Auto-generated method stub
- }
- // this function is where the game does whatever it has to do for each turn.
- @Override
- public void mouseClicked(MouseEvent e) {
- // TODO Auto-generated method stub
- // find where on the screen the click heppened
- double x=e.getX();
- double y=e.getY();
- int state;
- if (this.GameState()==0)
- {
- for (int i=0; i<9; i++)
- {
- // check each region to see if the click happened inside one of the cells
- // using > and < rather than >= and <= to guard against selecting the wrong cell
- if(x>this.cells[i].getxlower() && x<this.cells[i].getxupper())
- {
- // this if could be combined with the above, but neater this way
- if (y>this.cells[i].getylower() && y<this.cells[i].getyupper())
- {
- // we have found the cell clicked, now see if move is valid
- if (this.ValidMove(i))
- {
- // change the content of the cell
- this.cells[i].setContent(move);
- // switch turns
- if (move=="X") move="O";
- else move="X";
- // check the current state of the game
- state=this.GameState();
- if (state==1)
- {
- // player X has won
- status="Player X wins";
- }
- else if (state==2)
- {
- // player O has won
- status="Player O wins";
- }
- else if (state==3)
- {
- // all moves have been made, no winner
- status="Draw";
- }
- else
- {
- // game still ongoing
- status="Player "+move+"\'s move.";
- }
- // refreshes the screen
- repaint();
- // prevent any more iterations to save processing time, they would be false anyway
- break;
- }
- }
- }
- }
- }
- }
- // required by interface, but not used
- @Override
- public void mouseEntered(MouseEvent arg0) {
- // TODO Auto-generated method stub
- }
- // required by interface, but not used
- @Override
- public void mouseExited(MouseEvent arg0) {
- // TODO Auto-generated method stub
- }
- // required by interface, but not used
- @Override
- public void mousePressed(MouseEvent arg0) {
- // TODO Auto-generated method stub
- }
- // required by interface, but not used
- @Override
- public void mouseReleased(MouseEvent arg0) {
- // TODO Auto-generated method stub
- }
- }
- //Cell.java
- import java.awt.event.MouseEvent;
- import java.awt.event.MouseListener;
- import javax.swing.event.MouseInputListener;
- public class Cell{
- private String content;
- private double x;
- private double y;
- private double xlower;
- private double ylower;
- private double xupper;
- private double yupper;
- /* constructor Cell:
- * parameters:-
- * x: x co-ordinate for the text
- * y: y-co-ordinate for the text
- * xlower: the lower x bound for the cell
- * ylower: the lower y bound for the cell
- * xupper: the upper x bound for the cell
- * yupper: the upper y bound for the cell
- * text: what the cell should display
- *
- */
- public Cell(double x, double y, double xlower, double ylower, double xupper, double yupper, String text)
- {
- this.x=x;
- this.y=y;
- this.xlower=xlower;
- this.ylower=ylower;
- this.xupper=xupper;
- this.yupper=yupper;
- this.content=text;
- }
- public void setx(double x)
- {
- this.x=x;
- }
- public double getx()
- {
- return this.x;
- }
- public void sety(double y)
- {
- this.y=y;
- }
- public double gety()
- {
- return this.y;
- }
- public void setContent(String text)
- {
- this.content=text;
- }
- public String getContent()
- {
- return this.content;
- }
- // upper and lower bounds are never changed hence no setter function
- public double getxlower()
- {
- return this.xlower;
- }
- public double getylower()
- {
- return this.ylower;
- }
- public double getxupper()
- {
- return this.xupper;
- }
- public double getyupper()
- {
- return this.yupper;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement