package main; import java.awt.AWTException; import java.awt.Point; import java.awt.image.BufferedImage; import javax.swing.*; /** * Окно приложения * @author aNNiMON */ public class RobotFrame extends JFrame { /* Статус работы приложения */ private boolean isRunning; private Thread robotAction; /** Creates new form RobotFrame */ public RobotFrame() { initComponents(); isRunning = false; setAlwaysOnTop(true); boardSizeSpinner.setModel(new SpinnerNumberModel(14, 5, 40, 1)); cellSizeSpinner.setModel(new SpinnerNumberModel(24, 5, 100, 1)); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { startStop = new javax.swing.JButton(); jLabel1 = new javax.swing.JLabel(); windowPanel = new javax.swing.JPanel(); windowXTextField = new javax.swing.JTextField(); jLabel2 = new javax.swing.JLabel(); windowYTextField = new javax.swing.JTextField(); jLabel3 = new javax.swing.JLabel(); jLabel5 = new javax.swing.JLabel(); jLabel6 = new javax.swing.JLabel(); checkButton = new javax.swing.JButton(); boardSizeSpinner = new javax.swing.JSpinner(); jLabel7 = new javax.swing.JLabel(); cellSizeSpinner = new javax.swing.JSpinner(); detectButton = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setTitle("FloodItBot"); setResizable(false); startStop.setText("Start"); startStop.setActionCommand(""); startStop.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { startStopActionPerformed(evt); } }); jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); jLabel1.setText("Bot for FloodIt"); jLabel1.setFocusable(false); jLabel1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); windowPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Options")); windowXTextField.setText("0"); jLabel2.setText("x:"); windowYTextField.setText("0"); jLabel3.setText("y:"); jLabel5.setText("Window:"); jLabel6.setText("Cell size:"); checkButton.setText("Check"); checkButton.setActionCommand(""); checkButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { checkButtonActionPerformed(evt); } }); jLabel7.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel7.setText("Field size:"); detectButton.setText("Detect"); detectButton.setActionCommand(""); detectButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { detectButtonActionPerformed(evt); } }); javax.swing.GroupLayout windowPanelLayout = new javax.swing.GroupLayout(windowPanel); windowPanel.setLayout(windowPanelLayout); windowPanelLayout.setHorizontalGroup( windowPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(windowPanelLayout.createSequentialGroup() .addContainerGap() .addGroup(windowPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(detectButton, javax.swing.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE) .addComponent(checkButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE) .addGroup(windowPanelLayout.createSequentialGroup() .addGroup(windowPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel5) .addGroup(windowPanelLayout.createSequentialGroup() .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(windowXTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(jLabel3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(windowYTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(windowPanelLayout.createSequentialGroup() .addComponent(jLabel7) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(boardSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(windowPanelLayout.createSequentialGroup() .addComponent(jLabel6) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(cellSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE))) .addGap(0, 0, Short.MAX_VALUE))) .addContainerGap()) ); windowPanelLayout.setVerticalGroup( windowPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(windowPanelLayout.createSequentialGroup() .addComponent(jLabel5) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(windowPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel2) .addComponent(windowXTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel3) .addComponent(windowYTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(windowPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel6) .addComponent(cellSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(windowPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel7) .addComponent(boardSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(detectButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(checkButton)) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(windowPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(startStop, javax.swing.GroupLayout.DEFAULT_SIZE, 172, Short.MAX_VALUE)) .addGroup(layout.createSequentialGroup() .addGap(57, 57, 57) .addComponent(jLabel1) .addGap(0, 0, Short.MAX_VALUE))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel1) .addGap(18, 18, 18) .addComponent(windowPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(startStop) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); pack(); }// //GEN-END:initComponents private void startStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startStopActionPerformed if (isRunning) { startStop.setText("Start"); isRunning = false; } else { startStop.setText("Stop"); isRunning = true; robotAction = new Thread(new Runnable() { @Override public void run() { int windowX, windowY, boardSize, cellSize; BufferedImage detectImage; RobotUtils robot; // Получаем настройки try { robot = new RobotUtils(); detectImage = robot.getImage(-1, -1, -1, -1); windowX = Integer.valueOf(windowXTextField.getText()); windowY = Integer.valueOf(windowYTextField.getText()); boardSize = (Integer) boardSizeSpinner.getValue(); cellSize = (Integer) cellSizeSpinner.getValue(); } catch (Exception ex) { ex.printStackTrace(); return; } ImageUtils iu = new ImageUtils(detectImage, boardSize, cellSize, windowX, windowY); // Обрезаем картинку до вида игрового поля detectImage = iu.getBoardImage(); // Получаем цвета из картинки int[][] table = new int[boardSize][boardSize]; int offset = cellSize / 2; for (int i = 0; i < boardSize; i++) { for (int j = 0; j < boardSize; j++) { table[i][j] = detectImage.getRGB(j*cellSize + offset, i*cellSize + offset); } } BotFloodIt bfi = new BotFloodIt(table); // Получаем результирующую последовательность цветов byte[] result = bfi.getFillSequence(); int[] colors = bfi.getColors(); // Пытаемся получить координаты кнопок для автоматической игры Point[] buttons = iu.getButtons(colors); if (buttons == null) { // Если не удалось найти кнопки, то просто выводим последовательность в виде картинки BufferedImage out = iu.sequenceToImage(result, colors); showImageWindow("Result: "+result.length+" steps", out); } else { // Запускаем автоигру robot.autoClick(buttons, result); } isRunning = false; startStop.setText("Start"); } }); robotAction.start(); } }//GEN-LAST:event_startStopActionPerformed private void checkButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkButtonActionPerformed if (isRunning) return; // нельзя проверять настройки во время работы int windowX, windowY, boardSize, cellSize; BufferedImage detectImage; RobotUtils robot; try { robot = new RobotUtils(); detectImage = robot.getImage(-1, -1, -1, -1); windowX = Integer.valueOf(windowXTextField.getText()); windowY = Integer.valueOf(windowYTextField.getText()); boardSize = (Integer) boardSizeSpinner.getValue(); cellSize = (Integer) cellSizeSpinner.getValue(); } catch (Exception ex) { ex.printStackTrace(); return; } ImageUtils iu = new ImageUtils(detectImage, boardSize, cellSize, windowX, windowY); showImageWindow("Checking", iu.getBoardImage()); }//GEN-LAST:event_checkButtonActionPerformed private void detectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_detectButtonActionPerformed if (isRunning) return; // нельзя определять настройки во время работы RobotUtils robot; try { robot = new RobotUtils(); BufferedImage detectImage = robot.getImage(-1, -1, -1, -1); int boardSize = (Integer) boardSizeSpinner.getValue(); ImageUtils iu = new ImageUtils(detectImage, boardSize); Point pt = iu.getBoardParameters(); int cellSize = iu.getCellSize(); windowXTextField.setText(String.valueOf(pt.x)); windowYTextField.setText(String.valueOf(pt.y)); cellSizeSpinner.setValue(cellSize); } catch (AWTException ex) { ex.printStackTrace(); } }//GEN-LAST:event_detectButtonActionPerformed /** * Показать модальное окно с изображением * @param title заголовок окна * @param image изображение * @throws SecurityException */ private void showImageWindow(String title, BufferedImage image) throws SecurityException { ImageIcon icon = new ImageIcon(image); JLabel backlabel = new JLabel(icon); getLayeredPane().add(backlabel, new Integer(Integer.MIN_VALUE)); backlabel.setBounds(0, 0, icon.getIconWidth(), icon.getIconHeight()); JDialog dialog = new JDialog(this); dialog.setAlwaysOnTop(true); dialog.setLocationByPlatform(true); dialog.setTitle(title); dialog.setResizable(true); dialog.add(backlabel); dialog.pack(); dialog.setVisible(true); } /** * @param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ // /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(RobotFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(RobotFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(RobotFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(RobotFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } // /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { new RobotFrame().setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JSpinner boardSizeSpinner; private javax.swing.JSpinner cellSizeSpinner; private javax.swing.JButton checkButton; private javax.swing.JButton detectButton; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel5; private javax.swing.JLabel jLabel6; private javax.swing.JLabel jLabel7; private javax.swing.JButton startStop; private javax.swing.JPanel windowPanel; private javax.swing.JTextField windowXTextField; private javax.swing.JTextField windowYTextField; // End of variables declaration//GEN-END:variables }