우아한 프로그래밍
article thumbnail

게임설명

 

서버의 룰

  • 1 - 50까지의 숫자 중에서 랜덤 값으로 하나 선택 
  • 클라이언트에게 게임 시작 보내기
  • 클라이언트가 숫자 추측하면 UP, DOWN 판별해서 클라이언트에게 보내기
  • 클라이언트에게 추측횟수 보내기
  • 클라이언트가 숫자를 맞추면 클라이언트의 승리
  • 추측횟수가 5를 넘기면 서버의 승리

클라이언트의 룰

  • 서버가 게임 시작 보내면 숫자하나를 추측해서 서버에게 보내기
  • 서버가 UP을 보내면 이전 숫자보다 큰 숫자 보내기
  • DOWN을 보내면 이전 숫자보다 작은 숫자 보내기
  • 5회 내에 맞추면 클라이언트의 승리
  • 추측횟수가 5회를 넘어가면 서버의 승리

서버코드

import java.awt.BorderLayout;
import java.io.*;
import java.net.*;

import javax.swing.JFrame;
import javax.swing.JTextArea;


public class Server extends JFrame{

    // 출력 UI
    private JTextArea textArea;

    //Client와 통신하기 위한 Socket
    private  Socket socket = null;

    //서버 생성을 위한 ServerSocket
    private  ServerSocket serverSocket = null;

    //Client로부터 데이터를 읽어들이기 위한 입력스트림
    private  BufferedReader in = null;

    //Client로 데이터를 내보내기 위한 출력 스트림
    private  PrintWriter out = null;

    // 서버 포트
    private int port = 30000;

    // 랜덤숫자
    private int randomNumber = 0;

        // 남은 횟수
        private int remainCnt = 5;

    public Server() throws IOException {
            renderUI();
            initServer();
            doProcess();
        }

        /**
         * 서버초기화
         */
        private void initServer() throws IOException {
            //서버 생성
            serverSocket = new ServerSocket(port);

            // 랜덤숫자 생성
            randomNumber = (int)((Math.random() * 50) + 1);

    }

    /**
     * 클라이언트와 통신을 처리하는 함수
     */
    private void doProcess() throws IOException {

        try {
            // 클라이언트 접속대기
            socket = serverSocket.accept();
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));    //입력스트림 생성
            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))); //출력스트림 생성

            sendMessage("★★★ 서버에 접속되었습니다. ★★★ ");
            sendMessage("★★★ 게임을 시작합니다 ★★★");

            while (true) {

                String receiveMsg = receiveMessage();
                remainCnt--;

                textArea.append(String.format("서버로 부터 받은 숫자 %s \n", receiveMsg));

                if(  Integer.parseInt(receiveMsg ) > randomNumber){ // 추측숫자가  랜덤수 보다 큰경우
                    sendMessage("추측한 숫자보다 작습니다.");
                } else if ( Integer.parseInt(receiveMsg ) < randomNumber){ // 추측숫자가 랜덤수보다 작은경우
                    sendMessage("추측한 숫자보다 큽니다.");
                } else{
                    sendMessage("축하합니다. 당신의 승리입니다.");
                    break;
                }

                if( remainCnt == 0){
                    sendMessage("정말 안타깝군요. 나의 승리입니다.");
                    break;
                }else{
                    sendMessage(String.format("추측 횟수가 %d회 남았습니다.", remainCnt));
                }
            }

        } catch(IOException e) {
            e.printStackTrace();
        } finally {
            socket.close();
        }
    }

    /**
     * 클라이언트로 부터 메세지 수신
     */
    private String receiveMessage() throws IOException {
        return in.readLine();
    }

    /**
     * 클라이언트로 메세지 전송
     */
    private void sendMessage(String message) throws IOException {
        out.println(message);
        out.flush();
    }

    /**
     * 화면의 UI를 렌더링한다.
     */
    private void renderUI() {

        this.setTitle("서버");

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        textArea = new JTextArea(20, 30);
        textArea.setEditable(false);

        add(textArea, BorderLayout.CENTER);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) throws IOException {
        Server server = new Server();
    }
}

 

클라이언트 코드

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;

import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class Client  extends JFrame implements ActionListener {

    // 문자열 입력창
    private  JTextField textField;

    // 출력 UI
    private JTextArea textArea;

    //Server와 통신하기 위한 Socket
    private Socket socket = null;

    //Server로부터 데이터를 읽어들이기 위한 입력스트림
    private BufferedReader in = null;

    //서버로 내보내기 위한 출력 스트림
    PrintWriter out = null;

    InetAddress ia = null;

    // 서버 아이피
    private String serverId = "127.0.0.1";

    // 서버 포트
    private int serverPort = 30000;

    public Client() throws IOException {
        renderUI();
        initClient();
        doProcess();
    }

    /**
     * 클라이언트 초기화
     */
    private void initClient() throws IOException {
        ia = InetAddress.getByName(serverId);
        socket = new Socket(ia, serverPort);
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));


    }

    /**
     * 클라이언트와 통신을 처리하는 함수
     */
    private void doProcess() throws IOException {
        new Thread(() -> {
            try {
                while (true){
                    if( socket.isClosed()) break;
                    String msg = receiveMessage();
                    if( msg != null) textArea.append ( msg + "\n");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }

    /**
     * 화면의 UI를 렌더링한다.
     */
    private void renderUI() {

        this.setTitle("클라이언트");

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        textField = new JTextField(30);
        textField.addActionListener(this);

        textArea = new JTextArea(20, 30);
        textArea.setEditable(false);

        add(textField, BorderLayout.PAGE_END);
        add(textArea, BorderLayout.CENTER);
        pack();
        setVisible(true);
    }

    /**
     * 서버로 부터 메세지 수신
     */
    private String receiveMessage() throws IOException {
        return in.readLine();
    }

    /**
     * 서버로 메세지 전송
     */
    private void sendMessage(String message) throws IOException {
        out.println(message);
        out.flush();
    }

    @Override
    public void actionPerformed(ActionEvent evt) {
        try {
            String message = textField.getText();
            sendMessage(message);
            textField.setText("");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
        Client client = new Client();
    }

}

 

실행 예시

클라이언트의 승리

 

서버의 승리

profile

우아한 프로그래밍

@자바조아!

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!