Browse Source

Lots of improvements and Pattern Editor

Tankernn 8 years ago
parent
commit
f4a0fe2fef

+ 1 - 0
.classpath

@@ -6,6 +6,7 @@
 			<attribute name="maven.pomderived" value="true"/>
 			<attribute name="maven.pomderived" value="true"/>
 		</attributes>
 		</attributes>
 	</classpathentry>
 	</classpathentry>
+	<classpathentry kind="src" path="res"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
 		<attributes>
 		<attributes>
 			<attribute name="maven.pomderived" value="true"/>
 			<attribute name="maven.pomderived" value="true"/>

+ 111 - 36
src/main/java/eu/tankernn/mines/Mines.java

@@ -1,45 +1,85 @@
 package eu.tankernn.mines;
 package eu.tankernn.mines;
 
 
+import java.io.FileNotFoundException;
+import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
 import java.util.Random;
 import java.util.Random;
-import java.util.Scanner;
 
 
+import org.lwjgl.Sys;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.input.Mouse;
+import org.lwjgl.opengl.Display;
 import org.lwjgl.util.vector.Vector2f;
 import org.lwjgl.util.vector.Vector2f;
 
 
 import eu.tankernn.gameEngine.GameLauncher;
 import eu.tankernn.gameEngine.GameLauncher;
 import eu.tankernn.gameEngine.TankernnGame;
 import eu.tankernn.gameEngine.TankernnGame;
+import eu.tankernn.gameEngine.loader.font.FontType;
+import eu.tankernn.gameEngine.loader.font.GUIText;
 import eu.tankernn.gameEngine.loader.textures.Texture;
 import eu.tankernn.gameEngine.loader.textures.Texture;
 import eu.tankernn.gameEngine.renderEngine.gui.GuiRenderer;
 import eu.tankernn.gameEngine.renderEngine.gui.GuiRenderer;
 import eu.tankernn.gameEngine.renderEngine.gui.GuiTexture;
 import eu.tankernn.gameEngine.renderEngine.gui.GuiTexture;
