import java.applet.*;
import java.lang.*;
import java.awt.*;
import java.net.*;

public class Othello extends Applet implements Runnable {
  /**
   * The stete of a particular cell.
   */
  final int BLACK =  1;	
  final int WHITE = -1;
  final int EMPTY =  0;
  
  /**
   * Width of the board
   */
  final int WIDTH = 552;
  
  /**
   * Space at bottom right
   */
  final int SPACE = 120;
  
  /**
   * Directions
   */
  private final int UPPER 	= 0;
  private final int LOWER 	= 1;
  private final int RIGHT 	= 2;
  private final int LEFT  	= 3;
  private final int UPPERLEFT 	= 4;
  private final int UPPERRIGHT	= 5;
  private final int LOWERRIGHT	= 6;
  private final int LOWERLEFT	= 7;
  boolean direction[] = 
    {false, false, false, false, false, false, false, false};
  
  /**
   * Turn.
   */
  public int turn;
  
  /**
   * The othello board. matrix of 8 * 8.
   */
  protected int stone[][];

  /**
   * Number of stones on the board
   */
  protected int counter_black = 0, counter_white = 0;

  /** 
   * column and row data for audio.
   */
  int audioColumn, audioRow;

  /**
   * Computer player
   */
  OthelloPlayer computer;

  /**
   * Image
   */
  Image yoon;
  Image bush;
  Image map;

  /**
   * Initialize this applet.
   * Resizing and preparing AudioData.
   */
  public void init() {
    yoon = getImage(getDocumentBase(),"yoon.gif");
    bush = getImage(getDocumentBase(),"bush.gif");
    map = getImage(getDocumentBase(),"map.gif");

    stone = new int[8][8];
    
    for (int i = 0; i < 8; i++) {
      for (int j = 0; j < 8; j++) {
	stone[i][j] = EMPTY;
      }
    }
    stone[3][3] = BLACK; stone[4][3] = WHITE;
    stone[3][4] = WHITE; stone[4][4] = BLACK;
    
    countStone();		

    turn = BLACK;	
    
    for (int i = 1; i <= 8; i++) {
      getAudioClip(getCodeBase(), i + ".wav");
    }

    computer = new OthelloPlayer(this);	
  }
  

