본문 바로가기

프로그래밍/자바(JAVA)

[자바/JAVA] 자바로 만든 달팽이 [배열 사용]

자바로 만든 달팽이 소스코드 [배열 사용]



import java.awt.*;
import java.awt.event.*;
import java.lang.Thread;

public class SnailArray extends Frame implements ItemListener,ActionListener{
 Panel north,south,center; 
 Choice numChoice;
 Button ok, end, next, slide, restart;
 Checkbox chk1, chk2;
 CheckboxGroup cbg;
 Font font = new Font("Arial",Font.BOLD,16);
 Label norLabel, numLabel[];
 int num, useNUM, counter=1; // 입력되는 배열 갯수.. useNUM은 실행중 변화
 int ar[][];
 int x,y,k; // 가로 세로 이동종료 기준 변수
 boolean key;
 int xPos,yPos; // 메서드호출시 누적되어야 하므로 전역으로 선언
 int direction; // 상동 

 SnailArray() {  
  setTitle("달팽이 / 역달팽이 배열");   
   cbg = new CheckboxGroup();   
   north = new Panel();    
    chk1 = new Checkbox("달팽이",true,cbg);
     chk1.setFont(font);    
    north.add(chk1);
    chk2 = new Checkbox("역달팽이",false,cbg);     
     chk2.setFont(font);
    north.add(chk2);
    north.add(new Label());
    norLabel = new Label("Number Of Array",Label.RIGHT);
     norLabel.setForeground(Color.blue);
     norLabel.setFont(font);
    north.add(norLabel);
    numChoice = new Choice();
     numChoice.add("===");
     for(int i=3;i<14;i++) {
      numChoice.add(""+i);
     }
     numChoice.addItemListener(this);     
    north.add(numChoice);
    ok = new Button(" 확 인 ");
     ok.setEnabled(false);
     ok.addActionListener(this);
    north.add(ok);
   font = new Font("Arial",Font.BOLD,12);
   center = new Panel();
   center.setBackground(Color.blue);
   south = new Panel();
    slide = new Button("슬라이드형태로보기");
     slide.setEnabled(false);
     slide.addActionListener(this);
    south.add(slide);
    south.add(new Label("    "));
    south.add(new Label("    "));
    south.add(new Label("    "));
    south.add(new Label("    "));    
    next = new Button("출발&다음");
     next.setEnabled(false);
     next.addActionListener(this);
    south.add(next);
    south.add(new Label());
    south.add(new Label());
    restart = new Button("다시시작");
     restart.setEnabled(false);
     restart.addActionListener(this);
    south.add(restart);
    south.add(new Label());    
    end = new Button(" 종 료 "); 
     end.addActionListener(this);
    south.add(end);    
   add(north,"North");
   add(south,"South");
   add(new Label("    "),"West");
   add(new Label("    "),"East");
   add(center,"Center");   
  setSize(600,600);
  setVisible(true);
  addWindowListener(new WindowHandler());
 }
 /* Make numLabel Array */
 public void makeLabelArray (int n) {
  numLabel = new Label[n*n];
  for(int i=0;i<n*n;i++) {
   numLabel[i]=new Label("",Label.CENTER);
   numLabel[i].setFont(font);
   numLabel[i].setForeground(Color.white);
  }
  ar = new int [n][n];  
 } 
 /* ItemEvent Method */
 public void itemStateChanged(ItemEvent ie) {
  if(ie.getSource()==numChoice) {
   String str = (String)ie.getItem();
   if(str!="===") {
    ok.setEnabled(true);    
    num = Integer.parseInt(str);
    useNUM=num;
   }else
    ok.setEnabled(false);
  }  
 }
 /* ActionEvent Method */
 public void actionPerformed(ActionEvent ae) {
  if(ae.getSource()==ok) { // 확인버튼 
   /* 버튼 활성/비활성화 */
   ok.setEnabled(false);
   chk1.setEnabled(false);
   chk2.setEnabled(false);
   end.setEnabled(true);
   slide.setEnabled(true);
   next.setEnabled(true);
   restart.setEnabled(true);
   numChoice.setEnabled(false);
   center.setLayout(new GridLayout(num,num)); // 패널 레이아웃
   makeLabelArray(num);
   if(cbg.getSelectedCheckbox()==chk1) { // 달팽이배열 선택시
    xPos = 0;
    yPos = -1;
    direction = 1;
   }else if(cbg.getSelectedCheckbox()==chk2) { // 역달팽이배열 선택시
    xPos = num/2;
    yPos = num/2;
    direction = -1;
    y=1;
    if(num%2==0) { // 짝수 역달팽이일경우
     yPos--;
     direction*=-1;
    }
    ar[xPos][yPos]=counter;
   }
  }else if(ae.getSource()==end) {//종료버튼
   System.exit(0);
  }else if(ae.getSource()==restart) { // 다시시작버튼
   center.removeAll(); // 패널 비우기
   numChoice.select("==="); // 초이스선택 설정
   /* 버튼 활성/비활성화 */
   chk1.setEnabled(true);
   chk2.setEnabled(true);
   numChoice.setEnabled(true);   
   slide.setEnabled(false);
   next.setEnabled(false);
   restart.setEnabled(false);
   /* 변수 초기화 */
   counter=1;
   key=false;
   x=y=k=0;
  }else if(ae.getSource()==next) { //출발&다음 버튼
   slide.setEnabled(false);
   if(cbg.getSelectedCheckbox()==chk1) { // 달팽이배열 선택시
    snail();
    output();
   }else if(cbg.getSelectedCheckbox()==chk2) { // 역달팽이배열 선택시
    if(counter==1) {
     output();
     counter++;
    }else {
     minusSnail();
     output();
    }
   }
   if(counter>num*num) // 배열이 꽉찼으면
    next.setEnabled(false); // 다음 버튼 비활성화
   center.invalidate();
   center.validate();
   center.repaint();
  }else if(ae.getSource()==slide) { // 슬라이드 버튼
   /* 버튼 비활성화 */
   next.setEnabled(false);
   end.setEnabled(false);
   restart.setEnabled(false);
   slide.setEnabled(false);
   if(cbg.getSelectedCheckbox()==chk1) { // 달팽이배열 선택시
    snailSlide();    
   }else if(cbg.getSelectedCheckbox()==chk2) { // 역달팽이배열 선택시
    minusSnailSlide();
   }   
   end.setEnabled(true);
   restart.setEnabled(true);   
  }
 }
 /* 달팽이 배열 */
 public void snail () {  
  if(useNUM>0){
   if(x<useNUM) {
    key=true;
    yPos+=direction;
    ar[xPos][yPos]=counter++;
    x++;    
   }else {
    if(key) {
     useNUM--;
     key=false;
    }
    if(y<useNUM) {
     xPos+=direction;
     ar[xPos][yPos]=counter++;
     y++;
     if(y==useNUM) {
      direction*=-1;      
      x=y=0;
     }
    }
   }
  }
 }
 /* 달팽이 배열 슬라이드 */
 public void snailSlide () {
  while(useNUM>0) {
   for(x=0;x<useNUM;x++) { // 가로방향 변화
    yPos+=direction; // 가로인덱스 증가 혹은 감소
    ar[xPos][yPos]=counter++;
    slideOutput();
   }   
   useNUM--;
   if(useNUM<1) { // num값이 바로위에서 변화하므로 이부분에서 루프종료할지 체크
    break; //while 루프 종료
   }else {
    for(x=0;x<useNUM;x++) { // 세로방향 변화
     xPos+=direction; // 세로인덱스 증가 혹은 감소
     ar[xPos][yPos]=counter++;
     slideOutput();
    }    
    direction*=-1; // 증가, 감소 변환 키
   }
  } 
 }
 /* 패널에 그리기 */
 public void output () {
  int number=0;
  for(int i=0;i<num;i++) {
   for(int j=0;j<num;j++) {
    if(ar[i][j]==0) {
     numLabel[number].setText("");
    }else {
     numLabel[number].setText(String.valueOf(ar[i][j]));
    }
    center.add(numLabel[number]);   
    number++;
   }
  }
 }
 /* 슬라이드시 화면에 보이기 */
 public void slideOutput() {
  output();
   center.invalidate();
   center.validate();
   center.repaint();
   try{
    Thread.sleep(1000);
   } catch (InterruptedException ite) {}
 }
 /* 역달팽이 배열*/
 public void minusSnail() {
  if(y<num) {
   if(x<y) {
    yPos+=direction;
    ar[xPos][yPos]=counter++;
    x++;
    if(x==y) {
     key=true;
     y--;
     direction*=-1;
    }
   }else {
    if(k<y) {
     xPos+=direction;
     ar[xPos][yPos]=counter++;
     k++;
     if(k==y) {
      key=true;
      x=0;
      k=0;
     }
    }
   }
  }
  if(key) {
   y++;
   key=!key;
  }
  if(y==num)
   y--;
 }
 /* 역달팽이배열 슬라이드 */
 public void minusSnailSlide() {
  boolean flag=false;
  if(counter==1) {
   slideOutput();
   counter++;
  }
  for(y=1;y<=num;y++) {
   if(y==num) {
    y--;
    flag=true;
   }
   for(int i=0;i<y;i++) { // 가로방향 변화
    yPos+=direction; // 가로인덱스 증가 혹은 감소
    ar[xPos][yPos]=counter++;
    slideOutput();
   }
   if(flag) //flag=true일때
    break;
   direction*=-1; // 증가, 감소 변환 키
   for(int i=0;i<y;i++) { // 세로방향 변화
    xPos+=direction; // 세로인덱스 증가 혹은 감소
    ar[xPos][yPos]=counter++;
    slideOutput();
   }
  }
 }
 public static void main(String[] args) {
  new SnailArray();  
 }
}
/* WindowEvent */
class WindowHandler extends WindowAdapter {
 public void windowClosing(WindowEvent e) {
  Window w = e.getWindow();
  w.setVisible(false);
  w.dispose();
  System.exit(0);
 }
}