Initial Commit
- upload to github
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
target/
|
||||||
51
pom.xml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>berack96</groupId>
|
||||||
|
<artifactId>Minefield</artifactId>
|
||||||
|
<version>1.0.1</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<version>5.9.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>2.2</version>
|
||||||
|
<configuration>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>berack96.games.minefield.Game</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
||||||
201
src/main/java/berack96/games/minefield/Game.java
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
package berack96.games.minefield;
|
||||||
|
|
||||||
|
import berack96.games.minefield.frame.MenuFrame;
|
||||||
|
import berack96.games.minefield.object.Decisor;
|
||||||
|
import berack96.games.minefield.object.Field;
|
||||||
|
import berack96.games.minefield.object.view.FieldView;
|
||||||
|
import berack96.games.minefield.runexception.OutOfBoundsException;
|
||||||
|
import jbook.util.Input;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe che utilizza {@link Field} e {@link Decisor} per creare una interazione con l'utente.<br>
|
||||||
|
* Il gioco puo' esser fatto partire per console o come finestra.<br>
|
||||||
|
* Senza argomenti il gioco partira' in finestra.<br>
|
||||||
|
* <br>
|
||||||
|
* Lista dei possibili argomenti da passare al programma:<br>
|
||||||
|
* -nogui indica che il gioco partira' su console.<br>
|
||||||
|
* -safe=(true/false)<br>
|
||||||
|
* -mode=(EASY/MEDIUM/HARD/CUSTOM)<br>
|
||||||
|
* -dim=(colonne),(righe)<br>
|
||||||
|
* -mines=(num)<br>
|
||||||
|
*
|
||||||
|
* Questi argomenti per ora funzionano solo con il gioco in console<br>
|
||||||
|
* ovvero solo se si usa anche -nogui
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Game {
|
||||||
|
|
||||||
|
private static Field field;
|
||||||
|
private static boolean graphic = true;
|
||||||
|
|
||||||
|
private static Boolean safe = null;
|
||||||
|
private static Mode mode = null;
|
||||||
|
private static Integer columns = null;
|
||||||
|
private static Integer lines = null;
|
||||||
|
private static Integer mines = null;
|
||||||
|
|
||||||
|
public static void main(String[] arg) {
|
||||||
|
for(String s: arg) // looking for arguments
|
||||||
|
try {
|
||||||
|
|
||||||
|
if(s.matches("-nogui"))
|
||||||
|
graphic = false;
|
||||||
|
else if(s.matches("-safe=(.*)")) {
|
||||||
|
String temp[] = s.split("=");
|
||||||
|
safe = Boolean.getBoolean(temp[1]);
|
||||||
|
}
|
||||||
|
else if(s.matches("-mode=(.*)")) {
|
||||||
|
String temp2[] = s.split("=");
|
||||||
|
mode = Mode.valueOf(temp2[1]);
|
||||||
|
}
|
||||||
|
else if(s.matches("-dim=(.*)")) {
|
||||||
|
String temp3[] = s.split("=");
|
||||||
|
String t[] = temp3[1].split(",");
|
||||||
|
columns = Integer.valueOf(t[0]);
|
||||||
|
lines = Integer.valueOf(t[1]);
|
||||||
|
}
|
||||||
|
else if(s.matches("-mines=(.*)")) {
|
||||||
|
String temp5[] = s.split("=");
|
||||||
|
mines = Integer.valueOf(temp5[1]);
|
||||||
|
}
|
||||||
|
} catch(Exception e) {}
|
||||||
|
|
||||||
|
if(mode == null && (columns != null || lines != null || mines != null))
|
||||||
|
mode = Mode.CUSTOM;
|
||||||
|
|
||||||
|
if(graphic)
|
||||||
|
Game.startGraphic();
|
||||||
|
else
|
||||||
|
Game.startConsole();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void startConsole() {
|
||||||
|
String str;
|
||||||
|
|
||||||
|
// PARTENZA PROTETTA O MENO
|
||||||
|
if(safe == null) {
|
||||||
|
System.out.println("Vuoi la partenza protetta? (non troverai mine intorno alla prima cella scoperta)");
|
||||||
|
do {
|
||||||
|
System.out.print("[s/N] ");
|
||||||
|
|
||||||
|
str = Input.readString();
|
||||||
|
} while(!str.matches("(s|S|N|n)"));
|
||||||
|
|
||||||
|
safe = str.matches("(s|S)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// DIFFICOLTA DEL GIOCO
|
||||||
|
if(mode == null) {
|
||||||
|
System.out.println("A che difficolta' vuoi giocare? ");
|
||||||
|
do {
|
||||||
|
System.out.println("1 - Facile.");
|
||||||
|
System.out.println("2 - Medio.");
|
||||||
|
System.out.println("3 - Difficile.");
|
||||||
|
System.out.println("4 - Personalizzata.");
|
||||||
|
|
||||||
|
str = Input.readString();
|
||||||
|
} while(!str.matches("(1|2|3|4)"));
|
||||||
|
|
||||||
|
if(str.matches("1"))
|
||||||
|
mode = Mode.EASY;
|
||||||
|
else if(str.matches("2"))
|
||||||
|
mode = Mode.MEDIUM;
|
||||||
|
else if(str.matches("3"))
|
||||||
|
mode = Mode.HARD;
|
||||||
|
else if(str.matches("4"))
|
||||||
|
mode = Mode.CUSTOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DIFFICOLTA PERSONALIZATA
|
||||||
|
if(mode == Mode.CUSTOM) do {
|
||||||
|
|
||||||
|
if(columns == null)
|
||||||
|
columns = getNum("Inserisci quante colonne deve avere il campo: ", "Colonne = ", 1, Field.MAX_VAL);
|
||||||
|
if(lines == null)
|
||||||
|
lines = getNum("Inserisci quante righe deve avere il campo; ", "Righe = ", 1, Field.MAX_VAL);
|
||||||
|
if(mines == null)
|
||||||
|
mines = getNum("Inserisci le mine presenti nel campo: ", "Mine = ", 1, Field.MAX_VAL);
|
||||||
|
|
||||||
|
try {
|
||||||
|
field = Decisor.getNewField(safe, columns, lines, mines);
|
||||||
|
} catch(Exception e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
mines = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while(field == null);
|
||||||
|
else
|
||||||
|
field = Decisor.getNewField(safe, mode);
|
||||||
|
|
||||||
|
// code game
|
||||||
|
do {
|
||||||
|
System.out.println(FieldView.toString(field));
|
||||||
|
|
||||||
|
// coordinates used for interacting with user
|
||||||
|
int x = getNum(null, "X = ", 0, Integer.MAX_VALUE);
|
||||||
|
int y = getNum(null, "Y = ", 0, Integer.MAX_VALUE);;
|
||||||
|
|
||||||
|
System.out.println("Vuoi Scoprire la cella(S),\nSettarla come pericolosa(P),\nO rimuoverla dallo stato di pericolosa(R)?");
|
||||||
|
str = null;
|
||||||
|
|
||||||
|
do {
|
||||||
|
System.out.print("Inserisci scelta: ");
|
||||||
|
|
||||||
|
str = Input.readString();
|
||||||
|
} while(str.matches("(S|s|P|p|R|r)") == false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if(str.matches("(s|S)"))
|
||||||
|
field.cellUncover(x, y);
|
||||||
|
else if(str.matches("(P|p)"))
|
||||||
|
field.cellSetDangerous(x, y);
|
||||||
|
else
|
||||||
|
field.cellSetNotDangerous(x, y);
|
||||||
|
} catch (OutOfBoundsException e) {
|
||||||
|
System.out.println("Inserisci delle coordinate valide...");
|
||||||
|
}
|
||||||
|
} while(!Decisor.isALoose(field) && !Decisor.isAWin(field));
|
||||||
|
|
||||||
|
Decisor.uncoverAllMinesCells(field);
|
||||||
|
Decisor.uncoverAllDangerousCells(field);
|
||||||
|
|
||||||
|
System.out.println(FieldView.toString(field));
|
||||||
|
|
||||||
|
if(Decisor.isALoose(field))
|
||||||
|
System.out.println("Hai perso. SCARSO AHAHAHHA!");
|
||||||
|
else
|
||||||
|
System.out.println("Hai vinto.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void startGraphic() {
|
||||||
|
MenuFrame menuFr = new MenuFrame();
|
||||||
|
menuFr.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static int getNum(String messaggio, String campo, int min, int max) {
|
||||||
|
if(messaggio != null)
|
||||||
|
System.out.println(messaggio);
|
||||||
|
|
||||||
|
int num = min - 1;
|
||||||
|
do {
|
||||||
|
try {
|
||||||
|
num = Input.readInt(campo);
|
||||||
|
if(num<min) {
|
||||||
|
System.out.println("Inserire un numero che sia almeno " + min);
|
||||||
|
num = -1;
|
||||||
|
}
|
||||||
|
if(num>max) {
|
||||||
|
System.out.println("Inserire un numero minore di " + max);
|
||||||
|
num = -1;
|
||||||
|
}
|
||||||
|
} catch(java.lang.NumberFormatException e) {
|
||||||
|
System.out.println("Inserire un numero.");
|
||||||
|
}
|
||||||
|
} while(num < min);
|
||||||
|
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
src/main/java/berack96/games/minefield/Mode.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package berack96.games.minefield;
|
||||||
|
|
||||||
|
import berack96.games.minefield.object.Decisor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serve a scegliere una delle modalita' di gioco senza inserire ogni singolo parametro.<br>
|
||||||
|
* Insomma serve a velocizzare la partenza del gioco.<br>
|
||||||
|
* Da usare con {@link Decisor}
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public enum Mode {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modalita' di gioco facile
|
||||||
|
*/
|
||||||
|
EASY,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modalita' di gioco media
|
||||||
|
*/
|
||||||
|
MEDIUM,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modalita' di gioco difficile
|
||||||
|
*/
|
||||||
|
HARD,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modalita' di gioco personalizzata
|
||||||
|
*/
|
||||||
|
CUSTOM
|
||||||
|
}
|
||||||
BIN
src/main/java/berack96/games/minefield/assets/icons/1one.png
Normal file
|
After Width: | Height: | Size: 378 B |
BIN
src/main/java/berack96/games/minefield/assets/icons/2two.png
Normal file
|
After Width: | Height: | Size: 459 B |
BIN
src/main/java/berack96/games/minefield/assets/icons/3three.png
Normal file
|
After Width: | Height: | Size: 525 B |
BIN
src/main/java/berack96/games/minefield/assets/icons/4four.png
Normal file
|
After Width: | Height: | Size: 460 B |
BIN
src/main/java/berack96/games/minefield/assets/icons/5five.png
Normal file
|
After Width: | Height: | Size: 532 B |
BIN
src/main/java/berack96/games/minefield/assets/icons/6six.png
Normal file
|
After Width: | Height: | Size: 546 B |
BIN
src/main/java/berack96/games/minefield/assets/icons/7seven.png
Normal file
|
After Width: | Height: | Size: 385 B |
BIN
src/main/java/berack96/games/minefield/assets/icons/8eight.png
Normal file
|
After Width: | Height: | Size: 561 B |
BIN
src/main/java/berack96/games/minefield/assets/icons/flag.png
Normal file
|
After Width: | Height: | Size: 510 B |
|
After Width: | Height: | Size: 882 B |
|
After Width: | Height: | Size: 788 B |
BIN
src/main/java/berack96/games/minefield/assets/icons/mine.png
Normal file
|
After Width: | Height: | Size: 985 B |
84
src/main/java/berack96/games/minefield/frame/EndFrame.java
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package berack96.games.minefield.frame;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
import berack96.games.minefield.listener.EndFrameListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe che estende i {@link JPanel} in modo da creare una piccola finestra che appare alla fine del gioco.<br>
|
||||||
|
* <br>
|
||||||
|
* Essa contiene tre bottoni:<br>
|
||||||
|
* Menu che fa tornare ad un {@link MenuFrame},<br>
|
||||||
|
* Retry che fa riprovare la modalita' di gioco che era nel pannello {@link GameFrame},<br>
|
||||||
|
* Exit che serve a chiudere il gioco.
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class EndFrame extends JFrame{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private JLabel labelMsg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Costruttore: bisogna passargli la finestra di gioco corrente e una finestra menu.
|
||||||
|
*
|
||||||
|
* @param game Il gioco corrente che e' finito
|
||||||
|
* @param menu Il menu' che si vuole mostrare alla fine
|
||||||
|
*/
|
||||||
|
public EndFrame(GameFrame game, MenuFrame menu)
|
||||||
|
{
|
||||||
|
setTitle("MINEFIELD");
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setResizable(false);
|
||||||
|
|
||||||
|
getContentPane().setLayout(new GridLayout(2,1));
|
||||||
|
|
||||||
|
JPanel labelPanel = new JPanel();
|
||||||
|
labelMsg = new JLabel();
|
||||||
|
JPanel buttons = new JPanel();
|
||||||
|
JButton toMenu = new JButton("MENU");
|
||||||
|
JButton retry = new JButton("RETRY");
|
||||||
|
JButton quit = new JButton("EXIT");
|
||||||
|
|
||||||
|
EndFrameListener controller = new EndFrameListener(this, game, menu);
|
||||||
|
toMenu.addActionListener(controller);
|
||||||
|
retry.addActionListener(controller);
|
||||||
|
quit.addActionListener(controller);
|
||||||
|
|
||||||
|
labelPanel.add(labelMsg);
|
||||||
|
|
||||||
|
buttons.add(toMenu);
|
||||||
|
buttons.add(retry);
|
||||||
|
buttons.add(quit);
|
||||||
|
|
||||||
|
add(labelPanel);
|
||||||
|
add(buttons);
|
||||||
|
|
||||||
|
// centering window
|
||||||
|
Dimension size = new Dimension(240, 110);
|
||||||
|
int x = game.getLocation().x + game.getWidth()/2 - size.width/2;
|
||||||
|
int y = game.getLocation().y + game.getHeight()/2 - size.height/2;
|
||||||
|
|
||||||
|
setLocation(x, y);
|
||||||
|
setSize(size);
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setta il messaggio che si vuole mostrare nel pannello
|
||||||
|
*
|
||||||
|
* @param msg La stringa da mostrare
|
||||||
|
*/
|
||||||
|
public void setEndMsg(String msg)
|
||||||
|
{
|
||||||
|
labelMsg.setText("<html><center>"+msg+"</center></html>");
|
||||||
|
}
|
||||||
|
}
|
||||||
120
src/main/java/berack96/games/minefield/frame/GameFrame.java
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
package berack96.games.minefield.frame;
|
||||||
|
|
||||||
|
import java.awt.Container;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.FlowLayout;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
import berack96.games.minefield.listener.CellInFieldListener;
|
||||||
|
import berack96.games.minefield.object.Decisor;
|
||||||
|
import berack96.games.minefield.object.Field;
|
||||||
|
import berack96.games.minefield.object.FieldSafe;
|
||||||
|
import berack96.games.minefield.object.view.FieldView;
|
||||||
|
|
||||||
|
//TODO remove log lines
|
||||||
|
/**
|
||||||
|
* Classe che estende i {@link JPanel} in modo da creare una finestra del gioco.<br>
|
||||||
|
* Essa si serve di un {@link MenuFrame} per la finestra finale {@link EndFrame}<br>
|
||||||
|
* e anche di un {@link Field} gia' creato, in modo da creare una rappresentazione<br>
|
||||||
|
* grafica del gioco.
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GameFrame extends JFrame {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
final private MenuFrame menu;
|
||||||
|
|
||||||
|
private Field field;
|
||||||
|
private JPanel gamePanel;
|
||||||
|
private JLabel label;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Costruttore: crea una finestra di gioco a partire dal parametro field.
|
||||||
|
*
|
||||||
|
* @param menu Il menu' che si vuole mostrare eventualmente alla fine del gioco
|
||||||
|
* @param field Il campo di gioco
|
||||||
|
*/
|
||||||
|
public GameFrame(MenuFrame menu, Field field)
|
||||||
|
{
|
||||||
|
this.field = field;
|
||||||
|
this.menu = menu;
|
||||||
|
|
||||||
|
setTitle("MINEFIELD");
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setResizable(false);
|
||||||
|
|
||||||
|
Container c = getContentPane();
|
||||||
|
c.setLayout(new FlowLayout());
|
||||||
|
|
||||||
|
label = new JLabel(String.valueOf(field.getNumMines()-field.getNumDagerousCell()));
|
||||||
|
label.setVisible(true);
|
||||||
|
|
||||||
|
gamePanel = new FieldView(field, new CellInFieldListener(this, field)).toJPanel();
|
||||||
|
gamePanel.setVisible(true);
|
||||||
|
|
||||||
|
add(label);
|
||||||
|
add(gamePanel);
|
||||||
|
|
||||||
|
// centering window
|
||||||
|
Dimension dim = gamePanel.getPreferredSize();
|
||||||
|
dim.height += 57; // doing this for the flowlayout & for the label
|
||||||
|
dim.width += 10; // same here
|
||||||
|
|
||||||
|
Dimension dimScreen = Toolkit.getDefaultToolkit().getScreenSize();
|
||||||
|
int x = (dimScreen.width - dim.width)/2;
|
||||||
|
int y = (dimScreen.height - dim.height)/2;
|
||||||
|
setLocation(x, y);
|
||||||
|
|
||||||
|
setSize(dim);
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateView()
|
||||||
|
{
|
||||||
|
label.setText(String.valueOf(field.getNumMines()-field.getNumDagerousCell()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crea una nuova finestra {@link EndFrame} settata con endMsg.
|
||||||
|
*
|
||||||
|
* @param endMsg Il messaggio che si vuole mostrare
|
||||||
|
*/
|
||||||
|
public void launchEndFrame(String endMsg)
|
||||||
|
{
|
||||||
|
Decisor.uncoverAllMinesCells(field);
|
||||||
|
Decisor.uncoverAllDangerousCells(field);
|
||||||
|
|
||||||
|
EndFrame end = new EndFrame(this, menu);
|
||||||
|
end.setEndMsg(endMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resetta la griglia di gioco.<br>
|
||||||
|
* In questo modo si puo' giocare alla stessa difficolta' senza passare dal menu'.
|
||||||
|
*/
|
||||||
|
public void retryGame()
|
||||||
|
{
|
||||||
|
field = Decisor.getNewField(field.getClass() == FieldSafe.class, field.columns, field.lines, field.getNumMines());
|
||||||
|
|
||||||
|
gamePanel.setVisible(false);
|
||||||
|
remove(gamePanel); // remove all the component in the Frame
|
||||||
|
|
||||||
|
gamePanel = new FieldView(field, new CellInFieldListener(this, field)).toJPanel();
|
||||||
|
|
||||||
|
gamePanel.setVisible(true);
|
||||||
|
add(gamePanel);
|
||||||
|
|
||||||
|
updateView();
|
||||||
|
setVisible(true);
|
||||||
|
|
||||||
|
System.out.println("\n---New game started---"); // log line
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
366
src/main/java/berack96/games/minefield/frame/MenuFrame.java
Normal file
@@ -0,0 +1,366 @@
|
|||||||
|
package berack96.games.minefield.frame;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.FlowLayout;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.ButtonGroup;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JRadioButton;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
|
||||||
|
import berack96.games.minefield.Mode;
|
||||||
|
import berack96.games.minefield.frame.strings.StringMode;
|
||||||
|
import berack96.games.minefield.frame.strings.StringSafe;
|
||||||
|
import berack96.games.minefield.listener.MenuFrameListener;
|
||||||
|
import berack96.games.minefield.object.Field;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe che estende i {@link JPanel} in modo da creare una finestra per il menu' del gioco.<br>
|
||||||
|
* Essa e' formata in modo da avere 4 zone: in ognuna di esse l'utente deve fare delle scelte.<br>
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MenuFrame extends JFrame {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private MenuFrameListener listener;
|
||||||
|
|
||||||
|
// TOP
|
||||||
|
final private JPanel panelTop;
|
||||||
|
final private JRadioButton easy;
|
||||||
|
final private JRadioButton medi;
|
||||||
|
final private JRadioButton hard;
|
||||||
|
final private JRadioButton cust;
|
||||||
|
final private JLabel modeMsg;
|
||||||
|
private Mode mode;
|
||||||
|
|
||||||
|
// MID TOP
|
||||||
|
final private JPanel panelMidTop;
|
||||||
|
final private JTextField textColumns;
|
||||||
|
final private JTextField textLines;
|
||||||
|
final private JTextField textMines;
|
||||||
|
final private JPanel customPanel;
|
||||||
|
|
||||||
|
// MID BOT
|
||||||
|
final private JPanel panelMidBot;
|
||||||
|
final private JRadioButton yes;
|
||||||
|
final private JRadioButton no;
|
||||||
|
final private JLabel safeMsg;
|
||||||
|
private boolean safe;
|
||||||
|
|
||||||
|
// BOT
|
||||||
|
final private JPanel panelBot;
|
||||||
|
final private JLabel error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Costruttore: crea la finestra menu'
|
||||||
|
*/
|
||||||
|
public MenuFrame()
|
||||||
|
{
|
||||||
|
// set initial value for variable of JRadioButton
|
||||||
|
this.mode = Mode.EASY;
|
||||||
|
this.safe = true;
|
||||||
|
|
||||||
|
// add the listener
|
||||||
|
listener = new MenuFrameListener(this);
|
||||||
|
|
||||||
|
// basic things for the frame
|
||||||
|
setTitle("MINEFIELD");
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setResizable(false);
|
||||||
|
getContentPane().setLayout( new GridLayout(4, 1));
|
||||||
|
Dimension dim = new Dimension(350, 400);
|
||||||
|
|
||||||
|
// TOP frame
|
||||||
|
panelTop = new JPanel();
|
||||||
|
JPanel panelTopLabel = new JPanel();
|
||||||
|
JPanel panelTopButtons = new JPanel();
|
||||||
|
JLabel labelTop = new JLabel("Scegli una difficolta'");
|
||||||
|
easy = new JRadioButton("EASY", true);
|
||||||
|
medi = new JRadioButton("MEDIUM", false);
|
||||||
|
hard = new JRadioButton("HARD", false);
|
||||||
|
cust = new JRadioButton("CUSTOM", false);
|
||||||
|
ButtonGroup groupTop = new ButtonGroup();
|
||||||
|
|
||||||
|
easy.addActionListener(this.listener);
|
||||||
|
medi.addActionListener(this.listener);
|
||||||
|
hard.addActionListener(this.listener);
|
||||||
|
cust.addActionListener(this.listener);
|
||||||
|
|
||||||
|
groupTop.add(easy);
|
||||||
|
groupTop.add(medi);
|
||||||
|
groupTop.add(hard);
|
||||||
|
groupTop.add(cust);
|
||||||
|
|
||||||
|
panelTopButtons.add(easy);
|
||||||
|
panelTopButtons.add(medi);
|
||||||
|
panelTopButtons.add(hard);
|
||||||
|
panelTopButtons.add(cust);
|
||||||
|
|
||||||
|
panelTopLabel.add(labelTop);
|
||||||
|
|
||||||
|
panelTop.setLayout(new BoxLayout(this.panelTop, BoxLayout.Y_AXIS));
|
||||||
|
panelTop.setBorder(BorderFactory.createLineBorder(Color.black));
|
||||||
|
panelTop.add(panelTopLabel);
|
||||||
|
panelTop.add(panelTopButtons);
|
||||||
|
|
||||||
|
add(panelTop);
|
||||||
|
|
||||||
|
// MID TOP frame
|
||||||
|
panelMidTop = new JPanel();
|
||||||
|
modeMsg = new JLabel(StringMode.easy);
|
||||||
|
customPanel = new JPanel();
|
||||||
|
JLabel labelLength = new JLabel("Colonne:");
|
||||||
|
JLabel labelHeight = new JLabel("Righe:");
|
||||||
|
JLabel labelMines = new JLabel("Numero di mine:");
|
||||||
|
textColumns = new JTextField();
|
||||||
|
textLines = new JTextField();
|
||||||
|
textMines = new JTextField();
|
||||||
|
|
||||||
|
customPanel.setLayout(new GridLayout(3, 3));
|
||||||
|
|
||||||
|
customPanel.add(labelLength);
|
||||||
|
customPanel.add(textColumns);
|
||||||
|
customPanel.add(labelHeight);
|
||||||
|
customPanel.add(textLines);
|
||||||
|
customPanel.add(labelMines);
|
||||||
|
customPanel.add(textMines);
|
||||||
|
|
||||||
|
panelMidTop.setLayout(new FlowLayout());
|
||||||
|
panelMidTop.setBorder(BorderFactory.createLineBorder(Color.black));
|
||||||
|
panelMidTop.add(modeMsg);
|
||||||
|
// not adding custom panel 'cause there is the private function when needed.
|
||||||
|
|
||||||
|
add(panelMidTop);
|
||||||
|
|
||||||
|
// MID BOT frame
|
||||||
|
panelMidBot = new JPanel();
|
||||||
|
JPanel panelMidBotButtons = new JPanel();
|
||||||
|
JPanel panelMidBotMsg = new JPanel();
|
||||||
|
JLabel labelMidBot = new JLabel("Vuoi la partenza safe?");
|
||||||
|
yes = new JRadioButton("YES", true);
|
||||||
|
no = new JRadioButton("NO", false);
|
||||||
|
safeMsg = new JLabel(StringSafe.yes);
|
||||||
|
ButtonGroup groupMid = new ButtonGroup();
|
||||||
|
|
||||||
|
yes.addActionListener(listener);
|
||||||
|
no.addActionListener(listener);
|
||||||
|
|
||||||
|
groupMid.add(yes);
|
||||||
|
groupMid.add(no);
|
||||||
|
|
||||||
|
panelMidBotButtons.add(yes);
|
||||||
|
panelMidBotButtons.add(no);
|
||||||
|
|
||||||
|
panelMidBotMsg.add(safeMsg);
|
||||||
|
|
||||||
|
panelMidBot.setLayout(new BoxLayout(panelMidBot, BoxLayout.Y_AXIS));
|
||||||
|
panelMidBot.setBorder(BorderFactory.createLineBorder(Color.black));
|
||||||
|
panelMidBot.add(labelMidBot);
|
||||||
|
panelMidBot.add(panelMidBotButtons);
|
||||||
|
panelMidBot.add(panelMidBotMsg);
|
||||||
|
|
||||||
|
add(panelMidBot);
|
||||||
|
|
||||||
|
// BOT frame
|
||||||
|
panelBot = new JPanel();
|
||||||
|
JPanel panelBotLabel = new JPanel();
|
||||||
|
JPanel panelBotButton = new JPanel();
|
||||||
|
error = new JLabel();
|
||||||
|
JButton next = new JButton("NEXT");
|
||||||
|
|
||||||
|
next.addActionListener(listener);
|
||||||
|
|
||||||
|
panelBotLabel.add(error);
|
||||||
|
|
||||||
|
panelBotButton.add(next);
|
||||||
|
|
||||||
|
panelBot.setLayout(new BorderLayout());
|
||||||
|
panelBot.setBorder(BorderFactory.createLineBorder(Color.black));
|
||||||
|
|
||||||
|
panelBot.add(panelBotLabel, BorderLayout.CENTER);
|
||||||
|
panelBot.add(panelBotButton, BorderLayout.EAST);
|
||||||
|
|
||||||
|
add(panelBot);
|
||||||
|
|
||||||
|
// last things to do for the frame
|
||||||
|
setSize(dim);
|
||||||
|
|
||||||
|
// centering window
|
||||||
|
Dimension dimScreen = Toolkit.getDefaultToolkit().getScreenSize();
|
||||||
|
int x = (dimScreen.width - dim.width)/2;
|
||||||
|
int y = (dimScreen.height - dim.height)/2;
|
||||||
|
setLocation(x, y);
|
||||||
|
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funzione che serve al listener di questo frame {@link MenuFrameListener}<br>
|
||||||
|
* per aggiornare le frasi dei label e le varie variabili del menu'
|
||||||
|
*/
|
||||||
|
public void updateView()
|
||||||
|
{
|
||||||
|
if(easy.isSelected())
|
||||||
|
{
|
||||||
|
if(mode == Mode.CUSTOM)
|
||||||
|
removeCustomPanel();
|
||||||
|
mode = Mode.EASY;
|
||||||
|
modeMsg.setText(StringMode.easy);
|
||||||
|
}
|
||||||
|
else if(medi.isSelected())
|
||||||
|
{
|
||||||
|
if(mode == Mode.CUSTOM)
|
||||||
|
removeCustomPanel();
|
||||||
|
mode = Mode.MEDIUM;
|
||||||
|
modeMsg.setText(StringMode.medium);
|
||||||
|
}
|
||||||
|
else if(hard.isSelected())
|
||||||
|
{
|
||||||
|
if(mode == Mode.CUSTOM)
|
||||||
|
removeCustomPanel();
|
||||||
|
mode = Mode.HARD;
|
||||||
|
modeMsg.setText(StringMode.hard);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(mode != Mode.CUSTOM)
|
||||||
|
addCustomPanel();
|
||||||
|
mode = Mode.CUSTOM;
|
||||||
|
modeMsg.setText(StringMode.custom);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(yes.isSelected())
|
||||||
|
{
|
||||||
|
safe = true;
|
||||||
|
safeMsg.setText(StringSafe.yes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
safe = false;
|
||||||
|
safeMsg.setText(StringSafe.no);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce la stringa che si trova nel pannello delle colonne.
|
||||||
|
*
|
||||||
|
* @return La stringa inserita dall'utente
|
||||||
|
*/
|
||||||
|
public String getStringColumnsTextPanel()
|
||||||
|
{
|
||||||
|
return textColumns.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce la stringa che si trova nel pannello delle linee.
|
||||||
|
*
|
||||||
|
* @return La stringa inserita dall'utente
|
||||||
|
*/
|
||||||
|
public String getStringLinesTextPanel()
|
||||||
|
{
|
||||||
|
return textLines.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce la stringa che si trova nel pannello delle mine.
|
||||||
|
*
|
||||||
|
* @return La stringa inserita dall'utente
|
||||||
|
*/
|
||||||
|
public String getStringMinesTextPanel()
|
||||||
|
{
|
||||||
|
return textMines.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce il valore attuale del parametro safe.
|
||||||
|
*
|
||||||
|
* @return true/false
|
||||||
|
*/
|
||||||
|
public boolean getSafeValue()
|
||||||
|
{
|
||||||
|
return safe;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce il valore attuale della modalita' di gioco.
|
||||||
|
*
|
||||||
|
* @return {@link Mode}
|
||||||
|
*/
|
||||||
|
public Mode getModeValue()
|
||||||
|
{
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Se inserita una stinga verra' mostrata di colore rosso nel pannello.
|
||||||
|
*
|
||||||
|
* @param error La stringa da mettere in evidenza
|
||||||
|
*/
|
||||||
|
public void setError(String error)
|
||||||
|
{
|
||||||
|
this.error.setText("<html><font color='red'>"+error+"</font></html>");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Se inserito un campo, verra' creata una finestra di gioco {@link GameFrame}<br>
|
||||||
|
* e questa finestra menu' verra' nascosta tramite {@link #setVisible(boolean)}.
|
||||||
|
*
|
||||||
|
* @param field Il campo del gioco che si vuole giocare
|
||||||
|
*/
|
||||||
|
public void startNewGameFrame(Field field)
|
||||||
|
{
|
||||||
|
setVisible(false);
|
||||||
|
GameFrame gameFrame = new GameFrame(this, field);
|
||||||
|
gameFrame.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resetta ogni variabile del pannello e ogni oggetto grafico.
|
||||||
|
*/
|
||||||
|
public void resetVariablePanel()
|
||||||
|
{
|
||||||
|
easy.setSelected(true);
|
||||||
|
medi.setSelected(false);
|
||||||
|
hard.setSelected(false);
|
||||||
|
cust.setSelected(false);
|
||||||
|
|
||||||
|
yes.setSelected(true);
|
||||||
|
no.setSelected(false);
|
||||||
|
|
||||||
|
updateView();
|
||||||
|
|
||||||
|
setError("");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mostra il pannello per la personalizzazione della partita.
|
||||||
|
*/
|
||||||
|
private void addCustomPanel()
|
||||||
|
{
|
||||||
|
panelMidTop.add(customPanel);
|
||||||
|
customPanel.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nasconde il pannello per la personalizzazione della partita.
|
||||||
|
*/
|
||||||
|
private void removeCustomPanel()
|
||||||
|
{
|
||||||
|
customPanel.setVisible(false);
|
||||||
|
panelMidTop.remove(customPanel);
|
||||||
|
//panelMidTop.validate();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package berack96.games.minefield.frame.strings;
|
||||||
|
|
||||||
|
public class StringError {
|
||||||
|
|
||||||
|
public static final String noValue = "Inserisci dei numeri nei campi indicati";
|
||||||
|
|
||||||
|
public static final String noPositiveValue = "Inserisci dei valori positivi<br>"
|
||||||
|
+ "per la grandezza del campo";
|
||||||
|
|
||||||
|
public static final String minesLessThanZero = "Inserisci dei valori positivi<br>"
|
||||||
|
+ "per le mine";
|
||||||
|
|
||||||
|
public static final String minesGreaterThanField = "Inserisci un valore minore per le mine<br>"
|
||||||
|
+ "siccome non possono essere maggiori<br>"
|
||||||
|
+ "della grandezza del campo";
|
||||||
|
|
||||||
|
public static final String minesGreaterThanFieldSafe = "Inserisci un valore minore per le mine<br>"
|
||||||
|
+ "siccome non possono essere maggiori<br>"
|
||||||
|
+ "della grandezza del campo-8<br>"
|
||||||
|
+ "(perche' la prima cella non<br>"
|
||||||
|
+ "puo avere mine intorno)";
|
||||||
|
|
||||||
|
public static final String valueTooHigh = "Inserisci un valore minore per le grandezze<br>"
|
||||||
|
+ "siccome entrambe devono avere un valore<br>"
|
||||||
|
+ "minore di 100";
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package berack96.games.minefield.frame.strings;
|
||||||
|
|
||||||
|
public class StringMode {
|
||||||
|
|
||||||
|
public static final String easy = "<html><center>MODALITA' FACILE:<br>"
|
||||||
|
+ "Il campo non e' molto grande (8x8)<br>"
|
||||||
|
+ "e le mine non sono molte (10)</center></html>";
|
||||||
|
|
||||||
|
public static final String medium = "<html><center>MODALITA' MEDIA:<br>"
|
||||||
|
+ "Il campo e' di medie dimensioni (16x16)<br>"
|
||||||
|
+ "e le mine sono numerose (40)</center></html>";
|
||||||
|
|
||||||
|
public static final String hard = "<html><center>MODALITA' DIFFICILE:<br>"
|
||||||
|
+ "Il campo e' molto grande (16x32)<br>"
|
||||||
|
+ "e le mine sono molto numerose (80)</center></html>";
|
||||||
|
|
||||||
|
public static final String custom = "<html><center>MODALITA' PERSONALIZZATA:</center></html>";
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package berack96.games.minefield.frame.strings;
|
||||||
|
|
||||||
|
public final class StringSafe {
|
||||||
|
|
||||||
|
public static final String yes = "<html><center>La prima cella che viene scoperta<br>"
|
||||||
|
+ "non avra' nessuna mina intorno.</center></html>";
|
||||||
|
|
||||||
|
public static final String no = "<html><center>La prima cella che viene scoperta<br>"
|
||||||
|
+ "potra' avere mine intorno, o esserla.</center></html>";
|
||||||
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
package berack96.games.minefield.listener;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseListener;
|
||||||
|
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
|
||||||
|
import berack96.games.minefield.frame.GameFrame;
|
||||||
|
import berack96.games.minefield.object.Decisor;
|
||||||
|
import berack96.games.minefield.object.Field;
|
||||||
|
|
||||||
|
//TODO remove log lines
|
||||||
|
/**
|
||||||
|
* Classe che serve a controllare un {@link Field} generato in un {@link GameFrame}.<br>
|
||||||
|
* Questa classe modifica la cella in base all'azione dell'utente tramite i movimenti<br>
|
||||||
|
* e i pulsanti generati dal mouse.
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CellInFieldListener implements MouseListener {
|
||||||
|
|
||||||
|
private GameFrame frame;
|
||||||
|
private Field field;
|
||||||
|
|
||||||
|
public CellInFieldListener(GameFrame frame, Field field)
|
||||||
|
{
|
||||||
|
this.frame = frame;
|
||||||
|
this.field = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent arg0)
|
||||||
|
{
|
||||||
|
if(Decisor.isALoose(field) == false && Decisor.isAWin(field) == false)
|
||||||
|
{
|
||||||
|
JLabel label = (JLabel) arg0.getSource();
|
||||||
|
String[] str = label.getName().split("-");
|
||||||
|
|
||||||
|
int x = Integer.parseInt(str[0]);
|
||||||
|
int y = Integer.parseInt(str[1]);
|
||||||
|
|
||||||
|
System.out.println("User clicked on cell ("+label.getName()+")"); // log line
|
||||||
|
|
||||||
|
if(field.cellIsUncovered(x, y) == false)
|
||||||
|
{
|
||||||
|
if(arg0.getButton() == MouseEvent.BUTTON1)
|
||||||
|
field.cellUncover(x, y);
|
||||||
|
else if(arg0.getButton() == MouseEvent.BUTTON3)
|
||||||
|
{
|
||||||
|
if(field.cellIsDangerous(x, y) == false)
|
||||||
|
field.cellSetDangerous(x, y);
|
||||||
|
else
|
||||||
|
field.cellSetNotDangerous(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Decisor.isALoose(field))
|
||||||
|
{
|
||||||
|
frame.launchEndFrame("HAI PERSO");
|
||||||
|
System.out.println("---Game Lost---"); // log line
|
||||||
|
}
|
||||||
|
else if(Decisor.isAWin(field))
|
||||||
|
{
|
||||||
|
frame.launchEndFrame("HAI VINTO");
|
||||||
|
System.out.println("---Game Won---"); // log line
|
||||||
|
}
|
||||||
|
|
||||||
|
frame.updateView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent arg0)
|
||||||
|
{
|
||||||
|
JLabel label = (JLabel) arg0.getSource();
|
||||||
|
String[] str = label.getName().split("-");
|
||||||
|
|
||||||
|
int x = Integer.parseInt(str[0]);
|
||||||
|
int y = Integer.parseInt(str[1]);
|
||||||
|
|
||||||
|
if(field.cellIsUncovered(x, y) == false && field.cellIsDangerous(x, y) == false)
|
||||||
|
label.setBackground(Color.GRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent arg0)
|
||||||
|
{
|
||||||
|
JLabel label = (JLabel) arg0.getSource();
|
||||||
|
String[] str = label.getName().split("-");
|
||||||
|
|
||||||
|
int x = Integer.parseInt(str[0]);
|
||||||
|
int y = Integer.parseInt(str[1]);
|
||||||
|
|
||||||
|
if(field.cellIsUncovered(x, y) == false && field.cellIsDangerous(x, y) == false)
|
||||||
|
label.setBackground(Color.LIGHT_GRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent arg0)
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent arg0)
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package berack96.games.minefield.listener;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
|
|
||||||
|
import berack96.games.minefield.frame.EndFrame;
|
||||||
|
import berack96.games.minefield.frame.GameFrame;
|
||||||
|
import berack96.games.minefield.frame.MenuFrame;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe che contolla la finestra {@link EndFrame} e in base a che bottone<br>
|
||||||
|
* viene premuto viene effettuata una scelta.
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class EndFrameListener implements ActionListener {
|
||||||
|
|
||||||
|
private EndFrame end;
|
||||||
|
private GameFrame game;
|
||||||
|
private MenuFrame menu;
|
||||||
|
|
||||||
|
public EndFrameListener(EndFrame end, GameFrame game, MenuFrame menu)
|
||||||
|
{
|
||||||
|
this.end = end;
|
||||||
|
this.game = game;
|
||||||
|
this.menu = menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
JButton button = (JButton) e.getSource();
|
||||||
|
String s = button.getText();
|
||||||
|
|
||||||
|
if(s.matches("EXIT"))
|
||||||
|
{
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
else if(s.matches("RETRY"))
|
||||||
|
{
|
||||||
|
game.retryGame();
|
||||||
|
}
|
||||||
|
else if(s.matches("MENU"))
|
||||||
|
{
|
||||||
|
game.setVisible(false);
|
||||||
|
|
||||||
|
menu.resetVariablePanel();
|
||||||
|
menu.setVisible(true);
|
||||||
|
|
||||||
|
game.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
end.setVisible(false);
|
||||||
|
end.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package berack96.games.minefield.listener;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
|
|
||||||
|
import berack96.games.minefield.Mode;
|
||||||
|
import berack96.games.minefield.frame.MenuFrame;
|
||||||
|
import berack96.games.minefield.frame.strings.StringError;
|
||||||
|
import berack96.games.minefield.object.Decisor;
|
||||||
|
import berack96.games.minefield.object.Field;
|
||||||
|
import berack96.games.minefield.runexception.TooHighValueException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe che contolla la finestra {@link MenuFrame} e in base a che bottone<br>
|
||||||
|
* viene premuto o a che pulsante Radio viene scelto, viene effettuata una scelta.
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MenuFrameListener implements ActionListener {
|
||||||
|
|
||||||
|
private MenuFrame frame;
|
||||||
|
|
||||||
|
public MenuFrameListener(MenuFrame frame)
|
||||||
|
{
|
||||||
|
this.frame = frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent arg0)
|
||||||
|
{
|
||||||
|
frame.updateView();
|
||||||
|
if(frame.getModeValue() != Mode.CUSTOM)
|
||||||
|
frame.setError("");
|
||||||
|
|
||||||
|
int columns = 0,
|
||||||
|
lines = 0,
|
||||||
|
mines = 0;
|
||||||
|
|
||||||
|
try{
|
||||||
|
JButton button = (JButton) arg0.getSource();
|
||||||
|
|
||||||
|
if(button.getText().matches("NEXT"))
|
||||||
|
{
|
||||||
|
Field field;
|
||||||
|
|
||||||
|
if(frame.getModeValue() == Mode.CUSTOM)
|
||||||
|
{
|
||||||
|
columns = Integer.parseInt(this.frame.getStringColumnsTextPanel());
|
||||||
|
lines = Integer.parseInt(this.frame.getStringLinesTextPanel());
|
||||||
|
mines = Integer.parseInt(this.frame.getStringMinesTextPanel());
|
||||||
|
|
||||||
|
field = Decisor.getNewField(frame.getSafeValue(), columns, lines, mines);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
field = Decisor.getNewField(frame.getSafeValue(), frame.getModeValue());
|
||||||
|
|
||||||
|
frame.startNewGameFrame(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch(ClassCastException e) // not a JButton generated the action (in this case a JRadioButton have)
|
||||||
|
{
|
||||||
|
// DO NOTHING
|
||||||
|
}
|
||||||
|
catch(NumberFormatException e) // not a number is inserted in the text
|
||||||
|
{
|
||||||
|
frame.setError(StringError.noValue);
|
||||||
|
}
|
||||||
|
catch(IllegalArgumentException e) // the numbers inserted is not valid
|
||||||
|
{
|
||||||
|
if(columns<=0 || lines<=0)
|
||||||
|
frame.setError(StringError.noPositiveValue);
|
||||||
|
else if(mines<=0)
|
||||||
|
frame.setError(StringError.minesLessThanZero);
|
||||||
|
else if(frame.getSafeValue() && mines>=lines*columns-8)
|
||||||
|
frame.setError(StringError.minesGreaterThanFieldSafe);
|
||||||
|
else if(mines>= lines*columns)
|
||||||
|
frame.setError(StringError.minesGreaterThanField);
|
||||||
|
}
|
||||||
|
catch(TooHighValueException e)
|
||||||
|
{
|
||||||
|
frame.setError(StringError.valueTooHigh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
139
src/main/java/berack96/games/minefield/object/Cell.java
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
package berack96.games.minefield.object;
|
||||||
|
|
||||||
|
import java.util.Observable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe che serve a creare una cella per il campo.<br>
|
||||||
|
* Tramite le funzioni principali della cella si<br>
|
||||||
|
* possono sapere 4 cose:<br>
|
||||||
|
* - il numero di mine vicine {@link #nearMine}<br>
|
||||||
|
* - se la cella e' una mina {@link #isMine()}<br>
|
||||||
|
* - lo stato della cella {@link #getStatus()}<br>
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Cell extends Observable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indica le mine che si trovano vicino a questa cella
|
||||||
|
*/
|
||||||
|
public int nearMine;
|
||||||
|
|
||||||
|
private boolean isMine;
|
||||||
|
private boolean uncovered;
|
||||||
|
private CellStatus status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Costruttore: serve creare una nuova cella coperta con 0 mine intorno.
|
||||||
|
*/
|
||||||
|
public Cell() {
|
||||||
|
nearMine = 0;
|
||||||
|
isMine = false;
|
||||||
|
uncovered = false;
|
||||||
|
status = CellStatus.COVERED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serve a mettere la cella nello stato di "scoperta"<br>
|
||||||
|
* Una volta fatto la cella non potra' esser piu cambiata.<br>
|
||||||
|
* Essa potra' avere i seguenti valori:<br>
|
||||||
|
* - EXPLODED<br>
|
||||||
|
* - UNCOVERED<br>
|
||||||
|
* - GOTRIGHT<br>
|
||||||
|
* - GOTWRONG<br>
|
||||||
|
* <br>
|
||||||
|
* Per altro vedere {@link CellStatus}
|
||||||
|
*/
|
||||||
|
public void uncover() {
|
||||||
|
if(!this.uncovered) {
|
||||||
|
if(isMine) {
|
||||||
|
if(status == CellStatus.DANGEROUS)
|
||||||
|
status = CellStatus.GOTRIGHT;
|
||||||
|
else
|
||||||
|
status = CellStatus.EXPLODED;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(status == CellStatus.DANGEROUS)
|
||||||
|
status = CellStatus.GOTWRONG;
|
||||||
|
else
|
||||||
|
status = CellStatus.UNCOVERED;
|
||||||
|
}
|
||||||
|
uncovered = true;
|
||||||
|
|
||||||
|
setChanged();
|
||||||
|
notifyObservers();
|
||||||
|
clearChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serve ad avere lo stato della cella.<br>
|
||||||
|
* Vedi {@link CellStatus} per i possibili valori.
|
||||||
|
*
|
||||||
|
* @return CellStatus
|
||||||
|
*/
|
||||||
|
public CellStatus getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setta la cella come una mina solamente se<br>
|
||||||
|
* quest'ultima non e' stata scoperta.<br>
|
||||||
|
* Questa azione e' irreversibile.
|
||||||
|
*/
|
||||||
|
public void setMine() {
|
||||||
|
if(!uncovered)
|
||||||
|
isMine = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setta la cella nello stato di {@link CellStatus}.DANGEROUS<br>
|
||||||
|
* Se La funzione {@link #uncover()} e' gia stata chiamata<br>
|
||||||
|
* la cella non verra' settata come pericolosa.
|
||||||
|
*/
|
||||||
|
public void setDangerous() {
|
||||||
|
if(status == CellStatus.COVERED) {
|
||||||
|
status = CellStatus.DANGEROUS;
|
||||||
|
|
||||||
|
setChanged();
|
||||||
|
notifyObservers();
|
||||||
|
clearChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toglie la cella dallo stato {@link CellStatus}.DANGEROUS<br>
|
||||||
|
* e la mette come COVERED.<br>
|
||||||
|
* Se la cella non e' in stato DANGEROUS, la funzione<br>
|
||||||
|
* non fa nulla.
|
||||||
|
*/
|
||||||
|
public void setNotDangerous() {
|
||||||
|
if(status == CellStatus.DANGEROUS) {
|
||||||
|
status = CellStatus.COVERED;
|
||||||
|
|
||||||
|
setChanged();
|
||||||
|
notifyObservers();
|
||||||
|
clearChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dice se la cella e' una mina o meno.
|
||||||
|
*
|
||||||
|
* @return true se lo e'
|
||||||
|
*/
|
||||||
|
public boolean isMine() {
|
||||||
|
return isMine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dice se la cella e' gia stata scoperta.<br>
|
||||||
|
* AKA se la funzione {@link #uncover()} e' gia stata chiamata.
|
||||||
|
*
|
||||||
|
* @return true se non e' piu {@link CellStatus#COVERED}
|
||||||
|
*/
|
||||||
|
public boolean isUncovered() {
|
||||||
|
return uncovered;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package berack96.games.minefield.object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serve a comunicare lo stato della cella.<br>
|
||||||
|
* Essa puo' assumere questi stati in base al<br>
|
||||||
|
* fatto di essere o meno stata scoperrta.
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public enum CellStatus {
|
||||||
|
/**
|
||||||
|
* Se la cella non e' ancora stata scoperta.
|
||||||
|
*/
|
||||||
|
COVERED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Se la cella e' marchiata pericolosa.
|
||||||
|
*/
|
||||||
|
DANGEROUS,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dopo aver scoperto la cella: se essa e' una mina.
|
||||||
|
*/
|
||||||
|
EXPLODED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dopo aver scoperto la cella, se essa non e' una mina
|
||||||
|
*/
|
||||||
|
UNCOVERED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dopo aver scoperto la cella: se essa, marchiata precedentemente come pericolosa, e' effettivamente una mina.
|
||||||
|
*/
|
||||||
|
GOTRIGHT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dopo aver scoperto la cella: se essa, marchiata precedentemente cvome pericolosa, non e' una mina.
|
||||||
|
*/
|
||||||
|
GOTWRONG
|
||||||
|
}
|
||||||
160
src/main/java/berack96/games/minefield/object/Decisor.java
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
package berack96.games.minefield.object;
|
||||||
|
|
||||||
|
import berack96.games.minefield.Mode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe utile ad automatizzare alcuni meccanismi di gioco, come per esempio<br>
|
||||||
|
* {@link #getNewField(boolean, Mode)} che crea un nuovo campo data la modalita'.
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Decisor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crea un nuovo campo di gioco data la modalita' {@link Mode}.
|
||||||
|
*
|
||||||
|
* @param safe Se si vuole che il campo sia {@link FieldSafe}
|
||||||
|
* @param mode La modalita' di gioco
|
||||||
|
* @return Un nuovo campo
|
||||||
|
*/
|
||||||
|
public static Field getNewField(boolean safe, Mode mode) {
|
||||||
|
if(mode == Mode.EASY)
|
||||||
|
return getNewFieldEasy(safe);
|
||||||
|
else if(mode == Mode.MEDIUM)
|
||||||
|
return getNewFieldMedium(safe);
|
||||||
|
else if(mode == Mode.HARD)
|
||||||
|
return getNewFieldHard(safe);
|
||||||
|
else
|
||||||
|
throw new java.lang.IllegalArgumentException("mode must be Easy, Medium or Hard");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serve a creare un nuovo campo dati i parametri richiesti.
|
||||||
|
*
|
||||||
|
* @param safe Se si vuole che il campo sia {@link FieldSafe}
|
||||||
|
* @param columns Una grandezza del campo (larghezza)
|
||||||
|
* @param lines Una grandezza del campo (altezza)
|
||||||
|
* @param mines Quante mine ci sono nel campo
|
||||||
|
* @return Un nuovo campo
|
||||||
|
*/
|
||||||
|
public static Field getNewField(boolean safe, int columns, int lines, int mines) {
|
||||||
|
if(safe)
|
||||||
|
return new FieldSafe(columns, lines, mines);
|
||||||
|
return new FieldNoSafe(columns, lines, mines);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serve a creare un campo in modalita' facile
|
||||||
|
*
|
||||||
|
* @param safe Se si vuole che il campo sia {@link FieldSafe}
|
||||||
|
* @return Un nuovo campo
|
||||||
|
*/
|
||||||
|
public static Field getNewFieldEasy(boolean safe) {
|
||||||
|
return getNewField(safe, 8, 8, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serve a creare un campo in modalita' media
|
||||||
|
*
|
||||||
|
* @param safe Se si vuole che il campo sia {@link FieldSafe}
|
||||||
|
* @return Un nuovo campo
|
||||||
|
*/
|
||||||
|
public static Field getNewFieldMedium(boolean safe) {
|
||||||
|
return getNewField(safe, 16, 16, 40);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serve a creare un campo in modalita' difficile
|
||||||
|
*
|
||||||
|
* @param safe Se si vuole che il campo sia {@link FieldSafe}
|
||||||
|
* @return Un nuovo campo
|
||||||
|
*/
|
||||||
|
public static Field getNewFieldHard(boolean safe) {
|
||||||
|
return getNewField(safe, 32, 16, 80);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indica se nel campo inserito si e' riusciti a vincere.
|
||||||
|
*
|
||||||
|
* @param field Il campo da controllare
|
||||||
|
* @return true se si ha vinto
|
||||||
|
*/
|
||||||
|
public static boolean isAWin(Field field) {
|
||||||
|
// Basic
|
||||||
|
if(!field.isGenerated)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// First Condition
|
||||||
|
if(field.getNumMines() == field.getNumCoveredCell())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Second Condition
|
||||||
|
int minesGot = 0;
|
||||||
|
for(Cell cell : field)
|
||||||
|
if(cell.isMine() && cell.getStatus() == CellStatus.DANGEROUS)
|
||||||
|
minesGot++;
|
||||||
|
|
||||||
|
if(minesGot == field.getNumMines())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indica se nel campo inserito si ha perso.
|
||||||
|
*
|
||||||
|
* @param field Il campo da controllare
|
||||||
|
* @return true se si ha perso
|
||||||
|
*/
|
||||||
|
public static boolean isALoose(Field field) {
|
||||||
|
for(Cell cell : field)
|
||||||
|
if(cell.isUncovered() && cell.isMine())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scopre tutte le celle del campo.
|
||||||
|
*
|
||||||
|
* @param field Il campo da scoprire
|
||||||
|
*/
|
||||||
|
public static void uncoverAllCells(Field field) {
|
||||||
|
for(Cell cell : field)
|
||||||
|
cell.uncover();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scopre tutte celle pericolose del campo.
|
||||||
|
*
|
||||||
|
* @param field Il campo da scoprire
|
||||||
|
*/
|
||||||
|
public static void uncoverAllDangerousCells(Field field) {
|
||||||
|
for(Cell cell : field)
|
||||||
|
if(cell.getStatus() == CellStatus.DANGEROUS)
|
||||||
|
cell.uncover();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scopre tutte le mine del campo.
|
||||||
|
*
|
||||||
|
* @param field Il campo da scoprire
|
||||||
|
*/
|
||||||
|
public static void uncoverAllMinesCells(Field field) {
|
||||||
|
for(Cell cell : field)
|
||||||
|
if(cell.isMine())
|
||||||
|
cell.uncover();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scopre tutte le celle che non sono mine del campo.
|
||||||
|
*
|
||||||
|
* @param field Il campo da scoprire
|
||||||
|
*/
|
||||||
|
public static void uncoverAllNotMinesCells(Field field) {
|
||||||
|
for(Cell cell : field)
|
||||||
|
if(!cell.isMine())
|
||||||
|
cell.uncover();
|
||||||
|
}
|
||||||
|
}
|
||||||
415
src/main/java/berack96/games/minefield/object/Field.java
Normal file
@@ -0,0 +1,415 @@
|
|||||||
|
package berack96.games.minefield.object;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import berack96.games.minefield.runexception.OutOfBoundsException;
|
||||||
|
import berack96.games.minefield.runexception.TooHighValueException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe astratta in cui manca la funzione che genera il campo.<br>
|
||||||
|
* Essa contiene un tot numero di celle della classe {@link Cell}<br>
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class Field implements Iterable<Cell> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valore massimo del capo
|
||||||
|
*/
|
||||||
|
public static final int MAX_VAL = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Una delle grandezze del campo
|
||||||
|
*/
|
||||||
|
public final int lines;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Una delle grandezze del campo
|
||||||
|
*/
|
||||||
|
public final int columns;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valore che inizialmente e' settato a <b>false</b> e che<br>
|
||||||
|
* se messo a <b>true</b>, non fara' piu richiamare la funzione<br>
|
||||||
|
* {@link #generateField(int, int)} quando la funzione<br>
|
||||||
|
* {@link #cellUncover(int, int)} e' usata.
|
||||||
|
*/
|
||||||
|
protected boolean isGenerated;
|
||||||
|
|
||||||
|
private int numMines;
|
||||||
|
private Cell [][]matrix;
|
||||||
|
|
||||||
|
private int numCoveredCell;
|
||||||
|
private int numDangerousCell;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Costruttore che crea un campo senza mine o altro.<br>
|
||||||
|
* Genera solamente la base per futuri cambiamenti in esso.
|
||||||
|
*
|
||||||
|
* @param columns Una delle grandezze del campo (larghezza)
|
||||||
|
* @param lines Una delle grandezze del campo (altezza)
|
||||||
|
* @throws IllegalArgumentException nel caso in cui si inseriscano parametri sbagliati
|
||||||
|
* @throws TooHighValueException nel caso in cui i parametri siano maggiori di 100
|
||||||
|
*/
|
||||||
|
public Field(int columns, int lines) {
|
||||||
|
if(lines<0 || columns<0)
|
||||||
|
throw new java.lang.IllegalArgumentException("columns and lines must be greater than 0.");
|
||||||
|
if(lines>MAX_VAL || columns>MAX_VAL)
|
||||||
|
throw new TooHighValueException("columns and lines must be less than 100.");
|
||||||
|
|
||||||
|
this.isGenerated = false;
|
||||||
|
|
||||||
|
this.lines = lines;
|
||||||
|
this.columns = columns;
|
||||||
|
|
||||||
|
numMines = 0;
|
||||||
|
numDangerousCell = 0;
|
||||||
|
numCoveredCell = lines*columns;
|
||||||
|
|
||||||
|
matrix = new Cell[lines][columns];
|
||||||
|
|
||||||
|
for(int i=0; i<lines; i++)
|
||||||
|
for(int j=0; j<columns; j++)
|
||||||
|
this.matrix[i][j] = new Cell();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scopre la cella dalle coordinate selezionate.<br>
|
||||||
|
* Se la cella e' in uno stato di {@link CellStatus}.DANGEROUS,<br>
|
||||||
|
* essa non verra' scoperta e la funzione terminara'.<br>
|
||||||
|
* Se il campo non e' ancora stato creato, viene automaticamente creato.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
* @throws OutOfBoundsException nel caso in cui si inseriscano coordinate sbagliate
|
||||||
|
*/
|
||||||
|
public void cellUncover(int x, int y) {
|
||||||
|
checkCoordinates(x, y);
|
||||||
|
|
||||||
|
if(!isGenerated)
|
||||||
|
generateField(x, y);
|
||||||
|
|
||||||
|
if(!cellIsUncovered(x, y) && matrix[x][y].getStatus() != CellStatus.DANGEROUS) {
|
||||||
|
matrix[x][y].uncover();
|
||||||
|
numCoveredCell--;
|
||||||
|
if(matrix[x][y].nearMine == 0 && !matrix[x][y].isMine())
|
||||||
|
cellUncoverNeighbors(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scopre la cella dalle coordinate selezionate.<br>
|
||||||
|
* Se la cella e' in uno stato di {@link CellStatus}.DANGEROUS,<br>
|
||||||
|
* essa <b>VERRA'</b> comunque scoperta.<br>
|
||||||
|
* Se il campo non e' ancora stato creato, viene automaticamente creato.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
* @throws OutOfBoundsException nel caso in cui si inseriscano coordinate sbagliate
|
||||||
|
*/
|
||||||
|
public void cellUncoverIngnoringDangerousState(int x, int y) {
|
||||||
|
checkCoordinates(x, y);
|
||||||
|
|
||||||
|
if(!isGenerated)
|
||||||
|
generateField(x, y);
|
||||||
|
|
||||||
|
if(!cellIsUncovered(x, y)) {
|
||||||
|
matrix[x][y].uncover();
|
||||||
|
numCoveredCell--;
|
||||||
|
if(matrix[x][y].nearMine == 0 && matrix[x][y].isMine() == false)
|
||||||
|
cellUncoverNeighbors(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setta una determinata cella come {@link CellStatus}.DANGEROUS<br>
|
||||||
|
* Se la cella e' gia stata scoperta non succedera' nulla.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
* @throws OutOfBoundsException nel caso in cui si inseriscano coordinate sbagliate
|
||||||
|
*/
|
||||||
|
public void cellSetDangerous(int x, int y) {
|
||||||
|
checkCoordinates(x, y);
|
||||||
|
|
||||||
|
if(numMines != numDangerousCell && matrix[x][y].getStatus() == CellStatus.COVERED) {
|
||||||
|
matrix[x][y].setDangerous();
|
||||||
|
numDangerousCell++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toglie alla cella lo status di {@link CellStatus}.DANGEROUS<br>
|
||||||
|
* Se la cella non e' in stato di DANGEROUS, la funzione non fa nulla.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
* @throws OutOfBoundsException nel caso in cui si inseriscano coordinate sbagliate
|
||||||
|
*/
|
||||||
|
public void cellSetNotDangerous(int x, int y) {
|
||||||
|
checkCoordinates(x, y);
|
||||||
|
|
||||||
|
if(matrix[x][y].getStatus() == CellStatus.DANGEROUS) {
|
||||||
|
matrix[x][y].setNotDangerous();
|
||||||
|
numDangerousCell--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dice se la cella e' stata scoperta o meno.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
* @return true se e' stata scoperta
|
||||||
|
* @throws OutOfBoundsException nel caso in cui si inseriscano coordinate sbagliate
|
||||||
|
*/
|
||||||
|
public boolean cellIsUncovered(int x, int y) {
|
||||||
|
checkCoordinates(x, y);
|
||||||
|
return matrix[x][y].isUncovered();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indica se la cella e' nello stato pericoloso.<br>
|
||||||
|
* Per info: {@link CellStatus}.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
* @return true se lo e'
|
||||||
|
* @throws OutOfBoundsException nel caso in cui si inseriscano coordinate sbagliate
|
||||||
|
*/
|
||||||
|
public boolean cellIsDangerous(int x, int y) {
|
||||||
|
return matrix[x][y].getStatus() == CellStatus.DANGEROUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indica se la cella e' esplosa.<br>
|
||||||
|
* Per info: {@link CellStatus}.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
* @return true se lo e'
|
||||||
|
* @throws OutOfBoundsException nel caso in cui si inseriscano coordinate sbagliate
|
||||||
|
*/
|
||||||
|
public boolean cellIsExploded(int x, int y) {
|
||||||
|
return matrix[x][y].getStatus() == CellStatus.EXPLODED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indica se la cella e' stata marchiata come pericolosa,<br>
|
||||||
|
* e alla fine del gioco e' risultata essere una mina.<br>
|
||||||
|
* Per info: {@link CellStatus}.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
* @return true se lo e'
|
||||||
|
* @throws OutOfBoundsException nel caso in cui si inseriscano coordinate sbagliate
|
||||||
|
*/
|
||||||
|
public boolean cellIsGotRight(int x, int y) {
|
||||||
|
return matrix[x][y].getStatus() == CellStatus.GOTRIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indica se la cella e' una mina o meno.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
* @return true se e' una mina
|
||||||
|
* @throws OutOfBoundsException nel caso in cui si inseriscano coordinate sbagliate
|
||||||
|
*/
|
||||||
|
public boolean cellIsMine(int x, int y) {
|
||||||
|
checkCoordinates(x, y);
|
||||||
|
return matrix[x][y].isMine();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serve ad avere lo stato della cella.<br>
|
||||||
|
* Vedi {@link CellStatus} per i possibili valori.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
* @return lo stato della cella
|
||||||
|
* @throws OutOfBoundsException nel caso in cui si inseriscano coordinate sbagliate
|
||||||
|
*/
|
||||||
|
public CellStatus cellGetStatus(int x, int y) {
|
||||||
|
checkCoordinates(x, y);
|
||||||
|
return matrix[x][y].getStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indica il numero di mine vicine alla cella richiesta.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
* @return il numero di mine vicine alla cella
|
||||||
|
* @throws OutOfBoundsException nel caso in cui si inseriscano coordinate sbagliate
|
||||||
|
*/
|
||||||
|
public int cellGetNumNearMines(int x, int y) {
|
||||||
|
checkCoordinates(x, y);
|
||||||
|
return matrix[x][y].nearMine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return il numero delle mine che il campo contiene
|
||||||
|
*/
|
||||||
|
public int getNumMines() {
|
||||||
|
return numMines;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return il numero di celle ancora da scoprire
|
||||||
|
*/
|
||||||
|
public int getNumCoveredCell() {
|
||||||
|
return numCoveredCell;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return il numero delle celle gia scoperto
|
||||||
|
*/
|
||||||
|
public int getNumUncoveredCell() {
|
||||||
|
return ( lines * columns ) - numCoveredCell;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return il numero delle celle segnate pericolose
|
||||||
|
*/
|
||||||
|
public int getNumDagerousCell() {
|
||||||
|
return numDangerousCell;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce la cella desiderata. Restituendo la cella<br>
|
||||||
|
* questa funzione puo' esser considerata un modo per<br>
|
||||||
|
* rendere le cose piu' facili.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
* @return la cella desiderata
|
||||||
|
* @throws OutOfBoundsException nel caso in cui si inseriscano coordinate sbagliate
|
||||||
|
*/
|
||||||
|
public Cell getCell(int x, int y) {
|
||||||
|
checkCoordinates(x, y);
|
||||||
|
return matrix[x][y];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funzione che inserisce nel campo gia creato mine e numeri.<br>
|
||||||
|
* La funzione <b>DEVE</b> aggiornare il campo {@link #isGenerated},<br>
|
||||||
|
* in modo che sia generato una sola volta il campo.<br>
|
||||||
|
* Per creare il campo si possono usare le funzioni<br>
|
||||||
|
* {@link #insertMine(int, int)} e {@link #updateNumNearMines(int, int)} gia fornite.<br>
|
||||||
|
* Nel caso non si usasse questa funzione nel costruttore,<br>
|
||||||
|
* essa viene richiamata nella funzione {@link #cellUncover(int, int)}.<br>
|
||||||
|
* Il campo isGenerated evita che venga ripetuta l'operazione piu' volte,<br>
|
||||||
|
* quindi e' necessario che venga aggiornata in questa funzione.<br>
|
||||||
|
* Le coordinate sono fornite per passare, per esempio,<br>
|
||||||
|
* il punto della cella da cui l'utente ha iniziato a giocare.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
*/
|
||||||
|
protected abstract void generateField(int x, int y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marchia la cella come mina se non lo e' gia<br>
|
||||||
|
* Aaggiorna inoltre quante mine ci sono nel campo<br>
|
||||||
|
* reperibili tramite {@link #getNumMines()}.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
* @return true se la mina e' stata piazzata, false se la mina era gia presente
|
||||||
|
* @throws OutOfBoundsException nel caso in cui si inseriscano coordinate sbagliate
|
||||||
|
*/
|
||||||
|
protected boolean insertMine(int x, int y) {
|
||||||
|
checkCoordinates(x, y);
|
||||||
|
|
||||||
|
if(!matrix[x][y].isMine()) {
|
||||||
|
matrix[x][y].setMine();
|
||||||
|
numMines++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aggiorna il numero di mine che si trovano vicino alla cella richiesta.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
* @return Il numero di mine che la cella ha intorno
|
||||||
|
* @throws OutOfBoundsException nel caso in cui si inseriscano coordinate sbagliate
|
||||||
|
*/
|
||||||
|
protected int updateNumNearMines(int x, int y) {
|
||||||
|
checkCoordinates(x, y);
|
||||||
|
|
||||||
|
for(int i=x-1; i<=x+1; i++)
|
||||||
|
for(int j=y-1; j<=y+1; j++) try {
|
||||||
|
checkCoordinates(i, j);
|
||||||
|
|
||||||
|
if(matrix[i][j].isMine() && (i!=x || j!=y))
|
||||||
|
matrix[x][y].nearMine++;
|
||||||
|
} catch(OutOfBoundsException e) { /* do nothing and go on */ }
|
||||||
|
|
||||||
|
return matrix[x][y].nearMine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funzione che serve a controllare se le coordinate sono consone al campo.<br>
|
||||||
|
* Nel caso non lo siano, il programma lancera' una eccezione.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
* @throws OutOfBoundsException nel caso in cui si inseriscano coordinate sbagliate
|
||||||
|
*/
|
||||||
|
private void checkCoordinates(int x, int y) {
|
||||||
|
if(x<0 || y<0 || x>=lines || y>=columns)
|
||||||
|
throw new OutOfBoundsException("coordinates must be inside the field x(0-"+lines+"), y(0-"+columns+").\tX = "+x+" Y = "+y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scopre i vicini della cella che si passa.
|
||||||
|
*
|
||||||
|
* @param x Una coordinata della cella
|
||||||
|
* @param y Una coordinata della cella
|
||||||
|
*/
|
||||||
|
private void cellUncoverNeighbors(int x, int y) {
|
||||||
|
for(int i=x-1; i<=x+1; i++)
|
||||||
|
for(int j=y-1; j<=y+1; j++)
|
||||||
|
if(!(i==x && j==y)) try {
|
||||||
|
this.cellUncover(i, j);
|
||||||
|
} catch(OutOfBoundsException e) { /* do nothing and go on */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Cell> iterator() {
|
||||||
|
return new FieldIter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class FieldIter implements Iterator<Cell> {
|
||||||
|
|
||||||
|
private final Field field;
|
||||||
|
private int x = 0;
|
||||||
|
private int y = 0;
|
||||||
|
|
||||||
|
private FieldIter(Field field) {
|
||||||
|
this.field = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return y + 1 < field.columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cell next() {
|
||||||
|
if(x + 1 == field.lines) {
|
||||||
|
x = 0;
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
x++;
|
||||||
|
return field.getCell(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package berack96.games.minefield.object;
|
||||||
|
|
||||||
|
import berack96.games.minefield.runexception.TooHighValueException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe che crea un campo di celle {@link Cell}.<br>
|
||||||
|
* Quando l'utente scopre la prima cella, essa puo essere anche una mina.
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FieldNoSafe extends Field{
|
||||||
|
|
||||||
|
private final int numMines;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Costruisce il campo, contenente le mine e quante mine ogni cella ha intorno.
|
||||||
|
*
|
||||||
|
* @param columns Una delle grandezze del campo (lunghezza)
|
||||||
|
* @param lines Una delle grandezze del campo (altezza)
|
||||||
|
* @param numMines Quante mine deve contenere il campo
|
||||||
|
* @throws IllegalArgumentException nel caso in cui si inseriscano parametri sbagliati
|
||||||
|
* @throws TooHighValueException nel caso in cui i parametri siano maggiori di 100
|
||||||
|
*/
|
||||||
|
public FieldNoSafe(int columns, int lines, int numMines)
|
||||||
|
{
|
||||||
|
super(columns, lines);
|
||||||
|
|
||||||
|
if(numMines<=0)
|
||||||
|
throw new java.lang.IllegalArgumentException("the mines must be greater than 0.");
|
||||||
|
if(numMines>=columns*lines)
|
||||||
|
throw new java.lang.IllegalArgumentException("the mines must be less than the size of the whole field.");
|
||||||
|
|
||||||
|
this.numMines = numMines;
|
||||||
|
generateField(0, 0); // use of this function here because don't need safe start
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Genera il campo senza considerare le due coordinate in entrata
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void generateField(int x, int y)
|
||||||
|
{
|
||||||
|
|
||||||
|
// i will not use the argument, don't need it
|
||||||
|
|
||||||
|
super.isGenerated = true;
|
||||||
|
|
||||||
|
while(getNumMines()<numMines) // insert mines
|
||||||
|
{
|
||||||
|
int randX = (int)(Math.random()*lines);
|
||||||
|
int randY = (int)(Math.random()*columns);
|
||||||
|
|
||||||
|
insertMine(randX, randY);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<lines; i++) // update neighbor
|
||||||
|
for(int j=0; j<columns; j++)
|
||||||
|
updateNumNearMines(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
60
src/main/java/berack96/games/minefield/object/FieldSafe.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package berack96.games.minefield.object;
|
||||||
|
|
||||||
|
import berack96.games.minefield.runexception.TooHighValueException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe che crea un campo di celle {@link Cell}.<br>
|
||||||
|
* Quando l'utente scopre la prima cella, essa NON puo essere una mina,<br>
|
||||||
|
* e non puo avere mine intorno.
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FieldSafe extends Field{
|
||||||
|
|
||||||
|
private final int numMines;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crea il campo vouto. Esso si riempira' non appena verra'<br>
|
||||||
|
* scoperta la prima cella con al funzione {@link #cellUncover(int, int)}
|
||||||
|
* @param columns Una delle grandezze del campo.
|
||||||
|
*
|
||||||
|
* @param lines Una delle grandezze del campo
|
||||||
|
* @param numMines Quante mine deve contenere il campo
|
||||||
|
* @throws IllegalArgumentException nel caso in cui si inseriscano parametri sbagliati
|
||||||
|
* @throws TooHighValueException nel caso in cui i parametri siano maggiori di 100
|
||||||
|
*/
|
||||||
|
public FieldSafe(int columns, int lines, int numMines) {
|
||||||
|
super(columns, lines);
|
||||||
|
|
||||||
|
if(numMines<=0)
|
||||||
|
throw new java.lang.IllegalArgumentException("the mines must be greater than 0.");
|
||||||
|
if(numMines>=columns*lines-8)
|
||||||
|
throw new java.lang.IllegalArgumentException("the mines must be less than the size of the whole field -8 (for the safe start).");
|
||||||
|
|
||||||
|
this.numMines = numMines;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Genera il campo non creando mine vicino alla cella indicata dalle due coordinate
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void generateField(int x, int y) {
|
||||||
|
|
||||||
|
isGenerated = true;
|
||||||
|
|
||||||
|
while(this.getNumMines()<numMines) // insert mines
|
||||||
|
{
|
||||||
|
int randX = (int)(Math.random()*lines);
|
||||||
|
int randY = (int)(Math.random()*columns);
|
||||||
|
|
||||||
|
if((randX>=x-1 && randX<=x+1 && randY>=y-1 && randY<=y+1) == false)
|
||||||
|
this.insertMine(randX, randY);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<lines; i++)
|
||||||
|
for(int j=0; j<columns; j++)
|
||||||
|
this.updateNumNearMines(i, j); // update neighbor
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package berack96.games.minefield.object.view;
|
||||||
|
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe che contiene solamente le immagini da mostrare nel caso le si vogliano usare
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CellIcons
|
||||||
|
{
|
||||||
|
public static final ImageIcon mine = createImageIcon("mine.png");
|
||||||
|
|
||||||
|
public static final ImageIcon flag = createImageIcon("flag.png");
|
||||||
|
public static final ImageIcon flagRight = createImageIcon("flagRight.png");
|
||||||
|
public static final ImageIcon flagWrong = createImageIcon("flagWrong.png");
|
||||||
|
|
||||||
|
public static final ImageIcon one = createImageIcon("1one.png");
|
||||||
|
public static final ImageIcon two = createImageIcon("2two.png");
|
||||||
|
public static final ImageIcon three = createImageIcon("3three.png");
|
||||||
|
public static final ImageIcon four = createImageIcon("4four.png");
|
||||||
|
public static final ImageIcon five = createImageIcon("5five.png");
|
||||||
|
public static final ImageIcon six = createImageIcon("6six.png");
|
||||||
|
public static final ImageIcon seven = createImageIcon("7seven.png");
|
||||||
|
public static final ImageIcon eight = createImageIcon("8eight.png");
|
||||||
|
|
||||||
|
private static final String path = "berack96/games/minefield/assets/icons/";
|
||||||
|
|
||||||
|
private static ImageIcon createImageIcon(String name)
|
||||||
|
{
|
||||||
|
java.net.URL imgURL = ClassLoader.getSystemResource(path+name);
|
||||||
|
if (imgURL != null)
|
||||||
|
return new ImageIcon(imgURL);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("Couldn't find file: " + name);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
213
src/main/java/berack96/games/minefield/object/view/CellView.java
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
package berack96.games.minefield.object.view;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
|
||||||
|
import berack96.games.minefield.object.Cell;
|
||||||
|
import berack96.games.minefield.object.CellStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe che serve a restituire graficamente (stringa o jlabel) la cella che si desidera.
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CellView implements Observer {
|
||||||
|
|
||||||
|
private final Cell cell;
|
||||||
|
|
||||||
|
private String string;
|
||||||
|
private JLabel label;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Costruttore: la cella passata, sara' ora osservvata dall'istanza creata
|
||||||
|
*
|
||||||
|
* @param cell La cella
|
||||||
|
*/
|
||||||
|
public CellView(Cell cell)
|
||||||
|
{
|
||||||
|
this.cell = cell;
|
||||||
|
cell.addObserver(this);
|
||||||
|
|
||||||
|
string = CellView.toString(cell);
|
||||||
|
label = CellView.toJLabel(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ritorna la rappresentazione della cella sottoforma di stringa:<br>
|
||||||
|
* [ ] - {@link CellStatus#UNCOVERED} 0 mine vicine<br>
|
||||||
|
* [n] - {@link CellStatus#UNCOVERED} con "n" mine vicine<br>
|
||||||
|
* [D] - {@link CellStatus#DANGEROUS}<br>
|
||||||
|
* [*] - {@link CellStatus#EXPLODED}<br>
|
||||||
|
* [V] - {@link CellStatus#GOTRIGHT}<br>
|
||||||
|
* [X] - {@link CellStatus#GOTWRONG}<br>
|
||||||
|
* [#] - {@link CellStatus#COVERED}<br>
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ritorna la rappresentazione della cella sottoforma di JLabel:<br>
|
||||||
|
* {@link CellStatus#UNCOVERED} bianco con eventuale numero<br>
|
||||||
|
* {@link CellStatus#DANGEROUS} con icona di una bandiera<br>
|
||||||
|
* {@link CellStatus#EXPLODED} con una icona di una mina<br>
|
||||||
|
* {@link CellStatus#GOTRIGHT} con una icona di una bandierina cerchiata di verde<br>
|
||||||
|
* {@link CellStatus#GOTWRONG} - con una icona di una bandierina crociata di rosso<br>
|
||||||
|
* {@link CellStatus#COVERED} - grigio chiaro<br>
|
||||||
|
*
|
||||||
|
* @return JLabel
|
||||||
|
*/
|
||||||
|
public JLabel toJLabel()
|
||||||
|
{
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Observable arg0, Object arg1)
|
||||||
|
{
|
||||||
|
CellStatus status = cell.getStatus();
|
||||||
|
|
||||||
|
if(status == CellStatus.UNCOVERED)
|
||||||
|
{
|
||||||
|
label.setBackground(Color.WHITE);
|
||||||
|
label.setIcon(null);
|
||||||
|
|
||||||
|
if(cell.nearMine == 0)
|
||||||
|
string = "[ ]";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string = "["+cell.nearMine+"]";
|
||||||
|
switch(cell.nearMine)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
label.setIcon(CellIcons.one);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
label.setIcon(CellIcons.two);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
label.setIcon(CellIcons.three);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
label.setIcon(CellIcons.four);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
label.setIcon(CellIcons.five);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
label.setIcon(CellIcons.six);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
label.setIcon(CellIcons.seven);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
label.setIcon(CellIcons.eight);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(status == CellStatus.DANGEROUS)
|
||||||
|
{
|
||||||
|
string = "[D]";
|
||||||
|
label.setBackground(Color.LIGHT_GRAY);
|
||||||
|
label.setIcon(CellIcons.flag);
|
||||||
|
}
|
||||||
|
else if(status == CellStatus.EXPLODED)
|
||||||
|
{
|
||||||
|
string = "[*]";
|
||||||
|
label.setBackground(Color.LIGHT_GRAY);
|
||||||
|
label.setIcon(CellIcons.mine);
|
||||||
|
}
|
||||||
|
else if(status == CellStatus.GOTRIGHT)
|
||||||
|
{
|
||||||
|
string = "[V]";
|
||||||
|
label.setBackground(Color.LIGHT_GRAY);
|
||||||
|
label.setIcon(CellIcons.flagRight);
|
||||||
|
}
|
||||||
|
else if(status == CellStatus.GOTWRONG)
|
||||||
|
{
|
||||||
|
string = "[X]";
|
||||||
|
label.setBackground(Color.LIGHT_GRAY);
|
||||||
|
label.setIcon(CellIcons.flagWrong);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string = "[#]";
|
||||||
|
label.setBackground(Color.LIGHT_GRAY);
|
||||||
|
label.setIcon(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metodo statico che serve, passata una cella, a trasformarla in stringa<br>
|
||||||
|
* secondo {@link #toString()}.
|
||||||
|
*
|
||||||
|
* @param cell La cella da vedere
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public static String toString(Cell cell)
|
||||||
|
{
|
||||||
|
CellStatus status = cell.getStatus();
|
||||||
|
|
||||||
|
if(status == CellStatus.UNCOVERED)
|
||||||
|
{
|
||||||
|
if(cell.nearMine == 0)
|
||||||
|
return "[ ]";
|
||||||
|
else
|
||||||
|
return "["+cell.nearMine+"]";
|
||||||
|
}
|
||||||
|
else if(status == CellStatus.DANGEROUS)
|
||||||
|
return "[D]";
|
||||||
|
else if(status == CellStatus.EXPLODED)
|
||||||
|
return "[*]";
|
||||||
|
else if(status == CellStatus.GOTRIGHT)
|
||||||
|
return "[V]";
|
||||||
|
else
|
||||||
|
return "[#]";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metodo statico che serve, passata una cella, a trasformarla in jpanel<br>
|
||||||
|
* secondo {@link #toJLabel()}.
|
||||||
|
*
|
||||||
|
* @param cell La cella da vedere
|
||||||
|
* @return JLabel
|
||||||
|
*/
|
||||||
|
public static JLabel toJLabel(Cell cell)
|
||||||
|
{
|
||||||
|
CellStatus status = cell.getStatus();
|
||||||
|
JLabel label = new JLabel();
|
||||||
|
|
||||||
|
label.setOpaque(true);
|
||||||
|
label.setBorder(BorderFactory.createLineBorder(Color.BLACK));
|
||||||
|
label.setPreferredSize(new Dimension(25, 25));
|
||||||
|
label.setSize(label.getPreferredSize());
|
||||||
|
label.setVisible(true);
|
||||||
|
|
||||||
|
if(status == CellStatus.UNCOVERED)
|
||||||
|
{
|
||||||
|
label.setBackground(Color.WHITE);
|
||||||
|
if(cell.nearMine != 0)
|
||||||
|
label.setText("["+cell.nearMine+"]");
|
||||||
|
}
|
||||||
|
else if(status == CellStatus.DANGEROUS)
|
||||||
|
label.setBackground(Color.BLACK);
|
||||||
|
else if(status == CellStatus.EXPLODED)
|
||||||
|
label.setBackground(Color.RED);
|
||||||
|
else if(status == CellStatus.GOTRIGHT)
|
||||||
|
label.setBackground(Color.GREEN);
|
||||||
|
else
|
||||||
|
label.setBackground(Color.LIGHT_GRAY);
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
package berack96.games.minefield.object.view;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
import berack96.games.minefield.listener.CellInFieldListener;
|
||||||
|
import berack96.games.minefield.object.Field;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe che mostra il campo da gioco in modo grafico (tramite stringhe o jpanel).
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FieldView {
|
||||||
|
|
||||||
|
private final Field field;
|
||||||
|
|
||||||
|
private String string;
|
||||||
|
private JPanel panel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Costruttore in cui si inserisce il campo e un eventuale listener<br>
|
||||||
|
* su ogni cella del campo
|
||||||
|
*
|
||||||
|
* @param field Il campo da vedere
|
||||||
|
* @param listener il controllore delle celle
|
||||||
|
*/
|
||||||
|
public FieldView(Field field, CellInFieldListener listener)
|
||||||
|
{
|
||||||
|
this.field = field;
|
||||||
|
|
||||||
|
string = toString(field);
|
||||||
|
panel = toJPanel(field, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce il campo sottoforma di stringa.<br>
|
||||||
|
* Per valori celle vedi {@link CellView#toString()}.
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
string = toString(field);
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce il campo sottoforma di jpanel.<br>
|
||||||
|
* Per valori celle vedi {@link CellView#toJLabel()}.
|
||||||
|
*
|
||||||
|
* @return JPanel
|
||||||
|
*/
|
||||||
|
public JPanel toJPanel()
|
||||||
|
{
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metodo statico che serve, passato un campo, a trasformarlo in stringa<br>
|
||||||
|
* secondo {@link #toString()}.
|
||||||
|
*
|
||||||
|
* @param field il campo da vedere
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public static String toString(Field field)
|
||||||
|
{
|
||||||
|
String string = new String();
|
||||||
|
|
||||||
|
for(int i=0; i<field.lines; i++)
|
||||||
|
{
|
||||||
|
for(int j=0; j<field.columns; j++)
|
||||||
|
string += CellView.toString(field.getCell(i, j));
|
||||||
|
|
||||||
|
string += "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metodo statico che serve, passato un campo, a trasformarlo in jpanel<br>
|
||||||
|
* secondo {@link #toJPanel()}.
|
||||||
|
*
|
||||||
|
* @param field il campo da vedere
|
||||||
|
* @param listener eventuale controller da applicare ad ogni cella
|
||||||
|
* @return JPanel
|
||||||
|
*/
|
||||||
|
public static JPanel toJPanel(Field field, CellInFieldListener listener)
|
||||||
|
{
|
||||||
|
JPanel panel = new JPanel();
|
||||||
|
|
||||||
|
panel.setLayout(new GridLayout(field.lines, field.columns));
|
||||||
|
panel.setVisible(true);
|
||||||
|
|
||||||
|
for(int i=0; i<field.lines; i++)
|
||||||
|
for(int j=0; j<field.columns; j++)
|
||||||
|
{
|
||||||
|
JLabel cell = new CellView(field.getCell(i, j)).toJLabel();
|
||||||
|
|
||||||
|
cell.setName(i+"-"+j);
|
||||||
|
if(listener != null)
|
||||||
|
cell.addMouseListener(listener);
|
||||||
|
|
||||||
|
panel.add(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dimension dim = CellView.toJLabel(field.getCell(0, 0)).getPreferredSize();
|
||||||
|
|
||||||
|
panel.setPreferredSize(new Dimension(dim.height*field.columns, dim.width*field.lines));
|
||||||
|
panel.setSize(panel.getPreferredSize());
|
||||||
|
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package berack96.games.minefield.runexception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lanciata perche' le coordinate indicano una area al di fuori del campo.
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class OutOfBoundsException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public OutOfBoundsException()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public OutOfBoundsException(String arg0)
|
||||||
|
{
|
||||||
|
super(arg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package berack96.games.minefield.runexception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lanciata perche' il valore inserito e' torppo alto
|
||||||
|
*
|
||||||
|
* @author Jack
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TooHighValueException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public TooHighValueException()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TooHighValueException(String arg0)
|
||||||
|
{
|
||||||
|
super(arg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
217
src/main/java/jbook/util/Input.java
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
package jbook.util;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Una semplice classe per leggere stringhe e numeri
|
||||||
|
dallo standard input.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Input{
|
||||||
|
|
||||||
|
private static BufferedReader reader =
|
||||||
|
new BufferedReader(new InputStreamReader(System.in));
|
||||||
|
|
||||||
|
/**
|
||||||
|
Legge una linea di input. Nell'improbabile caso di una
|
||||||
|
IOException, il programma termina.
|
||||||
|
@return restituisce la linea di input che l'utente ha battuto.
|
||||||
|
*/
|
||||||
|
public static String readString(){
|
||||||
|
String inputLine = "";
|
||||||
|
try{
|
||||||
|
inputLine = reader.readLine();
|
||||||
|
}
|
||||||
|
catch(IOException e){
|
||||||
|
System.out.println(e);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
return inputLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String readString(String msg){
|
||||||
|
System.out.print(msg);
|
||||||
|
String inputLine = readString();
|
||||||
|
return inputLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Legge una linea di input e la converte in un byte.
|
||||||
|
Eventuali spazi bianchi prima e dopo l'intero vengono ignorati.
|
||||||
|
@return l'intero dato in input dall'utente
|
||||||
|
*/
|
||||||
|
public static byte readByte(){
|
||||||
|
String inputString = readString();
|
||||||
|
inputString = inputString.trim();
|
||||||
|
byte n = Byte.parseByte(inputString);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte readByte(String msg){
|
||||||
|
System.out.print(msg);
|
||||||
|
byte n = readByte();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Legge una linea di input e la converte in uno short.
|
||||||
|
Eventuali spazi bianchi prima e dopo l'intero vengono ignorati.
|
||||||
|
@return l'intero dato in input dall'utente
|
||||||
|
*/
|
||||||
|
public static short readShort(){
|
||||||
|
String inputString = readString();
|
||||||
|
inputString = inputString.trim();
|
||||||
|
short n = Short.parseShort(inputString);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static short readShort(String msg){
|
||||||
|
System.out.print(msg);
|
||||||
|
short n = readShort();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Legge una linea di input e la converte in un int.
|
||||||
|
Eventuali spazi bianchi prima e dopo l'intero vengono ignorati.
|
||||||
|
@return l'intero dato in input dall'utente
|
||||||
|
*/
|
||||||
|
public static int readInt(){
|
||||||
|
String inputString = readString();
|
||||||
|
inputString = inputString.trim();
|
||||||
|
int n = Integer.parseInt(inputString);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int readInt(String msg){
|
||||||
|
System.out.print(msg);
|
||||||
|
int n = readInt();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Legge una linea di input e la converte in un long.
|
||||||
|
Eventuali spazi bianchi prima e dopo l'intero vengono ignorati.
|
||||||
|
@return l'intero dato in input dall'utente
|
||||||
|
*/
|
||||||
|
public static long readLong(){
|
||||||
|
String inputString = readString();
|
||||||
|
inputString = inputString.trim();
|
||||||
|
long n = Long.parseLong(inputString);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long readLong(String msg){
|
||||||
|
System.out.print(msg);
|
||||||
|
long n = readLong();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Legge una linea di input e la converte in un numero
|
||||||
|
in virgola mobile a precisione singola. Eventuali spazi bianchi prima e
|
||||||
|
dopo il numero vengono ignorati.
|
||||||
|
@return il numero dato in input dall'utente
|
||||||
|
*/
|
||||||
|
public static float readFloat(){
|
||||||
|
String inputString = readString();
|
||||||
|
inputString = inputString.trim();
|
||||||
|
float x = Float.parseFloat(inputString);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float readFloat(String msg){
|
||||||
|
System.out.print(msg);
|
||||||
|
float x = readFloat();
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Legge una linea di input e la converte in un numero
|
||||||
|
in virgola mobile a precisione doppia. Eventuali spazi bianchi prima e
|
||||||
|
dopo il numero vengono ignorati.
|
||||||
|
@return il numero dato in input dall'utente
|
||||||
|
*/
|
||||||
|
public static double readDouble(){
|
||||||
|
String inputString = readString();
|
||||||
|
inputString = inputString.trim();
|
||||||
|
double x = Double.parseDouble(inputString);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double readDouble(String msg){
|
||||||
|
System.out.print(msg);
|
||||||
|
double x = readDouble();
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Legge una linea di input e ne estrae il primo carattere.
|
||||||
|
@return il primo carattere della riga data in input dall'utente
|
||||||
|
*/
|
||||||
|
public static char readChar(){
|
||||||
|
String inputString = readString();
|
||||||
|
char c = inputString.charAt(0);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static char readChar(String msg){
|
||||||
|
System.out.print(msg);
|
||||||
|
char c = readChar();
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Legge una linea di input e restituisce true se la stringa
|
||||||
|
e' equals a "true" a meno di maiuscole e minuscole, false altrimenti.
|
||||||
|
@return il booeano dato in input dall'utente
|
||||||
|
*/
|
||||||
|
public static boolean readBool(){
|
||||||
|
String inputString = readString();
|
||||||
|
inputString = inputString.trim();
|
||||||
|
boolean b = Boolean.parseBoolean(inputString);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean readBool(String msg){
|
||||||
|
System.out.print(msg);
|
||||||
|
boolean b = readBool();
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Legge una sequenza di stringhe conclusa dalla stringa vuota e
|
||||||
|
restituisce la sequenza in un nuovo array di stringhe.
|
||||||
|
@return l'array delle stringhe date in input dal'utente
|
||||||
|
*/
|
||||||
|
public static String[] readSeq(){
|
||||||
|
String[] seq = readSeq("");
|
||||||
|
return seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] readSeq(String prompt){
|
||||||
|
Vector<String> seqTemp = new Vector<String>();
|
||||||
|
System.out.print(prompt);
|
||||||
|
String inputString = readString();
|
||||||
|
while (inputString.length()>0) {
|
||||||
|
seqTemp.add(inputString);
|
||||||
|
System.out.print(prompt);
|
||||||
|
inputString = readString();
|
||||||
|
}
|
||||||
|
String[] seq = new String[seqTemp.size()];
|
||||||
|
return seqTemp.toArray(seq);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] readSeq(String msg, String prompt){
|
||||||
|
System.out.println(msg);
|
||||||
|
String[] seq = readSeq(prompt);
|
||||||
|
return seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
59
src/test/java/berack96/test/games/minefield/TestCell.java
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
package berack96.test.games.minefield;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import berack96.games.minefield.object.Cell;
|
||||||
|
import berack96.games.minefield.object.CellStatus;
|
||||||
|
|
||||||
|
public class TestCell {
|
||||||
|
|
||||||
|
public Cell cell;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public void initialize() {
|
||||||
|
cell = new Cell();
|
||||||
|
assertEquals(cell.getStatus(), CellStatus.COVERED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void cellUncover() {
|
||||||
|
assertFalse(cell.isUncovered());
|
||||||
|
cell.uncover();
|
||||||
|
assertTrue(cell.isUncovered());
|
||||||
|
assertEquals(cell.getStatus(), CellStatus.UNCOVERED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void cellMine() {
|
||||||
|
assertFalse(cell.isMine());
|
||||||
|
cell.setMine();
|
||||||
|
assertFalse(cell.isUncovered());
|
||||||
|
assertTrue(cell.isMine());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void cellDangerous() {
|
||||||
|
cell.setDangerous();
|
||||||
|
assertFalse(cell.isUncovered());
|
||||||
|
assertEquals(cell.getStatus(), CellStatus.DANGEROUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void cellUncoveredMine() {
|
||||||
|
cell.setMine();
|
||||||
|
cell.uncover();
|
||||||
|
assertEquals(cell.getStatus(), CellStatus.EXPLODED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void cellUncoveredMineDangerous() {
|
||||||
|
cell.setMine();
|
||||||
|
cell.setDangerous();
|
||||||
|
cell.uncover();
|
||||||
|
|
||||||
|
assertEquals(cell.getStatus(), CellStatus.GOTRIGHT);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package berack96.test.games.minefield;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import berack96.games.minefield.object.FieldNoSafe;
|
||||||
|
|
||||||
|
public class TestFieldNoSafe {
|
||||||
|
|
||||||
|
public FieldNoSafe field;
|
||||||
|
public final int height = 10;
|
||||||
|
public final int length = 20;
|
||||||
|
public final int mines = 10;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public void initialize() {
|
||||||
|
field = new FieldNoSafe(this.length, this.height, this.mines);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fieldStart() {
|
||||||
|
assertEquals(field.lines, this.height);
|
||||||
|
assertEquals(field.lines, this.length);
|
||||||
|
assertEquals(field.getNumCoveredCell(), this.height*this.length);
|
||||||
|
assertEquals(field.getNumDagerousCell(), 0);
|
||||||
|
assertEquals(field.getNumUncoveredCell(), 0);
|
||||||
|
assertEquals(field.getNumMines(), this.mines);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package berack96.test.games.minefield;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class TestFieldSafe {
|
||||||
|
|
||||||
|
}
|
||||||