30 Commits

Author SHA1 Message Date
Jenkins 42af096d06 Merge commit '896413211c40fcb697d435dca1435d5e0709e27f' into HEAD 3 years ago
kfkama 896413211c Bugfix worng colors on unflag 3 years ago
kfkama 9c2de1f2f7 Bugfix numbers not showen 3 years ago
Jenkins c851d634f8 Merge commit '3160bf1ed58da47da6d6d1011f72843e068acb8e' into HEAD 3 years ago
kfkama 3160bf1ed5 Merge branch 'Minesweeper_Game' into feature_Minesweeper_Playfield 3 years ago
kfkama 968c93804d Refactore Minesweeper, Playfield 3 years ago
kfkama 02c2b01d95 Reveal all bombs on game end 3 years ago
kfkama 7c6706bc20 Changed Colors 3 years ago
kfkama 430ff09228 Add reveal cell function 3 years ago
kfkama c6c2328e4a Changed victory end to reset 3 years ago
kfkama 5d1aba4408 Flagged number cells count as flooded 3 years ago
kfkama 7de023fa3e Flagged cells will not be flooded 3 years ago
kfkama d6178355de Bugfix early victory 3 years ago
kfkama 3c6f092049 Add flagging logic to cell 3 years ago
kfkama d0594cba7e Flagging on right click 3 years ago
kfkama b635c64d4f Game End: Victory 3 years ago
kfkama 4cbfc45a3d Game End: Clicked on Mine 3 years ago
kfkama d718f86c52 Made playfield resetable 3 years ago
kfkama 30903220e9 Refactore Playfield 3 years ago
kfkama b51cfb6732 Change update for celltype bomb 3 years ago
kfkama 4d97b75dba Add floodfill on click 3 years ago
kfkama cc10c4fdde Show proximity values on cells 3 years ago
kfkama 0e2ea58e57 Add bomb proximity with test 3 years ago
kfkama 380e848e38 Refactore Playfield 3 years ago
kfkama aa04d679bd Moved playfield logic to new class 3 years ago
kfkama 1dc0576f7b Add bomb placement 3 years ago
kfkama 665d7c1232 Add Cell to Minesweeper, replacing JButtons / Move playfield to center 3 years ago
kfkama 44a39db750 Add class Cell 3 years ago
kfkama 00b6ab308c Refactore MinesweeperGame 3 years ago
kfkama 88de22364d Add class MinesweeperGame with basic playfield gen. 3 years ago
  1. 143
      src/main/java/Minesweeper/Cell.java
  2. 27
      src/main/java/Minesweeper/MinesweeperGame.java
  3. 149
      src/main/java/Minesweeper/Playfield.java
  4. 53
      src/test/java/Minesweeper/MinesweeperGameTest.java

143
src/main/java/Minesweeper/Cell.java

@ -0,0 +1,143 @@
package Minesweeper;
import java.awt.Color;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JOptionPane;
enum CellType {
Number, Bomb
}
public class Cell extends JButton {
private static final Color FLAGCOLOR = Color.RED;
private static final Color FLOODEDCOLOR = Color.LIGHT_GRAY;
private static final Color HIDDENCOLOR = Color.WHITE;
private static final Color MINECOLOR = Color.BLACK;
private static final long serialVersionUID = 1L;
private Playfield playfield;
public CellType type;
public Point cord;
public boolean flagged = false;
public int value = 0;
public Cell(CellType _type, Playfield _playfield, Point _cord) {
type = _type;
cord = _cord;
playfield = _playfield;
setBackground(HIDDENCOLOR);
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
OnMouseClick();
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
super.mousePressed(e);
if (e.getButton() == 3) {
OnMouseRightClick();
}
}
});
}
protected void OnMouseClick() {
if (!flagged) {
reveal();
if (type != CellType.Bomb) {
flood();
} else {
playfield.revealAllBombs();
JOptionPane.showMessageDialog(getParent(),"KABOOM! Try again!");
playfield.reset();
}
}
}
protected void OnMouseRightClick() {
if (isEnabled()) {
if (flagged) {
flagged = false;
setBackground(HIDDENCOLOR);
if (type == CellType.Number) {
playfield.cellDried();
}
} else {
flagged = true;
setBackground(FLAGCOLOR);
if (type == CellType.Number) {
playfield.cellFlooded();
}
}
}
}
public void reveal() {
if (type == CellType.Number) {
if(value > 0) {
setText(String.valueOf(value));
}
} else {
setBackground(MINECOLOR);
}
}
public void flood() {
if (type == CellType.Bomb || flagged) {
return;
}
setBackground(FLOODEDCOLOR);
setEnabled(false);
reveal();
playfield.cellFlooded();
if (value == 0) {
if (cord.y > 0) {
if (playfield.cells[cord.y - 1][cord.x].type == CellType.Number
&& playfield.cells[cord.y - 1][cord.x].isEnabled()) {
playfield.cells[cord.y - 1][cord.x].flood();
}
}
if (cord.x < playfield.Size - 1) {
if (playfield.cells[cord.y][cord.x + 1].type == CellType.Number
&& playfield.cells[cord.y][cord.x + 1].isEnabled()) {
playfield.cells[cord.y][cord.x + 1].flood();
}
}
if (cord.y < playfield.Size - 1) {
if (playfield.cells[cord.y + 1][cord.x].type == CellType.Number
&& playfield.cells[cord.y + 1][cord.x].isEnabled()) {
playfield.cells[cord.y + 1][cord.x].flood();
}
}
if (cord.x > 0) {
if (playfield.cells[cord.y][cord.x - 1].type == CellType.Number
&& playfield.cells[cord.y][cord.x - 1].isEnabled()) {
playfield.cells[cord.y][cord.x - 1].flood();
}
}
}
}
}

