package main;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Scanner;
import java.io.*;
public class Sokoban extends JFrame implements KeyListener, ActionListener{
private static final long serialVersionUID = 1L;
private Level game;
private JPanel playground;
private JPanel container;
private JPanel info;
private JPanel buttons;
private JLabel top;
private JPanel header;
private JPanel moves;
private JButton undo;
private JButton newGame;
private JButton viewMoves;
private JButton restart;
private String levelMap;
private ImageIcon wall = new ImageIcon("resources/wall16x16.png");
private ImageIcon blank = new ImageIcon("resources/blank16x16.png");
private ImageIcon target = new ImageIcon("resources/target16x16.png");
private ImageIcon mover = new ImageIcon("resources/mover16x16.png");
private ImageIcon mover_on_target = new ImageIcon("resources/mover_on_target16x16.png");
private ImageIcon movable = new ImageIcon("resources/movable16x16.png");
private ImageIcon movable_on_target = new ImageIcon("resources/movable_on_target16x16.png");
/*
private ImageIcon wall = new ImageIcon(getClass().getResource("wall16x16.png"));
private ImageIcon blank = new ImageIcon(getClass().getResource("blank16x16.png"));
private ImageIcon target = new ImageIcon(getClass().getResource("target16x16.png"));
private ImageIcon mover = new ImageIcon(getClass().getResource("mover16x16.png"));
private ImageIcon mover_on_target = new ImageIcon(getClass().getResource("mover_on_target16x16.png"));
private ImageIcon movable = new ImageIcon(getClass().getResource("movable16x16.png"));
private ImageIcon movable_on_target = new ImageIcon(getClass().getResource("movable_on_target16x16.png"));
*/
public Sokoban(boolean chooseMap, String map) throws Exception {
this.remove(this);
this.setTitle("Sokoban");
this.setSize(600, 500);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.setLayout(new GridLayout(3,1));
this.setResizable(false);
this.setFocusable(true);
this.addKeyListener(this);
this.header = new JPanel();
this.header.setLayout(new GridLayout(2,1));
this.info = new JPanel();
this.header.add(info);
this.moves = new JPanel();
this.header.add(moves);
this.add(this.header);
Font headerFont = new Font("Verdana", Font.BOLD, 24);
this.top = new JLabel("Sokoban", SwingConstants.CENTER);
this.top.setFont(headerFont);
this.info.add(top);
this.info.setAlignmentY(CENTER_ALIGNMENT);
this.container = new JPanel();
this.add(container);
this.buttons = new JPanel();
this.undo = new JButton("Angre flytt (Z)");
this.viewMoves = new JButton("Vis alle flytt (V)");
this.restart = new JButton("Restart (R)");
this.newGame = new JButton("Nytt spill (N)");
this.buttons.add(undo);
this.buttons.add(viewMoves);
this.buttons.add(restart);
this.buttons.add(newGame);
this.undo.addActionListener(this);
this.viewMoves.addActionListener(this);
this.restart.addActionListener(this);
this.newGame.addActionListener(this);
this.add(buttons);
this.pickLevel(chooseMap, map);
}
public void pickLevel(boolean chooseMap, String map) {
if (chooseMap) {
JFileChooser fileChooser = new JFileChooser();
if(fileChooser.showOpenDialog(null)==JFileChooser.APPROVE_OPTION){
File file = fileChooser.getSelectedFile();
this.levelMap = file.getPath();
Scanner input = null;
try {
input = new Scanner(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
game = new Level(input.nextLine());
}
}
else {
if(map == null) {
Reader reader = null;
try {
reader = new FileReader("resources/level1.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
this.levelMap = "resources/level1.txt";
BufferedReader b = new BufferedReader(reader);
String level = null;
try {
level = b.readLine();
} catch (IOException e) {
e.printStackTrace();
}
game = new Level(level);
}
else {
Reader reader = null;
try {
reader = new FileReader(map);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
this.levelMap = map;
BufferedReader b = new BufferedReader(reader);
String level = null;
try {
level = b.readLine();
} catch (IOException e) {
e.printStackTrace();
}
game = new Level(level);
}
}
this.container.setSize(game.getWidth()*16, game.getHeight()*16);
this.draw();
}
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()){
case KeyEvent.VK_DOWN: if (game.checkMove(0, 1)) {game.doMove(0, 1); this.draw();} break;
case KeyEvent.VK_UP: if (game.checkMove(0, -1)) {game.doMove(0, -1); this.draw();} break;
case KeyEvent.VK_LEFT: if (game.checkMove(-1, 0)) {game.doMove(-1, 0); this.draw();} break;
case KeyEvent.VK_RIGHT: if (game.checkMove(1, 0)) {game.doMove(1, 0); this.draw();} break;
case KeyEvent.VK_Z: game.undoMove(); this.draw(); this.requestFocus(); break;
case KeyEvent.VK_V: this.displayMoves(); this.requestFocus(); break;
case KeyEvent.VK_R: this.pickLevel(false, this.levelMap); this.requestFocus(); break;
case KeyEvent.VK_N: this.pickLevel(true, null); this.requestFocus(); break;
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
public void actionPerformed(ActionEvent e) {
Object cause = e.getSource();
if (cause == restart) {
this.pickLevel(false, this.levelMap);
this.requestFocus();
}
if (cause == newGame) {
this.pickLevel(true, null);
this.requestFocus();
}
if (cause == undo) {
game.undoMove();
this.draw();
this.requestFocus();
}
if (cause == viewMoves) {
this.displayMoves();
this.requestFocus();
}
}
private void draw() {
this.container.removeAll();
this.moves.removeAll();
playground = new JPanel();
playground.setLayout(new GridLayout(game.getHeight(), game.getWidth(), 0, 0));
if (game.hasWon()) {
this.info.removeAll();
Font headerFont = new Font("Verdana", Font.BOLD, 24);
this.top = new JLabel("Du har vunnet!", SwingConstants.CENTER);
this.top.setFont(headerFont);
this.info.add(top);
this.info.setAlignmentY(CENTER_ALIGNMENT);
this.removeKeyListener(this);
}
this.container.add(playground);
String s = game.toString();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch(c) {
case '#':
this.playground.add(new JLabel(wall));
break;
case ' ':
this.playground.add(new JLabel(blank));
break;
case '.':
this.playground.add(new JLabel(target));
break;
case '@':
this.playground.add(new JLabel(mover));
break;
case '+':
this.playground.add(new JLabel(mover_on_target));
break;
case '$':
this.playground.add(new JLabel(movable));
break;
case '*':
this.playground.add(new JLabel(movable_on_target));
break;
default:
this.playground.add(new JLabel(blank));
break;
}
}
this.playground.revalidate();
this.moves.add(new JLabel("Antall flytt: "+game.getMoves()+". Antall dytt: "+game.getPushes()));
this.moves.revalidate();
}
public void displayMoves() {
History oldHistory = game.getHistory();
History newHistory = new History();
int j = oldHistory.getMoves();
for (int i = 0; i < j; i++) {
newHistory.add(game.undoMove());
}
this.draw();
int ant = newHistory.getMoves();
for (int i = 0; i < ant; i++) {
Log move = newHistory.remove();
game.doMove(move.getDx(), move.getDy());
try {
Thread.sleep(700);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(move.getDx()+", "+move.getDy());
this.draw();
}
}
public static void main(String[] args) throws Exception{
new Sokoban(false, null);
}
}