Rzuciłem okiem tylko na szybko na Twój projekt.
- 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.
- 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
-
Formatowanie woła o pomstę do nieba.
Tutaj uciekło coś w lewo, tu również, to sprawia, że zaczynamy się gubić w kodzie.
-
Łamanie zasady SRP. Myślę, że warto oddzielić Swing
a 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)
- 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