Advertisement
brilliant_moves

Othello.java

Sep 11th, 2012
290
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5 10.86 KB | None | 0 0
  1. import java.awt.*;
  2. import java.awt.event.*;
  3. import java.util.Random;
  4. import javax.swing.*;
  5.  
  6. public class Othello {
  7.  
  8.     public static void main(String[] args) {
  9.         OthelloJFrame frame = new OthelloJFrame();
  10.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  11.         // Set to a reasonable size.
  12.         frame.setSize(1024, 768);
  13.         frame.setVisible(true);
  14.     }
  15. }
  16.  
  17. class OthelloJFrame extends JFrame implements ActionListener {
  18.  
  19.     /**
  20.     *   Program:    Othello.java
  21.     *   Purpose:    Popular board game, human vs human, human vs computer
  22.     *   Creator:    Chris Clarke
  23.     *   Created:    02/12/2006
  24.     *   Note:       Also known as Reversi.
  25.     */ 
  26.  
  27.     Button          btnGo;
  28.     JLabel          lbl;
  29.     JPanel          panel;
  30.     int[][]         board;
  31.     int         rowChosen, colChosen;
  32.     int         colourToPlay;
  33.     boolean         calculating=false;
  34.     boolean         gameOver=false;
  35.     boolean         whiteCantGo, blackCantGo;
  36.     public static final int EMPTY = -1;
  37.     public static final int BLACK = 0;
  38.     public static final int WHITE = 1;
  39.     public static final int BOARDTOPLEFTX = 100;
  40.     public static final int BOARDTOPLEFTY = 100;
  41.     public static final int BOARDSIZE = 480;    // 60 * 8
  42.     public static final int SQUARESIZE = 60;
  43.    
  44.     public OthelloJFrame() {
  45.         setTitle("Othello by Chris Clarke");
  46.         setLayout(new BorderLayout());
  47.  
  48.         // Build control panel.
  49.         panel = new JPanel();
  50.         panel.setLayout(new FlowLayout());
  51.  
  52.         btnGo = new Button("Computer Goes");
  53.         btnGo.addActionListener(this);
  54.         panel.add(btnGo);
  55.  
  56.         lbl = new JLabel("Press space bar");
  57.         panel.add(lbl);
  58.         add(panel, BorderLayout.NORTH);
  59.  
  60.         // initialise board
  61.         board = new int[8][8];
  62.         initBoard();
  63.         this.setFocusable(true);
  64.             this.addMouseListener(new MouseAdapter() {
  65.                     public void mouseClicked(MouseEvent e) {
  66.                         mClicked( e.getX(), e.getY());
  67.             }
  68.  
  69.                     public void mousePressed(MouseEvent e) {}
  70.  
  71.                     public void mouseReleased(MouseEvent e) {}
  72.  
  73.                     public void mouseEntered(MouseEvent e) {}
  74.  
  75.                     public void mouseExited(MouseEvent e) {}
  76.  
  77.         });
  78.     } // OthelloJFrame
  79.  
  80.     public void initBoard() {
  81.         for (int row=0; row<8; row++)
  82.             for (int col=0; col<8; col++)
  83.                 board[row][col]=EMPTY;  // empty square
  84.         board[3][3]=WHITE;
  85.         board[4][4]=WHITE;
  86.         board[3][4]=BLACK;
  87.         board[4][3]=BLACK;
  88.  
  89.         colourToPlay=BLACK;
  90.         gameOver=false;
  91.         whiteCantGo=false;
  92.         blackCantGo=false;
  93.     } // initBoard
  94.  
  95.     public void paint(Graphics g) {
  96.         // do graphics
  97.  
  98.         AddLeadingSpace a = new AddLeadingSpace();
  99.  
  100.         // clrscr
  101.         g.setColor(Color.WHITE);
  102.         g.fillRect(0, 0, 1024, 768);
  103.  
  104.         // draw board
  105.         g.setColor(Color.GREEN);
  106.         g.fillRect(BOARDTOPLEFTX, BOARDTOPLEFTY, BOARDSIZE, BOARDSIZE);
  107.         // draw grid
  108.         g.setColor(Color.BLACK);
  109.         for (int row=0; row<9; row++)
  110.             g.drawLine(BOARDTOPLEFTX, BOARDTOPLEFTY+row*SQUARESIZE,
  111.              BOARDTOPLEFTX+BOARDSIZE, BOARDTOPLEFTY+row*SQUARESIZE);
  112.         for (int col=0; col<9; col++)
  113.             g.drawLine(BOARDTOPLEFTX+col*SQUARESIZE, BOARDTOPLEFTY,
  114.              BOARDTOPLEFTX+col*SQUARESIZE, BOARDTOPLEFTY+BOARDSIZE);
  115.         // draw disks & count them
  116.         int w=0, b=0;
  117.         for (int row=0; row<8; row++) {
  118.             for (int col=0; col<8; col++) {
  119.                 if (board[row][col]==WHITE) {
  120.                     g.setColor(Color.WHITE);
  121.                     g.fillOval(BOARDTOPLEFTX+col*SQUARESIZE,
  122.                      BOARDTOPLEFTY+row*SQUARESIZE, 60,60);
  123.                     w++;
  124.                 } else if (board[row][col]==BLACK) {
  125.                     g.setColor(Color.BLACK);
  126.                     g.fillOval(BOARDTOPLEFTX+col*SQUARESIZE,
  127.                      BOARDTOPLEFTY+row*SQUARESIZE, 60,60);
  128.                     b++;
  129.                 }
  130.             }
  131.         }
  132.  
  133.         g.setFont(new Font("Arial", Font.BOLD, 36));
  134.         g.setColor(Color.BLACK);
  135.         g.drawOval(BOARDTOPLEFTX+BOARDSIZE+2*SQUARESIZE,
  136.          BOARDTOPLEFTY+0*SQUARESIZE, 60,60);
  137.  
  138.         g.drawString(a.addSpace(w), BOARDTOPLEFTX+BOARDSIZE+4*SQUARESIZE,
  139.          BOARDTOPLEFTY+1*SQUARESIZE);
  140.         g.fillOval(BOARDTOPLEFTX+BOARDSIZE+2*SQUARESIZE,
  141.          BOARDTOPLEFTY+2*SQUARESIZE, 60,60);
  142.         g.drawString(a.addSpace(b), BOARDTOPLEFTX+BOARDSIZE+4*SQUARESIZE,
  143.          BOARDTOPLEFTY+3*SQUARESIZE);
  144.  
  145.         // delete colour to play message
  146.         g.setColor(Color.WHITE);
  147.         g.fillRect(BOARDTOPLEFTX+BOARDSIZE+50, BOARDTOPLEFTY+5*SQUARESIZE,
  148.          200, 200);
  149.         if (b+w==8*8||(whiteCantGo&&blackCantGo)) {
  150.             if (w>b)
  151.                 gameOver(g, "White Wins!");
  152.             else if (b>w)
  153.                 gameOver(g, "Black Wins!");
  154.             else
  155.                 gameOver(g, "It\'s a Draw!");
  156.         } else {
  157.             g.setColor(Color.BLACK);
  158.             if (colourToPlay==WHITE)
  159.                 g.drawString("It\'s White's turn",
  160.                  BOARDTOPLEFTX+BOARDSIZE+50, BOARDTOPLEFTY+5*SQUARESIZE);
  161.             else
  162.                 g.drawString("It\'s Black's turn",
  163.                  BOARDTOPLEFTX+BOARDSIZE+50, BOARDTOPLEFTY+5*SQUARESIZE);
  164.         }
  165.     } // paint
  166.  
  167.     public void gameOver(Graphics g, String s) {
  168.         // display game over message
  169.         g.setFont(new Font("Arial", Font.BOLD, 60));
  170.         g.setColor(Color.RED);
  171.         g.drawString("Game Over! "+s, BOARDTOPLEFTX, BOARDTOPLEFTY+BOARDSIZE+100);
  172.         gameOver = true;
  173.     } // gameOver
  174.  
  175.     public int captured() {
  176.         // look in all 8 directions, count number of disks captured
  177.         int c=colChosen;
  178.         int r=rowChosen;
  179.         int myColour, oppColour;
  180.         int disksCaptured=0;
  181.         int counter=0;
  182.         if (colourToPlay==WHITE) {
  183.             myColour=WHITE;
  184.             oppColour=BLACK;
  185.         } else {
  186.             myColour=BLACK;
  187.             oppColour=WHITE;
  188.         }
  189.         // must be an empty square
  190.         if (board[r][c]!=EMPTY)
  191.             return 0;
  192.         // left
  193.         while (c>0) {
  194.             c--;
  195.             if (board[r][c]==EMPTY)
  196.                 // discontinue this direction
  197.                 break;
  198.             if (board[r][c]==myColour) {
  199.                 if (counter==0)
  200.                     break;
  201.                 else {
  202.                     for (int i=colChosen-1; i>c; i--)
  203.                         if (!calculating)
  204.                             board[r][i]=myColour;
  205.                     disksCaptured+=counter;
  206.                     break;
  207.                 }
  208.             } else
  209.                 counter++;
  210.         }
  211.         counter=0;
  212.         c=colChosen;
  213.         // right
  214.         while (c<7) {
  215.             c++;
  216.             if (board[r][c]==EMPTY)
  217.                 // discontinue this direction
  218.                 break;
  219.             if (board[r][c]==myColour) {
  220.                 if (counter==0)
  221.                     break;
  222.                 else {
  223.                     for (int i=colChosen+1; i<c; i++)
  224.                         if (!calculating)
  225.                             board[r][i]=myColour;
  226.                     disksCaptured+=counter;
  227.                     break;
  228.                 }
  229.             } else
  230.                 counter++;
  231.         }
  232.         counter=0;
  233.         c=colChosen;
  234.         // up
  235.         while (r>0) {
  236.             r--;
  237.             if (board[r][c]==EMPTY)
  238.                 // discontinue this direction
  239.                 break;
  240.             if (board[r][c]==myColour) {
  241.                 if (counter==0)
  242.                     break;
  243.                 else {
  244.                     for (int i=rowChosen-1; i>r; i--)
  245.                         if (!calculating)
  246.                             board[i][c]=myColour;
  247.                     disksCaptured+=counter;
  248.                     break;
  249.                 }
  250.             } else
  251.                 counter++;
  252.         }
  253.         counter=0;
  254.         r=rowChosen;
  255.         // down
  256.         while (r<7) {
  257.             r++;
  258.             if (board[r][c]==EMPTY)
  259.                 // discontinue this direction
  260.                 break;
  261.             if (board[r][c]==myColour) {
  262.                 if (counter==0)
  263.                     break;
  264.                 else {
  265.                     for (int i=rowChosen+1; i<r; i++)
  266.                         if (!calculating)
  267.                             board[i][c]=myColour;
  268.                     disksCaptured+=counter;
  269.                     break;
  270.                 }
  271.             } else
  272.                 counter++;
  273.         }
  274.         counter=0;
  275.         r=rowChosen;
  276.         // left and up diagonal
  277.         while ((c>0)&&(r>0)) {
  278.             c--;
  279.             r--;
  280.             if (board[r][c]==EMPTY)
  281.                 // discontinue this direction
  282.                 break;
  283.             if (board[r][c]==myColour) {
  284.                 if (counter==0)
  285.                     break;
  286.                 else {
  287.                     int temp=rowChosen-1;
  288.                     for (int i=colChosen-1; i>c; i--)
  289.                         if (!calculating)
  290.                             board[temp--][i]=myColour;
  291.                     disksCaptured+=counter;
  292.                     break;
  293.                 }
  294.             } else
  295.                 counter++;
  296.         }
  297.         counter=0;
  298.         r=rowChosen;
  299.         c=colChosen;
  300.         // right and up diagonal
  301.         while ((c<7)&&(r>0)) {
  302.             c++;
  303.             r--;
  304.             if (board[r][c]==EMPTY)
  305.                 // discontinue this direction
  306.                 break;
  307.             if (board[r][c]==myColour) {
  308.                 if (counter==0)
  309.                     break;
  310.                 else {
  311.                     int temp=rowChosen-1;
  312.                     for (int i=colChosen+1; i<c; i++)
  313.                         if (!calculating)
  314.                             board[temp--][i]=myColour;
  315.                     disksCaptured+=counter;
  316.                     break;
  317.                 }
  318.             } else
  319.                 counter++;
  320.         }
  321.         counter=0;
  322.         r=rowChosen;
  323.         c=colChosen;
  324.         // left and down diagonal
  325.         while ((c>0)&&(r<7)) {
  326.             c--;
  327.             r++;
  328.             if (board[r][c]==EMPTY)
  329.                 // discontinue this direction
  330.                 break;
  331.             if (board[r][c]==myColour) {
  332.                 if (counter==0)
  333.                     break;
  334.                 else {
  335.                     int temp=rowChosen+1;
  336.                     for (int i=colChosen-1; i>c; i--)
  337.                         if (!calculating)
  338.                             board[temp++][i]=myColour;
  339.                     disksCaptured+=counter;
  340.                     break;
  341.                 }
  342.             } else
  343.                 counter++;
  344.         }
  345.         counter=0;
  346.         r=rowChosen;
  347.         c=colChosen;
  348.         // right and down diagonal
  349.         while ((c<7)&&(r<7)) {
  350.             c++;
  351.             r++;
  352.             if (board[r][c]==EMPTY)
  353.                 // discontinue this direction
  354.                 break;
  355.             if (board[r][c]==myColour) {
  356.                 if (counter==0)
  357.                     break;
  358.                 else {
  359.                     int temp=rowChosen+1;
  360.                     for (int i=colChosen+1; i<c; i++)
  361.                         if (!calculating)
  362.                             board[temp++][i]=myColour;
  363.                     disksCaptured+=counter;
  364.                     break;
  365.                 }
  366.             } else
  367.                 counter++;
  368.         }
  369.         return disksCaptured;
  370.     } // captured
  371.  
  372.     public void makeComputerMove() {
  373.         // simple heuristic chooses maximum captures
  374.         // Allow random element when there is a choice of moves of equal value
  375.         Random r = new Random();
  376.         calculating=true;   // so no disks change colour
  377.         int maxRow=-1, maxCol=-1, maxPoints=0;
  378.         for (int row=0; row<8; row++) {
  379.             for (int col=0; col<8; col++) {
  380.                 rowChosen=row;
  381.                 colChosen=col;
  382.                 int points = captured();
  383.                 if (points>maxPoints) {
  384.                     maxRow=rowChosen;
  385.                     maxCol=colChosen;
  386.                     maxPoints=points;
  387.                 } else if ((points==maxPoints) && (r.nextInt(2)==1)) {
  388.                     // 50% chance of r.Random(2) being 1
  389.                     maxRow=rowChosen;
  390.                     maxCol=colChosen;
  391.                     maxPoints=points;
  392.                 }
  393.             }
  394.         }
  395.  
  396.         if (maxPoints>0) {
  397.             // a move was chosen
  398.             calculating=false;  // so disks change colour
  399.             rowChosen=maxRow;
  400.             colChosen=maxCol;
  401.             captured(); // turn over captured disks
  402.             // put disk on board
  403.             board[rowChosen][colChosen] = colourToPlay;
  404.         } else {
  405.             if (colourToPlay==WHITE)
  406.                 whiteCantGo = true;
  407.             else
  408.                 blackCantGo = true;
  409.         }
  410.         // change colour to play
  411.         if (colourToPlay == WHITE)
  412.             colourToPlay = BLACK;
  413.         else
  414.             colourToPlay = WHITE;
  415.         repaint();
  416.     } // makeComputerMove
  417.  
  418.     public boolean mClicked(int x, int y) {
  419.         // register the square clicked on
  420.         if (gameOver) return false;
  421.         // if outside the board
  422.         if ((x<BOARDTOPLEFTX)||(x>BOARDTOPLEFTX+BOARDSIZE)
  423.          ||(y<BOARDTOPLEFTY)||(y>BOARDTOPLEFTY+BOARDSIZE))
  424.             return false;
  425.         for (int row=0; row<8; row++)
  426.             if ((y-BOARDTOPLEFTY)/SQUARESIZE==row)
  427.                 rowChosen=row;
  428.         for (int col=0; col<8; col++)
  429.             if ((x-BOARDTOPLEFTX)/SQUARESIZE==col)
  430.                 colChosen=col;
  431.         if (captured()>0) {
  432.             // put disk on board
  433.             board[rowChosen][colChosen] = colourToPlay;
  434.             // change colour to play
  435.             if (colourToPlay == WHITE)
  436.                 colourToPlay = BLACK;
  437.             else
  438.                 colourToPlay = WHITE;
  439.             repaint();
  440.         }
  441.         return true;
  442.     } // mClicked
  443.  
  444.     public void actionPerformed(ActionEvent e) {
  445.         if (e.getSource() == btnGo)
  446.             if (!gameOver) makeComputerMove();
  447.     } // actionPerformed
  448. } // class
  449.  
  450. class AddLeadingSpace {
  451.  
  452.     /*  Display numbers < 10 with a leading space
  453.     *   By Chris Clarke, February 2006
  454.     */
  455.  
  456.     String addSpace(int n) {
  457.         return n<10?" "+n:""+n;
  458.     }
  459. } // class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement