next up previous
Next: HTML-Seite für das Applet: Up: Von C++ zu Java Previous: C++ Implementation 11/11

Java Implementation

FourInaRow.java

import java.awt.*;       
import java.awt.event.*; // For MouseListener
import java.applet.Applet;


public class FourInaRow extends Applet
                        implements MouseListener, FourInaRowBase
{
  Board c_4 = new Board(); // The playing board
  Player contestant[] = new Player [NO_OF_PLAYERS]; // No of players
  
  int state = PLAY;
  int no = 0;
  int moveNumber = 0;

  public void init() 
  { 
	setSize(200, 200);
    addMouseListener(this);
    for (int i=0; i<NO_OF_PLAYERS; i++)
    {
		contestant[i] = new Player();
    }
	setBackground(BACKGROUND);
    c_4.printMessage(aboutString);
  }
  
  // paint is called by repaint()
  public void paint(Graphics g)
  {

	Dimension d = getSize();
	c_4.set_graphic_size(d);
    g.translate(0,d.height-40);
	c_4.displayBoard(g, d);

	// next lines: Display status message; also triggered with repaint()
    g.translate(0,-(d.height-40));
	g.setColor(BACKGROUND);
	g.drawString(c_4.last_message(),5,20);
	g.setColor(BLACK);
	g.drawString(c_4.message(),5,20);
	System.out.println(c_4.message());
	c_4.last_message(c_4.message());
    g.translate(0,d.height-40);
  }
   
  public void mouseReleased(MouseEvent e)
  {
    int x = e.getX();
    int y = e.getY();
	
	moveNumber++;

    Dimension d = getSize();
    int c = (x * DEF_COLUMNS) / d.width;
    int r = ((d.height - y) * DEF_ROWS) / d.height;
  
	c_4.printMessage("Move number " + moveNumber);
 
    if (!c_4.move_ok_for_column(c))
		c_4.printMessage("Illegal move");
    else
		c_4.drop_in_column(c, contestant[no].get_counter());
    
    repaint(); // Refresh the whole board
    state = c_4.situation();
    if (state == PLAY)
      no = (no+1)%NO_OF_PLAYERS;
    else 
      c_4.printMessage(contestant[no].announce(state)); // The result
  }
  
  public void mousePressed(MouseEvent e)
  {
  }
  
  public void mouseClicked(MouseEvent e) 
  {
  }
  
  public void mouseEntered(MouseEvent e) 
  {
  }

  public void mouseExited(MouseEvent e) 
  {
  }

  public String getAppletInfo() 
  {
    return aboutString;
  }
} 


interface FourInaRowBase
{
  final int MAXROW = 9; // Maximun Rows
  final int MAXCOLUMN = 9; // Maximum Columns

  final int DRAW = 0;
  final int WIN = 1;
  final int PLAY = 2;

  final int STONES_IN_A_WIN_LINE = 4;
  final int NO_OF_PLAYERS = 2;
  final int DEF_ROWS = 6; // Default number of rows
  final int DEF_COLUMNS = 7; // Default number of columns

  final Color INVISIBLE = Color.black;
  final Color BACKGROUND = new Color(225,225,255);
  final Color BLACK = Color.black;
  final int SELECT_REPRESENTATION = 1;
  final String aboutString = "Four in a Row by Gottfried Rudorfer";
}


class Counter implements FourInaRowBase
{
  public static void prelude()
  {
    the_counter_no = 0;
  }

  public Counter()
  {
    the_colour = INVISIBLE; 
  }

  public Counter(Color representation)
  {
    the_colour = representation;
  }
 
  public Counter(int dummy)
  {
    Color[] colors = {Color.white, Color.red, Color.green, Color.blue};
	String[] names = {"White", "Red", "Green", "Blue"};
    the_colour = colors[the_counter_no];
	the_colour_name = names[the_counter_no];
	the_counter_no++;
  }

  public Color colour() // Returns the colour of a counter
  {
    return the_colour;
  }
  
  public String colour_name() // Returns the colour of a counter
  {
    return the_colour_name;
  }
  
  private static int the_counter_no = 0; // Which colour to allocate next
  private Color the_colour; // The colour of the counter
  private String the_colour_name; // The name of the colour
}


class Cell implements FourInaRowBase
{
  public Cell()
  {
    the_counter = new Counter(INVISIBLE);
  }

  public void clear()
  {
    the_counter = new Counter(INVISIBLE);
  }
  public void drop(Counter c)
  {
    the_counter = new Counter(c.colour());
  }

  public Color holds()
  {
    return the_counter.colour();
  }

  public Graphics g()
  {
    return gr;
  }
  
  public void displayCounter(Graphics g, int xoff, int yoff, int xdiff, int ydiff)
  {
    g.setColor(the_counter.colour());
    g.fillOval(xoff, yoff, xdiff, ydiff);
    gr = g;
  }
  
  public void fill(Graphics g)
  {
    g.setColor(the_counter.colour());
  }

  private Counter the_counter;
  private Graphics gr;
}


