diff --git a/Quellcodes/alg_gr_highscorespiel/.gitignore b/Quellcodes/alg_gr_highscorespiel/.gitignore new file mode 100644 index 0000000..c1f4551 --- /dev/null +++ b/Quellcodes/alg_gr_highscorespiel/.gitignore @@ -0,0 +1,5 @@ +*.class +*.ctxt +*.sh +repo.adoc +*.~lock diff --git a/Quellcodes/alg_gr_highscorespiel/Base64.java b/Quellcodes/alg_gr_highscorespiel/Base64.java new file mode 100644 index 0000000..bb85f31 --- /dev/null +++ b/Quellcodes/alg_gr_highscorespiel/Base64.java @@ -0,0 +1,117 @@ +import java.io.ByteArrayOutputStream; +import java.util.Random; +import java.util.Arrays; +import javax.xml.bind.DatatypeConverter; + +/** + * + * Hilfsklasse zur Konvertierung in Base64 von Strings + * @author Emil Hernvall (https://gist.github.com/emilhernvall/953733) + */ + +public class Base64 +{ + public static String encode(String text) + { + byte[] data = text.getBytes(); + return encode(data); + } + + public static String encode(byte[] data) { + char[] tbl = { + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', + 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', + 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', + 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' }; + + StringBuilder buffer = new StringBuilder(); + int pad = 0; + for (int i = 0; i < data.length; i += 3) { + + int b = ((data[i] & 0xFF) << 16) & 0xFFFFFF; + if (i + 1 < data.length) { + b |= (data[i+1] & 0xFF) << 8; + } else { + pad++; + } + if (i + 2 < data.length) { + b |= (data[i+2] & 0xFF); + } else { + pad++; + } + + for (int j = 0; j < 4 - pad; j++) { + int c = (b & 0xFC0000) >> 18; + buffer.append(tbl[c]); + b <<= 6; + } + } + for (int j = 0; j < pad; j++) { + buffer.append("="); + } + + return buffer.toString(); + } + + + public static String decodeStr(String data) + { + return new String(decode(data)); + } + + public static byte[] decode(String data) + { + int[] tbl = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; + byte[] bytes = data.getBytes(); + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + for (int i = 0; i < bytes.length; ) { + int b = 0; + if (tbl[bytes[i]] != -1) { + b = (tbl[bytes[i]] & 0xFF) << 18; + } + // skip unknown characters + else { + i++; + continue; + } + + int num = 0; + if (i + 1 < bytes.length && tbl[bytes[i+1]] != -1) { + b = b | ((tbl[bytes[i+1]] & 0xFF) << 12); + num++; + } + if (i + 2 < bytes.length && tbl[bytes[i+2]] != -1) { + b = b | ((tbl[bytes[i+2]] & 0xFF) << 6); + num++; + } + if (i + 3 < bytes.length && tbl[bytes[i+3]] != -1) { + b = b | (tbl[bytes[i+3]] & 0xFF); + num++; + } + + while (num > 0) { + int c = (b & 0xFF0000) >> 16; + buffer.write((char)c); + b <<= 8; + num--; + } + i += 4; + } + return buffer.toByteArray(); + } +} diff --git a/Quellcodes/alg_gr_highscorespiel/BinaerSpiel.java b/Quellcodes/alg_gr_highscorespiel/BinaerSpiel.java new file mode 100644 index 0000000..3d6af8b --- /dev/null +++ b/Quellcodes/alg_gr_highscorespiel/BinaerSpiel.java @@ -0,0 +1,573 @@ +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.event.*; +import java.util.Random; + + +/** + * + * BinärSpiel: Man kann eine gewisse Zeit Binärzahlen in Dezimalzahlen umrechnen + * Die Ergebnisse werden an den Server geschickt + * V1.1: Rundenzeit vom Server steuerbar, Fehlerkorrektur + * V1.2: Gesamtzeit vom Server steuerbar + * + * @version 1.2 vom 18.02.2019 + * @author Thomas Schaller + * cc0-Lizenz ZPG IMP Klasse 9 + */ + +public class BinaerSpiel extends JFrame implements MySocketListener { + // Anfang Attribute + private JTextField jTFLoesung = new JTextField(); + private JTextField jTFAufgabe = new JTextField(); + private JButton bLeicht = new JButton(); + private JButton bMittel = new JButton(); + private JButton bSchwer = new JButton(); + private JButton bPruefen = new JButton(); + private JPanel jPanel1 = new JPanel(null, true); + private JLabel lRunde = new JLabel(); + private JLabel lZeit = new JLabel(); + private JPanel jPanel2 = new JPanel(null, true); + private JLabel ltPunkte = new JLabel(); + private JLabel lPunkte = new JLabel(); + private JButton jBVerbinden = new JButton(); + private JButton bRundestarten = new JButton(); + private JLabel lServer = new JLabel(); + private JTextField jTFAdress = new JTextField(); + private JLabel l = new JLabel(); + private JLabel l1 = new JLabel(); + private JLabel l3 = new JLabel(); + private JLabel l2 = new JLabel(); + private JLabel l5 = new JLabel(); + private JLabel l6 = new JLabel(); + private Timer timer1 = new Timer(1000, null); + private JLabel lSpielername = new JLabel(); + private JTextField jTFName = new JTextField(); + private JLabel l4 = new JLabel(); + private JLabel jLMeldung = new JLabel(); + private JLabel lcc2018ThomasSchallerVersion10 = new JLabel(); + private JPanel jPanel3 = new JPanel(null, true); + private JLabel lGesamt = new JLabel(); + private JLabel lGesamtzeit = new JLabel(); + // Ende Attribute + private int spielzeit = 60; + private int restzeit = 0; + private int gesamtzeit = 0; + private int zahl = 0; + private int punkte = 0; + private MySocket client = null; + private int lastLevel = 0; + private boolean spiellaeuft = false; + + + public BinaerSpiel (String title) { + super (title); + setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + int frameWidth = 597; + int frameHeight = 276; + setSize(frameWidth, frameHeight); + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + int x = (d.width - getSize().width) / 2; + int y = (d.height - getSize().height) / 2; + setLocation(x, y); + Container cp = getContentPane(); + cp.setLayout(null); + // Anfang Komponenten + jTFLoesung.setBounds(272, 168, 150, 28); + jTFLoesung.setEditable(true); + jTFLoesung.setEnabled(true); + jTFLoesung.setVisible(false); + jTFLoesung.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent evt) { + jTFLoesung_KeyPressed(evt); + } + }); + cp.add(jTFLoesung); + jTFAufgabe.setBounds(40, 168, 150, 28); + jTFAufgabe.setEditable(false); + jTFAufgabe.setEnabled(true); + jTFAufgabe.setVisible(false); + cp.add(jTFAufgabe); + bLeicht.setBounds(128, 168, 99, 25); + bLeicht.setText("einfach"); + bLeicht.setMargin(new Insets(2, 2, 2, 2)); + bLeicht.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + bLeicht_ActionPerformed(evt); + } + }); + bLeicht.setVisible(false); + bLeicht.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent evt) { + bLeicht_KeyPressed(evt); + } + }); + cp.add(bLeicht); + bMittel.setBounds(248, 168, 91, 25); + bMittel.setText("mittel"); + bMittel.setMargin(new Insets(2, 2, 2, 2)); + bMittel.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + bMittel_ActionPerformed(evt); + } + }); + bMittel.setVisible(false); + bMittel.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent evt) { + bMittel_KeyPressed(evt); + } + }); + cp.add(bMittel); + bSchwer.setBounds(368, 168, 83, 25); + bSchwer.setText("schwer"); + bSchwer.setMargin(new Insets(2, 2, 2, 2)); + bSchwer.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + bSchwer_ActionPerformed(evt); + } + }); + bSchwer.setVisible(false); + bSchwer.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent evt) { + bSchwer_KeyPressed(evt); + } + }); + cp.add(bSchwer); + bPruefen.setBounds(472, 168, 75, 25); + bPruefen.setText("Prüfen"); + bPruefen.setMargin(new Insets(2, 2, 2, 2)); + bPruefen.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + bPruefen_ActionPerformed(evt); + } + }); + bPruefen.setEnabled(true); + bPruefen.setVisible(false); + bPruefen.setSelected(true); + cp.add(bPruefen); + jPanel1.setBounds(192, 72, 177, 49); + jPanel1.setOpaque(false); + jPanel1.setBorder(BorderFactory.createBevelBorder(1, new Color(0xC0C0C0), Color.BLACK)); + cp.add(jPanel1); + lRunde.setBounds(8, 8, 86, 30); + lRunde.setText("Runde:"); + lRunde.setFont(new Font("Dialog", Font.BOLD, 22)); + lRunde.setForeground(new Color(0x800000)); + jPanel1.add(lRunde); + lZeit.setBounds(88, 8, 83, 30); + lZeit.setText("? sek"); + lZeit.setFont(new Font("Dialog", Font.BOLD, 22)); + lZeit.setForeground(new Color(0x800000)); + lZeit.setHorizontalAlignment(SwingConstants.RIGHT); + jPanel1.add(lZeit); + jPanel2.setBounds(8, 72, 177, 49); + jPanel2.setOpaque(false); + jPanel2.setBorder(BorderFactory.createBevelBorder(1, new Color(0xC0C0C0), Color.BLACK)); + cp.add(jPanel2); + jBVerbinden.setBounds(408, 40, 169, 25); + jBVerbinden.setText("Verbinden"); + jBVerbinden.setMargin(new Insets(2, 2, 2, 2)); + jBVerbinden.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + jBVerbinden_ActionPerformed(evt); + } + }); + cp.add(jBVerbinden); + ltPunkte.setBounds(8, 8, 110, 30); + ltPunkte.setText("Punkte:"); + ltPunkte.setFont(new Font("Dialog", Font.BOLD, 22)); + ltPunkte.setForeground(new Color(0x800000)); + jPanel2.add(ltPunkte); + lPunkte.setBounds(96, 8, 70, 30); + lPunkte.setText("0"); + lPunkte.setForeground(new Color(0x800000)); + lPunkte.setFont(new Font("Dialog", Font.BOLD, 22)); + lPunkte.setHorizontalAlignment(SwingConstants.RIGHT); + jPanel2.add(lPunkte); + bRundestarten.setBounds(120, 160, 353, 41); + bRundestarten.setText("Runde starten"); + bRundestarten.setMargin(new Insets(2, 2, 2, 2)); + bRundestarten.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + bRundestarten_ActionPerformed(evt); + } + }); + bRundestarten.setEnabled(false); + bRundestarten.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent evt) { + bRundestarten_KeyPressed(evt); + } + }); + cp.add(bRundestarten); + lServer.setBounds(8, 40, 110, 20); + lServer.setText("Server:"); + cp.add(lServer); + jTFAdress.setBounds(128, 40, 270, 25); + jTFAdress.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent evt) { + jTFAdress_KeyPressed(evt); + } + }); + cp.add(jTFAdress); + l.setBounds(24, 160, 14, 33); + l.setText("("); + l.setFont(new Font("Dialog", Font.BOLD, 24)); + l.setVisible(false); + cp.add(l); + l1.setBounds(256, 160, 14, 33); + l1.setText("("); + l1.setFont(new Font("Dialog", Font.BOLD, 24)); + l1.setVisible(false); + cp.add(l1); + l3.setBounds(192, 160, 10, 33); + l3.setText(")"); + l3.setFont(new Font("Dialog", Font.BOLD, 24)); + l3.setVisible(false); + cp.add(l3); + l2.setBounds(200, 184, 14, 20); + l2.setText("2"); + l2.setFont(new Font("Dialog", Font.BOLD, 11)); + l2.setVisible(false); + cp.add(l2); + l5.setBounds(424, 160, 14, 33); + l5.setText(")"); + l5.setFont(new Font("Dialog", Font.BOLD, 24)); + l5.setVisible(false); + cp.add(l5); + l6.setBounds(432, 184, 16, 20); + l6.setText("10"); + l6.setFont(new Font("Dialog", Font.BOLD, 11)); + l6.setVisible(false); + cp.add(l6); + timer1.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + timer1_ActionPerformed(evt); + } + }); + timer1.setRepeats(true); + timer1.setInitialDelay(0); + lSpielername.setBounds(8, 8, 110, 20); + lSpielername.setText("Spielername:"); + cp.add(lSpielername); + jTFName.setBounds(128, 8, 270, 25); + cp.add(jTFName); + l4.setBounds(224, 168, 22, 25); + l4.setText("->"); + l4.setFont(new Font("@System", Font.BOLD, 24)); + l4.setVisible(false); + cp.add(l4); + jLMeldung.setBounds(8, 128, 566, 20); + jLMeldung.setText(""); + cp.add(jLMeldung); + lcc2018ThomasSchallerVersion10.setBounds(8, 216, 566, 20); + lcc2018ThomasSchallerVersion10.setText("(cc) 2018, Thomas Schaller, Version 1.2"); + lcc2018ThomasSchallerVersion10.setHorizontalAlignment(SwingConstants.CENTER); + cp.add(lcc2018ThomasSchallerVersion10); + addWindowListener(new WindowAdapter() { + public void windowClosed(WindowEvent evt) { + BinaerSpiel_WindowClosed(evt); + } + }); + jPanel3.setBounds(376, 72, 201, 49); + jPanel3.setOpaque(false); + jPanel3.setBorder(BorderFactory.createBevelBorder(1, new Color(0xC0C0C0), Color.BLACK)); + cp.add(jPanel3); + lGesamt.setBounds(8, 8, 93, 30); + lGesamt.setText("Gesamt:"); + lGesamt.setFont(new Font("Dialog", Font.BOLD, 22)); + lGesamt.setForeground(new Color(0x800000)); + jPanel3.add(lGesamt); + lGesamtzeit.setBounds(112, 8, 83, 30); + lGesamtzeit.setText("? sek"); + lGesamtzeit.setFont(new Font("Dialog", Font.BOLD, 22)); + lGesamtzeit.setForeground(new Color(0x800000)); + lGesamtzeit.setHorizontalAlignment(SwingConstants.RIGHT); + jPanel3.add(lGesamtzeit); + // Ende Komponenten + setResizable(false); + setVisible(true); + } + + // Anfang Methoden + + private void neueAufgabe(int min, int max) { + Random r = new Random(); + do{ + zahl = r.nextInt(max-min)+min; + } while (jTFAufgabe.equals(Integer.toBinaryString(zahl))); + jTFAufgabe.setText(Integer.toBinaryString(zahl)); + jTFLoesung.setText(""); + + bPruefen.setVisible(true); + jTFLoesung.setVisible(true); + jTFAufgabe.setVisible(true); + l1.setVisible(true); + l2.setVisible(true); + l3.setVisible(true); + l4.setVisible(true); + l5.setVisible(true); + l6.setVisible(true); + l.setVisible(true); + bLeicht.setVisible(false); + bMittel.setVisible(false); + bSchwer.setVisible(false); + jTFLoesung.requestFocus(); + } + + public void bLeicht_ActionPerformed(ActionEvent evt) { + lastLevel = 0; + neueAufgabe(1,16); + } // end of bLeicht_ActionPerformed + + public void bMittel_ActionPerformed(ActionEvent evt) { + lastLevel = 1; + neueAufgabe(16,128); + + } // end of bMittel_ActionPerformed + + public void bSchwer_ActionPerformed(ActionEvent evt) { + lastLevel = 2; + neueAufgabe(128,1024); + + } // end of bSchwer_ActionPerformed + + public void bPruefen_ActionPerformed(ActionEvent evt) { + try{ + int loesung = Integer.parseInt(jTFLoesung.getText()); + if(loesung == zahl) { + jLMeldung.setText("Richtig! Du erhälst "+zahl+" Punkte."); + punkte += zahl; + lPunkte.setText(""+punkte); + } + else { + jLMeldung.setText("Leider falsch! Richtig wäre "+Integer.toBinaryString(zahl)+" -> "+zahl+" gewesen."); + } // end of if-else + + + } catch(Exception e) { + jLMeldung.setText("Deine Eingabe ist keine korrekte Zahl."); + + } + bPruefen.setVisible(false); + jTFAufgabe.setVisible(false); + jTFLoesung.setVisible(false); + bLeicht.setVisible(true); + bMittel.setVisible(true); + bSchwer.setVisible(true); + l1.setVisible(false); + l2.setVisible(false); + l3.setVisible(false); + l4.setVisible(false); + l5.setVisible(false); + l6.setVisible(false); + l.setVisible(false); + setLevelFocus(); + + } // end of bPruefen_ActionPerformed + + public void jBVerbinden_ActionPerformed(ActionEvent evt) { + + String a = jTFAdress.getText(); + int p = 44444; + if (client != null && client.isAktiv()) { + jTFName.setEnabled(true); + jTFAdress.setEnabled(true); + + jBVerbinden.setText("Verbinden"); + client.sendeNachricht("exit"); + client.trenneVerbindung(); + } else { + client = new MySocket(a, p, this); + if (client.isAktiv()) { + jTFName.setEnabled(false); + jTFAdress.setEnabled(false); + jBVerbinden.setText("Trennen"); + client.sendeNachricht(("user:"+jTFName.getText()+":alle")); + } + } // end of if-else + } // end of jBVerbinden_ActionPerformed + + + + public void bRundestarten_ActionPerformed(ActionEvent evt) { + bRundestarten.setVisible(false); + bLeicht.setVisible(true); + bMittel.setVisible(true); + bSchwer.setVisible(true); + setLevelFocus(); + restzeit = Math.min(spielzeit,gesamtzeit-1); + punkte = 0; + lZeit.setText(""+restzeit+" sek"); + lPunkte.setText(""+punkte); + timer1.start(); + spiellaeuft = true; + jLMeldung.setText(""); + + } // end of bRundestarten_ActionPerformed + + public void timer1_ActionPerformed(ActionEvent evt) { + restzeit--; + lZeit.setText(""+restzeit+" sek"); + lGesamtzeit.setText(""+gesamtzeit+" sek"); + if(restzeit == 0 || gesamtzeit == 0) { + timer1.stop(); + if(client != null) { + if(gesamtzeit > 0) { + client.sendeNachricht("punkte:"+punkte); + jLMeldung.setText("Deine Zeit ist abgelaufen. Du hast "+punkte+ " Punkte erreicht. Punkte wurden gespeichert."); + } else { + jLMeldung.setText("Die Gesamtzeit ist abgelaufen. Die Punkte konnten nicht mehr gespeichert werden."); + } // end of if-else + + } else { + jLMeldung.setText("Deine Zeit ist abgelaufen. Du hast "+punkte+ " Punkte erreicht. Serververbindung abgebrochen."); + } // end of if-else + spiellaeuft = false; + + bRundestarten.setVisible(true); + if(gesamtzeit > 0) { + bRundestarten.requestFocus(); + } else { + bRundestarten.setEnabled(false); + } // end of if-else + + bPruefen.setVisible(false); + jTFAufgabe.setVisible(false); + jTFLoesung.setVisible(false); + bLeicht.setVisible(false); + bMittel.setVisible(false); + bSchwer.setVisible(false); + l1.setVisible(false); + l2.setVisible(false); + l3.setVisible(false); + l4.setVisible(false); + l5.setVisible(false); + l6.setVisible(false); + l.setVisible(false); + } + + + + } // end of timer1_ActionPerformed + + + /** Neuer Client macht nichts + */ + public void neuerClient(MySocket client) { + } + + public void nachrichtEmpfangen(MySocket client) { + String n = client.holeNachricht(); + if(n.startsWith("round")){ + try{ + spielzeit = Integer.parseInt(n.substring(6)); + } catch (Exception e) { + spielzeit = 60; + } + restzeit = spielzeit; + lZeit.setText(""+restzeit+" sek"); + } + if(n.startsWith("game")){ + try{ + gesamtzeit = Integer.parseInt(n.substring(5)); + } catch (Exception e) { + gesamtzeit = 0; + } + lGesamtzeit.setText(""+gesamtzeit+" sek"); + if(gesamtzeit > 0 && !spiellaeuft) { + bRundestarten.setEnabled(true); + bRundestarten.requestFocus(); + } + + } + + + } + + public void verbindungBeendet(MySocket client) { + jTFName.setEnabled(true); + jTFAdress.setEnabled(true); + jBVerbinden.setText("Verbinden"); + client = null; + } + public void BinaerSpiel_WindowClosed(WindowEvent evt) { + client.sendeNachricht("exit"); + client.trenneVerbindung(); + + } // end of BinaerSpiel_WindowClosed + + public void jTFLoesung_KeyPressed(KeyEvent evt) { + if(evt.getKeyCode() == KeyEvent.VK_ENTER) + bPruefen_ActionPerformed(null); + } // end of jTFLoesung_KeyPressed + + public void setLevelFocus() { + if(lastLevel == 0) bLeicht.requestFocus(); + if(lastLevel == 1) bMittel.requestFocus(); + if(lastLevel == 2) bSchwer.requestFocus(); + } + + + public void bLeicht_KeyPressed(KeyEvent evt) { + if(evt.getKeyCode() == KeyEvent.VK_ENTER) + bLeicht_ActionPerformed(null); + + if(evt.getKeyCode() == KeyEvent.VK_LEFT){ + lastLevel = (lastLevel+2)%3; + setLevelFocus(); + } + + if(evt.getKeyCode() == KeyEvent.VK_RIGHT){ + lastLevel = (lastLevel+1)%3; + setLevelFocus(); + } + } // end of bLeicht_KeyPressed + + public void bMittel_KeyPressed(KeyEvent evt) { + if(evt.getKeyCode() == KeyEvent.VK_ENTER) + bMittel_ActionPerformed(null); + if(evt.getKeyCode() == KeyEvent.VK_LEFT){ + lastLevel = (lastLevel+2)%3; + setLevelFocus(); + } + + if(evt.getKeyCode() == KeyEvent.VK_RIGHT){ + lastLevel = (lastLevel+1)%3; + setLevelFocus(); + } + } // end of bMittel_KeyPressed + + public void bSchwer_KeyPressed(KeyEvent evt) { + if(evt.getKeyCode() == KeyEvent.VK_ENTER) + bSchwer_ActionPerformed(null); + if(evt.getKeyCode() == KeyEvent.VK_LEFT){ + lastLevel = (lastLevel+2)%3; + setLevelFocus(); + } + + if(evt.getKeyCode() == KeyEvent.VK_RIGHT){ + lastLevel = (lastLevel+1)%3; + setLevelFocus(); + } + } // end of bSchwer_KeyPressed + + public void jTFAdress_KeyPressed(KeyEvent evt) { + if(evt.getKeyCode() == KeyEvent.VK_ENTER) + jBVerbinden_ActionPerformed(null); + + } // end of jTFAdress_KeyPressed + + public void bRundestarten_KeyPressed(KeyEvent evt) { + if(evt.getKeyCode() == KeyEvent.VK_ENTER) + bRundestarten_ActionPerformed(null); + + } // end of bRundestarten_KeyPressed + + // Ende Methoden + + public static void main(String[] args) { + new BinaerSpiel("BinaerSpiel"); + } +} + diff --git a/Quellcodes/alg_gr_highscorespiel/BinaerSpiel.jfm b/Quellcodes/alg_gr_highscorespiel/BinaerSpiel.jfm new file mode 100644 index 0000000..74df4e1 --- /dev/null +++ b/Quellcodes/alg_gr_highscorespiel/BinaerSpiel.jfm @@ -0,0 +1,891 @@ +object BinaerSpiel: TFGUIForm + Left = 834 + Top = 524 + BorderIcons = [biSystemMenu] + Caption = 'BinaerSpiel' + ClientHeight = 237 + ClientWidth = 581 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -10 + Font.Name = 'MS Sans Serif' + Font.Style = [] + FormStyle = fsStayOnTop + OldCreateOrder = True + Position = poDesigned + ShowHint = True + Visible = True + OnClose = FormClose + OnCloseQuery = FormCloseQuery + OnResize = FormResize + FrameType = 5 + Resizable = False + Undecorated = False + Background = clBtnFace + windowClosed = 'BinaerSpiel_WindowClosed' + PixelsPerInch = 96 + TextHeight = 13 + object jTFAufgabe: TJTextField + Tag = 2 + Left = 40 + Top = 168 + Width = 150 + Height = 28 + Cursor = crIBeam + Hint = 'jTextField2' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [] + Foreground = 3355443 + Background = clWhite + Visible = False + HorizontalAlignment = LEFT + Text = '' + Editable = False + end + object bPruefen: TJButton + Tag = 4 + Left = 472 + Top = 168 + Width = 75 + Height = 25 + Hint = 'jButton4' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = 3355443 + Background = 15658734 + Visible = False + actionPerformed = 'bPruefen_ActionPerformed' + Text = 'Pr'#252'fen' + Mnemonic = 0 + DisplayedMnemonicIndex = 0 + Selected = True + BorderPainted = True + FocusPainted = False + ContentAreaFilled = True + HorizontalAlignment = CENTER + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + RolloverEnabled = False + Border.BorderType = NoBorder + Border.LineColor = clBlack + Border.LineThickness = 0 + Border.LineRounded = False + Border.EtchHighlightColor = clBlack + Border.EtchShadowColor = clBlack + Border.Etchtype = 0 + Border.BevelHighlightColor = clBlack + Border.BevelShadowColor = clBlack + Border.Beveltype = 0 + Border.MatteColor = clBlack + Border.MatteTop = 0 + Border.MatteLeft = 0 + Border.MatteBottom = 0 + Border.MatteRight = 0 + end + object jPanel1: TJPanel + Tag = 12 + Left = 192 + Top = 72 + Width = 177 + Height = 49 + Hint = 'jPanel1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = 3355443 + Background = clBtnFace + Border.BorderType = BevelBorder + Border.LineColor = clBlack + Border.LineThickness = 0 + Border.LineRounded = False + Border.EtchHighlightColor = clBlack + Border.EtchShadowColor = clBlack + Border.Etchtype = 0 + Border.BevelHighlightColor = clSilver + Border.BevelShadowColor = clBlack + Border.Beveltype = 1 + Border.MatteColor = clBlack + Border.MatteTop = 0 + Border.MatteLeft = 0 + Border.MatteBottom = 0 + Border.MatteRight = 0 + object lRunde: TJLabel + Tag = 1 + Left = 8 + Top = 8 + Width = 86 + Height = 30 + Hint = 'jLabel3' + Font.Charset = DEFAULT_CHARSET + Font.Color = clMaroon + Font.Height = -22 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = clMaroon + Background = clBtnFace + Text = 'Runde:' + HorizontalAlignment = LEFT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + object lZeit: TJLabel + Tag = 1 + Left = 88 + Top = 8 + Width = 83 + Height = 30 + Hint = 'jLabel4' + Font.Charset = DEFAULT_CHARSET + Font.Color = clMaroon + Font.Height = -22 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = clMaroon + Background = clBtnFace + Text = '60 sek' + HorizontalAlignment = RIGHT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + end + object jPanel2: TJPanel + Tag = 12 + Left = 8 + Top = 72 + Width = 177 + Height = 49 + Hint = 'jPanel2' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = 3355443 + Background = clBtnFace + Border.BorderType = BevelBorder + Border.LineColor = clBlack + Border.LineThickness = 0 + Border.LineRounded = False + Border.EtchHighlightColor = clBlack + Border.EtchShadowColor = clBlack + Border.Etchtype = 1 + Border.BevelHighlightColor = clSilver + Border.BevelShadowColor = clBlack + Border.Beveltype = 1 + Border.MatteColor = clBlack + Border.MatteTop = 0 + Border.MatteLeft = 0 + Border.MatteBottom = 0 + Border.MatteRight = 0 + object lPunkte: TJLabel + Tag = 1 + Left = 96 + Top = 8 + Width = 70 + Height = 30 + Hint = 'jLabel2' + Font.Charset = DEFAULT_CHARSET + Font.Color = clMaroon + Font.Height = -22 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = clMaroon + Background = clBtnFace + Text = '0' + HorizontalAlignment = RIGHT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + object ltPunkte: TJLabel + Tag = 1 + Left = 8 + Top = 8 + Width = 110 + Height = 30 + Hint = 'jLabel1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clMaroon + Font.Height = -22 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = clMaroon + Background = clBtnFace + Text = 'Punkte:' + HorizontalAlignment = LEFT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + end + object jBVerbinden: TJButton + Tag = 4 + Left = 408 + Top = 40 + Width = 169 + Height = 25 + Hint = 'jButton5' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = 3355443 + Background = 15658734 + actionPerformed = 'jBVerbinden_ActionPerformed' + Text = 'Verbinden' + Mnemonic = 0 + DisplayedMnemonicIndex = 0 + Selected = False + BorderPainted = True + FocusPainted = False + ContentAreaFilled = True + HorizontalAlignment = CENTER + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + RolloverEnabled = False + Border.BorderType = NoBorder + Border.LineColor = clBlack + Border.LineThickness = 0 + Border.LineRounded = False + Border.EtchHighlightColor = clBlack + Border.EtchShadowColor = clBlack + Border.Etchtype = 0 + Border.BevelHighlightColor = clBlack + Border.BevelShadowColor = clBlack + Border.Beveltype = 0 + Border.MatteColor = clBlack + Border.MatteTop = 0 + Border.MatteLeft = 0 + Border.MatteBottom = 0 + Border.MatteRight = 0 + end + object lServer: TJLabel + Tag = 1 + Left = 8 + Top = 40 + Width = 110 + Height = 20 + Hint = 'jLabel1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = 3355443 + Background = clBtnFace + Text = 'Server:' + HorizontalAlignment = LEFT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + object l: TJLabel + Tag = 1 + Left = 24 + Top = 160 + Width = 14 + Height = 33 + Hint = 'jLabel1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -24 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = clWindowText + Background = clBtnFace + Visible = False + Text = '(' + HorizontalAlignment = LEFT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + object timer1: TTimer + Tag = 49 + Left = 536 + Top = 136 + Width = 33 + Height = 28 + Hint = 'timer1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = 3355443 + Background = 15658734 + actionPerformed = 'timer1_ActionPerformed' + Coalesce = False + Delay = 1000 + InitialDelay = 0 + LogTimers = False + Repeats = True + end + object lSpielername: TJLabel + Tag = 1 + Left = 8 + Top = 8 + Width = 110 + Height = 20 + Hint = 'jLabel1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = 3355443 + Background = clBtnFace + Text = 'Spielername:' + HorizontalAlignment = LEFT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + object jTFName: TJTextField + Tag = 2 + Left = 128 + Top = 8 + Width = 270 + Height = 25 + Cursor = crIBeam + Hint = 'jTextField3' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [] + Foreground = 3355443 + Background = clWhite + HorizontalAlignment = LEFT + Text = '' + Editable = True + end + object jLMeldung: TJLabel + Tag = 1 + Left = 8 + Top = 128 + Width = 566 + Height = 20 + Hint = 'jLabel1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = 3355443 + Background = clBtnFace + Text = '' + HorizontalAlignment = LEFT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + object l1: TJLabel + Tag = 1 + Left = 256 + Top = 160 + Width = 14 + Height = 33 + Hint = 'jLabel1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -24 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = clWindowText + Background = clBtnFace + Visible = False + Text = '(' + HorizontalAlignment = LEFT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + object l2: TJLabel + Tag = 1 + Left = 200 + Top = 184 + Width = 14 + Height = 20 + Hint = 'jLabel1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = clWindowText + Background = clBtnFace + Visible = False + Text = '2' + HorizontalAlignment = LEFT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + object l3: TJLabel + Tag = 1 + Left = 192 + Top = 160 + Width = 10 + Height = 33 + Hint = 'jLabel1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -24 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = clWindowText + Background = clBtnFace + Visible = False + Text = ')' + HorizontalAlignment = LEFT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + object l5: TJLabel + Tag = 1 + Left = 424 + Top = 160 + Width = 14 + Height = 33 + Hint = 'jLabel1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -24 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = clWindowText + Background = clBtnFace + Visible = False + Text = ')' + HorizontalAlignment = LEFT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + object l4: TJLabel + Tag = 1 + Left = 224 + Top = 168 + Width = 22 + Height = 25 + Hint = 'jLabel1' + Font.Charset = HANGEUL_CHARSET + Font.Color = clWindowText + Font.Height = -24 + Font.Name = '@System' + Font.Style = [fsBold] + Foreground = clWindowText + Background = clBtnFace + Visible = False + Text = '->' + HorizontalAlignment = LEFT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + object l6: TJLabel + Tag = 1 + Left = 432 + Top = 184 + Width = 16 + Height = 20 + Hint = 'jLabel1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = clWindowText + Background = clBtnFace + Visible = False + Text = '10' + HorizontalAlignment = LEFT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + object lcc2018ThomasSchallerVersion10: TJLabel + Tag = 1 + Left = 8 + Top = 216 + Width = 566 + Height = 20 + Hint = 'jLabel1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = 3355443 + Background = clBtnFace + Text = '(cc) 2018, Thomas Schaller, Version 1.0' + HorizontalAlignment = CENTER + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + object jTFLoesung: TJTextField + Tag = 2 + Left = 272 + Top = 168 + Width = 150 + Height = 28 + Cursor = crIBeam + Hint = 'jTextField1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [] + Foreground = 3355443 + Background = clWhite + Visible = False + keyPressed = 'jTFLoesung_KeyPressed' + HorizontalAlignment = LEFT + Text = '' + Editable = True + end + object bLeicht: TJButton + Tag = 4 + Left = 128 + Top = 168 + Width = 99 + Height = 25 + Hint = 'jButton1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = 3355443 + Background = 15658734 + Visible = False + keyPressed = 'bLeicht_KeyPressed' + actionPerformed = 'bLeicht_ActionPerformed' + Text = 'einfach' + Mnemonic = 0 + DisplayedMnemonicIndex = 0 + Selected = False + BorderPainted = True + FocusPainted = False + ContentAreaFilled = True + HorizontalAlignment = CENTER + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + RolloverEnabled = False + Border.BorderType = NoBorder + Border.LineColor = clBlack + Border.LineThickness = 0 + Border.LineRounded = False + Border.EtchHighlightColor = clBlack + Border.EtchShadowColor = clBlack + Border.Etchtype = 0 + Border.BevelHighlightColor = clBlack + Border.BevelShadowColor = clBlack + Border.Beveltype = 0 + Border.MatteColor = clBlack + Border.MatteTop = 0 + Border.MatteLeft = 0 + Border.MatteBottom = 0 + Border.MatteRight = 0 + end + object bMittel: TJButton + Tag = 4 + Left = 248 + Top = 168 + Width = 91 + Height = 25 + Hint = 'jButton2' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = 3355443 + Background = 15658734 + Visible = False + keyPressed = 'bMittel_KeyPressed' + actionPerformed = 'bMittel_ActionPerformed' + Text = 'mittel' + Mnemonic = 0 + DisplayedMnemonicIndex = 0 + Selected = False + BorderPainted = True + FocusPainted = False + ContentAreaFilled = True + HorizontalAlignment = CENTER + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + RolloverEnabled = False + Border.BorderType = NoBorder + Border.LineColor = clBlack + Border.LineThickness = 0 + Border.LineRounded = False + Border.EtchHighlightColor = clBlack + Border.EtchShadowColor = clBlack + Border.Etchtype = 0 + Border.BevelHighlightColor = clBlack + Border.BevelShadowColor = clBlack + Border.Beveltype = 0 + Border.MatteColor = clBlack + Border.MatteTop = 0 + Border.MatteLeft = 0 + Border.MatteBottom = 0 + Border.MatteRight = 0 + end + object bSchwer: TJButton + Tag = 4 + Left = 368 + Top = 168 + Width = 83 + Height = 25 + Hint = 'jButton3' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = 3355443 + Background = 15658734 + Visible = False + keyPressed = 'bSchwer_KeyPressed' + actionPerformed = 'bSchwer_ActionPerformed' + Text = 'schwer' + Mnemonic = 0 + DisplayedMnemonicIndex = 0 + Selected = False + BorderPainted = True + FocusPainted = False + ContentAreaFilled = True + HorizontalAlignment = CENTER + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + RolloverEnabled = False + Border.BorderType = NoBorder + Border.LineColor = clBlack + Border.LineThickness = 0 + Border.LineRounded = False + Border.EtchHighlightColor = clBlack + Border.EtchShadowColor = clBlack + Border.Etchtype = 0 + Border.BevelHighlightColor = clBlack + Border.BevelShadowColor = clBlack + Border.Beveltype = 0 + Border.MatteColor = clBlack + Border.MatteTop = 0 + Border.MatteLeft = 0 + Border.MatteBottom = 0 + Border.MatteRight = 0 + end + object jTFAdress: TJTextField + Tag = 2 + Left = 128 + Top = 40 + Width = 270 + Height = 25 + Cursor = crIBeam + Hint = 'jTextField3' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [] + Foreground = 3355443 + Background = clWhite + keyPressed = 'jTFAdress_KeyPressed' + HorizontalAlignment = LEFT + Text = '' + Editable = True + end + object bRundestarten: TJButton + Tag = 4 + Left = 120 + Top = 160 + Width = 353 + Height = 41 + Hint = 'jButton6' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = 3355443 + Background = 15658734 + Enabled = False + keyPressed = 'bRundestarten_KeyPressed' + actionPerformed = 'bRundestarten_ActionPerformed' + Text = 'Runde starten' + Mnemonic = 0 + DisplayedMnemonicIndex = 0 + Selected = False + BorderPainted = True + FocusPainted = False + ContentAreaFilled = True + HorizontalAlignment = CENTER + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + RolloverEnabled = False + Border.BorderType = NoBorder + Border.LineColor = clBlack + Border.LineThickness = 0 + Border.LineRounded = False + Border.EtchHighlightColor = clBlack + Border.EtchShadowColor = clBlack + Border.Etchtype = 0 + Border.BevelHighlightColor = clBlack + Border.BevelShadowColor = clBlack + Border.Beveltype = 0 + Border.MatteColor = clBlack + Border.MatteTop = 0 + Border.MatteLeft = 0 + Border.MatteBottom = 0 + Border.MatteRight = 0 + end + object jPanel3: TJPanel + Tag = 12 + Left = 376 + Top = 72 + Width = 201 + Height = 49 + Hint = 'jPanel1' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = 3355443 + Background = clBtnFace + Border.BorderType = BevelBorder + Border.LineColor = clBlack + Border.LineThickness = 0 + Border.LineRounded = False + Border.EtchHighlightColor = clBlack + Border.EtchShadowColor = clBlack + Border.Etchtype = 0 + Border.BevelHighlightColor = clSilver + Border.BevelShadowColor = clBlack + Border.Beveltype = 1 + Border.MatteColor = clBlack + Border.MatteTop = 0 + Border.MatteLeft = 0 + Border.MatteBottom = 0 + Border.MatteRight = 0 + object lGesamt: TJLabel + Tag = 1 + Left = 8 + Top = 8 + Width = 93 + Height = 30 + Hint = 'jLabel3' + Font.Charset = DEFAULT_CHARSET + Font.Color = clMaroon + Font.Height = -22 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = clMaroon + Background = clBtnFace + Text = 'Gesamt:' + HorizontalAlignment = LEFT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + object lGesamtzeit: TJLabel + Tag = 1 + Left = 112 + Top = 8 + Width = 83 + Height = 30 + Hint = 'jLabel4' + Font.Charset = DEFAULT_CHARSET + Font.Color = clMaroon + Font.Height = -22 + Font.Name = 'Dialog' + Font.Style = [fsBold] + Foreground = clMaroon + Background = clBtnFace + Text = '? sek' + HorizontalAlignment = RIGHT + VerticalAlignment = CENTER + HorizontalTextPosition = RIGHT + VerticalTextPosition = CENTER + IconTextGap = 4 + DisplayedMnemonic = 0 + DisplayedMnemonicIndex = 0 + end + end +end diff --git a/Quellcodes/alg_gr_highscorespiel/JEClasses.jar b/Quellcodes/alg_gr_highscorespiel/JEClasses.jar new file mode 100644 index 0000000..269e208 Binary files /dev/null and b/Quellcodes/alg_gr_highscorespiel/JEClasses.jar differ diff --git a/Quellcodes/alg_gr_highscorespiel/MyServer.java b/Quellcodes/alg_gr_highscorespiel/MyServer.java new file mode 100644 index 0000000..660956d --- /dev/null +++ b/Quellcodes/alg_gr_highscorespiel/MyServer.java @@ -0,0 +1,112 @@ +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Scanner; +import java.io.PrintWriter; +import java.util.ArrayList; + +/** + * Die Klasse MyServer verwaltet einen ServerSocket. Sie erstellt einen ServerSocket an einem + * bestimmten Port und wartet dort auf Clients. Es können mehrere Clients gleichzeitig angemeldet sein. + * Eine Klasse, die diesen Server benutzt, muss MyServerSocketListener implementieren. Sie wird dann + * über die Methode neuerClient informiert, wenn sich ein neuer Client am Server angemeldet hat. + * Beschreibung + * + * + * @version 1.0 vom 15.11.2012 + * @author Thomas Schaller + */ + +public class MyServer extends Thread { + + // Anfang Attribute + private ServerSocket ss; + private int port; + private boolean aktiv = true; + private MyServerSocketListener listener; + // Ende Attribute + + /** Dieser Konstruktor erzeugt einen neuen ServerSocket, startet ihn aber nicht sofort. + * @param listener Klasse, die MyServerSocketListener implementiert und dann über neue Clients und eingehende Nachrichten informiert wird. + * @param port Port, den der ServerSocket abhört. + */ + + public MyServer(MyServerSocketListener listener, int port) { + this.port = port; + this.listener = listener; + try { + ss = new ServerSocket(port); + } catch(Exception e) { + System.out.println(e); + } // end of try + } + + // Anfang Methoden + /** Liefert den Port, den der Server abhört. + * @return Port + */ + public int getPort() { + return port; + } + + /** Liefert die lokale IP-Adresse des Servers + * @return IP + */ + public String getIP() { + try{ + return ss.getInetAddress().getLocalHost().getHostAddress(); + + } catch( Exception e) { + return ""; + } + + + } + + /** Startet das Abhören des Ports und das Annehmen der Clients + */ + public void starten() { + start(); + } + + /** Verwaltet das Annehmen der Clients (Diese Methode bitte nicht direkt aufrufen, sondern mit starten() aktivieren). + */ + public void run() { + aktiv = true; + try { + while(aktiv) { + System.out.println("Warte auf Client"); + Socket s = ss.accept(); + System.out.println("Client empfangen"); + MySocket ms = new MySocket(s, listener); + listener.neuerClient(ms); + } + } catch(Exception e) { + System.out.println("Server beendet!"); + } // end of try + + + } + + /** Bricht das Abhören des Ports ab. Es kann nicht wieder durch starten aktiviert werden. Dazu muss ein neuer Server erstellt werden. + */ + public void stoppen() { + aktiv = false; + try{ + ss.close(); + interrupt(); + } catch( Exception e) { + System.out.println(e); + } + } + + /** Meldet, ob der Server aktiv ist. + * @return true, falls der Server den Port abhört, sonst false. + */ + public boolean getAktiv() { + return aktiv; + } + + // Ende Methoden +} // end of Server + + diff --git a/Quellcodes/alg_gr_highscorespiel/MyServerSocketListener.java b/Quellcodes/alg_gr_highscorespiel/MyServerSocketListener.java new file mode 100644 index 0000000..ec80167 --- /dev/null +++ b/Quellcodes/alg_gr_highscorespiel/MyServerSocketListener.java @@ -0,0 +1,14 @@ +import java.net.ServerSocket; +import java.net.Socket; + +/** + * Listenerdefinitionen für MyServer . + * Klassen, die mit diesen beiden Klassen arbeiten müssen diese Listener implementieren. + * + * @version 1.0 vom 15.11.2012 + * @author Thomas Schaller + */ + + interface MyServerSocketListener extends MySocketListener { + void neuerClient(MySocket s); // ein neuer Client hat sich mit dem Server verbunden. +} diff --git a/Quellcodes/alg_gr_highscorespiel/MySocket.java b/Quellcodes/alg_gr_highscorespiel/MySocket.java new file mode 100644 index 0000000..a8d9309 --- /dev/null +++ b/Quellcodes/alg_gr_highscorespiel/MySocket.java @@ -0,0 +1,196 @@ +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Scanner; +import java.io.*; +import java.util.ArrayList; +import java.nio.charset.StandardCharsets; + + + +/** +* Die Klasse MySocket verwaltet eine Client-Server-Verbindung. Sie wartet auf eingehende Nachrichten und + * informiert ihren Listener, wenn eine Nachricht eingangen ist. Die Nachricht kann dann beim Socket abgeholt werden. + * Außerdem können Nachrichten in Form von Strings versendet werden. + * Der Listener wird außerdem informiert, wenn die Verbindung zusammengebrochen / beendet ist. + * Der Listener muss das Interface MySocketListener implementieren. + * + * + * @version 1.0 vom 15.11.2012 +* @author Thomas Schaller + */ + +public class MySocket extends Thread{ + + // Anfang Attribute2 + private boolean aktiv; + private Socket socket; + private BufferedReader eingang=null; + PrintWriter ausgang=null; + MySocketListener listener=null; + + // Ende Attribute2 + + /** Dieser Konstruktor erstellt einen MySocket aus einem schon vorhandenen Socket und ist für die Verwendung durch MyServer gedacht. + * @param s Socket, der durch MySocket verwaltet werden soll. + * @param listener Listener, der über eingehende Nachrichten und das Beenden der Verbindung informiert wird. Der Listener muss MySocketListener implementieren. + */ + public MySocket(Socket s, MySocketListener listener){ + this.socket = s; + this.listener = listener; + try { + eingang = new BufferedReader(new InputStreamReader(socket.getInputStream())); + ausgang = new PrintWriter(socket.getOutputStream()); + aktiv = true; + this.start(); + } catch(Exception e) {; + System.out.println(e); + e.printStackTrace(); + aktiv = false; + } // end of try + } + + /** Dieser Konstruktor erstellt einen neuen Socket. Er verbindet sich mit einem Server an der angegebenen Adresse unter dem angegebenen Port. Der Listener wird + * über eingehende Nachrichten und das Beenden der Verbindung informiert. + * @param address IP-Adresse oder Domain-Name des Servers + * @param port Portnummer, die der Server abhört + * @param listener Listener, der über eingehende Nachrichten und das Beenden der Verbindung informiert wird. Der Listener muss MySocketListener implementieren. + */ + public MySocket(String address, int port, MySocketListener listener) { + this.listener = listener; + try { + this.socket = new Socket(address, port); + eingang = new BufferedReader(new InputStreamReader(socket.getInputStream())); + ausgang = new PrintWriter(socket.getOutputStream()); + aktiv = true; + this.start(); + } catch(Exception e) { + System.out.println(e); + e.printStackTrace(); + aktiv = false; + } // end of try + } + + // Anfang Methoden2 + /** Verwaltet das Annehmen der Nachrichten (Diese Methode bitte nicht direkt aufrufen, sie wird automatisch gestartet). + */ + public void run(){ + try { + while (aktiv){ + if (listener != null && eingang.ready()) listener.nachrichtEmpfangen(this); + Thread.sleep(5); + } + } + catch (Exception e) { + if(socket!=null)try{socket.close();}catch(Exception ex){;} + System.err.println(e); + e.printStackTrace(); + } + aktiv = false; + if (listener != null) listener.verbindungBeendet(this); + + } + + + + + /** Liefert die eingangene Nachricht. Diese Methode bitte nur aufrufen, wenn der Listener über den Eingang einer Nachricht informiert wurde, da die Methode sonst bis + * zur nächsten eingehenden Nachricht wartet. + * @return Nachricht + */ + public String holeNachricht() { + try{ + + + if (aktiv && eingang.ready()) { + + String s = eingang.readLine(); + System.out.println(s); + byte[] b = Base64.decode(s); + /* for (int i = 0; i < b.length ; i++) { + System.out.print(b[i]); + System.out.print(" "); + } // end of for + System.out.println("");*/ + + return s; + } // end of if + } + catch(Exception e) { + e.printStackTrace(); + + return null; + } + + + return null; + } + + /** Versendet eine Nachricht an den Server. + * @param nachricht Zu sendender Text. + */ + public void sendeNachricht(String nachricht) { + try { + //byte[] b = nachricht; + /* for (int i = 0; i < b.length ; i++) { + System.out.print(b[i]); + System.out.print(" "); + } // end of for + System.out.println("");*/ + //ausgang.println(Base64.encode(nachricht)); + ausgang.println(nachricht); + // System.out.println(Base64.encode(nachricht)); + ausgang.flush(); + } catch(Exception e) { + System.out.println(e); + e.printStackTrace(); + if (listener != null) listener.verbindungBeendet(this); + aktiv = false; + } + } + + /** Bricht eine bestehende Client-Server-Verbindung ab. + */ + + public void trenneVerbindung() { + aktiv = false; + if (socket != null) { + try { + socket.close(); + } catch(Exception e) { + System.out.println(e); + e.printStackTrace(); + } + + } // end of if + socket = null; // end of try + } + + /** Liefert den Socket der Verbindung. Kann benutzt werden, um dann aus dem Socket weitere Informationen wie IP-Adressen oder Portnummern zu ermitteln. + * @return Socket, der Verbindung. + */ + public Socket getSocket() { + return socket; + } + + /** Liefert den Status der Verbindung. + * @return true, falls die Verbindung noch aktiv ist, sonst false. + */ + public boolean isAktiv() { + return aktiv; + } + + /** Räumt alles auf, damit der Thread nicht weiterläuft (bitte nicht aufrufen). + */ + public void finalize() { + // Schließen der Streams und des Sockets, wenn + // die Verbindung gelöscht wird wird + try { + trenneVerbindung(); + } + catch(Exception e) { + System.out.println(e); + e.printStackTrace(); + } + } + // Ende Methoden2 +} diff --git a/Quellcodes/alg_gr_highscorespiel/MySocketListener.java b/Quellcodes/alg_gr_highscorespiel/MySocketListener.java new file mode 100644 index 0000000..edcd1b7 --- /dev/null +++ b/Quellcodes/alg_gr_highscorespiel/MySocketListener.java @@ -0,0 +1,17 @@ +import java.net.ServerSocket; +import java.net.Socket; + +/** + * Listenerdefinitionen für MyServer und MySocket. + * Klassen, die mit diesen beiden Klassen arbeiten müssen diese Listener implementieren. + * + * @version 1.0 vom 15.11.2012 + * @author Thomas Schaller + */ + +interface MySocketListener { // Der Listener wird über folgendes informiert... + void nachrichtEmpfangen(MySocket s); // am Socket ist eine Nachricht eingegangen. Diese kann dann mit s.holeNachricht() abgeholt werden. + void verbindungBeendet(MySocket s); // die Verbindung wurde beendet oder ist zusammengebrochen. +} + + diff --git a/Quellcodes/alg_gr_highscorespiel/ScoreSaver.jar b/Quellcodes/alg_gr_highscorespiel/ScoreSaver.jar new file mode 100644 index 0000000..8628b68 Binary files /dev/null and b/Quellcodes/alg_gr_highscorespiel/ScoreSaver.jar differ diff --git a/Quellcodes/alg_gr_highscorespiel/ScoreSaver.java b/Quellcodes/alg_gr_highscorespiel/ScoreSaver.java new file mode 100644 index 0000000..b63e85f --- /dev/null +++ b/Quellcodes/alg_gr_highscorespiel/ScoreSaver.java @@ -0,0 +1,363 @@ +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.event.*; +import java.util.ArrayList; +import javax.swing.filechooser.*; + +/** + * + * ScoreSaver: Nimmt Ergebnisse vom BinärSpiel entgegen und speichert sie als CSV-Datei + * Erzeugt damit Datengrundlage für Highscore-Tabelle + * V1.1: Rundenzeit vom Server steuerbar, Fehlerkorrektur + * V1.2: Gesamtzeit vom Server steuerbar + * + * @version 1.2 vom 18.02.2019 + * @author Thomas Schaller + * cc0-Lizenz ZPG IMP Klasse 9 + */ + +public class ScoreSaver extends JFrame implements MyServerSocketListener { + // Anfang Attribute + private ArrayList clients; + private ArrayList names; + private Table csvDaten = new Table(); + private static boolean ende; + private MyServer server; + private JLabel jLabel1 = new JLabel(); + private JButton jBServerStarten = new JButton(); + private JButton jBSpielStarten = new JButton(); + //private JNumberField jNFPort = new JNumberField(); + private JList jList1 = new JList(); + private DefaultListModel jList1Model = new DefaultListModel(); + private JScrollPane jList1ScrollPane = new JScrollPane(jList1); + private JLabel jLabel2 = new JLabel(); + private JTextArea jTAPunkte = new JTextArea(); + private JScrollPane jList2ScrollPane = new JScrollPane(jTAPunkte); + private JLabel jLabel4 = new JLabel(); + private int changeClientListAktiv = 0; + private JLabel jLabel3 = new JLabel(); + private JButton jBSave = new JButton(); + private JButton jBClear = new JButton(); + private JTextField jTFTrennzeichen = new JTextField(); + private JLabel jLabel5 = new JLabel(); + private JLabel jLabel6 = new JLabel(); + private JLabel jLIPAdresse = new JLabel(); + private JNumberField jNFRundenzeit = new JNumberField(); + private JNumberField jNFSpielzeit = new JNumberField(); + private Timer timer1 = new Timer(1000, null); + private int spielzeit = 300; + // Ende Attribute + + public ScoreSaver() { + // Frame-Initialisierung + super(); + setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + int frameWidth = 618; + int frameHeight = 441; + setSize(frameWidth, frameHeight); + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + int x = (d.width - getSize().width) / 2; + int y = (d.height - getSize().height) / 2; + setLocation(x, y); + setTitle("Score-Saver"); + setResizable(false); + Container cp = getContentPane(); + cp.setLayout(null); + // Anfang Komponenten + jLIPAdresse.setBounds(20,8, 590,50 ); + jLIPAdresse.setText("IP-Adresse: Server inaktiv"); + jLIPAdresse.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 44 )); + jLIPAdresse.setHorizontalAlignment(JLabel.CENTER); + jLIPAdresse.setForeground(new Color(150,0,0)); + cp.add(jLIPAdresse); + + jLabel5.setBounds(20,68, 150,25 ); + jLabel5.setText("Dauer einer Runde (sek)"); + cp.add(jLabel5); + + jNFRundenzeit.setBounds(210, 68, 50, 25); + jNFRundenzeit.setInt(60); + cp.add(jNFRundenzeit); + + jLabel6.setBounds(320,68, 150,25 ); + jLabel6.setText("Gesamte Spielzeit (sek)"); + cp.add(jLabel6); + + jNFSpielzeit.setBounds(510, 68, 50, 25); + jNFSpielzeit.setInt(300); + cp.add(jNFSpielzeit); + + + jBServerStarten.setBounds(8, 98, 290, 25); + jBServerStarten.setText("Server ist inaktiv - Server starten?"); + jBServerStarten.setMargin(new Insets(2, 2, 2, 2)); + jBServerStarten.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + jBServerStarten_ActionPerformed(evt); + } + }); + cp.add(jBServerStarten); + + + jBSpielStarten.setBounds(304, 98, 285, 25); + jBSpielStarten.setText("Spiel starten"); + jBSpielStarten.setMargin(new Insets(2, 2, 2, 2)); + jBSpielStarten.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + jBSpielStarten_ActionPerformed(evt); + } + }); + cp.add(jBSpielStarten); + + // Spielteilnehmer + jList1.setModel(jList1Model); + + jList1ScrollPane.setBounds(8, 153, 290, 185); + cp.add(jList1ScrollPane); + jLabel2.setBounds(8, 130, 110, 20); + jLabel2.setText("Spielteilnehmer"); + cp.add(jLabel2); + + // Scores + jTAPunkte.setEditable(false); + jList2ScrollPane.setBounds(304, 153, 285, 185); + cp.add(jList2ScrollPane); + jLabel3.setBounds(304, 1300, 110, 20); + jLabel3.setText("Ergebnisse"); + cp.add(jLabel3); + + JLabel l = new JLabel(); + l.setBounds(20,342, 80,25 ); + l.setText("Trennzeichen"); + cp.add(l); + jTFTrennzeichen.setText(";"); + jTFTrennzeichen.setBounds(110,342,20,25); + jTFTrennzeichen.setHorizontalAlignment(JTextField.CENTER); + cp.add(jTFTrennzeichen); + + + jBSave.setBounds(150, 342, 190, 25); + jBSave.setText("Daten speichern"); + jBSave.setMargin(new Insets(2, 2, 2, 2)); + jBSave.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + jBSave_ActionPerformed(evt); + } + }); + cp.add(jBSave); + + jBClear.setBounds(370, 342, 190, 25); + jBClear.setText("Ergebnisse löschen"); + jBClear.setMargin(new Insets(2, 2, 2, 2)); + jBClear.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + jBClear_ActionPerformed(evt); + } + }); + cp.add(jBClear); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent evt) { + ChatServerGUI_WindowClosing(evt); + } + }); + jLabel4.setBounds(185, 382, 229, 20); + jLabel4.setText("(cc) 2018, Thomas Schaller, Version 1.2"); + jLabel4.setForeground(Color.GRAY); + cp.add(jLabel4); + + timer1.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + timer1_ActionPerformed(evt); + } + }); + timer1.setRepeats(true); + timer1.setInitialDelay(0); + + // Spielteilnehmer + + // Ende Komponenten + + setVisible(true); + + clients = new ArrayList(); + names = new ArrayList(); + server = null; + csvDaten.addColumn("Name"); + csvDaten.addColumn("Punkte"); + } // end of public ScoreSaver + + + + // Anfang Methoden + public void jBSave_ActionPerformed(ActionEvent evt) { + JFileChooser chooser = new JFileChooser(); + FileFilter filter = new FileNameExtensionFilter("csv-Dateien", + "csv"); + // Filter wird unserem JFileChooser hinzugefügt + chooser.addChoosableFileFilter(filter); + chooser.setAcceptAllFileFilterUsed(false); + // Dialog zum Oeffnen von Dateien anzeigen + int rueckgabeWert =chooser.showDialog(null, "Punkte speichern"); + + + /* Abfrage, ob auf "Speichern" geklickt wurde */ + if(rueckgabeWert == JFileChooser.APPROVE_OPTION) + { + char separator = ';'; + if(jTFTrennzeichen.getText().length()>0 && jTFTrennzeichen.getText().trim().charAt(0)!= ' '){ + separator = jTFTrennzeichen.getText().trim().charAt(0); + } + + csvDaten.saveCSV(chooser.getSelectedFile().getAbsolutePath(),"header",separator,'"'); + } + } + + public void neuerClient(MySocket client) { + this.clients.add(client); + this.names.add("?"); + } + + public void changeClientList() { + changeClientListAktiv++; + if (changeClientListAktiv == 1) { + do{ + changeClientListAktiv--; + DefaultListModel newListModel = new DefaultListModel(); + for (int i = 0; i < clients.size() ; i++ ) { + MySocket s = clients.get(i); + String n = names.get(i); + newListModel.addElement(n+"("+s.getSocket().getInetAddress()+":"+s.getSocket().getPort()+")"); + } // end of for + jList1.setModel(newListModel); + jList1.validate(); + } + while (changeClientListAktiv > 0 ); + } // end of if + } + + public void nachrichtEmpfangen(MySocket client) { + String s = client.holeNachricht(); + System.out.println("Habe Nachricht empfangen:"+s); + String[] ss = s.split(":"); + int i = clients.indexOf(client); + + if (ss[0].equals("exit")) { + s = s+names.get(i); + clients.remove(i); + names.remove(i); + client.trenneVerbindung(); + changeClientList(); + return; + } + + if (ss[0].equals("user")) { + names.set(i,ss[1]); + if(timer1.isRunning()) { + client.sendeNachricht("round "+jNFRundenzeit.getText()); + client.sendeNachricht("game "+jNFSpielzeit.getText()); + } + + changeClientList(); + return; + } + + if (ss[0].equals("punkte") && jNFSpielzeit.getInt()>0) { + jTAPunkte.append(names.get(i)+";"+ss[1]+"\n"); + TableRow tr = csvDaten.addRow(); + tr.setString("Name",names.get(i)); + tr.setString("Punkte",ss[1]); + + } // end of if + } // end of if + + + public void timer1_ActionPerformed(ActionEvent evt) { + int rest = jNFSpielzeit.getInt(); + if(rest > 0) { + jNFSpielzeit.setInt(jNFSpielzeit.getInt()-1); + for (MySocket c: clients) { + c.sendeNachricht("game "+jNFSpielzeit.getText()); + + } // end of for + + } else { + timer1.stop(); + jBSpielStarten.setEnabled(true); + jNFSpielzeit.setInt(spielzeit); + jNFSpielzeit.setEnabled(true); + jNFRundenzeit.setEnabled(true); + jBServerStarten.setEnabled(true); + + } // end of if-else + + } + + + public void verbindungBeendet(MySocket client) { + if (clients.contains(client)) { + + int i = clients.indexOf(client); + + clients.remove(i); + System.out.println("Verbindung mit "+client.getSocket().getInetAddress()+" Port: "+client.getSocket().getPort()+" verloren."); + for (MySocket c: clients) { + if (c!=client) { + c.sendeNachricht(("exit:"+names.get(i)+":alle")); + } // end of if + } + names.remove(i); + changeClientList(); + } // end of if + + } + + + + public static void main(String[] args) { + new ScoreSaver(); + } // end of main + + public void jBServerStarten_ActionPerformed(ActionEvent evt) { + if (jBServerStarten.getText().equals("Server ist inaktiv - Server starten?")) { + server = new MyServer(this, 44444); + server.starten(); + jBServerStarten.setText("Server läuft - Server stoppen?"); + jLIPAdresse.setText("IP-Server: "+server.getIP()); + + } else { + server.stoppen(); + server = null; + jBServerStarten.setText("Server ist inaktiv - Server starten?"); + jLIPAdresse.setText("IP-Server: inaktiv"); + } // end of if-else + } // end of jBStarten_ActionPerformed + + public void jBSpielStarten_ActionPerformed(ActionEvent evt) { + spielzeit = jNFSpielzeit.getInt(); + timer1.start(); + jBServerStarten.setEnabled(false); + jBSpielStarten.setEnabled(false); + jNFSpielzeit.setEnabled(false); + jNFRundenzeit.setEnabled(false); + for (MySocket c: clients) { + c.sendeNachricht("round "+jNFRundenzeit.getText()); + c.sendeNachricht("game "+jNFSpielzeit.getText()); + + } // end of for + + } // end of jBStarten_ActionPerformed + + public void jBClear_ActionPerformed(ActionEvent evt) { + csvDaten.clearRows(); + jTAPunkte.setText(""); + } // end of jBStarten_ActionPerformed + + + public void ChatServerGUI_WindowClosing(WindowEvent evt) { + if (server != null) server.stoppen(); + } // end of ChatServerGUI_WindowClosing + + // Ende Methoden +} // end of class ScoreSaver diff --git a/Quellcodes/alg_gr_highscorespiel/Table.java b/Quellcodes/alg_gr_highscorespiel/Table.java new file mode 100644 index 0000000..ef79e02 --- /dev/null +++ b/Quellcodes/alg_gr_highscorespiel/Table.java @@ -0,0 +1,895 @@ +/** + * Die Klasse Table vereinfacht den Zugriff auf CSV-Dateien. + * Die Klassen Table und TableRow ermöglichen einen einfachen Zugriff auf tabellenbasierte + * Dokumente. + * + * @author Thomas Schaller + * @version 1.0 vom 01.02.2019 + */ + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; +import java.io.*; +import java.util.Scanner; + +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.Attribute; +import org.jdom.JDOMException; +import org.jdom.input.SAXBuilder; +import org.jdom.output.XMLOutputter; +import org.jdom.output.Format; + +public class Table +{ + // Standardtrennzeichen für Spalten + private static final char DEFAULT_SEPARATOR = ';'; + // Standardmarkierung für Texte + private static final char DEFAULT_QUOTE = '"'; + // Standardtrennzeichen für Dezimalzahlen + private static final char DEFAULT_COMMA = ','; + + // mögliche Spaltentypen + private static final String UNKNOWN ="UNKOWN"; + private static final String INT = "INTEGER"; + private static final String DOUBLE = "DOUBLE"; + private static final String FLOAT = "FLOAT"; + + // interne Verwaltung des Dokuments als JDOM-Document-Objekt + private Document doc; + // Verweis auf Element für Kopfzeile + private Element header; + // Ende Attribute + + /** + * Erzeugt leeres Tabellen-Dokument. + */ + public Table() { + this.doc = new Document(); + doc.setRootElement(new Element("CSV-Data")); + this.header = new Element("Header"); + doc.getRootElement().addContent(header); + } + + + /** + * Erzeugt Tabellen-Dokument aus einer CSV-Datei. + * Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten. + * Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat, + * dann lassen Sie einfach die Option "header" weg. + * @param filename Dateiname der CSV-Datei. + * @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält. + * @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab) + * @param quote Kennung für Texte (meist '"'). + */ + public Table(String filename, String options, char separator, char quote) { + loadCSV(filename, options, separator, quote); + } + + /** + * Erzeugt Tabellen-Dokument aus einer CSV-Datei. + * Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"'). + * Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat, + * dann lassen Sie einfach die Option "header" weg. + * @param filename Dateiname der CSV-Datei. + * @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält. + */ + public Table(String filename, String options) { + loadCSV(filename, options); + } + + /** + * Erzeugt Tabellen-Dokument aus einer CSV-Datei. + * Liest den Inhalt einer Datei ohne Kopfzeile und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"'). + * @param filename Dateiname der CSV-Datei. + */ + public Table(String filename) { + loadCSV(filename); + } + + // Anfang Methoden + /** + * Liest den Inhalt einer CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"'). + * @param filename Dateiname der CSV-Datei. + */ + public void loadCSV(String filename) { + loadCSV(filename, ""); + } + + /** + * Liest den Inhalt einer CSV-Datei (Separator = ';', Kennung für Text = '"'). + * Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat, + * dann lassen Sie einfach die Option "header" weg. + * @param filename Dateiname der CSV-Datei. + * @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält. + */ + public void loadCSV(String filename, String options) { + loadCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE); + } + + /** + * Liest den Inhalt einer CSV-Datei. + * Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat, + * dann lassen Sie einfach die Option "header" weg. + * @param filename Dateiname der CSV-Datei. + * @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält. + * @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab) + * @param quote Kennung für Texte (meist '"'). + */ + public void loadCSV(String filename, String options, char separator, char quote) { + doc = new Document(); + doc.setRootElement(new Element("CSV-Data")); + header = new Element("Header"); + doc.getRootElement().addContent(header); + try { + File f = new File(filename); + Scanner scanner = new Scanner(new File(filename)); + if(options.toLowerCase().contains("header") && scanner.hasNext()) { + List entries = parseLine(scanner.nextLine(), separator, quote); + int i= 0; + for(String s : entries) { + Element entry = new Element("Column"); + header.addContent(entry); + entry.setAttribute("name", s); + entry.setAttribute("type", "unknown"); + i++; + } + } + + List cols = header.getChildren(); + + while (scanner.hasNext()) { + Element line = new Element("Row"); + doc.getRootElement().addContent(line); + List entries = parseLine(scanner.nextLine(), separator, quote); + int i= 0; + + for(String s : entries) { + + if(i==cols.size()) { + Element entry = new Element("Column"); + entry.setAttribute("type", "unknown"); + header.addContent(entry); + cols = header.getChildren(); + } + + Element entry = new Element("Entry"); + if(cols.get(i).getAttributeValue("name")!=null) entry.setName(cols.get(i).getAttributeValue("name")); + entry.setText(s); + line.addContent(entry); + i++; + } + } + scanner.close(); + + } catch (Exception e) { + System.out.println("Fehler beim Lesen der CSV-Datei"); + } + } + + /** + * Speichert das aktuelle Dokument als CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"'). + * @param filename Dateiname der CSV-Datei. + */ + public void saveCSV(String filename) { + saveCSV(filename, ""); + } + + /** + * Speichert das aktuelle Dokument als CSV-Datei (Separator = ';', Kennung für Text = '"'). + * Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll, + * dann lassen Sie einfach die Option "header" weg. + * @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll. + * @param filename Dateiname der CSV-Datei. + */ + public void saveCSV(String filename, String options) { + saveCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE); + } + + /** + * Speichert das aktuelle Dokument als CSV-Datei. + * Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll, + * dann lassen Sie einfach die Option "header" weg. + * @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll. + * @param filename Dateiname der CSV-Datei. + * @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab) + * @param quote Kennung für Texte (meist '"'). + */ + public void saveCSV(String filename, String options, char separator, char quote){ + try{ + File f = new File(filename); + PrintStream outputFile = new PrintStream (f); + System.out.println("Speicher in : "+f.getAbsolutePath()); + List columns = header.getChildren(); + String sq = ""+quote; + String ss = ""+separator; + if(quote =='"') sq = "\""; + if(separator =='"') ss = "\""; + + if(options.toLowerCase().contains("header")) { + String h = ""; + for(Element c : columns) { + h += ss + sq + c.getAttributeValue("name")+sq; + } + outputFile.println(h.substring(1)); + } + for(int i = 0; i parseLine(String cvsLine) { + return parseLine(cvsLine, DEFAULT_SEPARATOR, DEFAULT_QUOTE); + } + + /** HIlfsfunktion für die Analyse einer Dateizeile + * @param cvsLine Zeile aus der Datei + * @param sparator Trennzeichen für die Spalten + * @return Liste von String für die einzelnen Spalten + */ + private List parseLine(String cvsLine, char separator) { + return parseLine(cvsLine, separator, DEFAULT_QUOTE); + } + + /** HIlfsfunktion für die Analyse einer Dateizeile + * @param cvsLine Zeile aus der Datei + * @param sparator Trennzeichen für die Spalten + * @param customQuote Kennung für Strings + * @return Liste von String für die einzelnen Spalten + */ + private List parseLine(String cvsLine, char separator, char customQuote) { + + List result = new ArrayList<>(); + + //if empty, return! + if (cvsLine == null && cvsLine.isEmpty()) { + return result; + } + + //ggf. Default-Value laden + if (customQuote == ' ') { + customQuote = DEFAULT_QUOTE; + } + + if (separator == ' ') { + separator = DEFAULT_SEPARATOR; + } + + StringBuffer curVal = new StringBuffer(); + boolean inQuotes = false; + boolean startCollectChar = false; + boolean doubleQuotesInColumn = false; + + char[] chars = cvsLine.toCharArray(); + + for (char ch : chars) { + + if (inQuotes) { // aktueller Text ist in Quotes eingeschlossen + startCollectChar = true; + + if (ch == customQuote) { // Quotes werden beendet, aber Achtung bei "" => Metazeichen + inQuotes = false; + if (ch == '\"') { + doubleQuotesInColumn = true; + } + + } else { + + if (ch == '\"' && !doubleQuotesInColumn) { + doubleQuotesInColumn = true; + } else { + curVal.append(ch); + doubleQuotesInColumn = false; + } + + } + } else { + if (ch == customQuote) { + + inQuotes = true; + + //Fixed : allow "" in empty quote enclosed + if (ch == '\"'){ + if(doubleQuotesInColumn) { + curVal.append('"'); + doubleQuotesInColumn = false; + } else doubleQuotesInColumn = true; + + + } + } + else { + doubleQuotesInColumn = false; + if (ch == separator) { + + result.add(curVal.toString()); + + curVal = new StringBuffer(); + startCollectChar = false; + + } else if (ch == '\r') { + //ignore LF characters + continue; + } else if (ch == '\n') { + //the end, break! + break; + } else { + curVal.append(ch); + } + } + } + + } + result.add(curVal.toString()); + return result; + } + + /** + * Sucht die Nummer einer durch Namen gegebenen Spalte. + * @param name Name der Spalte + * @return Nummer der Spalte + */ + + private int findColumnNumber(String name) { + List columns = header.getChildren(); + int i = 0; + for(Element c : columns) { + if (c.getAttributeValue("name").toLowerCase().equals(name.toLowerCase())) { + return i; + + } + i++; + } + return -1; + } + + /** + * Fügt eine neue Spalte am Ende der Tabelle an. + */ + public void addColumn() { + Element entry = new Element("Column"); + entry.setAttribute("type", Table.UNKNOWN); + header.addContent(entry); + } + + /** + * Fügt eine neue Spalte am Ende der Tabelle an und benennt sie. + * @param title Bezeichnung der Spalte + */ + public void addColumn(String title) { + addColumn(); + Element nc = ((List)(header.getChildren())).get(header.getChildren().size()-1); + nc.setAttribute("name", title); + } + + /** + * Fügt eine neue Spalte am Ende der Tabelle an und benennt und typisiert sie. + * @param title Bezeichnung der Spalte + * @param type Typ der Spalte (UNKNOWN, DOUBLE, INTEGER, FLOAT) + */ + public void addColumn(String title, String type) { + addColumn(title); + Element nc = ((List)(header.getChildren())).get(header.getChildren().size()-1); + nc.setAttribute("type", type); + } + + /** + * Löscht eine Spalte. + * @param i Nummer der Spalte. + */ + public void removeColumn(int i) { + List lines = doc.getRootElement().getChildren(); + for(Element l : lines) { + if(l.getChildren().size()>i) l.removeContent(i); + } + } + + /** + * Löscht eine Spalte + * @param name Name der Spalte + */ + public void removeColumn(String name) { + try{ + removeColumn(findColumnNumber(name)); + } catch(Exception e) { System.out.println("Unbekannter Spaltenname");} + } + + /** + * Liefert die Anzahl der Spalten in der Tabelle + * @return Anzahl der Spalten + */ + public int getColumnCount() { + return header.getChildren().size(); + } + + /** + * Liefert die Anzahl der Zeilen in der Tabelle + * @return Anzahl der Zeilen + */ + public int getRowCount() { + return doc.getRootElement().getChildren().size()-1; + } + + /** + * Löscht alle Zeilen der Tabelle. + * Die Spaltenüberschriften und Typen bleiben erhalten. + */ + public void clearRows() { + doc.getRootElement().removeChildren("Row"); + } + + /** + * Fügt eine neue Zeile an das Ende der Tabelle an. + * @return ein TableRow-Objekt für diese neue Zeile + */ + public TableRow addRow() { + Element row = new Element("Row"); + doc.getRootElement().addContent(row); + return new TableRow(doc, row); + } + + /** + * Löscht eine Zeile + * @param i Nummer der Zeile + */ + public void removeRow(int i) { + if(i rows = doc.getRootElement().getChildren(); + return new TableRow(doc, rows.get(i+1)); + } + return null; + } + + /** + * Liefert die ganze Tabelle als Array von TableRow-Objekten + * @return Array von TableRow-Objekten + */ + public TableRow[] rows() { + TableRow[] rows = new TableRow[getRowCount()]; + for(int i = 0; i < getRowCount(); i++) { + rows[i] = getRow(i); + } + return rows; + } + + /** + * Liefert den Wert einer Zelle als Integer-Zahl + * @param row Zeilennummer + * @param column Spaltennummer + * @return Wert der Zelle + */ + public int getInt(int row, int column) { + return getRow(row).getInt(column); + } + + /** + * Liefert den Wert einer Zelle als Integer-Zahl + * @param row Zeilennummer + * @param name Name der Spalte + * @return Wert der Zelle + */ + public int getInt(int row, String name) { + return getRow(row).getInt(name); + } + + /** + * Setzt den Wert einer Zelle als Integer-Zahl + * @param row Zeilennummer + * @param column Spaltennummer + * @param value neuer Wert der Zelle + */ + public void setInt(int row, int column,int value) { + getRow(row).setInt(column, value); + } + + /** + * Setzt den Wert einer Zelle als Integer-Zahl + * @param row Zeilennummer + * @param name Name der Spalte + * @param value neuer Wert der Zelle + */ + public void setInt(int row, String name, int value) { + getRow(row).setInt(name, value); + } + + /** + * Liefert alle Werte einer Zeile als Integer-Array. + * @param row Nummer der Zeile + * @return int-Array, dass alle Werte der Zeile enthält + */ + public int[] getIntRow(int row) { + try{ + TableRow trow = getRow(row); + int anz = getColumnCount(); + int[] r = new int[anz]; + for(int i=0; i) (header.getChildren())).get(i).getAttributeValue("name"); + } else { + return ""; + } + } + + /** + * Erzeugt eine neue Zeile mit i Spalten + * Wenn bisher nicht genügend Spalten vorhanden sind, werden automatisch neue Spalten hinzugefügt (auch zum Header) + * @param i Anzahl der Spalten + */ + private Element buildRow(int i) { + List columns = header.getChildren(); + Element entry=null; + for(int j=0; j<=i; j++) { + + if(j==columns.size()) { + Element h = new Element("Column"); + h.setAttribute("type", "unknown"); + header.addContent(h); + columns = header.getChildren(); + } + if(j==current.getChildren().size()) { + entry = new Element("Entry"); + if(columns.get(j).getAttributeValue("name")!=null) entry.setName(columns.get(j).getAttributeValue("name")); + current.addContent(entry); + + } + + } + return entry; + + } + + /** + * Erzeugt eine neue Zeile. + * Es werden genügend Spalten erzeugt, das ein Wert in Spalte "name" eingetragen werden kann + * @param name Name der Spalte + */ + private Element buildRow(String name) { + List columns = header.getChildren(); + int i = 0; + for(Element c: columns) { + + if(c.getAttributeValue("name").toLowerCase().equals(name.toLowerCase())) { + return buildRow(i); + } + i++; + } + return null; + + } + + /** + * Liefert den Wert einer Zelle als String + * @param i Nummer der Spalte + * @return Wert der Zelle + */ + public String getString(int i) { + if(i >= current.getContent().size()) return ""; + Element e = (Element) current.getContent(i) ; + if(e!=null) { + return e.getText(); + } else { + return ""; + } + } + + /** + * Liefert den Wert einer Zelle als String + * @param name Name der Spalte + * @return Wert der Zelle + */ + public String getString(String name) { + Element e = current.getChild(name) ; + if(e!=null) { + return e.getText(); + } else { + return ""; + } + } + + /** + * Setzt den Wert einer Zelle als String + * @param i Nummer der Spalte + * @param text neuer Wert der Zelle + */ + public void setString(int i, String text) { + + Element e = buildRow(i); + if(e!=null) e.setText(text); + } + + /** + * Setzt den Wert einer Zelle als String + * @param name Name der Spalte + * @param text neuer Wert der Zelle + */ + public void setString(String name, String text) { + Element e = buildRow(name); + if(e!=null) e.setText(text); + } + + + /** + * Liefert den Wert einer Zelle als Int-Zahl + * @param i Nummer der Spalte + * @return Wert der Zelle + */ + public int getInt(int i) { + try{ + Element e = (Element) current.getContent(i) ; + return Integer.parseInt(e.getText()); + } catch(Exception e) { + return 0; + } + } + + /** + * Liefert den Wert einer Zelle als Int-Zahl + * @param name Name der Spalte + * @return Wert der Zelle + */ + public int getInt(String name) { + try{ + Element e = (Element) current.getChild(name) ; + return Integer.parseInt(e.getText()); + } catch(Exception e) { + return 0; + } + } + + /** + * Setzt den Wert einer Zelle als Int-Zahl + * @param i Nummer der Spalte + * @param value neuer Wert der Zelle + */ + public void setInt(int i,int value) { + + Element e = buildRow(i); + if(e!=null) e.setText(""+value); + } + + /** + * Setzt den Wert einer Zelle als Int-Zahl + * @param name Name der Spalte + * @param value neuer Wert der Zelle + */ + public void setInt(String name, int value) { + Element e = buildRow(name); + if(e!=null) e.setText(""+value); + } + + /** + * Liefert den Wert einer Zelle als Float-Zahl + * @param i Nummer der Spalte + * @return Wert der Zelle + */ + public float getFloat(int i) { + try{ + Element e = (Element) current.getContent(i) ; + return Float.parseFloat(e.getText().replace(",",".")); + } catch(Exception e) { + return 0; + } + } + + /** + * Liefert den Wert einer Zelle als Float-Zahl + * @param name Name der Spalte + * @return Wert der Zelle + */ + public float getFloat(String name) { + try{ + Element e = (Element) current.getChild(name) ; + return Float.parseFloat(e.getText().replace(",",".")); + + } catch(Exception e) { + return 0; + } + } + + /** + * Setzt den Wert einer Zelle als Float-Zahl + * @param i Nummer der Spalte + * @param value neuer Wert der Zelle + */ + public void setFloat(int i,float value) { + + Element e = buildRow(i); + if(e!=null) e.setText(format.format(value)); + } + + /** + * Setzt den Wert einer Zelle als Float-Zahl + * @param name Name der Spalte + * @param value neuer Wert der Zelle + */ + public void setFloat(String name, float value) { + Element e = buildRow(name); + if(e!=null) e.setText(format.format(value)); + } + + /** + * Liefert den Wert einer Zelle als Double-Zahl + * @param i Nummer der Spalte + * @return Wert der Zelle + */ + public double getDouble(int i) { + try{ + Element e = (Element) current.getContent(i) ; + return Double.parseDouble(e.getText().replace(",",".")); + + } catch(Exception e) { + return 0; + } + } + + /** + * Liefert den Wert einer Zelle als Double-Zahl + * @param name Name der Spalte + * @return Wert der Zelle + */ + public double getDouble(String name) { + try{ + Element e = (Element) current.getChild(name) ; + return Double.parseDouble(e.getText().replace(",",".")); + + } catch(Exception e) { + return 0; + } + } + + /** + * Setzt den Wert einer Zelle als Double-Zahl + * @param i Nummer der Spalte + * @param value neuer Wert der Zelle + */ + public void setDouble(int i,double value) { + + Element e = buildRow(i); + if(e!=null) e.setText(format.format(value)); + } + + /** + * Setzt den Wert einer Zelle als Double-Zahl + * @param name Name der Spalte + * @param value neuer Wert der Zelle + */ + public void setDouble(String name, double value) { + Element e = buildRow(name); + if(e!=null) e.setText(format.format(value)); + } + +} diff --git a/Quellcodes/alg_gr_highscorespiel/jdom-1.1.3.jar b/Quellcodes/alg_gr_highscorespiel/jdom-1.1.3.jar new file mode 100644 index 0000000..a287727 Binary files /dev/null and b/Quellcodes/alg_gr_highscorespiel/jdom-1.1.3.jar differ diff --git a/Quellcodes/alg_gr_highscorespiel/readme.adoc b/Quellcodes/alg_gr_highscorespiel/readme.adoc new file mode 100644 index 0000000..1164d6f --- /dev/null +++ b/Quellcodes/alg_gr_highscorespiel/readme.adoc @@ -0,0 +1,12 @@ += Material : Highscorespiel + +|=== +|Zuordnung| Programmierung +|Klassenstufe| IMP Klasse 9 +|Bildungsplanbezug | Dateien einlesen und verarbeiten +|Werkzeug| Java +|Autoren| Thomas Schaller +|=== + +== Inhalt +Einfaches Spiel (Dezimal in Binärzahlen umwandeln), um Daten für eine Highscoretabelle in einer Klasse zu erzeugen.