27
src/main/java/Minesweeper/MinesweeperGame.java

@ -0,0 +1,27 @@
package Minesweeper;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MinesweeperGame extends JPanel {
private static final long serialVersionUID = 1L;
public static final int WIDTH = 600, HEIGTH = 600;
public Playfield playfield;
public MinesweeperGame(int _playfieldSize, int _bombAmount) {
this.setSize(WIDTH, HEIGTH);
setLayout(null);
playfield = new Playfield(this, _playfieldSize, _bombAmount );
}
public static void main(String[] args) {
JFrame f = new JFrame();
MinesweeperGame MsG = new MinesweeperGame(8, 10);
f.add(MsG);
f.setSize(WIDTH, HEIGTH);
f.setLayout(null);
f.setVisible(true);
}
}

149
src/main/java/Minesweeper/Playfield.java

@ -0,0 +1,149 @@
package Minesweeper;
import java.awt.Point;
import javax.swing.JOptionPane;
public class Playfield {
private static final int CELLSIZE = 50;
public int Size;
private MinesweeperGame MsG;
public Cell[][] cells;
private int bombAmount;
private int cellsFlooded = 0;
public Playfield(MinesweeperGame _MsG, int _Size, int _bombAmount) {
MsG = _MsG;
Size = _Size;
bombAmount = _bombAmount;
generatePlayfield();
}
public void generatePlayfield() {
cells = new Cell[Size][Size];
int[] bPlacement = new int[bombAmount];
for (int i = 0; i < bPlacement.length; i++) {
bPlacement[i] = (int) (Math.random() * Size * Size);
for (int j = 0; j < i; j++) {
if (bPlacement[i] == bPlacement[j]) {
i--;
break;
}
}
}
for (int i = 0; i < Size; i++) {
for (int j = 0; j < Size; j++) {
cells[i][j] = new Cell(CellType.Number, this, new Point(j, i));
cells[i][j].setBounds(j * CELLSIZE + (MsG.WIDTH / 2 - Size * CELLSIZE / 2),
i * CELLSIZE + (MsG.HEIGTH / 2 - Size * CELLSIZE / 2), CELLSIZE, CELLSIZE);
MsG.add(cells[i][j]);
for (int k = 0; k < bPlacement.length; k++) {
if (bPlacement[k] == i * Size + j) {
cells[i][j].type = CellType.Bomb;
break;
}
}
}
}
for (int i = 0; i < Size; i++) {
for (int j = 0; j < Size; j++) {
if (cells[i][j].type == CellType.Number) {
calculateBombProximity(i, j);
}
}
}
MsG.repaint();
}
public void reset() {
cellsFlooded = 0;
for (int i = 0; i < Size; i++) {
for (int j = 0; j < Size; j++) {
MsG.remove(cells[i][j]);
}
}
generatePlayfield();
}
public void calculateBombProximity(int row, int column) {
if (row > 0) {
if (column > 0) {
if (cells[row - 1][column - 1].type == CellType.Bomb) {
cells[row][column].value++;
}
}
if (cells[row - 1][column].type == CellType.Bomb) {
cells[row][column].value++;
}
if (column < cells.length - 1) {
if (cells[row - 1][column + 1].type == CellType.Bomb) {
cells[row][column].value++;
}
}
}
if (row < cells.length - 1) {
if (column > 0) {
if (cells[row + 1][column - 1].type == CellType.Bomb) {
cells[row][column].value++;
}
}
if (cells[row + 1][column].type == CellType.Bomb) {
cells[row][column].value++;
}
if (column < cells.length - 1) {
if (cells[row + 1][column + 1].type == CellType.Bomb) {
cells[row][column].value++;
}
}
}
if (column > 0) {
if (cells[row][column - 1].type == CellType.Bomb) {
cells[row][column].value++;
}
}
if (column < cells.length - 1) {
if (cells[row][column + 1].type == CellType.Bomb) {
cells[row][column].value++;
}
}
}
public void cellFlooded() {
cellsFlooded++;
if (cellsFlooded >= Size * Size - bombAmount) {
revealAllBombs();
JOptionPane.showMessageDialog(MsG, "You won, congratulations!");
reset();
}
}
public void revealAllBombs() {
for (int i = 0; i < Size; i++) {
for (int j = 0; j < Size; j++) {
if(cells[i][j].type == CellType.Bomb) {
cells[i][j].reveal();
}
}
}
MsG.repaint();
}
public void cellDried() {
cellsFlooded--;
}
}

53
src/test/java/Minesweeper/MinesweeperGameTest.java

@ -0,0 +1,53 @@
package Minesweeper;
import static org.junit.jupiter.api.Assertions.*;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class MinesweeperGameTest {
@ParameterizedTest
@MethodSource("testBombs")
void testBombPlacement(int _playfieldSize, int _bombAmount) {
MinesweeperGame m = new MinesweeperGame(_playfieldSize, _bombAmount);
int bombCounter = 0;
for(Cell[] row : m.playfield.cells){
for (Cell c : row) {
if(c.type == CellType.Bomb) {
bombCounter++;
}
}
}
assertEquals(_bombAmount, bombCounter);
}
@Test
void testProximityPoints() {
MinesweeperGame m = new MinesweeperGame(3, 0);
m.playfield.cells[0][0].type = CellType.Bomb;
m.playfield.calculateBombProximity(1, 1);
assertEquals(1, m.playfield.cells[1][1].value);
}
private static Stream<Arguments> testBombs(){
return Stream.of(
Arguments.of(8, 10),
Arguments.of(8, 0),
Arguments.of(4, 12),
Arguments.of(10, 100),
Arguments.of(5, 1)
);
}
}
Loading…
Cancel
Save