🛑코드수정
경마프로그램(2) 작성예정
다시써야해서 매우 매우 귀찮고 화가난다.
📌Full Code
💾 [깃허브 Full Code]
📌HorseRacing Class
조건
- 1번 ~ 10번 경주마가 경주를 한다.
- 말은 Horse라는 이름의 클래스로 구성하고 말이름, 등수를 멤버변수로 갖는다.
- 등수를 오름차순으로 정렬할 수 있는 기능을 클래스에 구현한다.(Comparable)
- 경기 구간은 1~50구간으로 설정, 말의 위치는 > 로 나타낸다.
변수
- rankCnt : 각 말의 등수 및 경주가 끝났는지 체크하기위한 static변수
- end : while문을 끝내기 위한 변수
- horse : Horse클래스 객체를 담기 위한 ArrayList
for문 별 해석
- horse리스트에 Horse객체 10마리 담기 (ArrayList<Horse> horse)
for (int i = 1; i <= 10; i++) {
horse.add(new Horse(i + "번마"));
}
- racing 리스트에 RacingThread(name)객체를 담는다 (ArrayList<RacingThread> racing)
for (int i = 0; i < 10; i++) {
racing.add(new RacingThread(horse.get(i).getName()));
}
- name을 가져오기 위해 horse리스트에서 i번 배열을불러온다(= Horse객체)
horse.get(i)
- 불러온 Horse객체에 getName을 하여 이름을 불러온다.
horse.get(i).getName()
- 이름을 RacingThread 객체에 담는다
RacingThread(horse.get(i).getName())
- 10개의 쓰레드를 실행시킨다 (racing.get(i) = i번에 담긴 RacingThread 객체)
for (int i = 0; i < racing.size(); i++) {
racing.get(i).start();
}
public class HorseRacing {
static int rankCnt = 0;
static boolean end = false;
static ArrayList<Horse> horse = new ArrayList<>();
public static void main(String[] args) {
ArrayList<RacingThread> racing = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
horse.add(new Horse(i + "번마"));
}
for (int i = 0; i < 10; i++) {
racing.add(new RacingThread(horse.get(i).getName()));
}
for (int i = 0; i < racing.size(); i++) {
racing.get(i).start();
}
System.out.println("==========================[Bang]============================");
while (!end) {
for (RacingThread raceHorse : racing) {
try {
System.out.println(raceHorse);
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println();
}
Collections.sort(horse);
System.out.println("============================================================");
System.out.println();
System.out.println("[순위]");
for (Horse h : horse) {
System.out.println(h.getRank() + "등\t: " + h.getName());
}
}
}
📌RacingThread Class
변수
- name : 말의 이름
- ArrayList<String> section : 1~50구간을 리스트에 담는다.
- randomTime : 무작위 난수 생성
생성자, 메소드
- RacingThread(name) :
객체생성시 반환된 name을 저장하고 addSection()으로 각 말의 구간을 저장.
- addSection() : 콘솔에 출력될 말이 달리는 구간("-") 50개를 리스트에 저장.
(section내용) [-------------------------------------------]
- run() : implements 받은 Thread의 run()을 override한 메소드
- toString() : 콘솔에 말이 달리는 구간을 출력할 때 형태를 지정하는 메소드
'말이름 | ---------------------->------------------' 형태
run() 해석
- RacingThread가 실행되면 for문이 총 50번 실행된다.
- i=0 일 때 if문을 지나 section.set(i,">");이 실행된다.
section리스트에는 "-"가 50개 저장되어있으므로
section.set(0,">")이 실행되면 0번의 "-" 가 ">"로 대체된다.
(section 내용) [>------------------------------------------]
- Thread.sleep(randomTime)이 실행된다.
Thread가 다음 for문을 실행하기까지 randomTime만큼 멈춘다.(i=0-> sleep-> i=1)
- i=1일 때 if문안에 section.set(i-1,"-");이 실행된다.
section.set(0,"-")이 실행되면 0번에 있는 ">"가 "-"로 대체된다.
(section 내용) [-------------------------------------------]
if문을 나와 section.set(1,">");이 실행되면 1번의 "-"가 ">"로 대체된다.
(section 내용) [->-----------------------------------------]
- 반복
for (int i = 0; i < 50; i++) {
if (i != 0) {
section.set(i - 1, "-");
}
section.set(i, ">");
try {
Thread.sleep(randomTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
- for문이 50번 실행되면 HorseRacing.rankCnt++;실행
가장 먼저 for문이 끝난 Thread가 1등이므로 static으로 선언된 rankCnt=0;이
rankCnt++로 인해 1이 저장된다.
- if(rankCnt값이 10과 같으면) {end=true}
- 각 쓰레드의 for문이 종료될 때(경주가 끝남) rankCnt++이 실행되므로
10마리 모두 경주가 끝나야 rankCnt 값이 10이 된다.
- static으로 선언된 변수는 값이 프로그램 실행동안 사라지지 않고 계속 저장되어 있다.
- 1번쓰레드가 종료되면 rankCnt++ 실행 (rankCnt=1)
- 2번쓰레드가 종료되면 rankCnt++ 실행 (rankCnt=2)
:
- 10번쓰레드가 종료되면 rankCnt++ 실행 (rankCnt=10)
- rankCnt=10이므로 if문 실행 -> HorseRacing.end = true;
- end=true가 되면 경기가 모두 종료된다.
HorseRacing.rankCnt++;
if (HorseRacing.rankCnt >= HorseRacing.horse.size()) {
HorseRacing.end = true;
}
- 등수 저장
for (int i = 0; i < HorseRacing.horse.size(); i++) {
if (HorseRacing.horse.get(i).getName().equals(name)) {
HorseRacing.horse.get(i).setRank(HorseRacing.rankCnt);
}
}
class RacingThread extends Thread {
private String name;
private ArrayList<String> section = new ArrayList<>();
Random rnd = new Random();
int randomTime = rnd.nextInt(50) + 200;
public RacingThread(String name) {
this.name = name;
addSection();
}
public void addSection() {
for (int i = 0; i < 50; i++) {
section.add("-");
}
}
@Override
public void run() {
for (int i = 0; i < 50; i++) {
if (i != 0) {
section.set(i - 1, "-");
}
section.set(i, ">");
try {
Thread.sleep(randomTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
HorseRacing.rankCnt++;
if (HorseRacing.rankCnt >= HorseRacing.horse.size()) {
HorseRacing.end = true;
}
for (int i = 0; i < HorseRacing.horse.size(); i++) {
if (HorseRacing.horse.get(i).getName().equals(name)) {
HorseRacing.horse.get(i).setRank(HorseRacing.rankCnt);
}
}
}
@Override
public String toString() {
String str = "";
for (int i = 0; i < section.size(); i++) {
str += section.get(i);
}
return name + "\t| " + str;
}
}
📌Horse Class
class Horse implements Comparable<Horse> {
private String name;
private int rank;
public Horse(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getRank() {
return rank;
}
public void setRank(int rank) {
this.rank = rank;
}
@Override
public int compareTo(Horse horse) {
return Integer.compare(getRank(), horse.getRank());
}
}