Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.awt.*;
- import java.awt.event.*;
- import java.util.Random;
- import javax.swing.*;
- public class Othello {
- public static void main(String[] args) {
- OthelloJFrame frame = new OthelloJFrame();
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- // Set to a reasonable size.
- frame.setSize(1024, 768);
- frame.setVisible(true);
- }
- }
- class OthelloJFrame extends JFrame implements ActionListener {
- /**
- * Program: Othello.java
- * Purpose: Popular board game, human vs human, human vs computer
- * Creator: Chris Clarke
- * Created: 02/12/2006
- * Note: Also known as Reversi.
- */
- Button btnGo;
- JLabel lbl;
- JPanel panel;
- int[][] board;
- int rowChosen, colChosen;
- int colourToPlay;
- boolean calculating=false;
- boolean gameOver=false;
- boolean whiteCantGo, blackCantGo;
- public static final int EMPTY = -1;
- public static final int BLACK = 0;
- public static final int WHITE = 1;
- public static final int BOARDTOPLEFTX = 100;
- public static final int BOARDTOPLEFTY = 100;
- public static final int BOARDSIZE = 480; // 60 * 8
- public static final int SQUARESIZE = 60;
- public OthelloJFrame() {
- setTitle("Othello by Chris Clarke");
- setLayout(new BorderLayout());
- // Build control panel.
- panel = new JPanel();
- panel.setLayout(new FlowLayout());
- btnGo = new Button("Computer Goes");
- btnGo.addActionListener(this);
- panel.add(btnGo);
- lbl = new JLabel("Press space bar");
- panel.add(lbl);
- add(panel, BorderLayout.NORTH);
- // initialise board
- board = new int[8][8];
- initBoard();
- this.setFocusable(true);
- this.addMouseListener(new MouseAdapter() {
- public void mouseClicked(MouseEvent e) {
- mClicked( e.getX(), e.getY());
- }
- public void mousePressed(MouseEvent e) {}
- public void mouseReleased(MouseEvent e) {}
- public void mouseEntered(MouseEvent e) {}
- public void mouseExited(MouseEvent e) {}
- });
- } // OthelloJFrame
- public void initBoard() {
- for (int row=0; row<8; row++)
- for (int col=0; col<8; col++)
- board[row][col]=EMPTY; // empty square
- board[3][3]=WHITE;
- board[4][4]=WHITE;
- board[3][4]=BLACK;
- board[4][3]=BLACK;
- colourToPlay=BLACK;
- gameOver=false;
- whiteCantGo=false;
- blackCantGo=false;
- } // initBoard
- public void paint(Graphics g) {
- // do graphics
- AddLeadingSpace a = new AddLeadingSpace();
- // clrscr
- g.setColor(Color.WHITE);
- g.fillRect(0, 0, 1024, 768);
- // draw board
- g.setColor(Color.GREEN);
- g.fillRect(BOARDTOPLEFTX, BOARDTOPLEFTY, BOARDSIZE, BOARDSIZE);
- // draw grid
- g.setColor(Color.BLACK);
- for (int row=0; row<9; row++)
- g.drawLine(BOARDTOPLEFTX, BOARDTOPLEFTY+row*SQUARESIZE,
- BOARDTOPLEFTX+BOARDSIZE, BOARDTOPLEFTY+row*SQUARESIZE);
- for (int col=0; col<9; col++)
- g.drawLine(BOARDTOPLEFTX+col*SQUARESIZE, BOARDTOPLEFTY,
- BOARDTOPLEFTX+col*SQUARESIZE, BOARDTOPLEFTY+BOARDSIZE);
- // draw disks & count them
- int w=0, b=0;
- for (int row=0; row<8; row++) {
- for (int col=0; col<8; col++) {
- if (board[row][col]==WHITE) {
- g.setColor(Color.WHITE);
- g.fillOval(BOARDTOPLEFTX+col*SQUARESIZE,
- BOARDTOPLEFTY+row*SQUARESIZE, 60,60);
- w++;
- } else if (board[row][col]==BLACK) {
- g.setColor(Color.BLACK);
- g.fillOval(BOARDTOPLEFTX+col*SQUARESIZE,
- BOARDTOPLEFTY+row*SQUARESIZE, 60,60);
- b++;
- }
- }
- }
- g.setFont(new Font("Arial", Font.BOLD, 36));
- g.setColor(Color.BLACK);
- g.drawOval(BOARDTOPLEFTX+BOARDSIZE+2*SQUARESIZE,
- BOARDTOPLEFTY+0*SQUARESIZE, 60,60);
- g.drawString(a.addSpace(w), BOARDTOPLEFTX+BOARDSIZE+4*SQUARESIZE,
- BOARDTOPLEFTY+1*SQUARESIZE);
- g.fillOval(BOARDTOPLEFTX+BOARDSIZE+2*SQUARESIZE,
- BOARDTOPLEFTY+2*SQUARESIZE, 60,60);
- g.drawString(a.addSpace(b), BOARDTOPLEFTX+BOARDSIZE+4*SQUARESIZE,
- BOARDTOPLEFTY+3*SQUARESIZE);
- // delete colour to play message
- g.setColor(Color.WHITE);
- g.fillRect(BOARDTOPLEFTX+BOARDSIZE+50, BOARDTOPLEFTY+5*SQUARESIZE,
- 200, 200);
- if (b+w==8*8||(whiteCantGo&&blackCantGo)) {
- if (w>b)
- gameOver(g, "White Wins!");
- else if (b>w)
- gameOver(g, "Black Wins!");
- else
- gameOver(g, "It\'s a Draw!");
- } else {
- g.setColor(Color.BLACK);
- if (colourToPlay==WHITE)
- g.drawString("It\'s White's turn",
- BOARDTOPLEFTX+BOARDSIZE+50, BOARDTOPLEFTY+5*SQUARESIZE);
- else
- g.drawString("It\'s Black's turn",
- BOARDTOPLEFTX+BOARDSIZE+50, BOARDTOPLEFTY+5*SQUARESIZE);
- }
- } // paint
- public void gameOver(Graphics g, String s) {
- // display game over message
- g.setFont(new Font("Arial", Font.BOLD, 60));
- g.setColor(Color.RED);
- g.drawString("Game Over! "+s, BOARDTOPLEFTX, BOARDTOPLEFTY+BOARDSIZE+100);
- gameOver = true;
- } // gameOver
- public int captured() {
- // look in all 8 directions, count number of disks captured
- int c=colChosen;
- int r=rowChosen;
- int myColour, oppColour;
- int disksCaptured=0;
- int counter=0;
- if (colourToPlay==WHITE) {
- myColour=WHITE;
- oppColour=BLACK;
- } else {
- myColour=BLACK;
- oppColour=WHITE;
- }
- // must be an empty square
- if (board[r][c]!=EMPTY)
- return 0;
- // left
- while (c>0) {
- c--;
- if (board[r][c]==EMPTY)
- // discontinue this direction
- break;
- if (board[r][c]==myColour) {
- if (counter==0)
- break;
- else {
- for (int i=colChosen-1; i>c; i--)
- if (!calculating)
- board[r][i]=myColour;
- disksCaptured+=counter;
- break;
- }
- } else
- counter++;
- }
- counter=0;
- c=colChosen;
- // right
- while (c<7) {
- c++;
- if (board[r][c]==EMPTY)
- // discontinue this direction
- break;
- if (board[r][c]==myColour) {
- if (counter==0)
- break;
- else {
- for (int i=colChosen+1; i<c; i++)
- if (!calculating)
- board[r][i]=myColour;
- disksCaptured+=counter;
- break;
- }
- } else
- counter++;
- }
- counter=0;
- c=colChosen;
- // up
- while (r>0) {
- r--;
- if (board[r][c]==EMPTY)
- // discontinue this direction
- break;
- if (board[r][c]==myColour) {
- if (counter==0)
- break;
- else {
- for (int i=rowChosen-1; i>r; i--)
- if (!calculating)
- board[i][c]=myColour;
- disksCaptured+=counter;
- break;
- }
- } else
- counter++;
- }
- counter=0;
- r=rowChosen;
- // down
- while (r<7) {
- r++;
- if (board[r][c]==EMPTY)
- // discontinue this direction
- break;
- if (board[r][c]==myColour) {
- if (counter==0)
- break;
- else {
- for (int i=rowChosen+1; i<r; i++)
- if (!calculating)
- board[i][c]=myColour;
- disksCaptured+=counter;
- break;
- }
- } else
- counter++;
- }
- counter=0;
- r=rowChosen;
- // left and up diagonal
- while ((c>0)&&(r>0)) {
- c--;
- r--;
- if (board[r][c]==EMPTY)
- // discontinue this direction
- break;
- if (board[r][c]==myColour) {
- if (counter==0)
- break;
- else {
- int temp=rowChosen-1;
- for (int i=colChosen-1; i>c; i--)
- if (!calculating)
- board[temp--][i]=myColour;
- disksCaptured+=counter;
- break;
- }
- } else
- counter++;
- }
- counter=0;
- r=rowChosen;
- c=colChosen;
- // right and up diagonal
- while ((c<7)&&(r>0)) {
- c++;
- r--;
- if (board[r][c]==EMPTY)
- // discontinue this direction
- break;
- if (board[r][c]==myColour) {
- if (counter==0)
- break;
- else {
- int temp=rowChosen-1;
- for (int i=colChosen+1; i<c; i++)
- if (!calculating)
- board[temp--][i]=myColour;
- disksCaptured+=counter;
- break;
- }
- } else
- counter++;
- }
- counter=0;
- r=rowChosen;
- c=colChosen;
- // left and down diagonal
- while ((c>0)&&(r<7)) {
- c--;
- r++;
- if (board[r][c]==EMPTY)
- // discontinue this direction
- break;
- if (board[r][c]==myColour) {
- if (counter==0)
- break;
- else {
- int temp=rowChosen+1;
- for (int i=colChosen-1; i>c; i--)
- if (!calculating)
- board[temp++][i]=myColour;
- disksCaptured+=counter;
- break;
- }
- } else
- counter++;
- }
- counter=0;
- r=rowChosen;
- c=colChosen;
- // right and down diagonal
- while ((c<7)&&(r<7)) {
- c++;
- r++;
- if (board[r][c]==EMPTY)
- // discontinue this direction
- break;
- if (board[r][c]==myColour) {
- if (counter==0)
- break;
- else {
- int temp=rowChosen+1;
- for (int i=colChosen+1; i<c; i++)
- if (!calculating)
- board[temp++][i]=myColour;
- disksCaptured+=counter;
- break;
- }
- } else
- counter++;
- }
- return disksCaptured;
- } // captured
- public void makeComputerMove() {
- // simple heuristic chooses maximum captures
- // Allow random element when there is a choice of moves of equal value
- Random r = new Random();
- calculating=true; // so no disks change colour
- int maxRow=-1, maxCol=-1, maxPoints=0;
- for (int row=0; row<8; row++) {
- for (int col=0; col<8; col++) {
- rowChosen=row;
- colChosen=col;
- int points = captured();
- if (points>maxPoints) {
- maxRow=rowChosen;
- maxCol=colChosen;
- maxPoints=points;
- } else if ((points==maxPoints) && (r.nextInt(2)==1)) {
- // 50% chance of r.Random(2) being 1
- maxRow=rowChosen;
- maxCol=colChosen;
- maxPoints=points;
- }
- }
- }
- if (maxPoints>0) {
- // a move was chosen
- calculating=false; // so disks change colour
- rowChosen=maxRow;
- colChosen=maxCol;
- captured(); // turn over captured disks
- // put disk on board
- board[rowChosen][colChosen] = colourToPlay;
- } else {
- if (colourToPlay==WHITE)
- whiteCantGo = true;
- else
- blackCantGo = true;
- }
- // change colour to play
- if (colourToPlay == WHITE)
- colourToPlay = BLACK;
- else
- colourToPlay = WHITE;
- repaint();
- } // makeComputerMove
- public boolean mClicked(int x, int y) {
- // register the square clicked on
- if (gameOver) return false;
- // if outside the board
- if ((x<BOARDTOPLEFTX)||(x>BOARDTOPLEFTX+BOARDSIZE)
- ||(y<BOARDTOPLEFTY)||(y>BOARDTOPLEFTY+BOARDSIZE))
- return false;
- for (int row=0; row<8; row++)
- if ((y-BOARDTOPLEFTY)/SQUARESIZE==row)
- rowChosen=row;
- for (int col=0; col<8; col++)
- if ((x-BOARDTOPLEFTX)/SQUARESIZE==col)
- colChosen=col;
- if (captured()>0) {
- // put disk on board
- board[rowChosen][colChosen] = colourToPlay;
- // change colour to play
- if (colourToPlay == WHITE)
- colourToPlay = BLACK;
- else
- colourToPlay = WHITE;
- repaint();
- }
- return true;
- } // mClicked
- public void actionPerformed(ActionEvent e) {
- if (e.getSource() == btnGo)
- if (!gameOver) makeComputerMove();
- } // actionPerformed
- } // class
- class AddLeadingSpace {
- /* Display numbers < 10 with a leading space
- * By Chris Clarke, February 2006
- */
- String addSpace(int n) {
- return n<10?" "+n:""+n;
- }
- } // class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement