[bsh] Minesweeper
Author |
Message |
rizzix
|
Posted: Thu Feb 10, 2005 5:05 pm Post subject: [bsh] Minesweeper |
|
|
i was fooling around with BeanShell. heh its fun.. created a little app.. usually i dont post little apps.. but this language seriously requires attention.. i mean its the best java-ish scripting language i've used. Note that BeanShell is a superset of java.. so all java code is valid bsh but not all bsh code is valid Java.
here's an example using only some of its few added features. (by added i mean features not present in Java)
Java: | import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
final int ROWS = 12, COLS = 12, MINES = Math. round(ROWS*COLS/ 5), CELL_SIDE_LENGTH = 21;
class MineSquare extends JButton {
private int row, col; private int mines = 0;
private boolean isMine = false;
private boolean marked = false;
private boolean flag = false;
MineSquare (r, c ) {
row = r; col = c;
setMargin (new Insets(0, 0, 0, 0));
setBorder (BorderFactory. createLineBorder(Color. darkGray, 1));
reset ();
}
getRow () {return row; }
getCol () {return col; }
setMine () {isMine = true; }
hasMine () {return isMine; }
removeMine (){isMine = false; }
isFlaged () {return flag; }
flag () {flag = true; setLabel ("\u25CF");; }
unflag () {flag = false; setLabel (""); }
isMarked () {return marked; }
mark () {marked = true; }
unmark () {marked = false; }
incrementNeighbouringMineStatus () {setLabel (++mines+ ""); }
reveal () {
if (isFlaged () && hasMine ()) setBackground (Color. cyan);
else if (hasMine ()) {
setLabel ("X");
setBackground (Color. red);
}
if (mines == 0 && isMarked ()) {
setLabel (" ");
setBackground (Color. lightGray);
}
}
reset () {
setLabel (" ");
setBackground (Color. white);
setFocusable (false);
setEnabled (true);
isMine = false;
marked = false;
flag = false;
mines = 0;
}
}
class RandomSquareList {
private Vector v = new Vector();
addElement (m ) {v. addElement(m ); }
getRandomElement () {
int k = (int) (Math. random() * ROWS * COLS );
if (k < v. size()) return v. elementAt(k );
else return getRandomElement ();
}
getElementAt (i ) {
if (i > - 1 && i < v. size()) return v. elementAt(i );
else return null;
}
iterator () {return v. iterator(); }
elements () {return v; }
}
f = new JFrame("MineSweeper ("+ROWS+ "x"+COLS+ ","+MINES+ ")");
panel = new JPanel(new GridLayout(ROWS, COLS ), true);
panel. setPreferredSize(
new Dimension(ROWS*CELL_SIDE_LENGTH, COLS*CELL_SIDE_LENGTH )
);
f. getContentPane(). add(panel, BorderLayout. CENTER);
toolbar = new JToolBar();
resetButton = new JButton("Reset");
resetButton. setMargin(new Insets(2, 2, 3, 3));
toolbar. add(resetButton );
toolbar. addSeparator();
c = new Container();
c. setLayout(new FlowLayout(FlowLayout. RIGHT, 1, 2));
c. add(statusLabel = new JLabel(""));
toolbar. add(c );
f. getContentPane(). add(toolbar, BorderLayout. NORTH);
squareList = new RandomSquareList ();
revealCounts = 0;
randomlySetMines () {
var mines = 0, m;
while(mines++ < MINES ) {
m = squareList. getRandomElement();
if (m. hasMine()) mines--;
else m. setMine();
}
}
revealArea (MineSquare m ) {
if (m. isMarked()) return;
MineSquare neighbourCell; boolean isClear = true;
final int R = 0, C = 1, r = m. getRow(), c = m. getCol();
long clearCells = 0; //00000000
final int[][] cell = {
{r + 1, c }, //bottom
{r , c + 1}, //right
{r - 1, c }, //top
{r , c - 1}, //left
{r + 1, c + 1}, //bottom-right
{r + 1, c - 1}, //bottom-left
{r - 1, c - 1}, //top-left
{r - 1, c + 1} //top-right
};
for (int i = 0; i < 8; i++ ) {
neighbourCell = (
(cell [i ][R ] < ROWS && cell [i ][C ] < COLS &&
cell [i ][R ] > - 1 && cell [i ][C ] > - 1)
? squareList. getElementAt(cell [i ][R ]*COLS + cell [i ][C ])
: null
);
if (neighbourCell != null && !neighbourCell. isMarked())
if (neighbourCell. hasMine()) {
m. incrementNeighbouringMineStatus();
isClear = false;
} else clearCells |= Math. round(Math. pow(2, i ));
}
m. mark();
if (isClear ) {
for (long i = 0, k = 0; i < 8; i++ )
if ((clearCells & (k = Math. round(Math. pow(2, i )))) == k )
revealArea (
squareList. getElementAt(cell [i ][R ]*COLS + cell [i ][C ])
);
m. reveal();
}
revealCounts++;
}
revealMinesAndDisableAll () {
for (MineSquare m : squareList. elements()) {
m. reveal();
m. setEnabled(false);
}
}
actionPerformed (e ) {
MineSquare m = (MineSquare ) e. getSource();
if (m. isMarked()) return;
if ((e. getModifiers() & ActionEvent. CTRL_MASK) == ActionEvent. CTRL_MASK) {
if (m. isFlaged()) m. unflag();
else m. flag();
} else {
if (m. isFlaged()) return;
if (m. hasMine()) revealMinesAndDisableAll ();
else revealArea (m );
statusLabel. setText(
(((revealCounts )* 100)/ ((ROWS*COLS )-MINES ))+ "% revealed "
);
}
}
loadSquares () {
for (var i = 0, m; i < ROWS; i++ )
for (int j = 0; j < COLS; j++ ) {
panel. add(m = new MineSquare (i, j ));
m. addActionListener(this);
squareList. addElement(m );
}
}
resetSquares () {
for (MineSquare m : squareList. elements())
m. reset();
}
resetButton. addActionListener(
new ActionListener() {
actionPerformed (ActionEvent e ) {
resetSquares ();
randomlySetMines ();
statusLabel. setText("");
revealCounts = 0;
}
}
);
loadSquares ();
randomlySetMines ();
f. setResizable(false);
f. setDefaultCloseOperation(JFrame. EXIT_ON_CLOSE);
f. pack(); f. setVisible(true); |
Note that some may find this language as a pretty good tool to "teach" Java (if done correctly). Also note the language supports Untyped variables, Closures and Global variables as well as auto inteface implementation (like in the example above). All these features make scripting really easy. |
|
|
|
|
![](images/spacer.gif) |
Sponsor Sponsor
![Sponsor Sponsor](templates/subSilver/images/ranks/stars_rank5.gif)
|
|
![](images/spacer.gif) |
|
|