class Player implements FourInaRowBase
{
  public Player()
  {
    the_players_counter = new Counter(SELECT_REPRESENTATION);
  }

  Counter get_counter() // Get a counter
  {
    return the_players_counter;
  }

  String announce(final int what) // Announce win/draw
  {
  
	String playerName = the_players_counter.colour_name();
	String resultStr=playerName;
    switch(what)
    {
      case WIN:
			resultStr+=" wins.";
			break;
      case DRAW:
			resultStr+=" has filled the board.";
			break;
    }
	return resultStr;
  }
  
  private Counter the_players_counter;
}


class Board  extends Applet 
			 implements FourInaRowBase
{
  public Board()
  {
    reset();
  }

  public Board(final int rows, final int columns)
  {
    reset(rows, columns);
  }

  public void reset()
  {
    reset(DEF_ROWS, DEF_COLUMNS);
  }

  public void reset(final int rows, final int columns)
  {
    the_row_size = rows; the_column_size = columns;
    for (int i=0; i<the_column_size; i++)
    {
		for (int j=0; j<the_row_size; j++)
		{
			the_grid[j][i] = new Cell();
		}
		the_height[i] = 0;
      }
    the_last_row = the_last_col = 0;
    the_no_empty_cells = rows * columns;
	the_last_message = "";
  }

  public void drop_in_column(final int column, final Counter c)
  {
    the_last_col = column; the_last_row = the_height[column];
    add_counter_to_board(column, c);
  }

  public boolean move_ok_for_column(final int column)
  {
    if (column >= 0 && column < the_column_size)
    {
		if (the_height[column] < the_row_size)
		{
			return true;
		}
    }
    return false;
  }  

  public void displayBoard(Graphics g, Dimension d)
  {
    for (int i=the_row_size - 1; i >= 0; i--)
    {
		for (int j=0; j < the_column_size; j++)
		{
			int xunit = d.width / (1 + the_column_size);
			int yunit = d.height / (1 + the_row_size);
			the_grid[i][j].displayCounter(g, j * yunit, -i * xunit, yunit, xunit);
		}
    }
  }
  
  public void set_graphic_size(Dimension d)
  {
	the_graphic_size = d;
  }

  public int situation()
  {
    if (is_there_a_win() == true)
    {
		return WIN;
    }
    if (the_no_empty_cells == 0)
    {
		return DRAW;
    }
    return PLAY;
  }
  
  public String message() {
	return the_message;
  }
  
  public String last_message() {
	return the_last_message;
  }
  
  public void last_message(String msg) {
	the_last_message = msg;
  }
  
  public void printMessage(String messageText)
  {	

	the_message = messageText;
	repaint();
  }

  protected int check_for_a_win(final int dir, final int x_coord, 
            final int y_coord, final Color counter)
  {
    int x = x_coord; int y = y_coord;
    if ( (x >= 0) && (x < the_row_size) &&
	 (y >= 0) && (y < the_column_size) &&
	 (the_grid[x][y].holds() == counter) )
    {
	  switch(dir)
	  {
		  case 1:      y++; break;
		  case 2: x++; y++; break;
		  case 3: x++;      break;
		  case 4: x++; y--; break;

		  case 5:      y--; break;
		  case 6: x--; y--; break;
		  case 7: x--;      break;
		  case 8: x--; y++; break;

		  default: printMessage("internal error 1\n");
	  }
	  return 1 + check_for_a_win(dir, x, y, counter);
    }
    else 
    {
		return 0;
    }
  }

  protected void add_counter_to_board(final int column, final Counter players_counter)
  {
    int row = the_height[column];

    the_grid[row][column].drop(players_counter);
    the_grid[row][column].fill(the_grid[row][column].g());
    the_height[column]++;
    the_no_empty_cells--;
  }
  protected boolean is_there_a_win()
  {
    Color stone = the_grid[the_last_row][the_last_col].holds();
    for (int dir=1; dir <= 4; dir++)
    {
		int stones_in_a_line = 
			check_for_a_win(dir, the_last_row, the_last_col, stone) + 
			check_for_a_win(dir+4, the_last_row, the_last_col, stone) - 1;
		if ( stones_in_a_line >= STONES_IN_A_WIN_LINE )
		{
			return true;
		}
    }
    return false;
  }

  private Cell the_grid[][] = new Cell [MAXROW][MAXCOLUMN];
  private int the_height[] = new int [MAXCOLUMN]; // Current height of counters col
  private int the_row_size;
  private int the_column_size; // Size of playing area
  private int the_last_col;
  private int the_last_row; // Last counter placed
  private int the_no_empty_cells; // No. of cells still empty
  private String the_last_message; // Last printed message 
  private String the_message; // the message 
  private Dimension the_graphic_size; // Dimension of graphic
}


next up previous
Next: HTML-Seite für das Applet: Up: Von C++ zu Java Previous: C++ Implementation 11/11

© 1997 Gottfried Rudorfer, C++-AG, Lehrveranstaltungen, Abteilung für Angewandte Informatik, Wirtschaftsuniversität Wien, 3/19/1998