  /**
   * Paint this applet.
*/ public void paint(Graphics g) { drawBoard(g); for(int i = 0; i < 8; i++){ for(int j = 0; j < 8; j++){ if (stone[i][j] != 0){ drawStone(i, j, g); } } } drawTurn(g); drawCountStone(g); if (counter_black + counter_white == 64) { showWinner(g); } } /** * Draw the Othello board
*/ public void drawBoard (Graphics g) { setBackground(Color.blue); g.drawImage(map, 0, 0, this); g.setColor(Color.yellow); g.drawLine(0,0, 0,WIDTH); g.drawLine(WIDTH,0, WIDTH,WIDTH); g.drawLine(0,0, WIDTH,0); g.drawLine(0,WIDTH, WIDTH,WIDTH); for(int i = 1; i < 8; i++){ g.drawLine(WIDTH*i/8,0, WIDTH*i/8,WIDTH); g.drawLine(0,WIDTH*i/8, WIDTH,WIDTH*i/8); } } /** * Paint stones on the board.
*/ public void drawStone(int column, int row, Graphics g) { if (stone[column][row] == BLACK) { g.setColor(Color.black); g.drawImage(yoon, column * WIDTH / 8 + 5, row * WIDTH / 8 + 5, this); } else if (stone[column][row] == WHITE){ g.setColor(Color.white); g.drawImage(bush, column * WIDTH / 8 + 5, row * WIDTH / 8 + 5, this); } } /** * Display which trun. */ void drawTurn(Graphics g){ String black = "Yoon"; String white = "Opp."; String comment = " player's turn"; g.setColor(Color.yellow); if (turn == BLACK) { g.drawString(black + comment, WIDTH/2, WIDTH + 35); } else { g.drawString(white + comment, WIDTH/2, WIDTH + 35); } } /** * Show win or lose.
*/ void showWinner(Graphics g){ g.clearRect(0, 0, WIDTH+1, WIDTH+1); if (counter_black > counter_white) { for(int i = 0; i < 255; i++){ g.fillRect(0, 0, WIDTH+1, WIDTH+1); g.drawString("You", 150, 100); g.drawString("Won!", 130, 200); } } else if (counter_black < counter_white) { g.setColor(Color.black); g.fillRect(0, 0, WIDTH+1, WIDTH+1); for(int i = 255; i >=0; i--){ g.drawString("You", 150, 100); g.drawString("lost...", 75, 200); } } else { g.drawString("Draw", 100, 100); g.drawString("Game", 100, 200); } } /** * Count the number of stones. */ void countStone() { counter_black = 0; counter_white = 0; for(int i = 0; i < 8; i++){ for(int j = 0; j < 8; j++){ if(stone[i][j] == BLACK) counter_black++; if(stone[i][j] == WHITE) counter_white++; } } if (counter_black + counter_white == 64) { endGame(); init(); } } /** * Display winner. This method is called when the game is finished. */ public void endGame(){ if (counter_black > counter_white) { } else if (counter_black < counter_white) { } else { } try { Thread.sleep(3500); } catch(Exception e){ repaint(); update(getGraphics()); } } /** * Display the number of stones.
*/ void drawCountStone(Graphics g){ g.setColor(Color.white); g.fill3DRect(WIDTH+100, 145, 25,20, false); g.fill3DRect(WIDTH+100, 240, 25,20, false); g.setColor(Color.black); g.drawImage(yoon, WIDTH+30, 115, this); g.drawString("Yoon", WIDTH+20, 110); g.drawString("Opponent", WIDTH+20, 205); g.drawImage(bush, WIDTH+30, 210, this); g.drawString(Integer.toString(counter_black), WIDTH+105, 160); g.drawString(Integer.toString(counter_white), WIDTH+105, 255); } /** * When mouse button is released.
*/ public boolean mouseUp(Event e, int x, int y) { int column = (int)(x / (WIDTH / 8)); int row = (int)(y / (WIDTH / 8)); if (turn == BLACK) { if (checkStone(column, row, turn) == true){ turnStone(column, row, turn); playAudio(column, row); turn = - turn; update(getGraphics()); countStone(); try { Thread.sleep(1200); } catch (Exception excep){ } } } if (turn == WHITE) { computer.decide(); update(getGraphics()); countStone(); } return true; } /** * Speak out the column and the row by activating audio thread. */ public void playAudio(int column, int row){ if (turn == BLACK) { } else { } audioColumn = column + 1; audioRow = row + 1; (new Thread(this)).start(); } /** * Play the sound on another Thread.
*/ public void run() { play(getCodeBase(), audioColumn + ".wav"); try { Thread.sleep(500); } catch (Exception e) { } play(getCodeBase(), audioRow + ".wav"); } /** * Check whether a stone can be put anywhere. * @return boolean true if you can put a stone */ public boolean checkAll(int turn) { for(int i = 0; i < 8; i++){ for(int j = 0; j < 8; j++){ if(checkStone(i, j, turn)){ return true; } } } return false; } /** * Check whether a stone can be put there.
* @return boolean true if you can put a stone there */ public boolean checkStone(int column, int row, int color){ int i, j; for (i = 0; i < 8; i++){ direction[i] = false; } if(stone[column][row] != 0) { return false; } else { if (column > 1 && stone[column-1][row] == -color) { for (i = column-2; i > 0 && stone[i][row] == -color; i--); if (stone[i][row] == color) { direction[LEFT] = true; } } /* ±¦ */ if (column < 6 && stone[column+1][row] == -color) { for (i = column+2; i < 7 && stone[i][row] == -color; i++); if (stone[i][row] == color) { direction[RIGHT] = true; } } if (row > 1 && stone[column][row-1] == -color) { for (j = row-2; j > 0 && stone[column][j] == -color; j--); if (stone[column][j] == color) { direction[UPPER] = true; } } if (row < 6 && stone[column][row+1] == -color) { for (j = row+2; j < 7 && stone[column][j] == -color; j++); if (stone[column][j] == color) { direction[LOWER] = true; } } if (column > 1 && row > 1 && stone[column-1][row-1] == -color) { for (i = column-2, j = row-2; i > 0 && j > 0 && stone[i][j] == -color; i--, j--); if (stone[i][j] == color) { direction[UPPERLEFT] = true; } } if (column < 6 && row > 1 && stone[column+1][row-1] == -color) { for (i = column+2, j = row-2; i < 7 && j > 0 && stone[i][j] == -color; i++, j--); if (stone[i][j] == color) { direction[UPPERRIGHT] = true; } } if (column < 6 && row < 6 && stone[column+1][row+1] == -color) { for (i = column+2, j = row+2; i < 7 && j < 7 && stone[i][j] == -color; i++, j++); if (stone[i][j] == color) { direction[LOWERRIGHT] = true; } } if (column > 1 && row < 6 && stone[column-1][row+1] == -color) { for (i = column-2, j = row+2; i > 0 && j < 7 && stone[i][j] == -color; i--, j++); if (stone[i][j] == color) { direction[LOWERLEFT] = true; } } for (i = 0; i < 8; i++){ if (direction[i] == true){ return true; } } return false; } } /** * Turn the stone over. */ public void turnStone(int column, int row, int color) { stone[column][row] = color; int i,j; if (direction[LEFT] == true){ for (i = column-1; stone[i][row] != color; i--){ stone[i][row] = - stone[i][row]; } } if (direction[RIGHT] == true){ for (i = column + 1; stone[i][row] != color; i++){ stone[i][row] = - stone[i][row]; } } if (direction[UPPER] == true){ for (j = row - 1; stone[column][j] != color; j--){ stone[column][j] = - stone[column][j]; } } if (direction[LOWER] == true){ for (j = row + 1; stone[column][j] != color; j++){ stone[column][j] = - stone[column][j]; } } if (direction[UPPERLEFT] == true){ for (i = column-1, j = row-1; stone[i][j] != color; i--, j--){ stone[i][j] = - stone[i][j]; } } if (direction[UPPERRIGHT] == true){ for (i = column+1, j = row-1; stone[i][j] != color; i++, j--){ stone[i][j] = - stone[i][j]; } } if (direction[LOWERRIGHT] == true){ for (i = column+1, j = row+1; stone[i][j] != color; i++, j++){ stone[i][j] = - stone[i][j]; } } if (direction[LOWERLEFT] == true){ for (i = column-1, j = row+1; stone[i][j] != color; i--, j++){ stone[i][j] = - stone[i][j]; } } } } /** * This is a class which define the strategy of computer othello player.
*/ class OthelloPlayer { Othello parent; int i,j; OthelloPlayer(Othello parent){ this.parent = parent; } public void decide(){ if (parent.checkAll(parent.turn) == true) { do { i = (int)(Math.random() * 8); j = (int)(Math.random() * 8); } while (! parent.checkStone(i, j, parent.turn)); parent.turnStone(i, j, parent.turn); } parent.turn = - parent.turn; } }