tak dneska jednoduchoučké zadání od p. Hnětynky - naprogramovat hru connect4 - https://en.wikipedia.org/wiki/Connect_Four. Chtělo se po nás udělat GUI (zejména z JButtonů) a nějaké jednoduché verifikace.
Měl jsem to asi po hodině a čtvrt, prošlo na první pokus.
Moje řešení:
Main.java
public class Main {public static void main(String args[]) {try {if (args.length != 2) throw new IllegalArgumentException();int H = Integer.parseInt(args[0]);int W = Integer.parseInt(args[1]);Game g = new Game(H,W); // !!! tohle je pry antipattern, mělo by být mimo tryg.start();} catch (Exception e) {System.out.println("Illegal arguments!");}}
}
Game.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Game {public static final int WINCOUNT = 4;private final int H;private final int W;private JButton board[][];private JButton topButtons[];private JButton bottomButtons[];private JLabel status = new JLabel("");private boolean redPlaying = false;private Color color;private JFrame frame;
public Game(int h, int w) {H = h;W = w;board = new JButton[H][W];topButtons = new JButton[W];bottomButtons = new JButton[W];}
public void start() {SwingUtilities.invokeLater(new Runnable() {@Overridepublic void run() {createAndShowGui();swapPlayers();}});}
private void createAndShowGui() {frame = new JFrame("Game");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container panel = frame.getContentPane();JPanel boardPanel = new JPanel();boardPanel.setLayout(new GridLayout(H+2,W));
for (int ww = 0; ww < W; ww++) {topButtons[ww] = new JButton("+");
final int fw = ww;topButtons[ww].addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent actionEvent) {plus(fw);}});
boardPanel.add(topButtons[ww]);}
for (int hh = 0; hh < H; hh++) {for (int ww = 0; ww < W; ww++) {board[hh][ww] = new JButton();board[hh][ww].setEnabled(false);board[hh][ww].setBackground(Color.GRAY);board[hh][ww].setPreferredSize(new Dimension(45,45));boardPanel.add(board[hh][ww]);}}
for (int ww = 0; ww < W; ww++) {bottomButtons[ww] = new JButton("-");
final int fw = ww;bottomButtons[ww].addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent actionEvent) {minus(fw);}});
boardPanel.add(bottomButtons[ww]);}
panel.add(boardPanel, BorderLayout.CENTER);panel.add(status, BorderLayout.SOUTH);
frame.pack();frame.setVisible(true);
}
private void plus(int c) {int r = 0;boolean found = false;for (r = H-1; r >= 0; r--) {if (board[r][c].getBackground().equals(Color.GRAY)) {found = true;break;}}
if (found) {board[r][c].setBackground(color);} else {// neverSystem.out.println("err1");}
swapPlayers();}
private void minus(int c) {if (board[H-1][c].getBackground().equals(color)) {for (int r = H-1; r > 0; r--) {board[r][c].setBackground(board[r-1][c].getBackground());}board[0][c].setBackground(Color.GRAY);
} else {// neverSystem.out.println("err2");}
swapPlayers();}
private void swapPlayers() {
check();
redPlaying = !redPlaying;if (redPlaying) {status.setText("Red player moves!");color = Color.RED;
} else {status.setText("Blue player moves!");color = Color.BLUE;}
enableTop();enableBottom();
}
// !!! zbytečně velká časová složitost, ale bylo ot příjemně jednoduché na nakódění a prý to stačí :)private void check() {for (int hh = 0; hh < H; hh++) {for (int ww = 0; ww < W; ww++) {if (horizontalCount(hh,ww) >= WINCOUNT) {
// System.out.println("winH");for (int d = 0; d < WINCOUNT; d++) board[hh][ww+d].setText("X");terminate();} else if (verticalCount(hh,ww) >= WINCOUNT) {
// System.out.println("winV");for (int d = 0; d < WINCOUNT; d++) board[hh+d][ww].setText("X");terminate();
} else if (upDiagonalCount(hh,ww) >= WINCOUNT) {
// System.out.println("upD");for (int d = 0; d < WINCOUNT; d++) board[hh-d][ww+d].setText("X");terminate();
} else if (downDiagonalCount(hh,ww) >= WINCOUNT) {
// System.out.println("downD");for (int d = 0; d < WINCOUNT; d++) board[hh+d][ww+d].setText("X");terminate();
}}}}
private void terminate() {String winner = redPlaying ? "Red" : "Blue";JOptionPane.showMessageDialog(frame, winner + " player wins!!!");System.exit(0);}
private void enableTop() {for (int c = 0; c < W; c++) {if (board[0][c].getBackground().equals(Color.GRAY)) topButtons[c].setEnabled(true);else topButtons[c].setEnabled(false);}}
private void enableBottom() {for (int c = 0; c < W; c++) {if (board[H-1][c].getBackground().equals(color)) bottomButtons[c].setEnabled(true);else bottomButtons[c].setEnabled(false);}
}
private int horizontalCount(int h, int w) {int res = 0;try {while (board[h][w++].getBackground().equals(color)) res++;} finally {return res;}}
private int verticalCount(int h, int w) {int res = 0;try {while (board[h++][w].getBackground().equals(color)) res++;} finally {return res;}}
private int upDiagonalCount(int h, int w) {int res = 0;try {while (board[h--][w++].getBackground().equals(color)) res++;} finally {return res;}}
private int downDiagonalCount(int h, int w) {int res = 0;try {while (board[h++][w++].getBackground().equals(color)) res++;} finally {return res;}}
}
Tak snad to někomu pomůže, pokud vím, udělali to všichni.