JAVA 프로그래밍

문제

단일 클라이언트용 가위바위보 프로그램에서 네트워크 서버 부분의 문제입니다 이를 해결하는 프로그램의 다음 실행상태에 대해 빈칸을 채우세요 

프로그램의 실행순서 및 실행상태

 
①  
 
 
②  
 
1  public static void main( String[] args ) {  

3                                    new RockPaperScissorsNetwork( imagePath );

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  }

2   RockPaperScissorsNetwork panel = 

4   panel.connectAsServer();

PN3b  public void connectAsServer() {

PN31   network.connectAsServer( this );

N2b  public void connectAsServer( Runnable obj ) {

N22             serverSocket.accept();   

E001 // [클라이언트]에서 [서버]에게 접속 요청
④  
 
N21    socket = 

N23    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  }

N2e  } 

PN3e  }

5  }

E004 // [서버]에서 버튼을 누를 때까지 계속 대기(Event Dispatch Thread)
                                              
... 

E005 // [클라이언트]에서 보낸 첫 메시지([RPSN] 2(보)) 도착

 
⑤  
 
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 // [서버]에서 바위(1)를 선택
⑦  
 
 
⑧  
 
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] 1(바위)) 전송
⑩  
 
N6e  }

PN4e  }
                                              
... 

E008 // [클라이언트]에서 보낸 메시지([RPSN] 0(가위)) 도착
⑪  
 
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 // [클라이언트]에서 보낸 메시지가 도착할 때까지 계속 대기
                                              
... 

E009 // [클라이언트]에서 종료버튼(우측상단 X)를 클릭해서 메시지([RPSN] -1(종료)) 도착
⑬  
 
N51     return 

N5e  }

PN51   for ( String message = null; ( message = 

PN53     super.show( QUESTIONMARK, QUESTIONMARK );

P3b  public void show( int playerA, int playerB ) {

P3e  }
⑭  
 
PN54     break;

PN5e  }
                                              
... 

E010 // [서버]에서 프로그램 닫기(우측상단 X) 선택  
⑮  
 
 
⑯  
 
Wb    public void windowClosing( WindowEvent event ) { 

W1     panel.close();

PN6b  public void close() {

PN61   network.close();

N7b  public void close() {

N7e  }

PN6e  }

We    }


프로그램 코드

E001	// [클라이언트]에서 [서버]에게 접속 요청
E002	// [클라이언트]에서 보낸 메시지가 도착할 때까지 계속 대기
E003	// (수신전용스레드와 별개로) 메인 스레드 N41 이후 실행중 
E004	// [서버]에서 버튼을 누를 때까지 계속 대기(Event Dispatch Thread)
E005	// [클라이언트]에서 보낸 첫 메시지([RPSN] 2(보)) 도착
E006	// [서버]에서 바위(1)를 선택
E007	// [서버]에서 [클라이언트]에게 메시지([RPSN] 1(바위)) 전송
E008	// [클라이언트]에서 보낸 메시지([RPSN] 0(가위)) 도착
E009	// [클라이언트]에서 종료버튼(우측상단 X)를 클릭해서 메시지([RPSN] -1(종료)) 도착
E010	// [서버]에서 프로그램 닫기(우측상단 X) 선택  
E011	// 메인스레드와 수신전용스레드가 모두 종료하여 프로그램 종료 
	
	import javax.swing.*;
	import java.awt.event.*;
	import rpsGame.RockPaperScissorsNetwork;
	
	public class RockPaperScissorsServer
	{
1		public static void main( String[] args ) { 	
			final String imagePath = "C:\\Users\\user\\Downloads\\JAVA-main\\src\\rpsGame\\image\\";
2			RockPaperScissorsNetwork panel = 
3			                                 new RockPaperScissorsNetwork( imagePath );
	
			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			panel.connectAsServer();
5		}
	}
	
	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;
		}
	}