Next: HTML-Seite für das Applet:
Up: Von C++ zu Java
Previous: C++ Implementation 11/11
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
}
| © 1997 Gottfried Rudorfer, C++-AG, Lehrveranstaltungen, Abteilung für Angewandte Informatik, Wirtschaftsuniversität Wien, 3/19/1998 |