+import eu.tankernn.gameEngine.util.InternalFile;
 import eu.tankernn.mines.Tile.TileState;
 import eu.tankernn.mines.Tile.TileState;
 
 
 public class Mines extends TankernnGame {
 public class Mines extends TankernnGame {
 	public static String GAME_NAME = "Minesweeper";
 	public static String GAME_NAME = "Minesweeper";
+	public static Pos[] DEFAULT_PATTERN = { new Pos(0, 1), new Pos(0, -1), new Pos(1, 0), new Pos(1, 1), new Pos(1, -1),
+			new Pos(-1, 0), new Pos(-1, -1), new Pos(-1, 1) };
 
 
 	private Random rand = new Random();
 	private Random rand = new Random();
-	private Scanner sc = new Scanner(System.in);
+	private DecimalFormat format = new DecimalFormat("0.000 sec");
 	private GuiRenderer renderer;
 	private GuiRenderer renderer;
-	
-	private Texture hidden, checked, exploded, flagged;
+	private PatternEditor editor;
 
 
-	private int boardWidth, boardHeight;
+	private Texture hidden, exploded, flagged;
+	private Texture[] checked;
+	private GUIText timeText;
+	private long startTime;
+
+	private int boardWidth = 20, boardHeight = 20;
+	private int tileWidth, tileHeight;
 	private Tile[][] tiles;
 	private Tile[][] tiles;
-	private Pos[] pattern = {new Pos(0, 1), new Pos(0, -1), new Pos(1, 0), new Pos(1, 1), new Pos(1, -1), new Pos(-1, 0), new Pos(-1, -1), new Pos(-1, 1)};
-	private int totalMines;
-	private boolean running;
+	private Pos[] pattern = DEFAULT_PATTERN;
+	private int totalMines = 200;
+	private int hiddenTiles;
+	private boolean running = false;
+	private boolean justClicked = false;
 
 
 	public Mines(String name) {
 	public Mines(String name) {
 		super(name);
 		super(name);
 		renderer = new GuiRenderer(loader);
 		renderer = new GuiRenderer(loader);
 
 
-		totalMines = 10;
-		boardWidth = boardHeight = 7;
+		tileWidth = Display.getWidth() / boardWidth;
+		tileHeight = Display.getHeight() / boardHeight;
+
+		try {
+			hidden = loader.loadTexture("hidden.png");
+			checked = new Texture[10];
+			for (int i = 0; i < checked.length; i++)
+				checked[i] = loader.loadTexture(i + ".png");
+			exploded = loader.loadTexture("exploded.png");
+			flagged = loader.loadTexture("flagged.png");
+			FontType font = new FontType(loader.loadTexture("arial.png"), new InternalFile("arial.fnt"));
+			timeText = new GUIText(format.format(0), 1f, font, new Vector2f(0f, 0f), 100, false);
+			GUIText helpText = new GUIText("R - reset, \n E - edit pattern", 1f, font, new Vector2f(0.8f, 0f), 0.15f, false);
+			textMaster.loadText(timeText);
+			textMaster.loadText(helpText);
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		}
 
 
+		startGame(DEFAULT_PATTERN);
+	}
+
+	public void startGame(Pos[] pattern) {
+		this.pattern = pattern;
 		startGame();
 		startGame();
 	}
 	}
 
 
-	public void startGame() {
+	private void startGame() {
+		startTime = Sys.getTime();
+		hiddenTiles = boardHeight * boardWidth;
 		List<Pos> minePositions = new ArrayList<Pos>();
 		List<Pos> minePositions = new ArrayList<Pos>();
 		for (int i = 0; i < totalMines; i++) {
 		for (int i = 0; i < totalMines; i++) {
 			minePositions.add(new Pos(rand.nextInt(boardWidth), rand.nextInt(boardHeight)));
 			minePositions.add(new Pos(rand.nextInt(boardWidth), rand.nextInt(boardHeight)));
@@ -52,7 +92,7 @@ public class Mines extends TankernnGame {
 				tiles[x][y] = new Tile(minePositions.contains(new Pos(x, y)), new Pos(x, y));
 				tiles[x][y] = new Tile(minePositions.contains(new Pos(x, y)), new Pos(x, y));
 			}
 			}
 		}
 		}
-		
+
 		running = true;
 		running = true;
 	}
 	}
 
 
@@ -65,6 +105,8 @@ public class Mines extends TankernnGame {
 	}
 	}
 
 
 	public void calculateMinesAround(Tile tile) {
 	public void calculateMinesAround(Tile tile) {
+		hiddenTiles--;
+
 		int count = 0;
 		int count = 0;
 		List<Tile> testTiles = new ArrayList<Tile>();
 		List<Tile> testTiles = new ArrayList<Tile>();
 
 
@@ -96,39 +138,73 @@ public class Mines extends TankernnGame {
 					t.setState(TileState.EXPLODED);
 					t.setState(TileState.EXPLODED);
 	}
 	}
 
 
+	private void win() {
+		running = false;
+	}
+
 	@Override
 	@Override
 	public void update() {
 	public void update() {
-		
-		String[] command = sc.nextLine().split(" ");
-		
-		int x = Integer.parseInt(command[1]), y = Integer.parseInt(command[2]);
-		
-		switch (command[0]) {
-		case "flag":
-			tiles[x][y].toggleFlag();
-			break;
-		case "check":
-			check(tiles[x][y]);
-			break;
-		default:
-			System.out.println("Unknown command.");
+		// { // Command selection
+		// String[] command = sc.nextLine().split(" ");
+		//
+		// int x = Integer.parseInt(command[1]), y =
+		// Integer.parseInt(command[2]);
+		//
+		// switch (command[0]) {
+		// case "flag":
+		// tiles[x][y].toggleFlag();
+		// break;
+		// case "check":
+		// check(tiles[x][y]);
+		// break;
+		// default:
+		// System.out.println("Unknown command.");
+		// }
+		// }
+		{ // Mouse selection
+			if (Mouse.isButtonDown(1) || Mouse.isButtonDown(0)) {
+				if (!justClicked && running) {
+					justClicked = true;
+					int x, y;
+					x = Mouse.getX() / tileWidth;
+					y = Mouse.getY() / tileHeight;
+
+					if (Mouse.isButtonDown(0)) {
+						check(tiles[x][y]);
+					} else {
+						tiles[x][y].toggleFlag();
+					}
+				}
+			} else
+				justClicked = false;
 		}
 		}
-		
+
+		if (running)
+			timeText.setText(format.format(((float) (Sys.getTime() - startTime)) / Sys.getTimerResolution()));
+		else if (Keyboard.isKeyDown(Keyboard.KEY_R))
+			startGame();
+		else if (Keyboard.isKeyDown(Keyboard.KEY_E) && (editor == null || !editor.isShowing()))
+			editor = new PatternEditor(this);
+
+		if (hiddenTiles == totalMines)
+			win();
+
 		super.update();
 		super.update();
 	}
 	}
 
 
 	@Override
 	@Override
 	public void render() {
 	public void render() {
 		List<GuiTexture> toRender = new ArrayList<GuiTexture>();
 		List<GuiTexture> toRender = new ArrayList<GuiTexture>();
-		
+
 		for (int y = 0; y < boardHeight; y++) {
 		for (int y = 0; y < boardHeight; y++) {
 			for (int x = 0; x < boardWidth; x++) {
 			for (int x = 0; x < boardWidth; x++) {
 				Tile t = tiles[x][y];
 				Tile t = tiles[x][y];
-				System.out.print(t.getState().equals(TileState.CHECKED) ? Integer.toString(t.getMinesAround()) : t.getState().appearance);
+				System.out.print(t.getState().equals(TileState.CHECKED) ? Integer.toString(t.getMinesAround())
+						: t.getState().appearance);
 				Texture tex;
 				Texture tex;
 				switch (t.getState()) {
 				switch (t.getState()) {
 				case CHECKED:
 				case CHECKED:
-					tex = checked;
+					tex = checked[t.getMinesAround()];
 					break;
 					break;
 				case EXPLODED:
 				case EXPLODED:
 					tex = exploded;
 					tex = exploded;
@@ -143,22 +219,21 @@ public class Mines extends TankernnGame {
 					tex = hidden;
 					tex = hidden;
 					break;
 					break;
 				}
 				}
-				toRender.add(new GuiTexture(tex, new Vector2f(), new Vector2f()));
+				Vector2f scale = new Vector2f(1f / boardWidth, 1f / boardHeight);
+				toRender.add(new GuiTexture(tex,
+						new Vector2f(2 * scale.x * t.pos.x + scale.x - 1, 2 * scale.y * t.pos.y + scale.y - 1), scale));
 			}
 			}
 			System.out.println();
 			System.out.println();
 		}
 		}
 		System.out.println("-------------------");
 		System.out.println("-------------------");
-		
-		
+
 		renderer.render(toRender);
 		renderer.render(toRender);
-		
 
 
 		super.render();
 		super.render();
 	}
 	}
-	
+
 	@Override
 	@Override
 	public void cleanUp() {
 	public void cleanUp() {
-		sc.close();
 		super.cleanUp();
 		super.cleanUp();
 	}
 	}
 
 

+ 92 - 0
src/main/java/eu/tankernn/mines/PatternEditor.java

@@ -0,0 +1,92 @@
+package eu.tankernn.mines;
+
+import java.awt.BorderLayout;
+import java.awt.EventQueue;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.border.EmptyBorder;
+
+@SuppressWarnings("serial")
+public class PatternEditor extends JFrame {
+
+	private JPanel contentPane;
+	private int radius = 3, size = radius * 2 + 1;
+	private Mines gameInstance;
+
+	/**
+	 * Launch the application.
+	 */
+	public static void main(String[] args) {
+		EventQueue.invokeLater(new Runnable() {
+			public void run() {
+				try {
+					PatternEditor frame = new PatternEditor(null);
+					frame.setVisible(true);
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+		});
+	}
+
+	/**
+	 * Create the frame.
+	 */
+	public PatternEditor(Mines instance) {
+		gameInstance = instance;
+		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		contentPane = new JPanel();
+		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
+		contentPane.setLayout(new BorderLayout(0, 0));
+		setContentPane(contentPane);
+
+		JPanel grid = new JPanel();
+		grid.setLayout(new GridLayout(size, size));
+
+		JCheckBox[][] boxes = new JCheckBox[size][size];
+
+		for (int x = 0; x < boxes.length; x++) {
+			for (int y = 0; y < boxes[x].length; y++) {
+				JCheckBox box = new JCheckBox();
+				boxes[x][y] = box;
+				grid.add(box);
+			}
+		}
+
+		boxes[radius][radius].setEnabled(false);
+
+		JButton save = new JButton("Save");
+		save.addActionListener(new ActionListener() {
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				List<Pos> pattern = new ArrayList<Pos>();
+				for (int x = 0; x < boxes.length; x++) {
+					for (int y = 0; y < boxes[x].length; y++) {
+						if (boxes[x][y].isSelected())
+							pattern.add(new Pos(x - radius, y - radius));
+					}
+				}
+				if (gameInstance != null) {
+					gameInstance.startGame(pattern.toArray(new Pos[pattern.size()]));
+					dispose();
+				}
+			}
+		});
+
+		contentPane.add(grid, BorderLayout.CENTER);
+		contentPane.add(save, BorderLayout.SOUTH);
+
+		pack();
+		setTitle("Minesweeper pattern editor");
+		setVisible(true);
+	}
+}

+ 1 - 1
src/main/java/eu/tankernn/mines/Tile.java

@@ -31,7 +31,7 @@ public class Tile {
 	public void toggleFlag() {
 	public void toggleFlag() {
 		if (this.state.equals(TileState.HIDDEN))
 		if (this.state.equals(TileState.HIDDEN))
 			this.setState(TileState.FLAGGED);
 			this.setState(TileState.FLAGGED);
-		else
+		else if (this.state.equals(TileState.FLAGGED))
 			this.setState(TileState.HIDDEN);
 			this.setState(TileState.HIDDEN);
 	}
 	}