문제
단일 클라이언트용 가위바위보 프로그램에서 네트워크 클라이언트 부분의 문제입니다 이를 해결하는 프로그램의 다음 실행상태에 대해 빈칸을 채우세요
프로그램의 실행순서 및 실행상태
①
②
1 public static void main( String[] args ) {
3 new RockPaperScissorsNetwork( imagePath, serverIP );
PN2b public RockPaperScissorsNetwork( String imgPath, String serverIP ) {
PN21 this( imgPath );
PN1b public RockPaperScissorsNetwork( String imgPath ) {
PN11 super( imgPath );
P1b public RockPaperScissorsPanel( final String imgPath ) {
P1e }
③
PN13 new Network();
N1b public Network() {
N1e }
PN12 network =
PN1e }
PN22 network.connectAsClient( serverIP, this );
N3b public void connectAsClient( String serverIP, Runnable obj ) {
N32 new Socket( serverIP, serverPort );
E001 // [클라이언트]에서 [서버]에게 접속 요청하면 네트워크 연결 초기화
④
N31 socket =
N33 connectInOut( obj );
N4b public void connectInOut( Runnable obj ) {
N41 waitForCounterpart.start();
PN5b public void run() {
PN52 network.read() ) != null; ) {
N5b public String read() {
N52 in.readLine();
E002 // [서버]에서 보낸 데이터가 도착할 때까지 계속 대기
E003 // (수신전용스레드와 별개로) 메인 스레드 N41 이후 실행중
N4e }
N3e }
PN2e }
2 RockPaperScissorsNetwork panel =
4 }
E004 // [클라이언트]에서 버튼을 누를 때까지 계속 대기(Event Dispatch Thread)
E005 // [서버]가 보낸 데이터([RPSN] [서버] 1(바위)) 도착
⑤
⑥
N51 return
N5e }
PN51 for ( String message = null; ( message =
PN55 super.ready();
P2b public void ready() {
P2e }
⑦
PN56 counterpart = Integer.parseInt( message.replace( header, "" ).trim() );
PN52 network.read() ) != null; ) {
N5b public String read() {
N52 in.readLine();
E002 // [서버]에서 보낸 데이터가 도착할 때까지 계속 대기
E006 // [클라이언트]에서 가위(0)를 선택
⑧
⑨
PN4b public void actionPerformed( ActionEvent event ) {
PN41 super.show( player, counterpart );
P3b public void show( int playerA, int playerB ) {
P3e }
⑩
PN42 network.write( header + " " + player );
N6b public void write( String data ) {
N61 out.println( data );
E007 // [클라이언트]에서 [서버]에게 데이터([RPSN] [클라이언트] 0(가위))를 전송
⑪
N6e }
PN4e }
E008 // [클라이언트]에서 종료버튼(우측상단 X) 선택
⑫
⑬
Wb public void windowClosing( WindowEvent event ) {
W1 panel.close();
PN6b public void close() {
PN61 network.close();
N7b public void close() {
N7e }
PN6e }
We }
⑭
E009 // 메인스레드와 수신전용스레드가 모두 종료하여 프로그램 종료
프로그램 코드
E001 // [클라이언트]에서 [서버]에게 접속 요청하면 네트워크 연결 초기화
E002 // [서버]에서 보낸 데이터가 도착할 때까지 계속 대기
E003 // (수신전용스레드와 별개로) 메인 스레드 N41 이후 실행중
E004 // [클라이언트]에서 버튼을 누를 때까지 계속 대기(Event Dispatch Thread)
E005 // [서버]가 보낸 데이터([RPSN] [서버] 1(바위)) 도착
E006 // [클라이언트]에서 가위(0)를 선택
E007 // [클라이언트]에서 [서버]에게 데이터([RPSN] [클라이언트] 0(가위))를 전송
E008 // [클라이언트]에서 종료버튼(우측상단 X) 선택
E009 // 메인스레드와 수신전용스레드가 모두 종료하여 프로그램 종료
import javax.swing.*;
import java.awt.event.*;
import rpsGame.RockPaperScissorsNetwork;
public class RockPaperScissorsClient
{
1 public static void main( String[] args ) {
final String imagePath = "C:\\Users\\user\\Downloads\\JAVA-main\\src\\rpsGame\\image\\";
String serverIP = "localhost";
2 RockPaperScissorsNetwork panel =
3 new RockPaperScissorsNetwork( imagePath, serverIP );
JFrame frame = new JFrame( "가위바위보(클라이언트)" );
frame.getContentPane().add( panel );
frame.addWindowListener( new WindowAdapter() {
Wb public void windowClosing( WindowEvent event ) {
W1 panel.close();
We }
} );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.pack();
frame.setVisible(true);
4 }
}
package rpsGame;
import java.awt.event.ActionEvent;
import javax.swing.JOptionPane;
import network.Network;
public class RockPaperScissorsNetwork extends RockPaperScissorsPanel implements Runnable
{
private Network network;
private int counterpart;
private final String header = "[RPSN] ";
private final String disconnectMessage = " -1";
PN1b public RockPaperScissorsNetwork( String imgPath ) {
PN11 super( imgPath );
super.timer.stop();
super.show( QUESTIONMARK, QUESTIONMARK );
super.strPlayers.setText( "<html><body style='text-align:center;'>상대편이 준비중입니다 기다려주세요<br>[나]</body></html>" );
PN12 network =
PN13 new Network();
PN1e }
PN2b public RockPaperScissorsNetwork( String imgPath, String serverIP ) {
PN21 this( imgPath );
PN22 network.connectAsClient( serverIP, this );
network.write( header + " " + super.PAPER );
PN2e }
PN3b public void connectAsServer() {
PN31 network.connectAsServer( this );
PN3e }
@Override
PN4b public void actionPerformed( ActionEvent event ) {
int player = super.select( event );
PN41 super.show( player, counterpart );
PN42 network.write( header + " " + player );
PN4e }
@Override
PN5b public void run() {
PN51 for ( String message = null; ( message =
PN52 network.read() ) != null; ) {
if ( !message.contains( header ) )
continue;
else if ( message.contains( disconnectMessage ) ) {
close();
super.strPlayers.setText( "<html><body style='text-align:center;'>상대편이 종료하였습니다<br>[나]</body></html>" );
PN53 super.show( QUESTIONMARK, QUESTIONMARK );
PN54 break;
}
else {
super.strPlayers.setText( "<html><body style='text-align:center;'>[너]<br>[나]</body></html>" );
PN55 super.ready();
PN56 counterpart = Integer.parseInt( message.replace( header, "" ).trim() );
}
}
PN5e }
PN6b public void close() {
network.write( header + " " + disconnectMessage );
PN61 network.close();
PN6e }
}
package network;
import java.io.*;
import java.net.*;
public class Network
{
public static final int serverPort = 7700;
protected ServerSocket serverSocket;
protected Socket socket;
private BufferedReader in;
private PrintWriter out;
private Thread waitForCounterpart;
N1b public Network() {
serverSocket = null;
socket = null;
in = null;
out = null;
waitForCounterpart = null;
N1e }
N2b public void connectAsServer( Runnable obj ) {
try {
serverSocket = new ServerSocket( serverPort );
N21 socket =
N22 serverSocket.accept();
N23 connectInOut( obj );
} catch ( Exception e ) {
e.printStackTrace();
}
N2e }
N3b public void connectAsClient( String serverIP, Runnable obj ) {
try {
N31 socket =
N32 new Socket( serverIP, serverPort );
N33 connectInOut( obj );
} catch ( Exception e ) {
e.printStackTrace();
}
N3e }
N4b public void connectInOut( Runnable obj ) {
try {
in = new BufferedReader( new InputStreamReader( socket.getInputStream() ));
out = new PrintWriter( socket.getOutputStream(), true );
waitForCounterpart = new Thread( obj );
N41 waitForCounterpart.start();
} catch ( Exception e ) {
e.printStackTrace();
}
N4e }
N5b public String read() {
try {
if ( this.isConnecting() == true )
N51 return
N52 in.readLine();
} catch ( Exception e ) {
e.printStackTrace();
}
return null;
N5e }
N6b public void write( String data ) {
try {
if ( this.isConnecting() == true )
N61 out.println( data );
} catch ( Exception e ) {
e.printStackTrace();
}
N6e }
public boolean isConnecting() {
if ( ( socket != null )
&& ( in != null )
&& ( out != null )
&& ( waitForCounterpart != null )
&& ( waitForCounterpart.getState() != Thread.State.TERMINATED ) )
return true;
else
return false;
}
N7b public void close() {
try {
if ( waitForCounterpart != null ) {
waitForCounterpart.interrupt();
waitForCounterpart = null;
}
if ( in != null ) {
in.close();
in=null;
}
if ( out != null ) {
out.flush();
out.close();
out = null;
}
if ( socket != null ) {
socket.close();
socket = null;
}
if ( serverSocket != null ) {
serverSocket.close();
serverSocket = null;
}
} catch ( Exception e ) {
e.printStackTrace();
}
N7e }
}
package rpsGame;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class RockPaperScissorsPanel extends JPanel implements ActionListener
{
protected final int SCISSORS = 0, ROCK = 1, PAPER = 2, QUESTIONMARK = 3;
protected final int BASE = 0, WIN = 1;
protected JLabel imgPlayerA, imgPlayerB, strPlayers;
protected JButton[] button;
protected ImageIcon[][] image;
protected Timer timer;
P1b public RockPaperScissorsPanel( final String imgPath ) {
image = new ImageIcon[4][2];
image[SCISSORS ][BASE] = new ImageIcon( new ImageIcon( imgPath + "scissors.gif" ).getImage().getScaledInstance( 200, 200, Image.SCALE_SMOOTH ) );
image[SCISSORS ][WIN] = new ImageIcon( new ImageIcon( imgPath + "scissors_win.gif" ).getImage().getScaledInstance( 200, 200, Image.SCALE_SMOOTH ) );
image[ROCK ][BASE] = new ImageIcon( new ImageIcon( imgPath + "rock.gif" ).getImage().getScaledInstance( 200, 200, Image.SCALE_SMOOTH ) );
image[ROCK ][WIN] = new ImageIcon( new ImageIcon( imgPath + "rock_win.gif" ).getImage().getScaledInstance( 200, 200, Image.SCALE_SMOOTH ) );
image[PAPER ][BASE] = new ImageIcon( new ImageIcon( imgPath + "paper.gif" ).getImage().getScaledInstance( 200, 200, Image.SCALE_SMOOTH ) );
image[PAPER ][WIN] = new ImageIcon( new ImageIcon( imgPath + "paper_win.gif" ).getImage().getScaledInstance( 200, 200, Image.SCALE_SMOOTH ) );
image[QUESTIONMARK][BASE] = new ImageIcon( new ImageIcon( imgPath + "questionmark.gif" ).getImage().getScaledInstance( 200, 200, Image.SCALE_SMOOTH ) );
image[QUESTIONMARK][WIN] = new ImageIcon( new ImageIcon( imgPath + "questionmark.gif" ).getImage().getScaledInstance( 200, 200, Image.SCALE_SMOOTH ) );
this.imgPlayerA = new JLabel( image[QUESTIONMARK][BASE] );
this.imgPlayerB = new JLabel( image[QUESTIONMARK][BASE] );
this.strPlayers = new JLabel( "<html><body>[너]<br>[나]</body></html>", JLabel.CENTER );
this.add( this.imgPlayerB );
this.add( this.strPlayers );
this.add( this.imgPlayerA );
button = new JButton[3];
button[SCISSORS] = new JButton( new ImageIcon( image[SCISSORS][BASE].getImage().getScaledInstance( 30, 30, Image.SCALE_SMOOTH ) ) );
button[ROCK ] = new JButton( new ImageIcon( image[ROCK ][BASE].getImage().getScaledInstance( 30, 30, Image.SCALE_SMOOTH ) ) );
button[PAPER ] = new JButton( new ImageIcon( image[PAPER ][BASE].getImage().getScaledInstance( 30, 30, Image.SCALE_SMOOTH ) ) );
button[SCISSORS].addActionListener( this );
button[ROCK ].addActionListener( this );
button[PAPER ].addActionListener( this );
this.add( new JLabel(" 가위 바위 보를 선택하세요 ") );
this.add( button[SCISSORS] );
this.add( button[ROCK] );
this.add( button[PAPER] );
this.setBackground( Color.cyan );
this.setPreferredSize( new Dimension(220, 530) );
this.timer = new Timer( 1000, new ActionListener() {
@Override
public void actionPerformed( ActionEvent event ) {
ready();
timer.stop();
}
});
P1e }
P2b public void ready() {
imgPlayerA.setIcon( image[QUESTIONMARK][BASE] );
imgPlayerB.setIcon( image[QUESTIONMARK][BASE] );
button[0].setEnabled( true );
button[1].setEnabled( true );
button[2].setEnabled( true );
P2e }
@Override
public void actionPerformed( ActionEvent event ) {
int playerA = select( event );
int playerB = (int)( Math.random() * 3 );
show( playerA, playerB );
timer.start();
}
P3b public void show( int playerA, int playerB ) {
int playerA_winOrLose = BASE, playerB_winOrLose = BASE;
if ( ( ( playerA == SCISSORS ) && ( playerB == PAPER ) )
|| ( ( playerA == ROCK ) && ( playerB == SCISSORS ) )
|| ( ( playerA == PAPER ) && ( playerB == ROCK ) ) ) {
playerA_winOrLose = WIN;
}
else if ( ( ( playerA == PAPER ) && ( playerB == SCISSORS ) )
|| ( ( playerA == SCISSORS ) && ( playerB == ROCK ) )
|| ( ( playerA == ROCK ) && ( playerB == PAPER ) ) ) {
playerB_winOrLose = WIN;
}
imgPlayerA.setIcon( image[ playerA ][ playerA_winOrLose ] );
imgPlayerB.setIcon( image[ playerB ][ playerB_winOrLose ] );
button[0].setEnabled( false );
button[1].setEnabled( false );
button[2].setEnabled( false );
P3e }
public int select( ActionEvent event ) {
if( event.getSource() == button[SCISSORS] )
return SCISSORS;
else if ( event.getSource() == button[ROCK] )
return ROCK;
else
return PAPER;
}
}