Skip to content

[그리디] 염지환 사다리 미션 제출합니다 #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: jihwanyeom
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/main/java/LadderApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import controller.LadderController;

public class LadderApplication {
public static void main(String[] args) {
LadderController ladderController = new LadderController();
ladderController.run();
}
}
65 changes: 65 additions & 0 deletions src/main/java/controller/LadderController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package controller;

import domain.Ladder;
import domain.Name;
import domain.Player;
import domain.Players;
import domain.Result;
import domain.Results;
import view.InputView;
import view.OutputView;

public class LadderController {

private final Players players;
private final Results results;

public LadderController() {
players = Players.of(InputView.inputPlayerNames());
results = Results.of(InputView.inputResults());
}

public void run() {
Ladder ladder = createLadder();
OutputView.printLadderInfo(players, results, ladder);
players.moveDown(ladder);
runResultQueryLoop();
}

private Ladder createLadder() {
int ladderWidth = players.getPlayers().size();
int ladderHeight = InputView.inputHeight();
return new Ladder(ladderWidth, ladderHeight);
}

private void runResultQueryLoop() {
while (checkResultLoop());
}

private Boolean checkResultLoop() {
String name = InputView.inputPlayerNameToCheckResult();
if (name.isEmpty()) {
return false;
}
if (name.trim().equals("all")) {
printAllResults(players, results);
return true;
}
printSingleResult(name, players, results);
return true;
}

private void printAllResults(Players players, Results results) {
for (Player player : players.getPlayers()) {
Result result = results.findByPosition(player.getPosition());
OutputView.printResult(player, result);
}
}

private void printSingleResult(String name, Players players, Results results) {
Player player = players.findByName(new Name(name));
Result result = results.findByPosition(player.getPosition());
OutputView.printResult(player, result);
}

}
30 changes: 30 additions & 0 deletions src/main/java/domain/Ladder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package domain;

import java.util.ArrayList;
import java.util.List;

public class Ladder {

private final List<Line> lines;

public Ladder(int width, int height) {
validate(width, height);
lines = new ArrayList<>();
for (int i = 0; i < height; i++) {
lines.add(Line.from(width - 1));
}
}

private void validate(int width, int height) {
if (width <= 1) {
throw new IllegalArgumentException("사다리의 너비는 1보다 커야 합니다.");
}
if (height <= 0) {
throw new IllegalArgumentException("사다리의 높이는 0보다 커야 합니다.");
}
}

public List<Line> getLines() {
return lines;
}
}
39 changes: 39 additions & 0 deletions src/main/java/domain/Line.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package domain;

import java.util.ArrayList;
import java.util.List;

public class Line {

private final List<Point> points;

private Line(List<Point> points) {
this.points = points;
}

public static Line from(int width) {
return new Line(createRandomLine(width));
}

private static List<Point> createRandomLine(int width) {
List<Point> points = new ArrayList<>();
points.add(new Point(PointState.randomState()));
for (int i = 1; i < width; i++) {
Point lastState = points.get(points.size() - 1);
PointState newState = generateNextState(lastState);
points.add(new Point(newState));
}
return points;
}

private static PointState generateNextState(Point lastPoint) {
if (lastPoint.isMovable()) {
return PointState.NOT_MOVABLE;
}
return PointState.randomState();
}

public List<Point> getPoints() {
return points;
}
}
42 changes: 42 additions & 0 deletions src/main/java/domain/Name.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package domain;

import java.util.Objects;

public class Name {
private final String name;


public Name(String name) {
validate(name);
this.name = name;
}

private void validate(String name) {
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("이름은 null이나 빈 문자열일 수 없습니다.");
}
if (name.length() > 5) {
throw new IllegalArgumentException("이름은 5자 이하이어야 합니다.");
}
}

public String getName() {
return name;
}

@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object instanceof Name other) {
return Objects.equals(name, other.name);
}
return false;
}

@Override
public int hashCode() {
return Objects.hash(name);
}
}
61 changes: 61 additions & 0 deletions src/main/java/domain/Player.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package domain;

import java.util.List;

public class Player {
private final Name name;
private final Position position;

public Player(Name name, Position position) {
this.position = position;
this.name = name;
}

public void downLadder(Ladder ladder) {
List<Line> lines = ladder.getLines();
for (Line line : lines) {
checkAndMove(line);
}
}

public void checkAndMove(Line line) {
List<Point> points = line.getPoints();
if (checkLeft(points)) {
position.moveLeft();
return;
}
if (checkRight(points)) {
position.moveRight();
}
}

public boolean checkLeft(List<Point> points) {
Point leftPoint = null;
if (position.getPosition() > 0) {
leftPoint = points.get(position.getPosition() - 1);
}

return leftPoint != null && leftPoint.isMovable();
}

public boolean checkRight(List<Point> points) {
Point rightPoint = null;
if (position.getPosition() < points.size()) {
rightPoint = points.get(position.getPosition());
}

return rightPoint != null && rightPoint.isMovable();
}

public boolean hasName(Name other) {
return name.equals(other);
}

public Position getPosition() {
return position;
}

public Name getName() {
return name;
}
}
48 changes: 48 additions & 0 deletions src/main/java/domain/Players.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package domain;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class Players {
private final List<Player> players;

private Players(List<Player> players) {
this.players = players;
}

public static Players of(List<String> names) {
validate(names);
List<Player> players = names.stream()
.map(name -> new Player(new Name(name), new Position(names.indexOf(name))))
.collect(Collectors.toList());
return new Players(players);
}

private static void validate(List<String> names) {
Set<String> nameSet = new HashSet<>();
names.forEach(name -> checkDuplicate(nameSet, name));
}

private static void checkDuplicate(Set<String> nameSet, String name) {
if (!nameSet.add(name)) {
throw new IllegalArgumentException("중복된 이름이 있습니다: " + name);
}
}

public void moveDown(Ladder ladder) {
players.forEach(player -> player.downLadder(ladder));
}

public Player findByName(Name name) {
return players.stream()
.filter(player -> player.hasName(name))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 이름입니다: " + name.getName()));
}

public List<Player> getPlayers() {
return players;
}
}
22 changes: 22 additions & 0 deletions src/main/java/domain/Point.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package domain;

public class Point {
private PointState state;

public Point(PointState state) {
this.state = state;
}

public boolean isMovable() {
return state == PointState.MOVABLE;
}

public void setMovable(boolean movable) {
if (movable) {
state = PointState.MOVABLE;
}
if (!movable) {
state = PointState.NOT_MOVABLE;
}
}
}
26 changes: 26 additions & 0 deletions src/main/java/domain/PointState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package domain;

import java.util.Random;

public enum PointState {
MOVABLE("-----"),
NOT_MOVABLE(" ");

private final String display;
private static final Random random = new Random();

PointState(String display) {
this.display = display;
}

public String getDisplay() {
return display;
}

public static PointState randomState() {
if (random.nextBoolean()){
return MOVABLE;
}
return NOT_MOVABLE;
}
}
46 changes: 46 additions & 0 deletions src/main/java/domain/Position.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package domain;

import java.util.Objects;

public class Position {
private int position;

public Position(int position) {
validate(position);
this.position = position;
}

private void validate(int position) {
if (position < 0) {
throw new IllegalArgumentException("Position은 음수일 수 없습니다.");
}
}

public void moveLeft() {
position--;
}

public void moveRight() {
position++;
}

public int getPosition() {
return position;
}

@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (!(object instanceof Position other)) {
return false;
}
return position == other.position;
}

@Override
public int hashCode() {
return Objects.hash(position);
}
}
Loading