Kolko krzyzyk serwer, watki. Problem z zadaniem. Czy ktos moze wytlumaczyc?

0

Witam,

Dostalismy zadanie, aby przerobic slynna gre tic tac toa (kolko krzyzyk) . Przyklad pochodzi z ksiazki z serii deitel java programming.
Do naszych zadan nalezalo:
-przerobienie appletu na GUI swing,
-dodanie przycisku restart po zakonczeniu gry,
-zdeterminowac czy jest wygrana X, O lub remis,
-podanie numeru ip i portu przez args.

Wiekszosc udalo mi sie uzyskac poza wznowieniem gry po nacisnieciu restart. Ogolnie nie wiem jak to zrobic i troche zrobilem balagan w kodzie. Czy ktos z forumowiczow, lubiacy Jave bylby szklonny zerknac na kod i udzielic rady jak naprawic ten balagan?

Ponizej znajduje sie kod zrodlowy:
https://drive.google.com/drive/folders/1wTbMAaSUguxDi2hqQLPDZ0KsehVLNfKy?usp=sharing

0

Czas Zemsty...
Kto? Pytam, "kto?": udostępnia kod na google drive?

0

Dzizas krajst przepraszam. Tam jest ponad 600 linijek ! zaraz wrzucę tu

0
Zakręcony Krawiec napisał(a):

Dzizas krajst przepraszam. Tam jest ponad 600 linijek ! zaraz wrzucę tu

Koledze raczej chodziło o to żebyś to wrzucił na jakiegoś GitHuba, warto poświęcić chwilę i się tego nauczyć, bo w przyszłości zaowocuje.

0

Z jakiegos powodu nie moge edytowac pierwszego posta.

Oto wersja z gita
https://github.com/matszal/A4b/tree/master/src

1

Rzuciłem okiem tylko na szybko na Twój projekt.

  1. Po pierwsze jak dla mnie za duże metody, a w sumie ich brak. Popatrz na Twój konstruktor:
    public TicTacToeClient(String host, int port)
    {
        ticTacToeHost = host;
        ticTacToePort = port;

        //Container container = getContentPane();

        // set up JTextArea to display messages to user
        displayArea = new JTextArea( 4, 30 );
        displayArea.setEditable( false );
        add( new JScrollPane( displayArea ), BorderLayout.SOUTH );

        // set up panel for squares in board
        boardPanel = new JPanel();
        boardPanel.setLayout( new GridLayout( 3, 3, 0, 0 ) );

        // create board
        board = new Square[ 3 ][ 3 ];

        // When creating a Square, the location argument to the constructor
        // is a value from 0 to 8 indicating the position of the Square on
        // the board. Values 0, 1, and 2 are the first row, values 3, 4,
        // and 5 are the second row. Values 6, 7, and 8 are the third row.
        for ( int row = 0; row < board.length; row++ ) {

            for ( int column = 0; column < board[ row ].length; column++ ) {

                // create Square
                board[ row ][ column ] = new Square( ' ', row * 3 + column );
                boardPanel.add( board[ row ][ column ] );
            }
        }

        // textfield to display player's mark
        idField = new JTextField();
        idField.setEditable( false );
        add( idField, BorderLayout.NORTH );

        restartButton = new JButton("restart Game");
        restartButton.setVisible(false);
        add(restartButton, BorderLayout.EAST);
        restartButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                for (int i = 0; i < 3; i++)
                    for (int j = 0; j < 3; j++)
                    {
                        setMark(board[i][j], ' ');

                    }
                    startClient();
            }
        });

        // set up panel to contain boardPanel (for layout purposes)
        panel2 = new JPanel();
        panel2.add( boardPanel, BorderLayout.CENTER );
        add( panel2, BorderLayout.CENTER );
        setSize(300, 255);
        setVisible(true);

        startClient();
}

Podziel go na metody. Czytaj linijka po linijce, patrz co jest podobne albo robi jedną rzecz i twórz z nich metody, które w konstruktorze będą tylko wywoływane.

  1. Komentarze są dobre, ale nazwy metod są lepsze. Zrób tak, żeby Twój kod określał sam siebie.
// control thread that allows continuous update of displayArea
    public void run()
    {
        // get player's mark (X or O)
        try {
            myMark = input.readChar();

            // display player ID in event-dispatch thread
            SwingUtilities.invokeLater(
                    new Runnable() {
                        public void run()
                        {
                            idField.setText( "You are player \"" + myMark + "\"" );
                        }
                    }
            );

            myTurn = ( myMark == X_MARK ? true : false );

            // receive messages sent to client and output them
            while ( true ) {
                processMessage( input.readUTF() );
            }

        } // end try

        // process problems communicating with server
        catch ( IOException ioException ) {
            ioException.printStackTrace();
        }

    }  // end method run
  1. Formatowanie woła o pomstę do nieba.
    Tutaj uciekło coś w lewo, tu również, to sprawia, że zaczynamy się gubić w kodzie.

  2. Łamanie zasady SRP. Myślę, że warto oddzielić Swinga od samej gry. Niech będą w odpowiednich klasach. Nie bój się ich, może ich być więcej niż 3 ;)

    private char[] board;
    private JTextArea outputArea;
    private Player[] players;
    private int port;
    private ServerSocket server;
    private int currentPlayer;
    private final int PLAYER_X = 0, PLAYER_O = 1;
    private final char X_MARK = 'X', O_MARK = 'O';

    boolean continueGame = false;
    private int counter = 0;
    private int firstPressed =0;

    boolean startNewGame = true;
    boolean gameFinished = false;

To się samo prosi, zobacz ile różnych obiektów masz w jednej klasie. Coś co odpowiada za:

  • wygląd - JTextArea
  • połączenie sieciowe - ServerSocket
  • mechanikę gry - Player (o którym swoją drogą nic nie wiemy bo nie ma go w repo)
  1. Jeszcze jedna uwaga odnośnie tej linii:
server = new ServerSocket( port, 2 )

Numery portów reprezentowane są przez liczby naturalne z zakresu od 0 do 65535. Niektóre numery portów (od 0 do 1023) są określone jako ogólnie znane (ang. well known ports) oraz zarezerwowane na standardowo przypisane do nich usługi, takie jak np. WWW czy poczta elektroniczna. Dzięki temu można identyfikować nie tylko procesy, ale ogólnie znane usługi działające na odległych systemach. Numery od 1024 do 49151 są określone przez IANA jako zarejestrowane, (ang. registered), a od 49152 do 65535 jako dynamiczne/prywatne, (ang. dynamic/private).

Źródło - link

0

Niestety mam dzis deadline i musze to wyslac jak jest i zajac sie tym jak bedzie wiecej czasu dla samego siebie. Dopiero ucze sie Javy i stad ten balagan w kodzie. Jestem zdeterminowany zeby poszerzac swoja wiedze! Dzieki za uwagi

Jezeli chodzi o serverSocket to drugi parametr odpowiada za backlog

Jakie polecasz dobre zrodla do nauki JAvy?

0 użytkowników online, w tym zalogowanych: 0, gości: 0