From 518fe1094fa417ae2b1b5def7063c07ebfe89a9e Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 4 Mar 2017 20:07:21 +0300 Subject: [PATCH 01/63] task 1 done --- shell/src/main/java/commands/Cat.java | 47 ++++++ shell/src/main/java/commands/Echo.java | 28 ++++ shell/src/main/java/commands/Eq.java | 22 +++ shell/src/main/java/commands/Exit.java | 22 +++ shell/src/main/java/commands/OutSource.java | 55 +++++++ shell/src/main/java/commands/Pwd.java | 27 +++ shell/src/main/java/commands/Wc.java | 84 ++++++++++ shell/src/main/java/shell/Command.java | 29 ++++ .../src/main/java/shell/CommandExecutor.java | 25 +++ shell/src/main/java/shell/CommandFactory.java | 66 ++++++++ shell/src/main/java/shell/Environment.java | 40 +++++ shell/src/main/java/shell/Main.java | 8 + shell/src/main/java/shell/Parser.java | 121 ++++++++++++++ shell/src/main/java/shell/Preprocessor.java | 64 ++++++++ shell/src/main/java/shell/Shell.java | 41 +++++ shell/src/main/java/shell/Stream.java | 55 +++++++ shell/src/main/java/shell/Token.java | 154 ++++++++++++++++++ shell/src/main/java/shell/Tokenizer.java | 73 +++++++++ shell/src/test/java/ParserTests.java | 90 ++++++++++ shell/src/test/java/PreprocessorTests.java | 71 ++++++++ shell/src/test/java/TokenizerTests.java | 65 ++++++++ 21 files changed, 1187 insertions(+) create mode 100644 shell/src/main/java/commands/Cat.java create mode 100644 shell/src/main/java/commands/Echo.java create mode 100644 shell/src/main/java/commands/Eq.java create mode 100644 shell/src/main/java/commands/Exit.java create mode 100644 shell/src/main/java/commands/OutSource.java create mode 100644 shell/src/main/java/commands/Pwd.java create mode 100644 shell/src/main/java/commands/Wc.java create mode 100644 shell/src/main/java/shell/Command.java create mode 100644 shell/src/main/java/shell/CommandExecutor.java create mode 100644 shell/src/main/java/shell/CommandFactory.java create mode 100644 shell/src/main/java/shell/Environment.java create mode 100644 shell/src/main/java/shell/Main.java create mode 100644 shell/src/main/java/shell/Parser.java create mode 100644 shell/src/main/java/shell/Preprocessor.java create mode 100644 shell/src/main/java/shell/Shell.java create mode 100644 shell/src/main/java/shell/Stream.java create mode 100644 shell/src/main/java/shell/Token.java create mode 100644 shell/src/main/java/shell/Tokenizer.java create mode 100644 shell/src/test/java/ParserTests.java create mode 100644 shell/src/test/java/PreprocessorTests.java create mode 100644 shell/src/test/java/TokenizerTests.java diff --git a/shell/src/main/java/commands/Cat.java b/shell/src/main/java/commands/Cat.java new file mode 100644 index 0000000..6e36cd9 --- /dev/null +++ b/shell/src/main/java/commands/Cat.java @@ -0,0 +1,47 @@ +package commands; + +import shell.Command; +import shell.Environment; +import shell.Stream; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Scanner; + +public class Cat extends Command { + + public static final String NAME = "cat"; + + public Cat(List args, Environment env) { + super(args, env); + } + + @Override + public Stream run(Stream stream) { + + if (stream.hasNext()) { + return stream; + } + + Stream res = new Stream(); + if (args.isEmpty()) { + Scanner sc = new Scanner(System.in); + while (true) { + System.out.println(sc.nextLine()); + } + } else { + String filename = args.get(0); + Path file = Paths.get(filename); + try { + List lines = Files.readAllLines(file); + lines.forEach(res::write); + } catch (IOException e) { + e.printStackTrace(); + } + } + return res; + } +} diff --git a/shell/src/main/java/commands/Echo.java b/shell/src/main/java/commands/Echo.java new file mode 100644 index 0000000..d786511 --- /dev/null +++ b/shell/src/main/java/commands/Echo.java @@ -0,0 +1,28 @@ +package commands; + +import shell.Command; +import shell.Environment; +import shell.Stream; + +import java.util.List; +import java.util.stream.Collectors; + +public class Echo extends Command { + + public static final String NAME = "echo"; + + public Echo(List args, Environment env) { + super(args, env); + } + + @Override + public Stream run(Stream ignored) { + + String toPrint = args.stream().collect(Collectors.joining()); + + Stream stream = new Stream(); + stream.write(toPrint); + return stream; + } + +} diff --git a/shell/src/main/java/commands/Eq.java b/shell/src/main/java/commands/Eq.java new file mode 100644 index 0000000..641333d --- /dev/null +++ b/shell/src/main/java/commands/Eq.java @@ -0,0 +1,22 @@ +package commands; + +import shell.Command; +import shell.Environment; +import shell.Stream; + +import java.util.List; + +public class Eq extends Command { + + public Eq(List args, Environment env) { + super(args, env); + } + + @Override + public Stream run(Stream ignored) { + String var = args.get(0); + String val = args.get(1); + env.put(var, val); + return new Stream(); + } +} diff --git a/shell/src/main/java/commands/Exit.java b/shell/src/main/java/commands/Exit.java new file mode 100644 index 0000000..2a1fa60 --- /dev/null +++ b/shell/src/main/java/commands/Exit.java @@ -0,0 +1,22 @@ +package commands; + +import shell.Command; +import shell.Environment; +import shell.Stream; + +import java.util.List; + +public class Exit extends Command { + + public static final String NAME = "exit"; + + public Exit(List args, Environment env) { + super(args, env); + } + + @Override + public Stream run(Stream stream) { + System.exit(0); + return null; + } +} diff --git a/shell/src/main/java/commands/OutSource.java b/shell/src/main/java/commands/OutSource.java new file mode 100644 index 0000000..556d10c --- /dev/null +++ b/shell/src/main/java/commands/OutSource.java @@ -0,0 +1,55 @@ +package commands; + +import shell.Command; +import shell.Environment; +import shell.Stream; + +import java.io.*; +import java.util.List; +import java.util.stream.Collectors; + +public class OutSource extends Command { + + private String commandName; + + public OutSource(String commandName, List args, Environment env) { + super(args, env); + this.commandName = commandName; + } + + @Override + public Stream run(Stream stream) { + String command = commandName + " " + args.stream().collect(Collectors.joining(" ")); + Stream output = new Stream(); + try { + Process process = Runtime.getRuntime().exec(command); + write(process, stream); + output = read(process); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + return output; + } + + private void write(Process process, Stream stream) throws IOException { + Writer handle = new PrintWriter(process.getOutputStream()); + final int LINE_FEED = 10; + while (stream.hasNext()) { + handle.write(stream.read()); + handle.write(LINE_FEED); + } + handle.close(); + } + + private Stream read(Process process) throws IOException, InterruptedException { + Stream output = new Stream(); + BufferedReader reader = + new BufferedReader(new InputStreamReader(process.getInputStream())); + String line; + while ((line = reader.readLine()) != null) { + output.write(line); + } + process.waitFor(); + return output; + } +} diff --git a/shell/src/main/java/commands/Pwd.java b/shell/src/main/java/commands/Pwd.java new file mode 100644 index 0000000..a3985a7 --- /dev/null +++ b/shell/src/main/java/commands/Pwd.java @@ -0,0 +1,27 @@ +package commands; + +import shell.Command; +import shell.Environment; +import shell.Stream; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +public class Pwd extends Command { + + public static final String NAME = "pwd"; + + public Pwd(List args, Environment env) { + super(args, env); + } + + @Override + public Stream run(Stream ignored) { + Path currentRelativePath = Paths.get(""); + String currentDir = currentRelativePath.toAbsolutePath().toString(); + Stream stream = new Stream(); + stream.write(currentDir); + return stream; + } +} diff --git a/shell/src/main/java/commands/Wc.java b/shell/src/main/java/commands/Wc.java new file mode 100644 index 0000000..0eef945 --- /dev/null +++ b/shell/src/main/java/commands/Wc.java @@ -0,0 +1,84 @@ +package commands; + +import shell.Command; +import shell.Environment; +import shell.Stream; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Scanner; +import java.util.stream.Collectors; + +public class Wc extends Command { + + public static final String NAME = "wc"; + + public Wc(List args, Environment env) { + super(args, env); + } + + @Override + public Stream run(Stream stream) { + if (!args.isEmpty()) { + return handleFile(); + } else if (stream.hasNext()) { + return handleInputStream(stream); + } else { + handleStdIn(); + return new Stream(); + } + } + + private Stream handleFile() { + String fileName = args.get(0); + Path file = Paths.get(fileName); + try { + List lines = Files.readAllLines(file); + return parseLines(lines); + } catch (IOException e) { + e.printStackTrace(); + return new Stream(); + } + } + + private Stream handleInputStream(Stream stream) { + List lines = new ArrayList<>(); + while (stream.hasNext()) { + lines.add(stream.read()); + } + return parseLines(lines); + } + + private void handleStdIn() { + Scanner sc = new Scanner(System.in); + while (true) { + List lines = Collections.singletonList(sc.nextLine()); + Stream result = parseLines(lines); + System.out.println(result.read()); + } + } + + private Stream parseLines(List lines) { + int linesCount = lines.size(); + char[] concatenated = lines.stream().collect(Collectors.joining(" ")).toCharArray(); + long wordCount = 0; + for (char c : concatenated) { + if (c == ' ') { + wordCount++; + } + } + wordCount++; + + long byteCount = concatenated.length; + + String result = String.format(" %d %d %d", linesCount, wordCount, byteCount); + Stream stream = new Stream(); + stream.write(result); + return stream; + } +} diff --git a/shell/src/main/java/shell/Command.java b/shell/src/main/java/shell/Command.java new file mode 100644 index 0000000..b87bbc6 --- /dev/null +++ b/shell/src/main/java/shell/Command.java @@ -0,0 +1,29 @@ +package shell; + +import java.util.List; + +/** + * Abstract class which impersonates Command entity. + * Command can be run with Stream as an argument and can modify environment of a shell. + */ +public abstract class Command { + + protected List args; + protected Environment env; + + + /** + * @param args arguments of a command as a List + * @param env environment of current running shell + */ + public Command(List args, Environment env) { + this.args = args; + this.env = env; + } + + /** + * @param stream + * @return result data as a Stream object + */ + public abstract Stream run(Stream stream); +} diff --git a/shell/src/main/java/shell/CommandExecutor.java b/shell/src/main/java/shell/CommandExecutor.java new file mode 100644 index 0000000..0526c70 --- /dev/null +++ b/shell/src/main/java/shell/CommandExecutor.java @@ -0,0 +1,25 @@ +package shell; + +import java.util.List; + + +/** + * Entity to implement chained computations. + * Every computation is processed one after another + * and result of current one is passed to the next one. + */ +public class CommandExecutor { + private CommandExecutor() {} + + /** + * @param commands List of Command objects + * @return Stream object which contain result of a chain of computations + */ + public static Stream run(List commands) { + Stream stream = new Stream(); + for (Command command : commands) { + stream = command.run(stream); + } + return stream; + } +} diff --git a/shell/src/main/java/shell/CommandFactory.java b/shell/src/main/java/shell/CommandFactory.java new file mode 100644 index 0000000..c96c5ad --- /dev/null +++ b/shell/src/main/java/shell/CommandFactory.java @@ -0,0 +1,66 @@ +package shell; + +import commands.*; + +import java.util.List; +import java.util.stream.Collectors; + + +/** + * Factory which is used to construct Command objects relying on command token + */ +public class CommandFactory { + + + /** + * @param commandToken token, which contains command name as a String + * @param args arguments of a command + * @param env Environment object + * @return generated runnable Command object + */ + public static Command produce(Token commandToken, List args, Environment env) { + Command command; + switch (commandToken.getType()) { + case EQ: + command = new Eq(args, env); + return command; + case WORD: + command = getCommand(commandToken.toString(), args, env); + return command; + default: + return null; + } + } + + private static Command getCommand(String commandName, List args, Environment env) { + + Command command = null; + switch (commandName) { + case Echo.NAME: + command = new Echo(args, env); + break; + case Cat.NAME: + command = new Cat(args, env); + break; + case Wc.NAME: + command = new Wc(args, env); + break; + case Pwd.NAME: + command = new Pwd(args, env); + break; + case Exit.NAME: + command = new Exit(args, env); + break; + default: + command = new OutSource(commandName, args, env); + break; + + } + return command; + } + + private static String concat(List args) { + + return args.stream().collect(Collectors.joining()); + } +} diff --git a/shell/src/main/java/shell/Environment.java b/shell/src/main/java/shell/Environment.java new file mode 100644 index 0000000..e38a6e3 --- /dev/null +++ b/shell/src/main/java/shell/Environment.java @@ -0,0 +1,40 @@ +package shell; + +import java.util.HashMap; +import java.util.Map; + +/** + * Entity which represents a concept of environment which handles state of a running shell. + * It can be asked to give variable by its name and to accept new variable by name and value + */ +public class Environment { + private Map map; + + public Environment() { + this.map = new HashMap<>(); + } + + /** + * @param var name of requested variable + * @return value of a requested variable or empty string if such does not exist in environment + */ + public String get(String var) { + + String res = map.get(var); + + if (res == null) { + return ""; + } else { + return res; + } + } + + + /** + * @param var name of inserted variable + * @param val value of inserted variable + */ + public void put(String var, String val) { + map.put(var, val); + } +} diff --git a/shell/src/main/java/shell/Main.java b/shell/src/main/java/shell/Main.java new file mode 100644 index 0000000..56e8108 --- /dev/null +++ b/shell/src/main/java/shell/Main.java @@ -0,0 +1,8 @@ +package shell; + +public class Main { + public static void main(String[] args) { + Shell shell = new Shell(); + shell.run(); + } +} diff --git a/shell/src/main/java/shell/Parser.java b/shell/src/main/java/shell/Parser.java new file mode 100644 index 0000000..f19716e --- /dev/null +++ b/shell/src/main/java/shell/Parser.java @@ -0,0 +1,121 @@ +package shell; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; + +/** + * A DFA which accepts a list of tokens and evaluates + * corresponding shell command or a sequence of them + */ +public class Parser { + + private Queue queue; + private Environment env; + private List commands = new ArrayList<>(); + + private Parser(List tokens, Environment env) { + this.queue = new ArrayDeque<>(tokens); + this.env = env; + } + + + /** + * @param tokens List of tokens to parse as a chain of shell commands + * @param env Environment object + * @return List of generated commands + */ + public static List run(List tokens, Environment env) { + + Parser parser = new Parser(tokens, env); + parser.start(); + return parser.commands; + + } + + private void start() { + Token token = queue.poll(); + if (token.getType() == Token.Type.WORD) { + parseCommand(token); + } else { + error(); + } + + } + + private void parseCommand(Token firstWord) { + Token token = queue.poll(); + switch (token.getType()) { + case EQ: + parseEQ(firstWord); + break; + case WORD: + List args = new ArrayList<>(); + args.add(token.toString()); + parseArg(firstWord, args); + break; + case PIPE: + createCommand(firstWord, new ArrayList<>()); + start(); + break; + case EOF: + createCommand(firstWord, new ArrayList<>()); + break; + default: + error(); + break; + } + } + + private void createCommand(Token commandToken, List args) { + Command command = CommandFactory.produce(commandToken, args, env); + commands.add(command); + } + + private void parseEQ(Token var) { + Token val = queue.poll(); + switch (val.getType()) { + case WORD: + checkEQSyntax(); + List args = new ArrayList<>(); + args.add(var.toString()); + args.add(val.toString()); + createCommand(Token.eq(), args); + break; + default: + error(); + break; + } + } + + private void checkEQSyntax() { + Token token = queue.poll(); + if (token.getType() != Token.Type.EOF) { + error(); + } + } + + private void parseArg(Token command, List args) { + Token token = queue.poll(); + switch (token.getType()) { + case WORD: + args.add(token.toString()); + parseArg(command, args); + break; + case PIPE: + createCommand(command, args); + start(); + break; + case EOF: + createCommand(command, args); + break; + default: + error(); + break; + } + } + + private void error() {} + +} diff --git a/shell/src/main/java/shell/Preprocessor.java b/shell/src/main/java/shell/Preprocessor.java new file mode 100644 index 0000000..f8d103d --- /dev/null +++ b/shell/src/main/java/shell/Preprocessor.java @@ -0,0 +1,64 @@ +package shell; + +/** + * Takes care of substitution variable values in requested places + */ +public class Preprocessor { + + /** + * @param unprocessed unprocessed input String + * @param env Environment object + * @return String with substituted variables from environment + */ + public static String run(String unprocessed, Environment env) { + + char[] chars = unprocessed.toCharArray(); + + StringBuilder varName = new StringBuilder(); + StringBuilder processed = new StringBuilder(); + boolean varReading = false; + boolean isInsideDoubleQuotes = false; + boolean isInsideSingleQuotes = false; + + for (int i = 0; i < chars.length; i++) { + + if (!isInsideSingleQuotes && chars[i] == '$') { + varReading = true; + continue; + } + + if (varReading) { + varName.append(chars[i]); + if (isEndOfVarName(chars, i)) { + processed.append(env.get(varName.toString())); + varName.delete(0, chars.length); + varReading = false; + } + continue; + } + + if (chars[i] == '"' && !isInsideSingleQuotes) { + isInsideDoubleQuotes = !isInsideDoubleQuotes; + } + + if (chars[i] == '\'' && !isInsideDoubleQuotes) { + isInsideSingleQuotes = !isInsideSingleQuotes; + } + + processed.append(chars[i]); + } + + return processed.toString(); + } + + private static boolean isEndOfVarName(char[] chars, int index) { + + if (index == chars.length - 1) { + return true; + } + + char c = chars[index + 1]; + return c == ' ' || c == '"' || c == '\'' || c == '$'; + } + +} diff --git a/shell/src/main/java/shell/Shell.java b/shell/src/main/java/shell/Shell.java new file mode 100644 index 0000000..c4202c8 --- /dev/null +++ b/shell/src/main/java/shell/Shell.java @@ -0,0 +1,41 @@ +package shell; + +import java.util.List; +import java.util.Scanner; + +//todo возвращать код возврата +//todo исключения парсера +//прохождения нового теста токенайзера + +/** + * Main entity. Reads from stdin in an infinite loop and executes commands + */ +public class Shell { + + private Environment env; + + /** + * constructs Shell with empty environment + */ + Shell() { + env = new Environment(); + } + + /** + * runs Shell + */ + public void run() { + Scanner sc = new Scanner(System.in); + + while (true) { + String input = sc.nextLine(); + input = Preprocessor.run(input, env); + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + Stream stream = CommandExecutor.run(commands); + while (stream.hasNext()) { + System.out.println(stream.read()); + } + } + } +} diff --git a/shell/src/main/java/shell/Stream.java b/shell/src/main/java/shell/Stream.java new file mode 100644 index 0000000..1e7b2b3 --- /dev/null +++ b/shell/src/main/java/shell/Stream.java @@ -0,0 +1,55 @@ +package shell; + +import java.util.ArrayDeque; +import java.util.Queue; + +/** + * Entity to handle input and output of commands. + */ +public class Stream { + + private Queue vals; + + public Stream() { + this.vals = new ArrayDeque<>(); + } + + /** + * @return next line in stream or null if stream is empty + */ + public String read() { + return vals.poll(); + } + + /** + * @param val line to add to stream + */ + public void write(String val) { + vals.offer(val); + } + + /** + * @return true if stream has at least one line to read + */ + public boolean hasNext() { + return vals.peek() != null; + } + + /** + * @return concatenated lines in stream + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + Queue replacement = new ArrayDeque<>(); + while (hasNext()) { + String line = read(); + sb.append('\n'); + sb.append(line); + replacement.add(line); + } + vals = replacement; + sb.delete(0, 1); + return sb.toString(); + } +} diff --git a/shell/src/main/java/shell/Token.java b/shell/src/main/java/shell/Token.java new file mode 100644 index 0000000..0092ba4 --- /dev/null +++ b/shell/src/main/java/shell/Token.java @@ -0,0 +1,154 @@ +package shell; + +import java.util.ArrayList; + +/** + * Describes possible lexems + */ +public class Token { + + /** + * describes possible token types + */ + public enum Type { + SINGLE_QUOTE, + DOUBLE_QUOTE, + WHITESPACE, + PIPE, + WORD, + EQ, + EOF + } + + private String value; + private Type type; + + private static final String SINGLE_QUOTE = "'"; + private static final String DOUBLE_QUOTE = "\""; + private static final String EQUALITY_OPERATOR = "="; + private static final String WHITESPACE = " "; + private static final String PIPE = "|"; + private static final String EOF = "\0"; + + private Token(Token.Type type, String value) { + this.type = type; + this.value = value; + } + + /** + * @return new single quote token + */ + public static Token singleQuote() { + return new Token(Type.SINGLE_QUOTE, SINGLE_QUOTE); + } + + /** + * @return new double quote token + */ + public static Token doubleQuote() { + return new Token(Type.DOUBLE_QUOTE, DOUBLE_QUOTE); + } + + /** + * @return new '=' token + */ + public static Token eq() { + return new Token(Type.EQ, EQUALITY_OPERATOR); + } + + /** + * @return new whitespace token + */ + public static Token whitespace() { + return new Token(Type.WHITESPACE, WHITESPACE); + } + + /** + * @return new pipe token + */ + public static Token pipe() { + return new Token(Type.PIPE, PIPE); + } + + /** + * @param word + * @return new word token + */ + public static Token word(String word) { + return new Token(Type.WORD, word); + } + + /** + * @return new end of line token + */ + public static Token eof() { + return new Token(Type.EOF, EOF); + } + + + /** + * @param c + * @return tests if passed char can be a delimiter between words + */ + public static boolean isDelimiter(char c) { + ArrayList test = new ArrayList<>(); + test.add(SINGLE_QUOTE); + test.add(DOUBLE_QUOTE); + test.add(WHITESPACE); + test.add(EQUALITY_OPERATOR); + test.add(PIPE); + return test.contains(String.valueOf(c)); + } + + /** + * @param c + * @return generate corresponding token to passed char + */ + public static Token valueOf(char c) { + switch (String.valueOf(c)) { + case SINGLE_QUOTE: + return singleQuote(); + case DOUBLE_QUOTE: + return doubleQuote(); + case WHITESPACE: + return whitespace(); + case EQUALITY_OPERATOR: + return eq(); + case PIPE: + return pipe(); + default: + return word(String.valueOf(c)); + } + } + + public Type getType() { + return type; + } + + public String getValue() { + return value; + } + + @Override + public String toString() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Token token = (Token) o; + + if (value != null ? !value.equals(token.value) : token.value != null) return false; + return type == token.type; + } + + @Override + public int hashCode() { + int result = value != null ? value.hashCode() : 0; + result = 31 * result + (type != null ? type.hashCode() : 0); + return result; + } +} diff --git a/shell/src/main/java/shell/Tokenizer.java b/shell/src/main/java/shell/Tokenizer.java new file mode 100644 index 0000000..52d5179 --- /dev/null +++ b/shell/src/main/java/shell/Tokenizer.java @@ -0,0 +1,73 @@ +package shell; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; + +/** + * Takes care of translating given char string to list of lexemes. + */ +public class Tokenizer { + + /** + * @param input processed string corresponding to some shell command + * @return list of words and operators obtained from passed string + */ + public static List run(String input) { + + List tokens = new ArrayList<>(); + + char[] chars = input.toCharArray(); + for (int i = 0; i < chars.length;) { + char c = chars[i]; + if (!Token.isDelimiter(c)) { + String word = readWord(chars, i); + i += word.length(); + tokens.add(Token.word(word)); + continue; + } + Token.Type type = Token.valueOf(c).getType(); + switch (type) { + case SINGLE_QUOTE: + case DOUBLE_QUOTE: + i++; + String word = readWordInsideQuotes(chars, i, c); + i += word.length() + 1; + tokens.add(Token.word(word)); + break; + case EQ: + tokens.add(Token.eq()); + i++; + break; + case WHITESPACE: + i++; + break; + case PIPE: + tokens.add(Token.pipe()); + i++; + break; + } + } + + tokens.add(Token.eof()); + + return tokens; + } + + private static String readWordInsideQuotes(char[] chars, int i, char matcher) { + return readWordUntil(c -> c.equals(matcher), chars, i); + } + + private static String readWord(char[] chars, int i) { + return readWordUntil(Token::isDelimiter, chars, i); + } + + private static String readWordUntil(Predicate breaker, char[] chars, int i) { + StringBuilder sb = new StringBuilder(); + while (i < chars.length && !breaker.test(chars[i])) { + sb.append(chars[i++]); + } + return sb.toString(); + } + +} diff --git a/shell/src/test/java/ParserTests.java b/shell/src/test/java/ParserTests.java new file mode 100644 index 0000000..6e438af --- /dev/null +++ b/shell/src/test/java/ParserTests.java @@ -0,0 +1,90 @@ +import org.junit.Test; +import shell.*; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class ParserTests { + + @Test + public void smokeTest() { + Environment env = getEnv(); + String input = "hello=hacked"; + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + commands.get(0).run(new Stream()); + assertEquals("hacked", Preprocessor.run("$hello", env)); + } + + @Test + public void reduceTest() { + Environment env = getEnv(); + String input = "hello='hacked = | azazazazaa'"; + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + commands.get(0).run(new Stream()); + assertEquals("hacked = | azazazazaa", Preprocessor.run("$hello", env)); + } + + @Test + public void reduceWithSubstitutionTest() { + Environment env = getEnv(); + String input = "hello=\"hacked $vladimir\""; + input = Preprocessor.run(input, env); + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + commands.get(0).run(new Stream()); + assertEquals("hacked putin", Preprocessor.run("$hello", env)); + } + + @Test + public void recursiveReduceWithSubstitutionTest() { + Environment env = getEnv(); + String input = "hello=\"hacked $hello\""; + input = Preprocessor.run(input, env); + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + commands.get(0).run(new Stream()); + assertEquals("hacked world", Preprocessor.run("$hello", env)); + } + + @Test + public void echoTest() { + Environment env = getEnv(); + String input = "echo hello"; + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + Stream output = CommandExecutor.run(commands); + assertEquals("hello", output.toString()); + } + + @Test + public void echoToPipeToCatTest() { + Environment env = getEnv(); + String input = "echo hello | cat"; + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + Stream output = CommandExecutor.run(commands); + assertEquals("hello", output.toString()); + } + + @Test + public void echoToSedAsOutSourceTest() { + + Environment env = getEnv(); + String input = "echo \"hello_world\" | sed 's/hello/goodbye/'"; + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + Stream output = CommandExecutor.run(commands); + assertEquals("goodbye_world", output.toString()); + } + + private Environment getEnv() { + Environment env = new Environment(); + env.put("hello", "world"); + env.put("vladimir", "putin"); + + return env; + } +} diff --git a/shell/src/test/java/PreprocessorTests.java b/shell/src/test/java/PreprocessorTests.java new file mode 100644 index 0000000..3ee580c --- /dev/null +++ b/shell/src/test/java/PreprocessorTests.java @@ -0,0 +1,71 @@ +import org.junit.Test; +import shell.Environment; +import shell.Preprocessor; + +import static org.junit.Assert.assertEquals; + +public class PreprocessorTests { + + @Test + public void smokeTest() { + + Environment env = getEnv(); + + assertEquals("cat world | echo putin azazaza", + Preprocessor.run("cat $hello | echo $vladimir azazaza", env)); + } + + @Test + public void emptySubstitutionTest() { + + Environment env = getEnv(); + + assertEquals("", Preprocessor.run("$not_in_env", env)); + } + + @Test + public void lastSub() { + Environment env = getEnv(); + + assertEquals("world", Preprocessor.run("$hello", env)); + } + + @Test + public void varNameBreakers() { + Environment env = getEnv(); + + assertEquals("world'hidden' \"world\" worldputin putin", + Preprocessor.run("$hello'hidden' \"$hello\" $hello$vladimir $vladimir", env)); + } + + @Test + public void hidesInSingleQuotes() { + Environment env = getEnv(); + + assertEquals("'$hello' world", Preprocessor.run("'$hello' $hello", env)); + } + + @Test + public void handlesIncorrectInput() { + Environment env = getEnv(); + + assertEquals("'$hello", Preprocessor.run("'$hello", env)); + } + + @Test + public void nestedQuotes() { + Environment env = getEnv(); + + assertEquals("\"'hello'\" world", Preprocessor.run("\"'$test'\" world", env)); + } + + private Environment getEnv() { + Environment env = new Environment(); + env.put("hello", "world"); + env.put("vladimir", "putin"); + env.put("test", "hello"); + + return env; + } + +} diff --git a/shell/src/test/java/TokenizerTests.java b/shell/src/test/java/TokenizerTests.java new file mode 100644 index 0000000..34d6d22 --- /dev/null +++ b/shell/src/test/java/TokenizerTests.java @@ -0,0 +1,65 @@ +import org.junit.Test; +import shell.Token; +import shell.Tokenizer; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class TokenizerTests { + + @Test + public void smokeTest() { + List expected = new ArrayList<>(); + expected.add(Token.word("hello world")); + expected.add(Token.eof()); + + List actual = Tokenizer.run("'hello world'"); + + assertEquals(expected, actual); + } + + @Test + public void emptyTest() { + List expected = new ArrayList<>(); + expected.add(Token.eof()); + + List actual = Tokenizer.run(""); + + assertEquals(expected, actual); + } + + @Test + public void assignmentTest() { + List expected = new ArrayList<>(); + expected.add(Token.word("hello")); + expected.add(Token.eq()); + expected.add(Token.word("world")); + expected.add(Token.eof()); + + List actual = Tokenizer.run("hello=world"); + + assertEquals(expected, actual); + } + + @Test + public void mixedTest() { + List expected = new ArrayList<>(); + expected.add(Token.word("cat")); + expected.add(Token.word("input.txt")); + expected.add(Token.pipe()); + expected.add(Token.word("cat")); + expected.add(Token.pipe()); + expected.add(Token.word("grep")); + expected.add(Token.word("-v")); + expected.add(Token.word("azazaazz")); + expected.add(Token.word("long \"string\" constant")); + expected.add(Token.eof()); + + + List actual = Tokenizer.run("cat input.txt | cat | grep -v azazaazz 'long \"string\" constant' "); + + assertEquals(expected, actual); + } +} From 14c5beb67208f6b2e65df70137fcf589af21e48b Mon Sep 17 00:00:00 2001 From: simiyutin Date: Mon, 6 Mar 2017 15:53:08 +0300 Subject: [PATCH 02/63] more comments --- shell/src/main/java/commands/Cat.java | 3 +++ shell/src/main/java/commands/Echo.java | 4 ++++ shell/src/main/java/commands/Eq.java | 3 +++ shell/src/main/java/commands/Exit.java | 3 +++ shell/src/main/java/commands/OutSource.java | 3 +++ shell/src/main/java/commands/Pwd.java | 3 +++ shell/src/main/java/commands/Wc.java | 3 +++ shell/src/main/java/shell/Command.java | 2 ++ shell/src/main/java/shell/CommandExecutor.java | 1 + shell/src/main/java/shell/CommandFactory.java | 1 + shell/src/main/java/shell/Environment.java | 2 ++ shell/src/main/java/shell/Parser.java | 1 + shell/src/main/java/shell/Preprocessor.java | 1 + shell/src/main/java/shell/Shell.java | 3 --- shell/src/main/java/shell/Stream.java | 4 ++++ shell/src/main/java/shell/Token.java | 9 +++++++++ shell/src/main/java/shell/Tokenizer.java | 1 + 17 files changed, 44 insertions(+), 3 deletions(-) diff --git a/shell/src/main/java/commands/Cat.java b/shell/src/main/java/commands/Cat.java index 6e36cd9..d8c8e34 100644 --- a/shell/src/main/java/commands/Cat.java +++ b/shell/src/main/java/commands/Cat.java @@ -11,6 +11,9 @@ import java.util.List; import java.util.Scanner; +/** + * Reads file from parameter to stdout or reflects stdin to stdout + */ public class Cat extends Command { public static final String NAME = "cat"; diff --git a/shell/src/main/java/commands/Echo.java b/shell/src/main/java/commands/Echo.java index d786511..8c82e75 100644 --- a/shell/src/main/java/commands/Echo.java +++ b/shell/src/main/java/commands/Echo.java @@ -7,6 +7,10 @@ import java.util.List; import java.util.stream.Collectors; + +/** + * Prints arguments to output stream + */ public class Echo extends Command { public static final String NAME = "echo"; diff --git a/shell/src/main/java/commands/Eq.java b/shell/src/main/java/commands/Eq.java index 641333d..0661da5 100644 --- a/shell/src/main/java/commands/Eq.java +++ b/shell/src/main/java/commands/Eq.java @@ -6,6 +6,9 @@ import java.util.List; +/** + * Puts new variable in context or changes variable value + */ public class Eq extends Command { public Eq(List args, Environment env) { diff --git a/shell/src/main/java/commands/Exit.java b/shell/src/main/java/commands/Exit.java index 2a1fa60..31aa230 100644 --- a/shell/src/main/java/commands/Exit.java +++ b/shell/src/main/java/commands/Exit.java @@ -6,6 +6,9 @@ import java.util.List; +/** + * Exits shell + */ public class Exit extends Command { public static final String NAME = "exit"; diff --git a/shell/src/main/java/commands/OutSource.java b/shell/src/main/java/commands/OutSource.java index 556d10c..193e2fa 100644 --- a/shell/src/main/java/commands/OutSource.java +++ b/shell/src/main/java/commands/OutSource.java @@ -8,6 +8,9 @@ import java.util.List; import java.util.stream.Collectors; +/** + * Passes input arguments and stream to external shell and reads result from its stdout + */ public class OutSource extends Command { private String commandName; diff --git a/shell/src/main/java/commands/Pwd.java b/shell/src/main/java/commands/Pwd.java index a3985a7..4d66b04 100644 --- a/shell/src/main/java/commands/Pwd.java +++ b/shell/src/main/java/commands/Pwd.java @@ -8,6 +8,9 @@ import java.nio.file.Paths; import java.util.List; +/** + * Prints current directory + */ public class Pwd extends Command { public static final String NAME = "pwd"; diff --git a/shell/src/main/java/commands/Wc.java b/shell/src/main/java/commands/Wc.java index 0eef945..5c6d2f5 100644 --- a/shell/src/main/java/commands/Wc.java +++ b/shell/src/main/java/commands/Wc.java @@ -14,6 +14,9 @@ import java.util.Scanner; import java.util.stream.Collectors; +/** + * Counts lines, words and bytes in given file or input stream + */ public class Wc extends Command { public static final String NAME = "wc"; diff --git a/shell/src/main/java/shell/Command.java b/shell/src/main/java/shell/Command.java index b87bbc6..07c30b1 100644 --- a/shell/src/main/java/shell/Command.java +++ b/shell/src/main/java/shell/Command.java @@ -13,6 +13,7 @@ public abstract class Command { /** + * Public constructor * @param args arguments of a command as a List * @param env environment of current running shell */ @@ -22,6 +23,7 @@ public Command(List args, Environment env) { } /** + * Used as interface to command object. Takes input stream and returns result as output stream. * @param stream * @return result data as a Stream object */ diff --git a/shell/src/main/java/shell/CommandExecutor.java b/shell/src/main/java/shell/CommandExecutor.java index 0526c70..bf9dcf3 100644 --- a/shell/src/main/java/shell/CommandExecutor.java +++ b/shell/src/main/java/shell/CommandExecutor.java @@ -12,6 +12,7 @@ public class CommandExecutor { private CommandExecutor() {} /** + * Sequentially executes chained list of commands. * @param commands List of Command objects * @return Stream object which contain result of a chain of computations */ diff --git a/shell/src/main/java/shell/CommandFactory.java b/shell/src/main/java/shell/CommandFactory.java index c96c5ad..3e75950 100644 --- a/shell/src/main/java/shell/CommandFactory.java +++ b/shell/src/main/java/shell/CommandFactory.java @@ -13,6 +13,7 @@ public class CommandFactory { /** + * Factory method to generate commands from tokens. * @param commandToken token, which contains command name as a String * @param args arguments of a command * @param env Environment object diff --git a/shell/src/main/java/shell/Environment.java b/shell/src/main/java/shell/Environment.java index e38a6e3..7562aa4 100644 --- a/shell/src/main/java/shell/Environment.java +++ b/shell/src/main/java/shell/Environment.java @@ -15,6 +15,7 @@ public Environment() { } /** + * Get value of variable * @param var name of requested variable * @return value of a requested variable or empty string if such does not exist in environment */ @@ -31,6 +32,7 @@ public String get(String var) { /** + * Put variable value * @param var name of inserted variable * @param val value of inserted variable */ diff --git a/shell/src/main/java/shell/Parser.java b/shell/src/main/java/shell/Parser.java index f19716e..c8ab817 100644 --- a/shell/src/main/java/shell/Parser.java +++ b/shell/src/main/java/shell/Parser.java @@ -22,6 +22,7 @@ private Parser(List tokens, Environment env) { /** + * Parses list of tokens into list of commands * @param tokens List of tokens to parse as a chain of shell commands * @param env Environment object * @return List of generated commands diff --git a/shell/src/main/java/shell/Preprocessor.java b/shell/src/main/java/shell/Preprocessor.java index f8d103d..e19b9c8 100644 --- a/shell/src/main/java/shell/Preprocessor.java +++ b/shell/src/main/java/shell/Preprocessor.java @@ -6,6 +6,7 @@ public class Preprocessor { /** + * Substitutes variables in unprocessed string * @param unprocessed unprocessed input String * @param env Environment object * @return String with substituted variables from environment diff --git a/shell/src/main/java/shell/Shell.java b/shell/src/main/java/shell/Shell.java index c4202c8..739d030 100644 --- a/shell/src/main/java/shell/Shell.java +++ b/shell/src/main/java/shell/Shell.java @@ -3,9 +3,6 @@ import java.util.List; import java.util.Scanner; -//todo возвращать код возврата -//todo исключения парсера -//прохождения нового теста токенайзера /** * Main entity. Reads from stdin in an infinite loop and executes commands diff --git a/shell/src/main/java/shell/Stream.java b/shell/src/main/java/shell/Stream.java index 1e7b2b3..5a6a3f4 100644 --- a/shell/src/main/java/shell/Stream.java +++ b/shell/src/main/java/shell/Stream.java @@ -15,6 +15,7 @@ public Stream() { } /** + * Read one line from stream * @return next line in stream or null if stream is empty */ public String read() { @@ -22,6 +23,7 @@ public String read() { } /** + * Write one line to stream * @param val line to add to stream */ public void write(String val) { @@ -29,6 +31,7 @@ public void write(String val) { } /** + * Check if stream has more lines to read * @return true if stream has at least one line to read */ public boolean hasNext() { @@ -36,6 +39,7 @@ public boolean hasNext() { } /** + * String representation of a stream object * @return concatenated lines in stream */ @Override diff --git a/shell/src/main/java/shell/Token.java b/shell/src/main/java/shell/Token.java index 0092ba4..c4583c4 100644 --- a/shell/src/main/java/shell/Token.java +++ b/shell/src/main/java/shell/Token.java @@ -36,6 +36,7 @@ private Token(Token.Type type, String value) { } /** + * Static factory method * @return new single quote token */ public static Token singleQuote() { @@ -43,6 +44,7 @@ public static Token singleQuote() { } /** + * Static factory method * @return new double quote token */ public static Token doubleQuote() { @@ -50,6 +52,7 @@ public static Token doubleQuote() { } /** + * Static factory method * @return new '=' token */ public static Token eq() { @@ -57,6 +60,7 @@ public static Token eq() { } /** + * Static factory method * @return new whitespace token */ public static Token whitespace() { @@ -64,6 +68,7 @@ public static Token whitespace() { } /** + * Static factory method * @return new pipe token */ public static Token pipe() { @@ -71,6 +76,7 @@ public static Token pipe() { } /** + * Static factory method * @param word * @return new word token */ @@ -79,6 +85,7 @@ public static Token word(String word) { } /** + * Static factory method * @return new end of line token */ public static Token eof() { @@ -87,6 +94,7 @@ public static Token eof() { /** + * Test if given char corresponds to somme delimiter token * @param c * @return tests if passed char can be a delimiter between words */ @@ -101,6 +109,7 @@ public static boolean isDelimiter(char c) { } /** + * Static factory method * @param c * @return generate corresponding token to passed char */ diff --git a/shell/src/main/java/shell/Tokenizer.java b/shell/src/main/java/shell/Tokenizer.java index 52d5179..00f158c 100644 --- a/shell/src/main/java/shell/Tokenizer.java +++ b/shell/src/main/java/shell/Tokenizer.java @@ -10,6 +10,7 @@ public class Tokenizer { /** + * Start tokenizer on preprocessed string * @param input processed string corresponding to some shell command * @return list of words and operators obtained from passed string */ From 436381a683855bf0d9e63fb18468cd555505679d Mon Sep 17 00:00:00 2001 From: simiyutin Date: Mon, 6 Mar 2017 16:24:44 +0300 Subject: [PATCH 03/63] Create README.md --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..5f43aa7 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# au_software_design + +##1. Shell + +###Command line utility similar to Unix shell. + +Supported features: + +* echo command +* cat command +* wc command +* exit command +* pwd command +* environment variables +* unknown commands are passed to system shell as separate process through Java.Process library. + From 12f41aa71be5dab9b8e24841ce8b46ebc85788c9 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Tue, 7 Mar 2017 13:23:23 +0300 Subject: [PATCH 04/63] Update README.md --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f43aa7..266fc9b 100644 --- a/README.md +++ b/README.md @@ -13,4 +13,15 @@ Supported features: * pwd command * environment variables * unknown commands are passed to system shell as separate process through Java.Process library. - + +###Class diagram +![shell class diagram](https://www.gliffy.com/go/share/image/smx5dub0j39jxied850w.png?utm_medium=live-embed&utm_source=custom) + + Data flow: + * Main: run Shell object. + * Shell: Read line from System.in. +   * Preprocessor: Substitute environment variables in input string. E. g. "Hello, $name" -> "Hello, Alex" + * Tokeniser: Split string into a list of tokens: words and operators. + * Parser: Parse list of tokens as sequence of commands divided by pipes. + * Command Executor: Perform chained computation passing output of one comand as input to the next one. + * Pass result to System.in and loop again. From ac8f8cbbacea430a27e0044c4fe54078fb54ed8c Mon Sep 17 00:00:00 2001 From: simiyutin Date: Tue, 7 Mar 2017 14:13:37 +0300 Subject: [PATCH 05/63] exceptions --- .../2.10/taskArtifacts/cache.properties.lock | Bin 17 -> 55 bytes .../.gradle/2.10/taskArtifacts/fileHashes.bin | Bin 22067 -> 22739 bytes .../2.10/taskArtifacts/fileSnapshots.bin | Bin 30333 -> 47470 bytes .../2.10/taskArtifacts/taskArtifacts.bin | Bin 22269 -> 31965 bytes shell/build.gradle | 6 +++ shell/src/main/java/commands/Cat.java | 8 +++- shell/src/main/java/commands/Echo.java | 3 +- shell/src/main/java/commands/Eq.java | 3 +- shell/src/main/java/commands/Exit.java | 3 +- shell/src/main/java/commands/OutSource.java | 9 ++-- shell/src/main/java/commands/Pwd.java | 3 +- shell/src/main/java/commands/Wc.java | 3 +- .../exceptions/CommandExecutionException.java | 10 +++++ .../main/java/exceptions/ParserException.java | 11 +++++ .../main/java/exceptions/ShellException.java | 17 ++++++++ shell/src/main/java/shell/Command.java | 4 +- .../src/main/java/shell/CommandExecutor.java | 13 ++++-- shell/src/main/java/shell/Parser.java | 41 ++++++++++-------- shell/src/test/java/ParserTests.java | 25 +++++++++-- 19 files changed, 123 insertions(+), 36 deletions(-) create mode 100644 shell/src/main/java/exceptions/CommandExecutionException.java create mode 100644 shell/src/main/java/exceptions/ParserException.java create mode 100644 shell/src/main/java/exceptions/ShellException.java diff --git a/shell/.gradle/2.10/taskArtifacts/cache.properties.lock b/shell/.gradle/2.10/taskArtifacts/cache.properties.lock index 7a2565a4de4e1f5ee642cb703aa0609349b5624c..9b611430cdcf69ab3bef76113d5390143f06dff1 100644 GIT binary patch literal 55 zcmZQ}IWh$jrcSEoIe;?C$@bE3PuIm{^#bGYI!!nQ!zDN zBTk7zHuoO9n-6UdUzzQ~mD$T*$!s@*MZC{+neAFDvzM#LZ0Aau?ZKAW+WdR68=jlY zrsNlMHfw_EtUyc{2I5&v%r^mKv79hpHPBAnxq=b=PGkb?w3wLC0*JICG0_^(sMUuF zkAq6>e9ZR>2-S(igl(W*2lpESM!IR3D7&OoS8Bq}Z!3#P@?X4T{$;Q?#V;qGLZPmZ zasn6P8Q@L91cbY5%;qpc<;0tk(-=BgJ&T7_two&(D}orU9`+P2xaRDL<3?^F_eYOi ztTr3II5UvD&-V!p&TqSsmxiC8nD0f&FtoSof<(A4YIFNOQ4N!gFbdG_?-T zg#})?sLSCGo57fikhQ);Lt{9kzBDW1roW&hCI6G_`sI3F9LAzTg}|s3hG=@Teow%` z&DCi5H562^8BfFfwgqk);}?gx7#=GJqq&N0>FWl{53i0k_!s&Gse`uV0$kSU^(=pB2hr1?la$CS2 z^6mO5{HfPAv-r#WV z^|Pzh8(YmrdfcS}UnKSMsC3l?V%~f< z)t;B~54|weZnTfFeS_6+2sDA9{1iZSXR#Zft)D9XBO_i)W z##fj7-R=9cK%1`@$6;(~RkM5FJXtbjfd1pEa_(c&=d4;7dQr5}#%nMef2@yR9L6+Z z*A;I6#+FMrH|)wg_NETST7zOW!v1SN{i&3FMQaBAy6(;yu=q<}yZ$u z(l`D1Hv;A7r%KN1L>SKw@P0amuV!)v-Jv7(`L_bv&RSL17<+K8FuA6x&oin9`DsF4 zQDfW>bh}?bK{KIBe>;?Xw7Q|>G998C!i>bsjkw#SC#> zlVn!ffotBxDvJf1HFRHUD8Hj+o_TcaKoarFpXolBSeL_aSr;(vX8xk2sf4IKPD;G{jo9D`&5F;kUBAV+|2kj#qPNREQf zBe7ZAIT}AdA`xUI#?!T0KywumF@hL|mJ_~N>-j8WIUDpBEjgp;GJ@p>`wjNqN3bQ> z;WLA6da2>>$BE&m?41NLBlgvOg-zQw%iv_LS54HwnP(6! zONXd$F6<{LK}yw~+vkGTjfEJBy9%VLx`ZRXmxMqEx;?Qt*u^$iE}z(QC)he?@e38h z8Z89bLkK%XLN8jI)x?8wFQ*zG4LYRqkvvFnB{77khe;?eHJ!C+#jV7J7V?&@#RfE_ zWQ&wMN$BaQGI!94Qn0Q};;^EJvkO7QDS!J1SFJt=}1roxX^AIYRq_q{egdBWKJxU(*qL9 z^a%c8j@`Yaa~`U$wKKvy5wrk8io*nC^fu#Awxs{0hea#zf@9u?B_zbGL`M!r{Gt%e F{C^PWwPpYS delta 1549 zcmZ9MX;4#F6vvYn3Zx}KElD0A5JLbfvUCIjC`heP9tmM-ScM72GEziYgh(tMD}@4T zEpU}0SX4mN78oMRQkH~J%Dz+>%Rp-ZaRG|0S`n#W-*Wpw&zC#*o!|YRbM86!jVb93 zHS_{DlLn2WR36|KssS)ZV-U$r@CC|2Fb7bA`XGT}U>e`~s=*4r6ZHZwV-Dgk2I0nX zL@WfO#t)Hzd7w6_M*Q?ayr~=s(^+n{KZk!(yA>>U#j3MA4=7JGlXG{Lu zw7=DhgIi0nEs5E`dpL}&W01|ESR|ihJuz4G*Y@0axxvJHmfx?AXm&3#AQ%EpVNQB@ z3TLPj^Z_CTa1S%m!asfv*0E4Ds`#Q)rDY#Gq4lf)`73$?9*qErer7}t<$*_}O_oJQ z6V@$TxLWzUp#LH)%ALpoeTNEx1B5rpQ!l%JFkd73uKR0svV9l4x9 zzgk)q^#4MMuv|zHVUK&V4O8_z9n~mmR%lHSx&)4iEYLky-?zOeNa|SftQl5$*Va?c z2o`7-g`p>_-*Wa(9+KT3RE!PV3U5H?CSW5DIp=~)Pwfgv%E*Vs4UXfO?zApxfzCH51%@7>z>76F zQgWgEq{J1ua&S&K&LttkvIqz*0=0+>_V^2VcBk_uKDlT3uWOfp-F7J97zrBH2T-6^ zBA^Gb`S_i6>_25?U#K7VsCRo^mK@tha@s!a6o-IK5)OFj&($i_N#_F-3E8Y3W)HUG z@YB7>OVnr9WM3b7Mo>0Lona}-3H(F+L>_ZfuhaN4zg5ff5Y-IBG7p&PSrQumuw^-= zPdikz7E&=9@A4^BI!!@32vIYbk&t6rwR<3`=-CTJT-AJr;_>Y?$l}6;=^h{jhpzps zZLL3wZF}%Q{8OF%aR@b2kX}3qHEtjNYNzLN`PV8N@1$$rEf7#iTagz9(JM))Jcaqf zymCwQ(Wv{IZF=~TP)SWey2E5@D*=~yZi&+D+I0`s!{Gd>)Z5*;q?)QVhyoGvritlX zO7G5-@9@(Ui`@u z#@a-7yCEo>At*Zs+=HF)^*TricE;BW;A(Ie5w=)i7gf*TUP~@zpWhJvY(E*+J{I z+U5D&0fKfQGsJ?&m$6QIvCjlxGC}c)$`0B8PD+LG0h!2Xh^sAL{c?eG!IVjJ%PNCW U*EKu3m16%~q1do8YNa{;2X~wV2mk;8 diff --git a/shell/.gradle/2.10/taskArtifacts/fileSnapshots.bin b/shell/.gradle/2.10/taskArtifacts/fileSnapshots.bin index b6a62f2d51d515332c21471b5c7a0317459b20d3..c057143ed6e8db321cbe969015a9dd1bca8f26e1 100644 GIT binary patch delta 4741 zcmeHKc~nzp7Egi@mH^)iAV~=*$XaEo5iJT55Hu`-fXJ{zSR`SSu%n`;Ajmja_0s_r z5h$n?iXd2u3tfZ(R06!eXQV zcwJefGE9yNyE3o|sc&xEr6I5MHrWZ9u){?a5Z7?>ACqee zSmQ%rbG-H6A(FCS(mLH$6M4TjV#I$yykwa9jr;|LLDhf2K5zW&L{}{;La1AL{#?cG zFC%SA?C+_Ww9$WlxQ?Z>&?1JH#*+gcEn)I23Pd02q?)}Q(m%nJd4M}fcT)kGfv0+R zRxqFLA@bgL8El>}^#T_VxB>L6{&7{yk+p>Cm?n`^zytj}D2~Nk!9|+gR5TF6z255@ zfg{@=B4%a0VzpOCKc2cv1$R#bP<;o^TS^jo8av|iD$Ac-`8Nwk+%XH41$$|B0he=Z znexke>x|_-n+o`$yE+wk!0NuYbPD;Y27Zxwek=FO0?~wa910capQg31S3SO0ne(qT z5{_?n>y&n)D;Wj{k?Ht_AcXu&UtT@UiA9Au z33}JW1eW

d-RR*^0TcL&(1Civ$VD7ocslX$?$Q43g|myB{J9c43jK@jLP19eWSE%^H{LakjWWGo6q%8 zQ%)$m0_YDLIEuNVu8BRbK5f!Kr6=8GaML3#BI0<-$#MuGcYNDe=H>(bKDSeA-qT(} zfDS&csBU#hTl!K(=u|!o>azreeAMK-dh7X7adA_c$8R;I?hLlyy5b!CTfTqE4w-pq z!Ba*p6mlb1FJb+2=V`9GTl)gxT{Hk&oe2IWsXmZDXiq7fe>ZEJICa+tt?8H1gu2mz zU5!FmdOq;eyKe9x4?{oGy__K!rraz3?Kr2P3?p)~neDYDb zMU|V(f)vGMtjZ87P%6d+tP=tzQa*PI0Z#)hN`j?fuL-Q z5lQzqgB3EppnNK=r}Lm)gfgrON|{+*@Ggo8sKB6L!EaedW{27zQVZ%!c@*L=!5iYf z2)(9E>U6Ail3>{eOE?zMfW|SSO#ULo%~qR~U7@q<9brDr+$!E&LMzX1CJ?iu4fO=*1hWk$YB3&asgB7NR^2Q=uoJQbUr|BQ z7NOHFrM$|{Ay{G55L0+lAcV3EioEs_j-D;_=rey zg3IjXG&onjaKPp=>^ODEh^++Xja}bcz31M4~!ct#v7H7LhlL j$mII@W)b<%i^$A*>%VOq=zE;LZOl2}{<#+s5u5fC)hx&% delta 69 zcmaF&iRtef#trrojQo=eBqSy;kVu$pASp39K{8?T4Ir%`B{4Ze%0u8k6fl4RW7S5* Qzv3GWW{YhO@X*x*0NaNfp#T5? diff --git a/shell/.gradle/2.10/taskArtifacts/taskArtifacts.bin b/shell/.gradle/2.10/taskArtifacts/taskArtifacts.bin index 04bc858e1d8a35eb4367280e2950e944b62d5f9c..1318f3477d5fa7e82a326890e5dc812c139d9a73 100644 GIT binary patch delta 482 zcmeynmhtXS#tEX9EDT@}76+u}L)bp~3=GU0A?yGJ1_m}e2s`XA0|UD^gw5c#QSpNK zWH|{BsW^}SP{5S%_|wdG7FLLo!XJ|xB*dgV_Q9kB0%qlKcRk(CJu3j8ETm{$1AxN`Y%8I|hqRo*fo7IXA42iBW#?em}9z zYkVu1HW&MJacP_}2D-@>h)qG5sp_ux+;)%W{kz&iJ}fFp7O(rB#S@wNAYe1tlr=uS zn>{?`nKz&HSir2s?u@4S|4Z)c;@{6)lF3V7F3r@nB&_fNGoQI~8(8z^H9k4ao9lew z8hOGQ7dmk`rJ@mElGmsn7Hl& E0A~cQd;kCd delta 114 zcmccnlkx9b#tEXF3{W7pG4QPT#02BXauOa=KKcKlfGOeerCnE4p7*EZ$aHIFO< diff --git a/shell/build.gradle b/shell/build.gradle index afbf593..1620193 100644 --- a/shell/build.gradle +++ b/shell/build.gradle @@ -2,6 +2,8 @@ group 'simiyutin' version '1.0-SNAPSHOT' apply plugin: 'java' +apply plugin: 'application' +mainClassName = "shell.Main" sourceCompatibility = 1.8 @@ -9,6 +11,10 @@ repositories { mavenCentral() } +run{ + standardInput = System.in +} + dependencies { testCompile group: 'junit', name: 'junit', version: '4.11' } diff --git a/shell/src/main/java/commands/Cat.java b/shell/src/main/java/commands/Cat.java index d8c8e34..3bb7021 100644 --- a/shell/src/main/java/commands/Cat.java +++ b/shell/src/main/java/commands/Cat.java @@ -1,10 +1,12 @@ package commands; +import exceptions.CommandExecutionException; import shell.Command; import shell.Environment; import shell.Stream; import java.io.IOException; +import java.nio.charset.MalformedInputException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -23,7 +25,7 @@ public Cat(List args, Environment env) { } @Override - public Stream run(Stream stream) { + public Stream run(Stream stream) throws CommandExecutionException { if (stream.hasNext()) { return stream; @@ -41,8 +43,10 @@ public Stream run(Stream stream) { try { List lines = Files.readAllLines(file); lines.forEach(res::write); + } catch (MalformedInputException e) { + throw new CommandExecutionException("Cannot determine file encoding"); } catch (IOException e) { - e.printStackTrace(); + throw new CommandExecutionException("Error while reading file: " + e.toString()); } } return res; diff --git a/shell/src/main/java/commands/Echo.java b/shell/src/main/java/commands/Echo.java index 8c82e75..1ff5827 100644 --- a/shell/src/main/java/commands/Echo.java +++ b/shell/src/main/java/commands/Echo.java @@ -1,5 +1,6 @@ package commands; +import exceptions.CommandExecutionException; import shell.Command; import shell.Environment; import shell.Stream; @@ -20,7 +21,7 @@ public Echo(List args, Environment env) { } @Override - public Stream run(Stream ignored) { + public Stream run(Stream ignored) throws CommandExecutionException { String toPrint = args.stream().collect(Collectors.joining()); diff --git a/shell/src/main/java/commands/Eq.java b/shell/src/main/java/commands/Eq.java index 0661da5..c2d3127 100644 --- a/shell/src/main/java/commands/Eq.java +++ b/shell/src/main/java/commands/Eq.java @@ -1,5 +1,6 @@ package commands; +import exceptions.CommandExecutionException; import shell.Command; import shell.Environment; import shell.Stream; @@ -16,7 +17,7 @@ public Eq(List args, Environment env) { } @Override - public Stream run(Stream ignored) { + public Stream run(Stream ignored) throws CommandExecutionException { String var = args.get(0); String val = args.get(1); env.put(var, val); diff --git a/shell/src/main/java/commands/Exit.java b/shell/src/main/java/commands/Exit.java index 31aa230..0123e00 100644 --- a/shell/src/main/java/commands/Exit.java +++ b/shell/src/main/java/commands/Exit.java @@ -1,5 +1,6 @@ package commands; +import exceptions.CommandExecutionException; import shell.Command; import shell.Environment; import shell.Stream; @@ -18,7 +19,7 @@ public Exit(List args, Environment env) { } @Override - public Stream run(Stream stream) { + public Stream run(Stream stream) throws CommandExecutionException { System.exit(0); return null; } diff --git a/shell/src/main/java/commands/OutSource.java b/shell/src/main/java/commands/OutSource.java index 193e2fa..6e30db1 100644 --- a/shell/src/main/java/commands/OutSource.java +++ b/shell/src/main/java/commands/OutSource.java @@ -1,5 +1,6 @@ package commands; +import exceptions.CommandExecutionException; import shell.Command; import shell.Environment; import shell.Stream; @@ -21,7 +22,7 @@ public OutSource(String commandName, List args, Environment env) { } @Override - public Stream run(Stream stream) { + public Stream run(Stream stream) throws CommandExecutionException { String command = commandName + " " + args.stream().collect(Collectors.joining(" ")); Stream output = new Stream(); try { @@ -29,17 +30,17 @@ public Stream run(Stream stream) { write(process, stream); output = read(process); } catch (IOException | InterruptedException e) { - e.printStackTrace(); + throw new CommandExecutionException("System error: " + e.toString()); } return output; } private void write(Process process, Stream stream) throws IOException { Writer handle = new PrintWriter(process.getOutputStream()); - final int LINE_FEED = 10; + final int lineFeed = 10; while (stream.hasNext()) { handle.write(stream.read()); - handle.write(LINE_FEED); + handle.write(lineFeed); } handle.close(); } diff --git a/shell/src/main/java/commands/Pwd.java b/shell/src/main/java/commands/Pwd.java index 4d66b04..6f940ad 100644 --- a/shell/src/main/java/commands/Pwd.java +++ b/shell/src/main/java/commands/Pwd.java @@ -1,5 +1,6 @@ package commands; +import exceptions.CommandExecutionException; import shell.Command; import shell.Environment; import shell.Stream; @@ -20,7 +21,7 @@ public Pwd(List args, Environment env) { } @Override - public Stream run(Stream ignored) { + public Stream run(Stream ignored) throws CommandExecutionException { Path currentRelativePath = Paths.get(""); String currentDir = currentRelativePath.toAbsolutePath().toString(); Stream stream = new Stream(); diff --git a/shell/src/main/java/commands/Wc.java b/shell/src/main/java/commands/Wc.java index 5c6d2f5..ba545a8 100644 --- a/shell/src/main/java/commands/Wc.java +++ b/shell/src/main/java/commands/Wc.java @@ -1,5 +1,6 @@ package commands; +import exceptions.CommandExecutionException; import shell.Command; import shell.Environment; import shell.Stream; @@ -26,7 +27,7 @@ public Wc(List args, Environment env) { } @Override - public Stream run(Stream stream) { + public Stream run(Stream stream) throws CommandExecutionException { if (!args.isEmpty()) { return handleFile(); } else if (stream.hasNext()) { diff --git a/shell/src/main/java/exceptions/CommandExecutionException.java b/shell/src/main/java/exceptions/CommandExecutionException.java new file mode 100644 index 0000000..fc1e1e7 --- /dev/null +++ b/shell/src/main/java/exceptions/CommandExecutionException.java @@ -0,0 +1,10 @@ +package exceptions; + +/** + * This is used when errors while commands execution encountered + */ +public class CommandExecutionException extends ShellException { + public CommandExecutionException(String what) { + super(what); + } +} diff --git a/shell/src/main/java/exceptions/ParserException.java b/shell/src/main/java/exceptions/ParserException.java new file mode 100644 index 0000000..8905ef8 --- /dev/null +++ b/shell/src/main/java/exceptions/ParserException.java @@ -0,0 +1,11 @@ +package exceptions; + + +/** + * This is thrown when command has incorrect syntax + */ +public class ParserException extends ShellException { + public ParserException(String what) { + super(what); + } +} diff --git a/shell/src/main/java/exceptions/ShellException.java b/shell/src/main/java/exceptions/ShellException.java new file mode 100644 index 0000000..ccf8203 --- /dev/null +++ b/shell/src/main/java/exceptions/ShellException.java @@ -0,0 +1,17 @@ +package exceptions; + + +/** + * Base class for shell exceptions + */ +public class ShellException extends Exception { + private String what = ""; + public ShellException(String what) { + this.what = what; + } + + @Override + public String toString() { + return what; + } +} diff --git a/shell/src/main/java/shell/Command.java b/shell/src/main/java/shell/Command.java index 07c30b1..cf0c8f9 100644 --- a/shell/src/main/java/shell/Command.java +++ b/shell/src/main/java/shell/Command.java @@ -1,5 +1,7 @@ package shell; +import exceptions.CommandExecutionException; + import java.util.List; /** @@ -27,5 +29,5 @@ public Command(List args, Environment env) { * @param stream * @return result data as a Stream object */ - public abstract Stream run(Stream stream); + public abstract Stream run(Stream stream) throws CommandExecutionException; } diff --git a/shell/src/main/java/shell/CommandExecutor.java b/shell/src/main/java/shell/CommandExecutor.java index bf9dcf3..ed14ae6 100644 --- a/shell/src/main/java/shell/CommandExecutor.java +++ b/shell/src/main/java/shell/CommandExecutor.java @@ -1,5 +1,7 @@ package shell; +import exceptions.CommandExecutionException; + import java.util.List; @@ -18,9 +20,14 @@ private CommandExecutor() {} */ public static Stream run(List commands) { Stream stream = new Stream(); - for (Command command : commands) { - stream = command.run(stream); - } + try { + for (Command command : commands) { + stream = command.run(stream); + } + } catch (CommandExecutionException e) { + System.out.println(e.toString()); + return new Stream(); + } return stream; } } diff --git a/shell/src/main/java/shell/Parser.java b/shell/src/main/java/shell/Parser.java index c8ab817..57ad608 100644 --- a/shell/src/main/java/shell/Parser.java +++ b/shell/src/main/java/shell/Parser.java @@ -1,5 +1,7 @@ package shell; +import exceptions.ParserException; + import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; @@ -28,24 +30,27 @@ private Parser(List tokens, Environment env) { * @return List of generated commands */ public static List run(List tokens, Environment env) { - - Parser parser = new Parser(tokens, env); - parser.start(); - return parser.commands; - + try { + Parser parser = new Parser(tokens, env); + parser.start(); + return parser.commands; + } catch (ParserException e) { + System.out.println(e.toString()); + return new ArrayList<>(); + } } - private void start() { + private void start() throws ParserException { Token token = queue.poll(); if (token.getType() == Token.Type.WORD) { parseCommand(token); } else { - error(); + error("Expression must start with a command"); } } - private void parseCommand(Token firstWord) { + private void parseCommand(Token firstWord) throws ParserException { Token token = queue.poll(); switch (token.getType()) { case EQ: @@ -64,17 +69,17 @@ private void parseCommand(Token firstWord) { createCommand(firstWord, new ArrayList<>()); break; default: - error(); + error("Unexpected token"); break; } } - private void createCommand(Token commandToken, List args) { + private void createCommand(Token commandToken, List args) throws ParserException { Command command = CommandFactory.produce(commandToken, args, env); commands.add(command); } - private void parseEQ(Token var) { + private void parseEQ(Token var) throws ParserException { Token val = queue.poll(); switch (val.getType()) { case WORD: @@ -85,19 +90,19 @@ private void parseEQ(Token var) { createCommand(Token.eq(), args); break; default: - error(); + error("Violated syntax of assignment operator"); break; } } - private void checkEQSyntax() { + private void checkEQSyntax() throws ParserException { Token token = queue.poll(); if (token.getType() != Token.Type.EOF) { - error(); + error("Violated syntax of assignment operator"); } } - private void parseArg(Token command, List args) { + private void parseArg(Token command, List args) throws ParserException { Token token = queue.poll(); switch (token.getType()) { case WORD: @@ -112,11 +117,13 @@ private void parseArg(Token command, List args) { createCommand(command, args); break; default: - error(); + error("Violated syntax of argument list"); break; } } - private void error() {} + private void error(String what) throws ParserException { + throw new ParserException(what); + } } diff --git a/shell/src/test/java/ParserTests.java b/shell/src/test/java/ParserTests.java index 6e438af..617658d 100644 --- a/shell/src/test/java/ParserTests.java +++ b/shell/src/test/java/ParserTests.java @@ -1,3 +1,4 @@ +import exceptions.CommandExecutionException; import org.junit.Test; import shell.*; @@ -13,7 +14,11 @@ public void smokeTest() { String input = "hello=hacked"; List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - commands.get(0).run(new Stream()); + try { + commands.get(0).run(new Stream()); + } catch (CommandExecutionException e) { + e.printStackTrace(); + } assertEquals("hacked", Preprocessor.run("$hello", env)); } @@ -23,7 +28,11 @@ public void reduceTest() { String input = "hello='hacked = | azazazazaa'"; List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - commands.get(0).run(new Stream()); + try { + commands.get(0).run(new Stream()); + } catch (CommandExecutionException e) { + e.printStackTrace(); + } assertEquals("hacked = | azazazazaa", Preprocessor.run("$hello", env)); } @@ -34,7 +43,11 @@ public void reduceWithSubstitutionTest() { input = Preprocessor.run(input, env); List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - commands.get(0).run(new Stream()); + try { + commands.get(0).run(new Stream()); + } catch (CommandExecutionException e) { + e.printStackTrace(); + } assertEquals("hacked putin", Preprocessor.run("$hello", env)); } @@ -45,7 +58,11 @@ public void recursiveReduceWithSubstitutionTest() { input = Preprocessor.run(input, env); List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - commands.get(0).run(new Stream()); + try { + commands.get(0).run(new Stream()); + } catch (CommandExecutionException e) { + e.printStackTrace(); + } assertEquals("hacked world", Preprocessor.run("$hello", env)); } From bae7b44e1c2a976ce8ce4197f04ad7dc20a9c446 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Tue, 7 Mar 2017 14:17:57 +0300 Subject: [PATCH 06/63] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 266fc9b..eff4d63 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ###Command line utility similar to Unix shell. -Supported features: +####Supported features: * echo command * cat command @@ -14,13 +14,14 @@ Supported features: * environment variables * unknown commands are passed to system shell as separate process through Java.Process library. -###Class diagram +####Class diagram ![shell class diagram](https://www.gliffy.com/go/share/image/smx5dub0j39jxied850w.png?utm_medium=live-embed&utm_source=custom) - Data flow: +####Data flow: * Main: run Shell object. * Shell: Read line from System.in. -   * Preprocessor: Substitute environment variables in input string. E. g. "Hello, $name" -> "Hello, Alex" +   + * Preprocessor: Substitute environment variables in input string. E. g. "Hello, $name" -> "Hello, Alex" * Tokeniser: Split string into a list of tokens: words and operators. * Parser: Parse list of tokens as sequence of commands divided by pipes. * Command Executor: Perform chained computation passing output of one comand as input to the next one. From cf1f13b0d1e496216bcac3b13549205433b3a23e Mon Sep 17 00:00:00 2001 From: simiyutin Date: Tue, 7 Mar 2017 14:18:20 +0300 Subject: [PATCH 07/63] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eff4d63..d02f125 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ * environment variables * unknown commands are passed to system shell as separate process through Java.Process library. -####Class diagram +####Class diagram: ![shell class diagram](https://www.gliffy.com/go/share/image/smx5dub0j39jxied850w.png?utm_medium=live-embed&utm_source=custom) ####Data flow: From 87259a60c2ae3f301981a83374cef7fb5572e634 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Wed, 8 Mar 2017 23:07:01 +0300 Subject: [PATCH 08/63] grep command added --- shell/build.gradle | 4 + shell/src/main/java/commands/Grep.java | 116 ++++++++++++++++++ shell/src/main/java/shell/CommandFactory.java | 3 + 3 files changed, 123 insertions(+) create mode 100644 shell/src/main/java/commands/Grep.java diff --git a/shell/build.gradle b/shell/build.gradle index 1620193..95758ca 100644 --- a/shell/build.gradle +++ b/shell/build.gradle @@ -17,4 +17,8 @@ run{ dependencies { testCompile group: 'junit', name: 'junit', version: '4.11' + + // https://mvnrepository.com/artifact/commons-cli/commons-cli + compile group: 'commons-cli', name: 'commons-cli', version: '1.2' + } diff --git a/shell/src/main/java/commands/Grep.java b/shell/src/main/java/commands/Grep.java new file mode 100644 index 0000000..961ea32 --- /dev/null +++ b/shell/src/main/java/commands/Grep.java @@ -0,0 +1,116 @@ +package commands; + +import exceptions.CommandExecutionException; +import org.apache.commons.cli.*; +import shell.Command; +import shell.Environment; +import shell.Stream; + +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Grep extends Command { + + public static final String NAME = "grep"; + + private boolean isInsensitive = false; + private boolean isFullWord = false; + private int linesAfterMatch = 0; + + public Grep(List args, Environment env) { + super(args, env); + } + + @Override + public Stream run(Stream stream) throws CommandExecutionException { + + Options options = new Options(); + options.addOption("i", false, "case insensitivity"); + options.addOption("w", false, "full word search"); + options.addOption("A", true, "number of lines to append after match"); + CommandLine cmd = parseArgs(options); + + isInsensitive = cmd.hasOption('i'); + isFullWord = cmd.hasOption('w'); + try { + String a = cmd.getOptionValue('A'); + linesAfterMatch = a == null ? 0 : Integer.valueOf(a); + return grep(stream, cmd.getArgs()); + } catch (NumberFormatException e) { + throw new CommandExecutionException("grep: incorrect '-A' value, required number"); + } + } + + private Stream grep(Stream stream, String[] args) throws CommandExecutionException { + + if (args.length == 0) { + throw new CommandExecutionException("grep: pattern must be provided"); + } else if (args.length > 1) { + String pattern = args[0]; + String fileName = args[1]; + Stream fileStream = new Cat(Collections.singletonList(fileName), new Environment()).run(new Stream()); + return grepFromStream(pattern, fileStream); + } else { + String pattern = args[0]; + return grepFromStream(pattern, stream); + } + } + + private Stream grepFromStream(String regex, Stream input) { + + Stream output = new Stream(); + + if (isFullWord) { + regex = String.format("\\b%s\\b", regex); + } + + if (isInsensitive) { + regex = "(?i)" + regex; + } + + Pattern pattern = Pattern.compile("(" + regex + ")"); + + while (input.hasNext()) { + String line = input.read(); + Matcher m = pattern.matcher(line); + if (m.find()) { + String replaced = m.replaceAll(colorize("$1")); + output.write(replaced); + appendN(input, output, linesAfterMatch); + } + } + + return output; + } + + private void appendN(Stream input, Stream output, int n) { + for (int i = 0; i < n; i++) { + if (input.hasNext()) { + output.write(input.read()); + } else { + break; + } + } + } + + private String colorize(String string) { + final int esc = 27; + final String csi = (char) esc + "["; + final String redModifier = "31m"; + final String resetModifier = "0m"; + return csi + redModifier + string + csi + resetModifier; + } + + private CommandLine parseArgs(Options options) throws CommandExecutionException { + CommandLineParser parser = new PosixParser(); + try { + String[] arr = new String[0]; + CommandLine cmd = parser.parse(options, args.toArray(arr)); + return cmd; + } catch (ParseException e) { + throw new CommandExecutionException("grep: wrong arguments"); + } + } +} diff --git a/shell/src/main/java/shell/CommandFactory.java b/shell/src/main/java/shell/CommandFactory.java index 3e75950..2f0d6ef 100644 --- a/shell/src/main/java/shell/CommandFactory.java +++ b/shell/src/main/java/shell/CommandFactory.java @@ -49,6 +49,9 @@ private static Command getCommand(String commandName, List args, Environ case Pwd.NAME: command = new Pwd(args, env); break; + case Grep.NAME: + command = new Grep(args, env); + break; case Exit.NAME: command = new Exit(args, env); break; From 209ea7f5f619e13c8b138b9fa23be87a7aca54bc Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 11 Mar 2017 17:37:02 +0300 Subject: [PATCH 09/63] tests --- shell/src/test/java/GrepTests.java | 134 +++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 shell/src/test/java/GrepTests.java diff --git a/shell/src/test/java/GrepTests.java b/shell/src/test/java/GrepTests.java new file mode 100644 index 0000000..4c409fb --- /dev/null +++ b/shell/src/test/java/GrepTests.java @@ -0,0 +1,134 @@ +import exceptions.CommandExecutionException; +import org.junit.Test; +import shell.*; + +import java.util.List; + +import static junit.framework.TestCase.assertEquals; + +public class GrepTests { + + @Test + public void smokeTest() { + + String input = "echo 'hello world' | grep hello"; + String expected = colorize("hello") + " world"; + testTemplate(input, expected); + + } + + @Test + public void noMatchTest() { + + String input = "echo 'hello world' | grep noMatch"; + String expected = ""; + testTemplate(input, expected); + + } + + @Test + public void insensitivityTest() { + + String input = "echo 'hello world' | grep -i HELLO"; + String expected = colorize("hello") + " world"; + testTemplate(input, expected); + + } + + @Test + public void wholeWordTest() { + + String input = "echo 'hello hell.' | grep -w hell"; + String expected = "hello " + colorize("hell") + "."; + testTemplate(input, expected); + + } + + @Test + public void linesAfterTest() throws CommandExecutionException { + + Stream input = new Stream(); + input.write("hello"); + input.write("1"); + input.write("2"); + input.write("3"); + input.write("4"); + input.write("5"); + input.write("6"); + input.write("7"); + input.write("8"); + input.write("9"); + + String command = "grep -A 3 hello"; + + List tokens = Tokenizer.run(command); + List commands = Parser.run(tokens, new Environment()); + Stream output = commands.get(0).run(input); + + Stream expected = new Stream(); + expected.write(colorize("hello")); + expected.write("1"); + expected.write("2"); + expected.write("3"); + + assertEquals(expected.toString(), output.toString()); + + } + + @Test + public void overflowLinesTest() throws CommandExecutionException { + + Stream input = new Stream(); + input.write("hello"); + input.write("1"); + input.write("2"); + input.write("3"); + + String command = "grep -A 10 hello"; + + List tokens = Tokenizer.run(command); + List commands = Parser.run(tokens, new Environment()); + Stream output = commands.get(0).run(input); + + Stream expected = new Stream(); + expected.write(colorize("hello")); + expected.write("1"); + expected.write("2"); + expected.write("3"); + + assertEquals(expected.toString(), output.toString()); + + } + + @Test + public void multipleMatchTest() { + + String input = "echo 'hello hell' | grep hell"; + String expected = String.format("%so %s", colorize("hell"), colorize("hell")); + testTemplate(input, expected); + + } + + + private Stream interpret(String input) { + Environment env = new Environment(); + List tokens = Tokenizer.run(input); + List commands = Parser.run(tokens, env); + Stream output = CommandExecutor.run(commands); + return output; + } + + private void testTemplate(String input, String expected) { + Stream output = interpret(input); + String actual = output.toString(); + assertEquals(expected, actual); + } + + private String colorize(String string) { + final int esc = 27; + final String csi = (char) esc + "["; + final String redModifier = "31m"; + final String resetModifier = "0m"; + return csi + redModifier + string + csi + resetModifier; + } +} From 57caaa3c7696b1c3dee10811a56bb55842d0136f Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 11 Mar 2017 17:38:36 +0300 Subject: [PATCH 10/63] comments --- shell/src/main/java/commands/Grep.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shell/src/main/java/commands/Grep.java b/shell/src/main/java/commands/Grep.java index 961ea32..27eb6fe 100644 --- a/shell/src/main/java/commands/Grep.java +++ b/shell/src/main/java/commands/Grep.java @@ -11,6 +11,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * Searches in input stream or file using regular expressions. + */ public class Grep extends Command { public static final String NAME = "grep"; From 2dcc5354ac3f7e9506e5112424e15406448c97e9 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 11 Mar 2017 18:40:50 +0300 Subject: [PATCH 11/63] Update README.md --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 266fc9b..1032283 100644 --- a/README.md +++ b/README.md @@ -25,3 +25,19 @@ Supported features: * Parser: Parse list of tokens as sequence of commands divided by pipes. * Command Executor: Perform chained computation passing output of one comand as input to the next one. * Pass result to System.in and loop again. + + +##2. Grep +###Command similar to UNIX grep utility. + +####Supports: +* Reading from standard input or from file. +* Parameters: + * -i: case insensivity. + * -w: whole words search. + * -A %number%: Number of lines to add to output after each matched line. + +####Implementation: +* For regular expressions java.util.regex package is used. + +* For parsing command line arguments Apache Commons CLI library was chosen, because it is pretty easy to use and fits our requirements very well. Other libraries like JCommander and args4j were considered as an option, but were rejected as a little overkill at this point. If number of arguments will grow seriously, it may be reasonable to switch to one of these libraries, because of usage of annotations for introducing parameters. From 26a50788a5fb37c2d1cc1565bbed275ea03da1ef Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 11 Mar 2017 22:57:22 +0300 Subject: [PATCH 12/63] fixes --- shell/src/main/java/shell/Command.java | 4 +-- shell/src/main/java/shell/CommandFactory.java | 5 --- shell/src/main/java/shell/Shell.java | 2 +- shell/src/main/java/shell/Token.java | 11 +++---- shell/src/test/java/ParserTests.java | 32 +++++-------------- 5 files changed, 16 insertions(+), 38 deletions(-) diff --git a/shell/src/main/java/shell/Command.java b/shell/src/main/java/shell/Command.java index cf0c8f9..983fc2e 100644 --- a/shell/src/main/java/shell/Command.java +++ b/shell/src/main/java/shell/Command.java @@ -26,8 +26,8 @@ public Command(List args, Environment env) { /** * Used as interface to command object. Takes input stream and returns result as output stream. - * @param stream - * @return result data as a Stream object + * @param stream input data as a Stream object + * @return output data as a Stream object */ public abstract Stream run(Stream stream) throws CommandExecutionException; } diff --git a/shell/src/main/java/shell/CommandFactory.java b/shell/src/main/java/shell/CommandFactory.java index 3e75950..553b6dc 100644 --- a/shell/src/main/java/shell/CommandFactory.java +++ b/shell/src/main/java/shell/CommandFactory.java @@ -59,9 +59,4 @@ private static Command getCommand(String commandName, List args, Environ } return command; } - - private static String concat(List args) { - - return args.stream().collect(Collectors.joining()); - } } diff --git a/shell/src/main/java/shell/Shell.java b/shell/src/main/java/shell/Shell.java index 739d030..ef681d2 100644 --- a/shell/src/main/java/shell/Shell.java +++ b/shell/src/main/java/shell/Shell.java @@ -14,7 +14,7 @@ public class Shell { /** * constructs Shell with empty environment */ - Shell() { + public Shell() { env = new Environment(); } diff --git a/shell/src/main/java/shell/Token.java b/shell/src/main/java/shell/Token.java index c4583c4..1ddd76f 100644 --- a/shell/src/main/java/shell/Token.java +++ b/shell/src/main/java/shell/Token.java @@ -3,7 +3,7 @@ import java.util.ArrayList; /** - * Describes possible lexems + * Describes possible lexemes */ public class Token { @@ -77,7 +77,7 @@ public static Token pipe() { /** * Static factory method - * @param word + * @param word string to encapsulate in newly created token * @return new word token */ public static Token word(String word) { @@ -94,9 +94,8 @@ public static Token eof() { /** - * Test if given char corresponds to somme delimiter token - * @param c - * @return tests if passed char can be a delimiter between words + * Tests if given char corresponds to any delimiter token + * @param c character to test */ public static boolean isDelimiter(char c) { ArrayList test = new ArrayList<>(); @@ -110,7 +109,7 @@ public static boolean isDelimiter(char c) { /** * Static factory method - * @param c + * @param c character to get corresponding token * @return generate corresponding token to passed char */ public static Token valueOf(char c) { diff --git a/shell/src/test/java/ParserTests.java b/shell/src/test/java/ParserTests.java index 617658d..5ebf524 100644 --- a/shell/src/test/java/ParserTests.java +++ b/shell/src/test/java/ParserTests.java @@ -9,60 +9,44 @@ public class ParserTests { @Test - public void smokeTest() { + public void smokeTest() throws Exception { Environment env = getEnv(); String input = "hello=hacked"; List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - try { - commands.get(0).run(new Stream()); - } catch (CommandExecutionException e) { - e.printStackTrace(); - } + commands.get(0).run(new Stream()); assertEquals("hacked", Preprocessor.run("$hello", env)); } @Test - public void reduceTest() { + public void reduceTest() throws Exception { Environment env = getEnv(); String input = "hello='hacked = | azazazazaa'"; List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - try { - commands.get(0).run(new Stream()); - } catch (CommandExecutionException e) { - e.printStackTrace(); - } + commands.get(0).run(new Stream()); assertEquals("hacked = | azazazazaa", Preprocessor.run("$hello", env)); } @Test - public void reduceWithSubstitutionTest() { + public void reduceWithSubstitutionTest() throws Exception { Environment env = getEnv(); String input = "hello=\"hacked $vladimir\""; input = Preprocessor.run(input, env); List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - try { - commands.get(0).run(new Stream()); - } catch (CommandExecutionException e) { - e.printStackTrace(); - } + commands.get(0).run(new Stream()); assertEquals("hacked putin", Preprocessor.run("$hello", env)); } @Test - public void recursiveReduceWithSubstitutionTest() { + public void recursiveReduceWithSubstitutionTest() throws Exception { Environment env = getEnv(); String input = "hello=\"hacked $hello\""; input = Preprocessor.run(input, env); List tokens = Tokenizer.run(input); List commands = Parser.run(tokens, env); - try { - commands.get(0).run(new Stream()); - } catch (CommandExecutionException e) { - e.printStackTrace(); - } + commands.get(0).run(new Stream()); assertEquals("hacked world", Preprocessor.run("$hello", env)); } From 1879ced96c0c26b3caba1b9060e42f494b1ff3fa Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 11 Mar 2017 23:18:40 +0300 Subject: [PATCH 13/63] reversed domain name packages --- shell/build.gradle | 2 +- .../{ => com/simiyutin/au/shell}/commands/Cat.java | 10 +++++----- .../{ => com/simiyutin/au/shell}/commands/Echo.java | 10 +++++----- .../java/{ => com/simiyutin/au/shell}/commands/Eq.java | 10 +++++----- .../{ => com/simiyutin/au/shell}/commands/Exit.java | 10 +++++----- .../simiyutin/au/shell}/commands/OutSource.java | 10 +++++----- .../{ => com/simiyutin/au/shell}/commands/Pwd.java | 10 +++++----- .../java/{ => com/simiyutin/au/shell}/commands/Wc.java | 10 +++++----- .../simiyutin/au/shell/core}/Command.java | 4 ++-- .../simiyutin/au/shell/core}/CommandExecutor.java | 4 ++-- .../simiyutin/au/shell/core}/CommandFactory.java | 5 ++--- .../simiyutin/au/shell/core}/Environment.java | 2 +- .../{shell => com/simiyutin/au/shell/core}/Main.java | 2 +- .../{shell => com/simiyutin/au/shell/core}/Parser.java | 4 ++-- .../simiyutin/au/shell/core}/Preprocessor.java | 2 +- .../{shell => com/simiyutin/au/shell/core}/Shell.java | 2 +- .../{shell => com/simiyutin/au/shell/core}/Stream.java | 2 +- .../{shell => com/simiyutin/au/shell/core}/Token.java | 2 +- .../simiyutin/au/shell/core}/Tokenizer.java | 2 +- .../core}/exceptions/CommandExecutionException.java | 2 +- .../au/shell/core}/exceptions/ParserException.java | 2 +- .../au/shell/core}/exceptions/ShellException.java | 2 +- .../java/{ => com/simiyutin/au/shell}/ParserTests.java | 5 +++-- .../simiyutin/au/shell}/PreprocessorTests.java | 6 ++++-- .../{ => com/simiyutin/au/shell}/TokenizerTests.java | 6 ++++-- 25 files changed, 65 insertions(+), 61 deletions(-) rename shell/src/main/java/{ => com/simiyutin/au/shell}/commands/Cat.java (84%) rename shell/src/main/java/{ => com/simiyutin/au/shell}/commands/Echo.java (68%) rename shell/src/main/java/{ => com/simiyutin/au/shell}/commands/Eq.java (63%) rename shell/src/main/java/{ => com/simiyutin/au/shell}/commands/Exit.java (59%) rename shell/src/main/java/{ => com/simiyutin/au/shell}/commands/OutSource.java (87%) rename shell/src/main/java/{ => com/simiyutin/au/shell}/commands/Pwd.java (70%) rename shell/src/main/java/{ => com/simiyutin/au/shell}/commands/Wc.java (90%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Command.java (88%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/CommandExecutor.java (88%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/CommandFactory.java (95%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Environment.java (96%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Main.java (77%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Parser.java (97%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Preprocessor.java (98%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Shell.java (95%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Stream.java (97%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Token.java (99%) rename shell/src/main/java/{shell => com/simiyutin/au/shell/core}/Tokenizer.java (98%) rename shell/src/main/java/{ => com/simiyutin/au/shell/core}/exceptions/CommandExecutionException.java (82%) rename shell/src/main/java/{ => com/simiyutin/au/shell/core}/exceptions/ParserException.java (79%) rename shell/src/main/java/{ => com/simiyutin/au/shell/core}/exceptions/ShellException.java (84%) rename shell/src/test/java/{ => com/simiyutin/au/shell}/ParserTests.java (97%) rename shell/src/test/java/{ => com/simiyutin/au/shell}/PreprocessorTests.java (92%) rename shell/src/test/java/{ => com/simiyutin/au/shell}/TokenizerTests.java (93%) diff --git a/shell/build.gradle b/shell/build.gradle index 1620193..5247b51 100644 --- a/shell/build.gradle +++ b/shell/build.gradle @@ -3,7 +3,7 @@ version '1.0-SNAPSHOT' apply plugin: 'java' apply plugin: 'application' -mainClassName = "shell.Main" +mainClassName = "com.simiyutin.au.shell.core.Main" sourceCompatibility = 1.8 diff --git a/shell/src/main/java/commands/Cat.java b/shell/src/main/java/com/simiyutin/au/shell/commands/Cat.java similarity index 84% rename from shell/src/main/java/commands/Cat.java rename to shell/src/main/java/com/simiyutin/au/shell/commands/Cat.java index 3bb7021..6198516 100644 --- a/shell/src/main/java/commands/Cat.java +++ b/shell/src/main/java/com/simiyutin/au/shell/commands/Cat.java @@ -1,9 +1,9 @@ -package commands; +package com.simiyutin.au.shell.commands; -import exceptions.CommandExecutionException; -import shell.Command; -import shell.Environment; -import shell.Stream; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.Command; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Stream; import java.io.IOException; import java.nio.charset.MalformedInputException; diff --git a/shell/src/main/java/commands/Echo.java b/shell/src/main/java/com/simiyutin/au/shell/commands/Echo.java similarity index 68% rename from shell/src/main/java/commands/Echo.java rename to shell/src/main/java/com/simiyutin/au/shell/commands/Echo.java index 1ff5827..80487d5 100644 --- a/shell/src/main/java/commands/Echo.java +++ b/shell/src/main/java/com/simiyutin/au/shell/commands/Echo.java @@ -1,9 +1,9 @@ -package commands; +package com.simiyutin.au.shell.commands; -import exceptions.CommandExecutionException; -import shell.Command; -import shell.Environment; -import shell.Stream; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.Command; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Stream; import java.util.List; import java.util.stream.Collectors; diff --git a/shell/src/main/java/commands/Eq.java b/shell/src/main/java/com/simiyutin/au/shell/commands/Eq.java similarity index 63% rename from shell/src/main/java/commands/Eq.java rename to shell/src/main/java/com/simiyutin/au/shell/commands/Eq.java index c2d3127..e088b7d 100644 --- a/shell/src/main/java/commands/Eq.java +++ b/shell/src/main/java/com/simiyutin/au/shell/commands/Eq.java @@ -1,9 +1,9 @@ -package commands; +package com.simiyutin.au.shell.commands; -import exceptions.CommandExecutionException; -import shell.Command; -import shell.Environment; -import shell.Stream; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.Command; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Stream; import java.util.List; diff --git a/shell/src/main/java/commands/Exit.java b/shell/src/main/java/com/simiyutin/au/shell/commands/Exit.java similarity index 59% rename from shell/src/main/java/commands/Exit.java rename to shell/src/main/java/com/simiyutin/au/shell/commands/Exit.java index 0123e00..8a9d4e9 100644 --- a/shell/src/main/java/commands/Exit.java +++ b/shell/src/main/java/com/simiyutin/au/shell/commands/Exit.java @@ -1,9 +1,9 @@ -package commands; +package com.simiyutin.au.shell.commands; -import exceptions.CommandExecutionException; -import shell.Command; -import shell.Environment; -import shell.Stream; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.Command; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Stream; import java.util.List; diff --git a/shell/src/main/java/commands/OutSource.java b/shell/src/main/java/com/simiyutin/au/shell/commands/OutSource.java similarity index 87% rename from shell/src/main/java/commands/OutSource.java rename to shell/src/main/java/com/simiyutin/au/shell/commands/OutSource.java index 6e30db1..2e369ef 100644 --- a/shell/src/main/java/commands/OutSource.java +++ b/shell/src/main/java/com/simiyutin/au/shell/commands/OutSource.java @@ -1,9 +1,9 @@ -package commands; +package com.simiyutin.au.shell.commands; -import exceptions.CommandExecutionException; -import shell.Command; -import shell.Environment; -import shell.Stream; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.Command; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Stream; import java.io.*; import java.util.List; diff --git a/shell/src/main/java/commands/Pwd.java b/shell/src/main/java/com/simiyutin/au/shell/commands/Pwd.java similarity index 70% rename from shell/src/main/java/commands/Pwd.java rename to shell/src/main/java/com/simiyutin/au/shell/commands/Pwd.java index 6f940ad..d802de4 100644 --- a/shell/src/main/java/commands/Pwd.java +++ b/shell/src/main/java/com/simiyutin/au/shell/commands/Pwd.java @@ -1,9 +1,9 @@ -package commands; +package com.simiyutin.au.shell.commands; -import exceptions.CommandExecutionException; -import shell.Command; -import shell.Environment; -import shell.Stream; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.Command; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Stream; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/shell/src/main/java/commands/Wc.java b/shell/src/main/java/com/simiyutin/au/shell/commands/Wc.java similarity index 90% rename from shell/src/main/java/commands/Wc.java rename to shell/src/main/java/com/simiyutin/au/shell/commands/Wc.java index ba545a8..f2e9222 100644 --- a/shell/src/main/java/commands/Wc.java +++ b/shell/src/main/java/com/simiyutin/au/shell/commands/Wc.java @@ -1,9 +1,9 @@ -package commands; +package com.simiyutin.au.shell.commands; -import exceptions.CommandExecutionException; -import shell.Command; -import shell.Environment; -import shell.Stream; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.Command; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Stream; import java.io.IOException; import java.nio.file.Files; diff --git a/shell/src/main/java/shell/Command.java b/shell/src/main/java/com/simiyutin/au/shell/core/Command.java similarity index 88% rename from shell/src/main/java/shell/Command.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Command.java index 983fc2e..76190ac 100644 --- a/shell/src/main/java/shell/Command.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Command.java @@ -1,6 +1,6 @@ -package shell; +package com.simiyutin.au.shell.core; -import exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; import java.util.List; diff --git a/shell/src/main/java/shell/CommandExecutor.java b/shell/src/main/java/com/simiyutin/au/shell/core/CommandExecutor.java similarity index 88% rename from shell/src/main/java/shell/CommandExecutor.java rename to shell/src/main/java/com/simiyutin/au/shell/core/CommandExecutor.java index ed14ae6..d6d7d73 100644 --- a/shell/src/main/java/shell/CommandExecutor.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/CommandExecutor.java @@ -1,6 +1,6 @@ -package shell; +package com.simiyutin.au.shell.core; -import exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; import java.util.List; diff --git a/shell/src/main/java/shell/CommandFactory.java b/shell/src/main/java/com/simiyutin/au/shell/core/CommandFactory.java similarity index 95% rename from shell/src/main/java/shell/CommandFactory.java rename to shell/src/main/java/com/simiyutin/au/shell/core/CommandFactory.java index 553b6dc..0f70efa 100644 --- a/shell/src/main/java/shell/CommandFactory.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/CommandFactory.java @@ -1,9 +1,8 @@ -package shell; +package com.simiyutin.au.shell.core; -import commands.*; +import com.simiyutin.au.shell.commands.*; import java.util.List; -import java.util.stream.Collectors; /** diff --git a/shell/src/main/java/shell/Environment.java b/shell/src/main/java/com/simiyutin/au/shell/core/Environment.java similarity index 96% rename from shell/src/main/java/shell/Environment.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Environment.java index 7562aa4..37dcc9c 100644 --- a/shell/src/main/java/shell/Environment.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Environment.java @@ -1,4 +1,4 @@ -package shell; +package com.simiyutin.au.shell.core; import java.util.HashMap; import java.util.Map; diff --git a/shell/src/main/java/shell/Main.java b/shell/src/main/java/com/simiyutin/au/shell/core/Main.java similarity index 77% rename from shell/src/main/java/shell/Main.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Main.java index 56e8108..b22e91e 100644 --- a/shell/src/main/java/shell/Main.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Main.java @@ -1,4 +1,4 @@ -package shell; +package com.simiyutin.au.shell.core; public class Main { public static void main(String[] args) { diff --git a/shell/src/main/java/shell/Parser.java b/shell/src/main/java/com/simiyutin/au/shell/core/Parser.java similarity index 97% rename from shell/src/main/java/shell/Parser.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Parser.java index 57ad608..1adc5ef 100644 --- a/shell/src/main/java/shell/Parser.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Parser.java @@ -1,6 +1,6 @@ -package shell; +package com.simiyutin.au.shell.core; -import exceptions.ParserException; +import com.simiyutin.au.shell.core.exceptions.ParserException; import java.util.ArrayDeque; import java.util.ArrayList; diff --git a/shell/src/main/java/shell/Preprocessor.java b/shell/src/main/java/com/simiyutin/au/shell/core/Preprocessor.java similarity index 98% rename from shell/src/main/java/shell/Preprocessor.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Preprocessor.java index e19b9c8..154e4d1 100644 --- a/shell/src/main/java/shell/Preprocessor.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Preprocessor.java @@ -1,4 +1,4 @@ -package shell; +package com.simiyutin.au.shell.core; /** * Takes care of substitution variable values in requested places diff --git a/shell/src/main/java/shell/Shell.java b/shell/src/main/java/com/simiyutin/au/shell/core/Shell.java similarity index 95% rename from shell/src/main/java/shell/Shell.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Shell.java index ef681d2..dab43d4 100644 --- a/shell/src/main/java/shell/Shell.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Shell.java @@ -1,4 +1,4 @@ -package shell; +package com.simiyutin.au.shell.core; import java.util.List; import java.util.Scanner; diff --git a/shell/src/main/java/shell/Stream.java b/shell/src/main/java/com/simiyutin/au/shell/core/Stream.java similarity index 97% rename from shell/src/main/java/shell/Stream.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Stream.java index 5a6a3f4..2873004 100644 --- a/shell/src/main/java/shell/Stream.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Stream.java @@ -1,4 +1,4 @@ -package shell; +package com.simiyutin.au.shell.core; import java.util.ArrayDeque; import java.util.Queue; diff --git a/shell/src/main/java/shell/Token.java b/shell/src/main/java/com/simiyutin/au/shell/core/Token.java similarity index 99% rename from shell/src/main/java/shell/Token.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Token.java index 1ddd76f..70defcd 100644 --- a/shell/src/main/java/shell/Token.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Token.java @@ -1,4 +1,4 @@ -package shell; +package com.simiyutin.au.shell.core; import java.util.ArrayList; diff --git a/shell/src/main/java/shell/Tokenizer.java b/shell/src/main/java/com/simiyutin/au/shell/core/Tokenizer.java similarity index 98% rename from shell/src/main/java/shell/Tokenizer.java rename to shell/src/main/java/com/simiyutin/au/shell/core/Tokenizer.java index 00f158c..d902e0f 100644 --- a/shell/src/main/java/shell/Tokenizer.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/Tokenizer.java @@ -1,4 +1,4 @@ -package shell; +package com.simiyutin.au.shell.core; import java.util.ArrayList; import java.util.List; diff --git a/shell/src/main/java/exceptions/CommandExecutionException.java b/shell/src/main/java/com/simiyutin/au/shell/core/exceptions/CommandExecutionException.java similarity index 82% rename from shell/src/main/java/exceptions/CommandExecutionException.java rename to shell/src/main/java/com/simiyutin/au/shell/core/exceptions/CommandExecutionException.java index fc1e1e7..b34eda5 100644 --- a/shell/src/main/java/exceptions/CommandExecutionException.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/exceptions/CommandExecutionException.java @@ -1,4 +1,4 @@ -package exceptions; +package com.simiyutin.au.shell.core.exceptions; /** * This is used when errors while commands execution encountered diff --git a/shell/src/main/java/exceptions/ParserException.java b/shell/src/main/java/com/simiyutin/au/shell/core/exceptions/ParserException.java similarity index 79% rename from shell/src/main/java/exceptions/ParserException.java rename to shell/src/main/java/com/simiyutin/au/shell/core/exceptions/ParserException.java index 8905ef8..c7d68a1 100644 --- a/shell/src/main/java/exceptions/ParserException.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/exceptions/ParserException.java @@ -1,4 +1,4 @@ -package exceptions; +package com.simiyutin.au.shell.core.exceptions; /** diff --git a/shell/src/main/java/exceptions/ShellException.java b/shell/src/main/java/com/simiyutin/au/shell/core/exceptions/ShellException.java similarity index 84% rename from shell/src/main/java/exceptions/ShellException.java rename to shell/src/main/java/com/simiyutin/au/shell/core/exceptions/ShellException.java index ccf8203..77003e3 100644 --- a/shell/src/main/java/exceptions/ShellException.java +++ b/shell/src/main/java/com/simiyutin/au/shell/core/exceptions/ShellException.java @@ -1,4 +1,4 @@ -package exceptions; +package com.simiyutin.au.shell.core.exceptions; /** diff --git a/shell/src/test/java/ParserTests.java b/shell/src/test/java/com/simiyutin/au/shell/ParserTests.java similarity index 97% rename from shell/src/test/java/ParserTests.java rename to shell/src/test/java/com/simiyutin/au/shell/ParserTests.java index 5ebf524..4429e8e 100644 --- a/shell/src/test/java/ParserTests.java +++ b/shell/src/test/java/com/simiyutin/au/shell/ParserTests.java @@ -1,6 +1,7 @@ -import exceptions.CommandExecutionException; +package com.simiyutin.au.shell; + import org.junit.Test; -import shell.*; +import com.simiyutin.au.shell.core.*; import java.util.List; diff --git a/shell/src/test/java/PreprocessorTests.java b/shell/src/test/java/com/simiyutin/au/shell/PreprocessorTests.java similarity index 92% rename from shell/src/test/java/PreprocessorTests.java rename to shell/src/test/java/com/simiyutin/au/shell/PreprocessorTests.java index 3ee580c..38a3f52 100644 --- a/shell/src/test/java/PreprocessorTests.java +++ b/shell/src/test/java/com/simiyutin/au/shell/PreprocessorTests.java @@ -1,6 +1,8 @@ +package com.simiyutin.au.shell; + import org.junit.Test; -import shell.Environment; -import shell.Preprocessor; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Preprocessor; import static org.junit.Assert.assertEquals; diff --git a/shell/src/test/java/TokenizerTests.java b/shell/src/test/java/com/simiyutin/au/shell/TokenizerTests.java similarity index 93% rename from shell/src/test/java/TokenizerTests.java rename to shell/src/test/java/com/simiyutin/au/shell/TokenizerTests.java index 34d6d22..f524f10 100644 --- a/shell/src/test/java/TokenizerTests.java +++ b/shell/src/test/java/com/simiyutin/au/shell/TokenizerTests.java @@ -1,6 +1,8 @@ +package com.simiyutin.au.shell; + import org.junit.Test; -import shell.Token; -import shell.Tokenizer; +import com.simiyutin.au.shell.core.Token; +import com.simiyutin.au.shell.core.Tokenizer; import java.util.ArrayList; import java.util.List; From 954103907c9d04cc331c6887096a2d5017aa5ce4 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 11 Mar 2017 23:20:15 +0300 Subject: [PATCH 14/63] .gradle folder removed --- .../.gradle/2.10/taskArtifacts/cache.properties | 1 - .../2.10/taskArtifacts/cache.properties.lock | Bin 55 -> 0 bytes shell/.gradle/2.10/taskArtifacts/fileHashes.bin | Bin 22739 -> 0 bytes .../2.10/taskArtifacts/fileSnapshots.bin | Bin 47470 -> 0 bytes .../2.10/taskArtifacts/outputFileStates.bin | Bin 18722 -> 0 bytes .../2.10/taskArtifacts/taskArtifacts.bin | Bin 31965 -> 0 bytes .../.gradle/3.1/taskArtifacts/cache.properties | 1 - .../3.1/taskArtifacts/cache.properties.lock | Bin 17 -> 0 bytes shell/.gradle/3.1/taskArtifacts/fileHashes.bin | Bin 18697 -> 0 bytes .../.gradle/3.1/taskArtifacts/fileSnapshots.bin | Bin 19105 -> 0 bytes .../.gradle/3.1/taskArtifacts/taskArtifacts.bin | Bin 19472 -> 0 bytes 11 files changed, 2 deletions(-) delete mode 100644 shell/.gradle/2.10/taskArtifacts/cache.properties delete mode 100644 shell/.gradle/2.10/taskArtifacts/cache.properties.lock delete mode 100644 shell/.gradle/2.10/taskArtifacts/fileHashes.bin delete mode 100644 shell/.gradle/2.10/taskArtifacts/fileSnapshots.bin delete mode 100644 shell/.gradle/2.10/taskArtifacts/outputFileStates.bin delete mode 100644 shell/.gradle/2.10/taskArtifacts/taskArtifacts.bin delete mode 100644 shell/.gradle/3.1/taskArtifacts/cache.properties delete mode 100644 shell/.gradle/3.1/taskArtifacts/cache.properties.lock delete mode 100644 shell/.gradle/3.1/taskArtifacts/fileHashes.bin delete mode 100644 shell/.gradle/3.1/taskArtifacts/fileSnapshots.bin delete mode 100644 shell/.gradle/3.1/taskArtifacts/taskArtifacts.bin diff --git a/shell/.gradle/2.10/taskArtifacts/cache.properties b/shell/.gradle/2.10/taskArtifacts/cache.properties deleted file mode 100644 index 34e0db3..0000000 --- a/shell/.gradle/2.10/taskArtifacts/cache.properties +++ /dev/null @@ -1 +0,0 @@ -#Sat Mar 04 19:36:05 MSK 2017 diff --git a/shell/.gradle/2.10/taskArtifacts/cache.properties.lock b/shell/.gradle/2.10/taskArtifacts/cache.properties.lock deleted file mode 100644 index 9b611430cdcf69ab3bef76113d5390143f06dff1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55 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 diff --git a/shell/.gradle/2.10/taskArtifacts/fileSnapshots.bin b/shell/.gradle/2.10/taskArtifacts/fileSnapshots.bin deleted file mode 100644 index c057143ed6e8db321cbe969015a9dd1bca8f26e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47470 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 diff --git a/shell/.gradle/2.10/taskArtifacts/outputFileStates.bin b/shell/.gradle/2.10/taskArtifacts/outputFileStates.bin deleted file mode 100644 index 9cea602cf49e1fa2c867ea47e097566963a38fb8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18722 zcmeI(yGz4R6vy$46cp(D?ouPUcZlRK(C>xI;rtE>oX;9!%?e>?b$NvM=-!qN z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009L4f`GN`Y|-p)VvIDXl{9Nth`|=8Z8U|w zIbK^Ca7WQC^(Eor{X8BIYWp&`Rc=p*Gxglmw#*+@{`orbkW3ez^+5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0;9m+@5oc}9xlKPeu&|dK zN*|3$3f()so9XB(joxnfPe1hMrNdIW*MFLPiLSn7i|UtzUvEB$)YjU~<0t=TZ~8-% Tt%=h!|7kFlS&vojvugSc+xL({ diff --git a/shell/.gradle/2.10/taskArtifacts/taskArtifacts.bin b/shell/.gradle/2.10/taskArtifacts/taskArtifacts.bin deleted file mode 100644 index 1318f3477d5fa7e82a326890e5dc812c139d9a73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31965 zcmeI4du$X%7{KT5T3)SKGzvyU(3tSL-HL!Didy@y&`M7z_!j1Fr`K)wc9+@N_KL<= zv{g_{E#+BKA`dm;4+;1J@j;0EK?Owxl~k)35wU3eLyV8$%owYJ#CP>uO6neKM( zb{@a)`)0oRX71Vw5E_+pChf00e*l5C8%|00;m9AOHk_01yBI|6u}c^LgWjxeXjO z-S4$Dr>z#D+-&}DX8ppGLpv%;*12yLhrFGHEz37dp4R!(Q8)j-VlUsn=-5wd8Zt87 z{Kda``T3ugl(oEh;`T&2Z+iKm&{{2P>9O5zK56puy{ns#mL{%n0Rlh(2mk>f00e*l z5C8%|00;m9AOHk_01yBIKmZ5;0U!VbfB+Bx0zd!=00AHX1b_e#00KY&2mk>f00e*l z5C8%|00;m9AOHmVK%ng!{-H%Y-64|i*_&DpKfgCJX7dXtfA9QoNKWOXOK8nUo$v27 zXjF<)tY}2SrYbRPRa=sx;;3#|OpRDlInS9(OoK9Ux3GXj42l_1c(KV>g{UpC5h33Q zk^H->w@+Gm;L8zD9U5Aab$I%4d0K0GVaFA>ZSAqPu&pbasz;^Sn06`O_m*5~#E2X= zsA|dBUN}Xz6uGiiwknCH$zfa76j@WlmYWg0TFMR1o0AusS6o&uRbh%|9$a(F*8S^W z{^9lUP5XZ9nE!dr=%`(;Rt$7ITu{Et-y2IG{w)7yAe+BG|W}tX2Z}3)_VrEf?*mZOq7V3 z8df!x)wxXwTrJILPBzW0k^VD&>%8K+@Js9VgtK#_?bsisK{CUHh|i(6NLN*#4IS9p(9U{x#A3n?{dKlKm{77VtBSu>It@y?mS4$9@f z_cvZ7pS5In{<|%&9GE!dmswLL?{9tR+AB|=>VlM5w#FH7IcDCMVIlolVd6Q<6V*#;112Zjg}QQ>>Z+)nk^qS?BCK)y}Z5AR_NG2a!&eYU* zKL912h%}XuyNSznWIauAs+JrfmAMYqstQ%(N+YRyM6(qV!c3@851@*%Rmnl^EO@+m zP6r1_!ULhCV zNJpz3%_>#(YN8~teWD$?tGRvR82**zxaa6OpXwE>FNyW(gox6lT-;5{y%>Jt!8H5l z#>VBFvdc!-M)EiWE-~(W_tOP*zWmzjamI>PC%&$jvIQoeO zO?OsjC}BPRrZ}~M`!@N z(HK^B@J6}%!1586k31yNb>27U?r(gzacbUk`$mr4Tlhuhl*bz~7w7Ky_$#nX2<#*R zR}k1qMaBj^uroNn+f;hyMAng!r`ryV)}zl~>R-BP!Q!_A!>_%vegF(s_}(y;!c?je zh{THMez&OH05C!W#Q*>R diff --git a/shell/.gradle/3.1/taskArtifacts/fileHashes.bin b/shell/.gradle/3.1/taskArtifacts/fileHashes.bin deleted file mode 100644 index 6d05f69772ff4a8c75a80dbb3321adabcbca537c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18697 zcmeI%K_~=K9LMoTij3?WY;AiJ2U}=L(zQwrexDPY?=13wwxqH z9LSY&*{g%Fw{cU7a-cS=c+<>loA&6Y@2fZO-*5Ugz0Y+2gkU`^!&j z*TKf^O?~5G@#JxD`1|v2B3!&Q-v@&Y@m$|XX>T#7xv*W%Si8pNs~&80q}|3Z-@bSP diff --git a/shell/.gradle/3.1/taskArtifacts/fileSnapshots.bin b/shell/.gradle/3.1/taskArtifacts/fileSnapshots.bin deleted file mode 100644 index 6963709d7a7d660037646f6d361235df84f1382a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19105 zcmeI(JxJVO9LMqG9%{j>Hj8k$Iti^2r9v$f1P9+hI+VkulJlbHadJoQY(P4RAR@ki zs8HG>Rt2#LMH~dB6w%G4pl%9Iz7<>qp)K}#NP=s?PURc;U!MH)@I1eKZVYMEw3u=0 zAKKkfb~j{%00IagfB*srAbb~0J#^_v=ke)EUxjh7{H-S2M({a4AGtJCw3 z?OwmRE9l3IruXKiUVQi09}D`yS@uV~d;B7R00IagfB*srAb`cb&ajayLrL63x=D~yTJuce*CGab=|^1`pdH#_Q60#|MQ zN!E-ip??dpwdp!mE@wM_lBfPbnouS5#Sp1o m87kB~VYtzsl}8V!#}5bJzONp-G}M+^wPjS6P!&-v&G-w_&mjW< diff --git a/shell/.gradle/3.1/taskArtifacts/taskArtifacts.bin b/shell/.gradle/3.1/taskArtifacts/taskArtifacts.bin deleted file mode 100644 index 395bf7c20f0a96c92fd3a412c05fdcd9173ea066..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19472 zcmeI%O=uHA7zW@;QxT-qAQU2kUZhxPcB@4X+DmIztEiR4sNf+?He+_`HoMGBvetkn z1;O}t)Pvwbv0(8oqEN6Pda6YbJX;TXP!Aq;*3FXiP|Qt{cVTyD=lA=bnVga(B%S)% zx=8yPXctj}00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafK;VB7DCk5sM9HLwd&0t| zfRK?sT}X`BThH|LKfD(;Pmag`AH;86KNPj$2>}Q|00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX?}zaTJ5NODo%&%-;> zim10)qRMviw&1>M?0j?X-Pf1fu1-^Nkh^T@{osl*pW1)Z7oN|A;!K9spMw0A=A)sH z*W~X}Vb#FGe14FM-1nl@xc_Q-_=zVfMn%xF%M9vsLs5BN8iAm`p2s*Hy^C39dx9!f zPNbe*Z~Vxv^xZkKyzn_#+It|8nwuJXdv<&JS>`VLHv3`AWgT$uV#0L18D^F|!KF!S z#oeYXn@(U#hqZP1IvagOQipQm*`rpm zkhgNh$*E)3t@G`f=)ex=KCU;T8_=%<@kJ$%(_qn^f2iud}~n9 Date: Sat, 11 Mar 2017 23:26:52 +0300 Subject: [PATCH 15/63] post merge fix --- .../{ => com/simiyutin/au/shell}/commands/Grep.java | 10 +++++----- .../java/{ => com/simiyutin/au/shell}/GrepTests.java | 6 ++++-- 2 files changed, 9 insertions(+), 7 deletions(-) rename shell/src/main/java/{ => com/simiyutin/au/shell}/commands/Grep.java (93%) rename shell/src/test/java/{ => com/simiyutin/au/shell}/GrepTests.java (96%) diff --git a/shell/src/main/java/commands/Grep.java b/shell/src/main/java/com/simiyutin/au/shell/commands/Grep.java similarity index 93% rename from shell/src/main/java/commands/Grep.java rename to shell/src/main/java/com/simiyutin/au/shell/commands/Grep.java index 27eb6fe..015eaf0 100644 --- a/shell/src/main/java/commands/Grep.java +++ b/shell/src/main/java/com/simiyutin/au/shell/commands/Grep.java @@ -1,10 +1,10 @@ -package commands; +package com.simiyutin.au.shell.commands; -import exceptions.CommandExecutionException; +import com.simiyutin.au.shell.core.Command; +import com.simiyutin.au.shell.core.Environment; +import com.simiyutin.au.shell.core.Stream; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; import org.apache.commons.cli.*; -import shell.Command; -import shell.Environment; -import shell.Stream; import java.util.Collections; import java.util.List; diff --git a/shell/src/test/java/GrepTests.java b/shell/src/test/java/com/simiyutin/au/shell/GrepTests.java similarity index 96% rename from shell/src/test/java/GrepTests.java rename to shell/src/test/java/com/simiyutin/au/shell/GrepTests.java index 4c409fb..9e1a8d4 100644 --- a/shell/src/test/java/GrepTests.java +++ b/shell/src/test/java/com/simiyutin/au/shell/GrepTests.java @@ -1,6 +1,8 @@ -import exceptions.CommandExecutionException; +package com.simiyutin.au.shell; + +import com.simiyutin.au.shell.core.*; +import com.simiyutin.au.shell.core.exceptions.CommandExecutionException; import org.junit.Test; -import shell.*; import java.util.List; From dc44b313e9271902501bd8db02c972bad944afc0 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Thu, 30 Mar 2017 01:09:26 +0300 Subject: [PATCH 16/63] book store class diagram --- book_store/.book_store_class_diagram.vpp.lck | 0 book_store/book_store_class_diagram.vpp | Bin 0 -> 678912 bytes .../book_store_class_diagram.vpp.bak_000f | Bin 0 -> 678912 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 book_store/.book_store_class_diagram.vpp.lck create mode 100644 book_store/book_store_class_diagram.vpp create mode 100644 book_store/book_store_class_diagram.vpp.bak_000f diff --git a/book_store/.book_store_class_diagram.vpp.lck b/book_store/.book_store_class_diagram.vpp.lck new file mode 100644 index 0000000..e69de29 diff --git a/book_store/book_store_class_diagram.vpp b/book_store/book_store_class_diagram.vpp new file mode 100644 index 0000000000000000000000000000000000000000..69465641575ba68b3ae72d3befa119e1ebd06f1b GIT binary patch literal 678912 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≀rz!Bvi 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∈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


;d%4 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≀rz!Bvi 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∈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
;d%4 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 Date: Fri, 31 Mar 2017 11:59:05 +0300 Subject: [PATCH 17/63] minor updatee --- book_store/book_store_class_diagram.vpp | Bin 678912 -> 733184 bytes .../book_store_class_diagram.vpp.bak_000f | Bin 678912 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 book_store/book_store_class_diagram.vpp.bak_000f diff --git a/book_store/book_store_class_diagram.vpp b/book_store/book_store_class_diagram.vpp index 69465641575ba68b3ae72d3befa119e1ebd06f1b..b71e5cc9112498ebd063be95ff6e2b421fc849dc 100644 GIT binary patch delta 16065 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≀rz!Bvi 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∈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
;d%4 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 Date: Thu, 13 Apr 2017 00:59:16 +0300 Subject: [PATCH 18/63] gitignore modification --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7c08765..d1ec458 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /**/.idea/ /**/build +/**/*.vpp.bak* From 26cb7ed57e0f22a640fa8580446f22e6e175d81b Mon Sep 17 00:00:00 2001 From: simiyutin Date: Thu, 13 Apr 2017 01:02:04 +0300 Subject: [PATCH 19/63] roguelike arch --- .gitignore | 2 +- book_store/.book_store_class_diagram.vpp.lck | 0 roguelike/arch/roguelike_class.svg | 705 +++++++++++++++++++ roguelike/arch/roguelike_class_diagram.vpp | Bin 0 -> 644096 bytes roguelike/arch/roguelike_component.svg | 183 +++++ 5 files changed, 889 insertions(+), 1 deletion(-) delete mode 100644 book_store/.book_store_class_diagram.vpp.lck create mode 100644 roguelike/arch/roguelike_class.svg create mode 100644 roguelike/arch/roguelike_class_diagram.vpp create mode 100644 roguelike/arch/roguelike_component.svg diff --git a/.gitignore b/.gitignore index d1ec458..362bb5b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ /**/.idea/ /**/build -/**/*.vpp.bak* +/**/*.vpp.* diff --git a/book_store/.book_store_class_diagram.vpp.lck b/book_store/.book_store_class_diagram.vpp.lck deleted file mode 100644 index e69de29..0000000 diff --git a/roguelike/arch/roguelike_class.svg b/roguelike/arch/roguelike_class.svg new file mode 100644 index 0000000..a71478c --- /dev/null +++ b/roguelike/arch/roguelike_class.svg @@ -0,0 +1,705 @@ + + +Models-health : int-level : int-equipment : List<Item>BeingMob-name : String-inventory : List<Item>Player-DRAGON-GHOST-PRINCESS<<enumeration>>MobType-map : Tile[][]-mobs : List<Pair<Mob, Position...-player : Pair<Player, Position>GameState-x : int-y : intPositionTile-STONE-FIRE-FLOOR<<enumeration>>TileType-red : int-blue : int-green : intColor-level : intItemControllerLogic-WEAPON-WEARING<<enumeration>>ItemType+run()Game+iterateState()+iterateMobs()+updatePlayerPosition()+handleCollisions()+collectItem()+talkToPrincess()+meetWithGhost()+fight()+die()Logic-framerate : int+renderFrame()+getInputs()+schedule()Scheduler-RIGHT-LEFT-UP-DOWN<<enumeration>>Direction*111111*1*111Powered ByVisual Paradigm Community Edition diff --git a/roguelike/arch/roguelike_class_diagram.vpp b/roguelike/arch/roguelike_class_diagram.vpp new file mode 100644 index 0000000000000000000000000000000000000000..819fd3582316ace322019bd12276154dbdbcdff4 GIT binary patch literal 644096 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%0Df(%pvPDnM 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 O`)MO7wu4z^O8*bLsECmO literal 0 HcmV?d00001 diff --git a/roguelike/arch/roguelike_component.svg b/roguelike/arch/roguelike_component.svg new file mode 100644 index 0000000..324649f --- /dev/null +++ b/roguelike/arch/roguelike_component.svg @@ -0,0 +1,183 @@ + + +<<component>>Models<<component>>Logic<<component>>ControllerLogicGameStatePowered ByVisual Paradigm Community Edition From e4cdc9e789650b79cdb21172a88ac1dfa0e7f4a3 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Mon, 8 May 2017 21:51:45 +0300 Subject: [PATCH 20/63] first stubs --- roguelike/arch/roguelike_class_diagram.vpp | Bin 644096 -> 686080 bytes .../impl/libs/ascii-panel/asciiPanel.jar | Bin 0 -> 76989 bytes roguelike/impl/pom.xml | 21 +++++++ roguelike/impl/src/main/java/Game.java | 5 ++ roguelike/impl/src/main/java/Main.java | 11 ++++ roguelike/impl/src/main/java/Scheduler.java | 53 ++++++++++++++++++ .../impl/src/main/java/io/PlayScreen.java | 18 ++++++ roguelike/impl/src/main/java/io/Screen.java | 13 +++++ .../impl/src/main/java/io/StartScreen.java | 19 +++++++ 9 files changed, 140 insertions(+) create mode 100644 roguelike/impl/libs/ascii-panel/asciiPanel.jar create mode 100644 roguelike/impl/pom.xml create mode 100644 roguelike/impl/src/main/java/Game.java create mode 100644 roguelike/impl/src/main/java/Main.java create mode 100644 roguelike/impl/src/main/java/Scheduler.java create mode 100644 roguelike/impl/src/main/java/io/PlayScreen.java create mode 100644 roguelike/impl/src/main/java/io/Screen.java create mode 100644 roguelike/impl/src/main/java/io/StartScreen.java diff --git a/roguelike/arch/roguelike_class_diagram.vpp b/roguelike/arch/roguelike_class_diagram.vpp index 819fd3582316ace322019bd12276154dbdbcdff4..bc48460c1c1364b657a400ba6bec9d833be9d484 100644 GIT binary patch delta 3762 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
jk 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ʏrY4hGe{3I-zR7p4u@9e`SJBoxZR^|QWi>Q4UFcdU zLe~rYxZO^i@#^E{*n1~K$IJ%@=(pMcY` z^mpZ0v>k`U)9ITurmGU#`3TB4;&{V)9c}>|I>u?If5kj(`Cw_%weeBXtRoV^aMXiT zZNt^@$QA?n)}EXp2gAMW>*Vr(Suz_dUCxcDNObYeH4P2jZcKhGHf&Yfx8&Sin8Dpa z(#c3pKpo-|D~DloX=%zMDDde+VnnnPJ$8rX#=o&OS6SmO#b?8_`)hddubnHKz(93G z8Yt#@#DB+Y8pwbgCjuX}%A&EHYVs)iBb%PptV=V$%w^BI516R>&gs41T$!E=p2drK zVDja)3^`tu5}I@?Pf))^C+nOYWdfVppdTkHmF7*oNS4dU5x(eL);taHFFqd7X7(%T znTKGd-)d=WK`%{u2L2b^cHBOhE7=N+1 zdRrt<&|jEVUU2`AdNCGhwJwln)>&MyV+!}zq%di-&)`ug)Fpo`IID`?l+#KD%!n%l zV;a61@c@zIB*@*XEs7JQyRAH$IMwr!f!wDDT-xoRPerA|&b`rUUJWP<-RjgcAstKI z-?48-|2j+1;QvjySrU74`)OAe= ztN(fG<1)vUd8d`?`J4q`3xoLd_v;=x(j;`>a!8_&+QXV?ctO@G_GPk4G2ZzKLqzDF z{$-rXxml|dK5ou(P0z|rR})?*W#}8(!u!r=03&o~%~n__u6cM%eS@grsS+qIBNcz4}j#>bO%h+8OT&Q zTH9%q05|*dh>%hy4v?!-;)?(WIqUvdJii;uQt z|Lj-YU1yMVvM*bH&d+ldxtbF}55)3~g^^|FN-h#kaSq5OS{r_PA3Cw*0_jqKVr<~^ zM2}k4=W>VDx?*x9LRc~p;SmXo?1Ud3PGJm*3ly4@V-wgd8?FmY7EVt+(x=Le=4@eJ zAwVFF^Xpb=Uh~jxmsGW3csW5UW$7Xxhv%JWe9dY49n3@iTNyUI;}>TvHaO+NsEMoO zMfl+fMlBFkys3(7*fUmz)}^GvJf;~J8so4tDROz4)G+EIa|gJ(@@Z+DLobAP6*GOtcx%%vov1yn0PQ@bTsz+SFDR`)#*V9r*vDE{~}JbCPHiN))(n| z@?C*$%(p%fV13l_{tUS@at9i)&Z8i)-i2VeIM{U2r#WSQB%Cse}eqWu_TFEEMZdv zwnh}Aa|#QRRQd5lAB`CTmcexwoU?vi_ylO~!I(4ARvikxr&FboR5^@!(3;eo!wG^B zxpj|2*OU>pM4nU?6e8eSln4h)W!d$RY zLr4`9+tiGa(fn9|AzSn_H=gF-J_aa1NiORQ%~s-^q6Pvvl0v?iOzxJi3k90##aZ3N z%gNnu(45Y{1#d_HPOv?FobA=c>Hp&K3)KMEqE`%O;J0KtR`t4=G;sdw< zYr*y30I+yVKeh^#DFXU6uty(BB?fNY41D z>h878y;Aj`#WQ841-xm|X_@I;?Z2BClSKsXF_GAGvmyGd@FftNpj%9MeUnaR3pdrp zf=>lTI>M~6<#XgAE7Jrs#}$V6tvlasFTYJ1;$oy=tHjZs44ReqMA4o3u*44jxvxUh z$_;$NqX!Mf!!b~=GA0e?10S*KCStM6cEv0~LHg$`msAsL7qNy|$nlv-IAT&sM}zGW zd`#$S;km5^;@6DXFUu}GXW-4=XqCAC`aJ`T`K&l>`XxPkqqDA-71cWoO`<;~B36>;Xdre?VwPvA;t zQIEfeMp(hJW6!miCR6SHb@Ott{T>~eUUTSv{Y>_Ri(Vk28kz_U&JTr#Q^ z;=rM>A6Z=?jKW5)tRGy{)3GDI#=n?spcgJTS)04UIGX&V(eASmT=@f|hMGQl8x+(9 zSXb>z(DF60r&iA!U$N0|W-;yhAFB4w;hI}N)4ogao1-m=Kv{$rwY}3P*(2xUm7{9- zS41y<;18`e(U)`N{`8z&t?Pt_c@n$wz&6yOtW5<|T==Hc!kq{LtENIdFnJq<8WVUB zom7ZZ7Ljpp2|||Q;xB0N>pB^dbgs0ne8zt2Ak&`FVh=9n8f6`c!Jm{@$QU>;;P>HbTIvH6)9q{jG35YF=*`rcS z7W%c>%9FT##e;`G0{hghm<8GSScSbihIAEtXBm;Tn;bz&o0xMNgAHGxQSLwz7)30h z^%BGn--(m)W6;aQHi#Y_)r>pN-1T49IlO0d4}aDd*%hWDrB_fw+?hD+fG`y-_nZ^G zrZA>(a8g64_xW`lCcsOzr37Lf{}>tT4p<;ZRv{)@9BE{t_A za2=-ny{Zj%&~8=|U?BWKh%j0lQ(a}f7RAGs<fNpqu8gaF;TjW zCbg1lf-?_;>aD~+&m4Va(KN@VW~oGxd_R zlgx*7b}|qc)k}>Z)*)>UEuDNXYr57Px65n`&IEmTj_`me8q+Mn!%MN;Ex)U%L4W(XVHC8!I`b3oTVQ zl`5h_8tfE^xfr&mytSXRR*d*dtf^3*h1)u!g&p^rde`;|8-)qfjnNS)BYg56vZu0* zqs>Kotvq}CEt!ohzK_+?_scI!gD$4)a-XJ1G?lh30U{+Lmd5psup`wEYB;F%`s2dq z)IA|8<9>faFRsUTE-)7ldR|umSpY|t3u{R{odGM(3sWXniW<2ta;!5?}eC*5`WB6Zu}CzdFb6AfL0 zi}aW&Asy|oJ12#b@-)?$15E1#?;i>;ul2G_%wF%Floxl1OL^@#k%+$~zCSSjfLW7W zQIj!UqVP+1Yqb~8I(4dX#k}x?qEVQc-X&rvn90*pQMe~bV=rrjP1`MMJy~dpLB~s` z3+n5*8q)MIi%MG`EN}g$Bdph=MH~bShtQ z;IXPy5UJUYmdp8v!58A0C03b$nwZ2p!G8)arRanCgbfxnRRaPKi zgH5{9bJmT{QWNW|Ss0kC)OM^*BR9hnJU^J3IB(3)Bh< zQwx zs&!iYKD_YbhL7%ogM&qcg@r{#`uqC&`ujO-mkE)eh>3~W?blna=1Ttk`!|uvAt5Ga zx6(ky&CN|tE>4Ly^xXyr?Kaxk`1$#Xh=`b&n5d|zxVSvmn(e-K1U{el9xv8_=gaXK z85t=lDLFaaE=QAk9qwkPrstbo-cvbz>FMd-PnR1l4qFNWAC3NBpFbcGaCtqhr}IUK z<0WY^WJnXfv%KZ1)QKYvfBv{QJMTMteovdezP_KI-?y>g_xvd-&Fu7t$Ki4*>+0$% zD=TYjYpbif-yhGI496y?rfR6F;tKe6HZ(L;RGbd{LZwj1;dMKmpAz`e)zi~cQE_>_ zKVh+$%;NKI{%$ojHQn9a`T0BRZ7wk}F>-Qp6B83hQ@IXSR&9K4zFqYwe2?>c1&ojLdOx1O+#NCKcY1se zs#2rY{Ckv#hx$E!d;$VJb#>Rn1pb|#cZU~iEm2WXSKrUz>+|FL+TRa{-|zkTDEC`f zvt*F_ebx7uyHo~)ZoiM$@89-(eZIW`(Qg(aU)Z7g@E(rpgjp1z3Rfh(8jlg)j;nQS zF;&xSa)^Fj)#|KFZG;PsBKtx@w@Kl|>_Y!Vhp8wD5=_`<$WXVu5~^1?us?X}BC8M`TPwSPZBlZgLf=!e!i|<4Bn8d$$ z>^*Tj1q})0fu6O!(oY>E@TV-a} z8!X{z4OW6O^*2L+!2B!Ja_6NzuS!LGBRbb3VQ-pjEDb}pZ0I6_X`W$Hl~z3xjS|iW zv{sT4jbU*$;DGoh@?|3Ex?5Y7aB&ukoiZR-5Gu56E1I31oFg&k+LU*4g|e(U#$@3i ziy`^GBHi4RH?<3erZrSk%Wo+>JNuA)y!CG$;ng4I>?mcDJnARsb?ByvjdI3x+vWiW zpiN6WM2I!v-|7t!bPubSDRr?QB@T4FP~EK(%vi8d%Ei}A6fcC~3^Go(qUcX8uiTB{ zXj?17%J9}s32S)O(Eak3c4XD%HNR;YF1is*6PI7N^_5Hm&G35$cvA^PuX2nc3ICAe zR8H^JBefC--PPAyqJWNEa}v+d%1e{SalpQxffT{xv6hZrm4j$!&AbC!Xcc`bscdS1T&VZwNUam>? z2j+3A?dQdQL9v>!oR6up8J5*pi0jq>M+p>f|dSjlekbb+q&x2MRa z(9E7WH2zU`J2cUOGEEQ9hftJ#J)fGU99x5ovV}f~;cuHcM|u>6d4DLPEb|s*vEMgr zosIM=U?7cB5rmc6roC$MT02FJ!=shS_rvI@P7&JA5Kv|7T$Hb3l@LpRAGNml&XoC< z^fc&SM_X;c!LZpl*k+5m!lc&uZeeL3Hduh(;A;Io)Nod<;h7*Zu0kil+81H+w!2c0?Fd_Z&`k7>Tvo zNmDy&pX@b`u>Ay}L>X39gDcV@)|*)Um82ze061j+|L}EAF`@)umhSG`wr$(CZQHhS z+qP}nwr$(CjoZCFv)RnZOwZKj(a>@1938d=VsFumJdh8(fT3(YIuw zNvxyNrJN_ce!Lgim0{*bV#aY-+!3FDa|{;~VmKhn6kVH!K(10m zqvMeu8tLcegms`#K&)U=kk_b)+`&ze#J5xGxs#&rwb1aSVa;Z7^YAP1{}UITZUSdu^yH48w3 z4iDN|g@HqR_136qv}G~EPs86))`}tZw|5Mqh;n4at~f?JbL9Cb9l$qTfgheZ?Npn1 zGCkHqrA)fjGR&fsS8nvNJKXVDEZ%4B4kP6xa2C#oX?UJfLQ`ux6E($UNHbDAL2|3Er7To+=v{qVi7S3-S%cT-zB%C?I_d4XJsR7D>m z?3=%h7=_Pm!4Rj^K&8xRw(K#?#ycAkSBl?fDM4c9AJITnIp%GBHU_0Z_tr!J!o+I=w9It7Pn(;Q?ZzD2a}#5#ai2#_wC zi-PD}yw&1T`gBxo51>M}>n%SlV}=;A$aCy#MhydteyMR*n&@w6?xlU(K!;Rl&p9G( zI0l$)_<){lnpSJ^e$B2nb|I9q*x3897KFU255(TP&CgBLXRDU5WNMv)q*9?20sN?1 zp+UOj3=XVRk2wqDMPIX=@{KI-)MX=ll&Rhlear>2Y^4N^xiSgNGEDXgF(@jA9frxjxjctbul>z!Wdd+fls*2kMkS!0!D6v^B$75fkMvy;# zYUnTEX4mSjsaWI_w&Ik;t+NX0c1P|Q0Xqv~{zy7@;Gd>Yaaq}OAMB-UeZ0zQQk1w{ z0%SaRnbSJe2pQj~xq;L8kgQFeOGqj32izx1gu@c*A5^jWR4bZnDtB>fmY>b|JJ|F? zAU);T7;^@JRzaQKdgIkmGQdUi%ep9izIvmi6{o`l@EannI6MVg%FK>Y?QPn2r7uHF zqCYhH@>D(>5HbCVM~8B|n{FnTfp%JzV=GZ9O!e{xJ8blQXUd>+?_d+MPk;6f=O4<1 zzM}^y>q&^&wAj<5{)!n}=jA&xBN0HF26bNKesq&Ocz!mMpM+oXeH(i(`@tf{Am!h$ z-#u!br4mTIfR^&$j=RN0F$7=sl+_HBOJCX5UOBq6rwdHu@n><0B$2SiOnKcB=~6E# zjWHzg2JoX-gy*1mODj=6H}uEq>ya(qk(8>>hqu&G8aT_@?%N__QjJnVhiS&>&jGZS z4GPVL)&`j7T_Jce!VI38i18O)RyJ%W^mM}K!9s>tmdUw(;Li)II~fr)EB!A$)6Hf} zC7Bapt-OL@$n=pmbjG>u8itTe5F^-Q|K` zWnp?4`SyL6k6?m>)6iBmuNBenP&jh^7-qt59zdt&b>)oc#_|B3s~lP@X$?=z z4sf`mJOq@DucN*aB+Pj{jd+=EyoR|DMZe2?!Oa#g)X0kfnUD;vW+>s2O5*O&T@4K@ z|HDNMU7#|4lrQ!cyxszNvnq#k7OnQT=2hzRj}nXQY@}bu9W6}0Dr5IrDaP@hkh!2p z(}i;wdfw`wrOk8I$+rE!7Xbty`stV14`V{TYM#Jx`a<$znj{@gas%%5Z z1bM^PyP3Rt@D<-@Lf<`?>@-*AZe?7+zh89MqCMM4R zHPHhmLR&xn4-loi-xu@1e@jCFfUEER{$BpaH2eR~u5W|DA_5|-lF!lu06;VTXLfz# zT4%kbiX2)b_2*}D8Ll+dhUw}`+Faw#ex*AYABbR_bWqi&%8M6IzSBlaakF#6AT#N5 zl)l-wSNmuCg)akN&Ss3)oNF{U*0YbN6(?ubSosVrrpN2_SOsqs(utItO3M1`P{`?BEt_(VsCTc!XY04mV|wb4 zXtH2&q3y>*3q);~FI})NF|)$sSQBO@^0rUdSH_GqW;=r4Vs3T)-s}+wK0v9k>T!I#%N)y5(R0G!|j)z{~FRmGDmhtin z{T2KQY*QWArjETwt$y{-Za*hAnT?;ArJ~b^MiA$qq-juO;(n+~bW>crPN7bH^tOI8 zC=T{J{wvWg5TZ=&mm1FCIB!fC3JOfTw7iwTX-32p8KZIjsC0(BTM zwf8C%f_st$v|;tTZ0+w+lRpU(f{6@NqQxo=`GYCBbo1i$6R&Kmk)jE&3*JM=M>oz8 zh>zGlc49uy$O*&oI*?>ed1#;HkZ`g`fLb&G$0=cnhP$}T7OYgor zIzUhl{e}o7D;5_-+x8-@JJU6|q0Q5JR{?%oW_?g^9EmC%xZROE`4ETI3}4ZE#6LMg zAA>A{>7ch_t4app6iI|>!cBr2;KCMYYX#2SF+%L=;E?}a1D zYz`uKPUp`%{Z1p$h=sBYU-+3POm~wIaP$L$s4tM$u&4Y$)`yzBzq|ap`D~(jX!A_1 z=;kGZmU>k#Joy%~Vf3*;NGOcpnLFtv5C8xU?s=ni4sDhBOA>WFAHtT_d4e9L<^NgP zfxllfWYtwWyxtjs)`=km0d`Mtnbu}PbT+38>HnS4I@PGABVE8IC@d~B#w`27?~Phrom?XOb*c03`WhVcHc?AT3~ z>#rvu9EHLsEq|*&+E~m;_ZTIo<6ie|J?hRDh$@2xuZVlKL(QTbhH)gOQ@EN>#-fyn zwsJE}ST?G_RMzUuG0U?}G>7uWW?FeB9)h}N!e{NK+mPvIQa1xyGyAr7dI-{YI|btK z*Q1!(Z`Cc!G`u}D!cMo}jp8}(-Pzo0sKJ9om!N-H{{D5{F^K)^!?X~OBW{wcqN;IB z!0nF06i8q6$e<_KI(sFT7WV2PG!Ixf&`-&8fB2x-`vH+nR>*9sq#d6LAitjSJw^Bg{&8vx+P}qp9vHP zt6p?_%mirH7F5CcRe_c(I5m+?p+Qw{)4$L)W0b^l`1P%q;(D#n=8BlVaXQVWLOUzY)a+rz$Pg6fj`+cpqq)r20t9z#%H%msI0zF9$6 zelDdc2O=c21~owL%hOboNlf#2Az?9UwIAzWJ89U0&Gh5gJFGzx(qzCb5B8(w5IHgH zYJwXiii~~Y!~Ss!47k1b=A0_%nJCztHaQ=?%!^*Jk@J4F;+2R-*8S!3Qf4Jj;qb7i zbMiWG=vtGWGgL(=K#KZ zNwPDYRSY-bgBq40|4X=22j7pod{Ma~gdK`!+XiwOvo%6D)^pV64)~RHq|nc;i$>et zcg*8lBlJo1@M_G9vx#@J&89%YURlb#3NE=yg=O;%8NMP-39yQ>u3}{2fk-QRf4J6l^QKqi*Ep({yXAOe?vIq58xkAjE-W*)Iu0toxm@@VK8-a?@0Zm$7c(iXTbBO#OZ1#dmj8=LDr2 zz6M5f@>^+z&M}lK8aF?t=(;5tK5-OmgKM>e6(*ljT>B%AAJ^8y zGSpbfty&wEYn?Y^Q~Cw`e#mfn(GXH41v1y>?(gZ$jz5PevjW-Z)N}S1#5SW7jW*69 zM&*qUsob?Z9Rg%x#JtNr<&mw)SzjVKQPKpJT$oI-GLvQyX5ZbwxB4U%RO3cGxRu|P zRf4yjQN2tAb?SoB4dV~5Ro;ib0_q*US{}6@lT|mAY$=6Q&7of~tC0!Jv??k1gK32Y zPa9}&Cdgd}7~BB?!^BzYGfzecB%DR*qpv7>;^t2Tlnc)UO__@G><3A*(tr^RMDR1$c36W z)VbEng-@GwkiVpmui#>{5VRuX$O?WGDI<^XRkaI?&Ol5 z+~;TbCD?jaZ|??_GAR|~H%P6LcaQsXbTEp~M>cf!I!|9Uz^Ea8xIkj7{F^q&O6*F^ zs+%l?q6*hGTeZV+tzu^>Jg|W5)(7PZzqTu)!45U6tu(8YzNRv?_Xw-5#{<*I;5z#7^WhTJonT<6mv~MY9UpF=kP2Z{gPuC$rE>Smuyx2FFa^6tyVK?JU+|3nQzFM4|;%Sxr&M zX`fB3S6%{xKD5Q2oN41SM$>qc|%}1B{!;^Ma^44+#aMa;$hKJp*Rk6@~SFq7v_>o zOx9WSY9?x{X@S}s2xjJVV<(vH!-U=+@rBCY-v!Y|DUz3>f|g5EW+}ezN2otrFa*zD zG|iXn-@I|eCXzVhfK1AK-h}pOVhJ&V>h&ydGXex-D>}wc*^7*$(sSwlI;G;)T~3s- zevbY_s6e0vJ62;ES^@>uKE41s#k($}#cB{m_NQMmFT7`!n>0 zgtA5bggm)eU0~K7a;1IB*;w zkRN|JQV=p>-}dN?-UJT8(<|YRh8R+a{hjN}lf#Ss=?_P1OgQ!cUP)0{&hp7(NxvpEn$sliM#ob3UG*L{OJE--OcI)=NDO0UQ8&wKS}$Z7_#{ z#D6rmMfSaFkFAeiTGGe8)WyH%tc*T*+?pOfDgBF^t3n`Ups$%PDyhN2=|!v%{;W3@ z+b^N_)@!w{b>CH`_@CI3-soP$sIF`|#^%pSvQN10-4?z3xLpW-AG*87r-+f6Z+bN* znbX98ZJDy%f7H(~xu3L`{jy@mJm&)^2&bXiQKkwDBO9BY{RzKh;cefKi zrB=(=dw#xwfW0DA*-rrl{$NY%4E&2TU?o6F@!bR@f0BSEwo*YTCIC>5?I;0#`o9KN z?n2hz-Q9Oz@9b6HsnlC@m3%lXI4stC+kZsA%!~ki)-`?N@74Q0nyL3$i=kS`nQ;@&*ET2MImHcH<+FSr* zGg=T-AQ^Bj<;2R+!F#mdy|M;1b zy1T(FCQuWX;~GibhuW+A{528j(jq4pMIX2DB{ym22}cv_UdfSg0F~0wfh8LChWr!< z$=RD!@U2j!IEPy1F|Th4bvWH1F)N60dY{a@)Eva2{}x z#vXQUUWxk~TCWv=_nE)%erV3|gwFRM_~6d-$$smR+YzSBu}sr z_S0;Ua3enr$dVbA)o4Q1B<5Sl=qe zlGP#yB(TDJHa7$|Cf@ss;XqFjCO)FAH?NlA3S)rEQ_;aFbvIc$?&X~MK&0Z@wGjl= zWYGY7;M*Dp;OUnAHXO&`gv^GG16*u<=HnDZlu5CEzNK9GkSj~JHg>B)^W#wlb&tgO z`2Ao^vUQf)P!N|>$V0>|6Qky5cFJtiINxfjn&IIT}`e6a#KILEmgECJ)3J zc9%n!mHw`OE+~(@pd))nAwtwyVpG_|L{n@bmAUZ@^!6;XieUGRpD?h_>#!vonYSpEN9k*DD)leAa+Nd4uwp8ThWD;k7IEOX*C3mz zsp|FE`zVKj+%b15q?Uz;-oezXz_u<*%PfFO z4j0?qR?bZ}!6eWN2Z_vtuvor^-&Bk<FM;V!XQF-Gb3w!6& zd=8)*_UCy_Vp?*9+&g*|A5~|&Oaol2G)WHbGgAXhp8bWV44218WAujE%0bzd&~xX- zxd40ab_N}h7%n%-)dsq2E`YnZGy4iv{=512MIjr1RF3brwweWy4Ki}`8)u^iF>86- z5JJ5Lz-Q=ZDJS2?SiVMci=h34$CNhvYyFQt+>4hEE>K@&IW!Q2nsjrK79s^`y)*VM zQaK*mMYf9i*P_xA&jCy?)+QJ=TTn_<%1^CtL9cA@!hC0+I=4G&2;;S5X?%ix@Z%n) zwmu0|IPsV$73+By28Vh2S{hc@mZS1Tsz#Q*=vAL$_yTw1l1*4l>Yga?Jr;aAum{Zv ze!!FQ8l%;eWK=8_q_&l)ilv2C74zXz4Rq{cjP92;W8@;K#H51Y@XD(kId%^amZ}-Cf~jJX{~2v}Nulr+Pfq z`3&;{%;+{!h7*6P(BG_+e4>hNGcHjNCfGvl@U)e4`>reCCie*YLdjoOPPoxO?t_b8 zX)HMyEv`hcYQkv&PX#)O9j@FAU7e|PEY+Fa_~u>%Wou5SqrQXXdB=kf3$I5uNzxk3 z+UiguYWi>=&BTY5`42wOR(aa2!A#TEV7JXd5!gZl7BGVx7z(}TGE9lPFH>23>RX#Y z%9N3hlsA%$+Z-AVP+2Lq*(bEK5)KFxphh1&8j9{8nR4q@31J*f6Wer|yB#p~Ac?Zz z$hL1-`&z9v`PR7@YZhKzoo~WB*m0CO&pjGc8$@YG8`>+ws8f}dd{EfOgGzp^X=G*= z{QZhHR_gVXWctwTL0#pcdX{f!Mkg>0B{J|2@N}Ar_^e-NHWfL$>W)m~si%|Wz~$gK z9b_XSy!}xV38h54UvB*U_N5r3fw{&83m|;Oh}gSex0XNe^2}*&@i73QcV*cBF*9){ zP`8HL3eJ_)EJQ!NL}5>>g@Q_Y&FY$ZEpkjncXl|Q)J%9qgpGl#lHpKg2aNn8w-OUx zrzt>qO-YDif1849+)-8s)Xg4_@k#t?qD*o&q(1d3Nipl29(%nm@r(`GijQ)Feb?{pe z<3n~}n(E793m+dTIM+X#C!PZ5(|vs*q|i^2S$-DVQHnm;p-`fk)q%>*1fnHB=k23V zBopPoxJl>DTvP-q84!l7p*M^pJH6pIB#{kN?3&6`^49B0+|;&?AQE<|AG@+;*bm-p z?UP{CK`s5!v-vqIx?W5o%|6UI01@f)$QT+%T+FO^Y^$YHPtJk!SSd0W)p+;DlA#CT zsTjSs8))E(h*!`!xO$ZfT)QE5%rt!@mcYG|(D^2kc2ysF^wz~~AOVA=Yp&}QTs~=5 zkyv%`fXsyrrehF#iea4;g3_YIXzXK-pT}rrt|8cvs;I-Xn*URwHv9S={&x!`G4L9- zi>SH(X9ykwqksJ;epq_wVq|dz{wX@VOHnojLjcHJ0Nx^) zlSy`yxBV^1!my-P(uEX6`UeK(06ovzbD8UTxX=ujL2g-Q6L!*?Yw0z10JcpPnX} zk{oo)NF$Nf=N~1Xwx|pmI^k0vd7Lv%(POR}e+iY8-9Tu~&)9CYV)S-oz2ZETQ%2m{ z(XldM12Bd3dK;=EW9+tTp5$ki^c zB|l){c6Ft=a4nRBi34wJX-FrbPsMTN3e)h~3)cafbpAk6cH1(5Yg0BEg@0cMd`|LW zGvs!T1)4p9&e06nPCc4N7p1e#;VsZPUQU-i?0)se)K2tjMPJWBR4NlLzqr++c30kz zmvJt+;h=@GOqO_jnGVu=ugMrtuOl9#St!KdOZ3#MXF3loTPs@NK zD{c7q^(G+(>g9>ImwkB8Jd-;LxNyLP&&EW$#eCLnC{aHBC2BXxTK)6bP^IA6`AqIs zb`+mp!*JP2yJ*94n*#6FwJ4Bi4i1_K_EKhkxYY1~>nu7rf|KeUkeegk4Yqq7=F|a^ z)r<<2@Xmcu%Hp3TwaGnHD{p#{cBe|4Tk8`pid}==wvbJun9#k0y$_7{tk@Z><5vvU zevqPvE#i&L@6W|}5*J_K0j42|D#JepR3}zYI*eGBaE?765q7!7vM5b3ZSv(?WR?WH z%bSrgE4Se)2cmoCG0-!?>9a*w@b0`=3oOlxI+A5gCj7;|nYt1>MiVfx>@GKfZc((t zBdS$IWJceyH27=%@9^gGod@*=a=yQnccC)on=>2TZ|sMT-tvG6Y0czAt3vTfbYKTB z{y|q9L?fCSB4vAvC3&U>N^0`N>%KRSj@;~kn=IOA|0r}VvW6lXt(KnfP6?lQJgC#u z=qs;FX(UzFahJkdO!Wj6DJsn5E|Or^-io?7KM$*!LM2L4v$X45%Iqn)6@X03`NtF@ z@|&r}8~65hX%P$y7ndtnr6WcnMIo{#V!18b=UnU4`L|m&*NtMi^-ha65|31cWozoH zDll2KX%6T$wLn9xa3rWIW{3n`%ZJ|Fhn)=r+k;33fV!Z=u?1f%v+HDE`pZtJ72#UF z&YJlgmv_Rs%SR|~Ny5XVThbVcvEaPRyIT`aSA$S|4R~-a+gV%(=^7Vt7*?SX0_A>T zoO~luz9ul!dKWro&+1WKUKS;n8~;*gZasLoINrYa^9kdia$TGCkE)Ji z#AvTAShwX+krGnU>Q5wV7cG^0=hq%cK%OysP8o9z?K52{94)t}DGVyanFJJF8ztkU z+)M^6WYOv3*$3FLtoPr6q%HWxwpTy`P9tkr)7FwEp%6ATz&XnpO@48!Ojn>Vk5Xd~ zD)_c-m3WxUL#UWlgw<}OUBnj46;`Ii?~(3amxp9dM(S{x6SISQ=Jb9_;gcH)Yhl9A(LWKBG99l5dh8vj9c1(8MR(^W)XWoXh)2s?E4M!2+TF1Ww zw2w#P2p}J^(;BHu4$7*GJeh|Qp)5uje_s&pe@SE+CyNH1;!L{&zlcXcvV(oEVKD=+ zXD|`&Wu!Bbrc1c!3Xv!)cMwTx@u|#949hreSM1H_e_{4p;3mkMP(^T*BCL!%VPA6` zPRexBi$&wMGGf_cqx_FWL-$fNr6Q(=P!44q0&%7a_Y-j6bXcE#&M9n2c)L$6z^kt& zmht?+!Gw4%aW*v~DYvOT!yqQw5pzh$$+Gf|m9@&rmMTyT-5Oqgs{9Gt@*6XQao}sm z>_Pnj7Z^MqqZ-doulk!@>${faYbkavg!5i%pwOR>RT@0s%5j&$5L@DTPW&Y`K01RI znR1X!EFop%-~==GM(D1#PA=1A5FK9Bm&&^#EBTdM*ew$r@Z>uP72d}jwC;qi4YYhh zg<}6U-v8a0op!vW{Svo8nJo@J{3t#*VQ#b4w^BUa6~4O(YG=GaKH0LKAb1=31-sZA zkMheRJFG!jKk@(`u|-rn2mM=P)hG|PTD86V6-mtLQ;%YjcU7wgNm<-E=5y^*SKz$_tLC9ojLfQ~l^-$;uApY>IZ+1l}h6dIW4ZJO4yS6PCHnVtS zqf!`;Q&Jr&NOAlSL4w?B0Z^w1aKpi zHB4;^ZHM`&lXm*P=_Mh4cOD7F+Jhm-C0A_hBM}t+W|r1-JafBe8hmzXSz~wcpx^HBh7kC4_OkGMkroE zc>SIMe}DdhB6MLKCh3$a?S7cp^SxEDvb`n%0}p`~tzW+-6pBa^o>oJAobebourddI z94%V?k7h_~a$Qc!--*krHb#?I&%2f`msb=9MFyki{;(eN`T!Oya>Lbpq65cO z??#d-2Cg!(P8&whV38iaEQ>huQO|~}!9+t*?6a&z>CbAx!|zvV;ovZT&AoMvH5)gK zB`G%;{{-(1tq$i1LjNL?vja1LfY}cQjR)Y1=Wgo0>PKLHBXLDqd^F`b-?G6Cis}Qz zL|gvgk&=`9jCBvWC{Q@w?=n3_8DkBiu)Lfwx_Ku#>e22^JD*Hb^M}@pcdKM{gR>0E zP%^wdXLUS4mS3~mk&H_GqcA=w=-JcpJedom6q9)=N4Tb|7RlFkI_O z|5l<&RmH)?y63(rA4r#k^k)h|EeW>bpY?6hJ#R2cByxlUix)E|egC$YTL>N(tYJdI zN!xLnD%VEU>gI515oP0XHfJ#IyrK(%R028;nszET(E0cwfi%f*y!1e2Xu2p1jnl1O zSi$F_sp;!KO?fEaPTYXcU591LniD^N8wzI>APp zVwA1NcfiohIR~?pbF&F5ItKk7IVR5vLN-6W=04;N-2IEZ36Ewb=@4Ir2BuLekRBzH zCdsS%p6`)?fHqEy9BTL$;G`>@R^k?lY9Gd}`%DEmVdUT_=S4e`My!d;cioMdr-{fY z*!0tJCm<2aBMi06sZF)beB@uQs8tCK`LM+neFdgk7Jd9hM&1?(+v5a#dxJ^kl#rPK?yZ2s3E^K^2DqV_lNT z=v-vYW!0QLTA$=InveMtYtQ7GO5Amsc>wY0WO*gzb!f&5Y{Va33(Sm(5887nNlrtm zN@)=u^1AYxwuPD!N%RcWQ46YJXjyx9ycam^q7??IZi+>U^V+Z7mf}1R|Q){zQu}f1G9~z@gE~ur zDD0V)V-TW8Ikn3a-^@)GQvaqA_>T+d-bcB2o{?HAhZFrB)2lJ?rF)8V*t^{oydO9M zgC?~MKuXb1(;iW_q^N76TLCkl-;u-F&5kS9oSjQ#>@bYNHis1P+R29+vPl+{Jmq1! zUP`QUHa$^jMW2N!pe15WQOkJ;qCB9dqCPvPp(p@bM%r-`JJ7^^+^#K_iWhVpE@qEb zI6id_!}2hG0ODH=Q~TuS9q{C>f_tXKN)c9cCiO|B9LW@MV)bN*S0G@U&uqbD_#=02{tJ3|#xZ zrP8Gx#!J&t0|V%>#uGS=@>t>zi5{BIuGQP=BZ=y9$_)AWe!u{l$2B+pqm<4lr*?%N zR~O>oxEhh*%3gzGhsC3^UCJ{Kt}}t8`mL_*bzE>YBRNi6W8?|h&|n~|jbHuY*+JXSMM^4J1O~@cL?5 zp;4f;PC_cS*jMjXDK2lBbtF@GxZ`Bq%{p>)eL5JWGwCPSKeWGn2qC>hN$j&(kzrw2 zt1HFkpw;w88W ze@hu0q%)tJWwoFDH|J)3SzK(fEK|xiMgMm!5FX<_5c^j{YVffeuj|zpe8Z6Ci7^PTWV>kA?~-tBx&b zpE^tetcMK*3FgBVBZ)XL1CWWR(Cs78ysE3>| zcFMQ>B@OKx@6I(zk70GrNZ#Qgh%WpV^bVY6T#tc{Uc_T_P5hjs{0$4yjAWr)FnGUR#OwxGViVEe3I5a(I4rbA5I) zaaU>$l>^5?Bw92{MOdy z&wJszuiC#t?8G0Hm~p;|`sVnj2S6?X>+i*fpO+1@m6xv{iK(C1r3G=lxFyF%m!?Oh zhL?~rNC@zVJ4o<*NChGV3s@}nrA3X=E$Y|kjPuRF&+o7%)ApwLo1vN!_zk=_X)|XOM9PdO| zdbGXM6b8nHFC;!K&Dq;p)^n>MUcwMGO?ba1zruZ4u$WG_(Q>7>Wm<`=zmSBU>lR0R zPq(+UDK#E3%+ZfTWQVq~E6PsDp)QZsZfZN}zbhlI&6uITwrx`Lll#YKdl5Q#LEOsg zwZ^y~dQ*Z?vygbUDt};E@=*{q@z5f@@w8EcR2Fda$7Wk$J`tIUcMlgug;Xy(u6^K=ekfzCf5*y4T&*_oX( zM#LJ)0r>Jw$xWO*i{@iRve5Gd*eUNYQ~h&U851v&G=(y7U($Wyr~gPb`sHWooupyDu`pGygQg=y@FIm^>nt+h{D#{?)S=Qmjg$2h^)QTROb z9WZnwwu(K;sMU9ERl*}`N8Q1%U>(#dv9WUOlC&M}_7tD?ZJ%9tW!lg`A>r7HMAgab z6HO@MVg;K(DEYaxj1Zv;1u3wwt!Xge{n;^}%5Mn9xW(juT2d0Jk=YyFTkf(+;9U}a zPW8(IY$~*oJkyAoHtB3=vhSjSnRTdz^FoxKK}7^X|HRgf(%mCRqah+=cEKqW*8a71 zhs*01kqhIG+yl3HsWg%oB3*$RIktrTtLoex*BiL;eh`$D>rWk(o zLLheqwAFheL7#On_qBhFLCS@k!O0zuT3hyz9l7nszx~miBm0omC4TzYjBO=YR463K zP1ZW4&PrhlO-o?bpw4`c7LF}+NK8%)-sS#vC99&3oRCh}0H{*3W=S5j8wTvI!^y?w zL-6YPq_EzHiN!_Fe$pNC*1!o3$%{Hdji>Lob}f!G(AIHLpJl|#I>mo{e>Bz8(h?3m z_WS)1!)C2NF?)qFX0`%q5lb8<$xgyr>PFKR(duN^%7(AGkqq_KOQ5*t=biSg@b+J* zJAU{S7$cKMm@eqSrDRyA&3!$5Hw+;~?37@i+|$5`5w8q9GS6%aJSRWgr3}xt@k_G& z#E-e9oP|+>5-h41841u3dE~4Nm$ratKXZ>xHU|BDFsfbL_HPTQG)Z5xpv7XwQL#hB zDk@!*c9-|235F0m>I4^Mlyb)^a+P=^I}DX&Y6oJux=0t!JgBu*d5Pu2Y!F$G;@aa%v!I!6b6;#Cgbujd z<*n)cA@JDJO|<2#Sd+I;=^Ei2Z_I{`Q*}D!-X}^Ob^zmK4;fYQ6j-9W+p*Ynw zd%~Fd_fp3@**G~Fsj=lB6_|yq zSh%xr!j5D-q!hanh<1OI9>Pm2>hvFgW5B`7BkAx5w)=CaP1AV3KyAvheB}9~2i4 zfsMiIa5UmJ@-5{)8zfwkw87n!rLK#t;{{|fW8xopul%&=d&>BKYjhK)?K0S<_u+nc z9r)E?(={tN^}Fz3q+FMh@m(QI?iOQ|mnfbTH2w+6_%q`oS(0oS1Uo5tv>VO(j5qj! z$Q@$&rw_P!myRz^ho=UwfnEN%sDlUwjLQp-728|(vS~eA0P*c;AGt$ii{c7XrfM5xeuO z+wehYDhLg(x;8aHjtnK2)40TiOQ2GvM3`f0(-_VjMf;IWr`GdJNdTq_Ed1?IHDNQj z@s=>?ciOg$oD$|H3WNs7qfq%z5HZ;g1mi@3YeYB!xdA?3J`B`}a)TdjoQg34x5m4p zx=-12&?X9`j|hi6{TeM|?SC}KZ({2LYQwK$&+g5mxLXJX(5Dv*aV?)#4&sGWjx}VL zk}##!+=qeZhqH%>&N%P&oR>?gDK``sGRSkCqM!G%4#(5tx9B zA&c0P7~YmQYD6-^wr3BPzmg$IRy*9^?m%_Xn6jX}_s=oiHx4S{dWw_f>0vB?Gq z;K(zT=thw6Y_J;A1%B*8((}EWp5Aw1%nlqjm5jw4vMiBEyoe#_x>P7ye`Y6Sy@Ccir zjmk};d|oD4i2axYP;f$S0b{>rFv%@pUwIvk&dI#PZWag@vzOK?Fg|}D{-Za`#1@vO z9rx**JT!gYtaHi{*2qC)PbjUZ(0r72F+EtMB`S>kMm(LSB%*MS=h@YV1}<$$9Ae9X z+nZkd-Hf*`L*lOH9Yn&Fuy`rl->YogWt%ZrAAg_yfO7m5=ehbO7soF5#|Ua8MHQn< zP%LY)^%hMd*F)vSP+&19meTNOf9cO5}n9H5xieer!{>R%KE%Q=vNtV;fa5 z9{}5~R{c2k8*%8sF?rQIUH=uN-f-c}N@?T$n!NQf{R?|6pxic2wQQ?=a_hO7iW@Hm z{#XS=b(0T=i;zWQ&1P3Fr1Nk_KS?N!D6TWiN{Sn>#{S=7@A6!qs{}DxQv9wVzg`Z{ zGdQZux!xc+o}$OINCMQB-d~81ixOXn+?AJ@L`&MPhf@*{EgBb4P64N*5X=of9L8L( zZLrkA0A$SE zoNh#3v7(AI&b@@@KTm_^f5Vv)K+RdbrHRgm`%iRQ6`ok*L~R-?4GOlAjoa=!H`V|3 zi=&g*x8N$gynPT{o>?7syZmAc{wa3VedxTl+Ng~0TX@&sDJGoslnOK^tnK2i+;iwX zk<*~50>|1k6Yf>obnZ4L{Z+3-5BW=*>d$5U0Eh#8N|$IwJ7G;=n$idI5OdsdhAn?KCG*dcYWrXpS7AP_bEVm(n)d6 zd57%=WNfKy>iRR~5k4-Zy`4~yhXb9ik-t*+3;8EhIoGmsIJj81aQw;fkcS{wVo814 zaDaLLE;5I~!$6Y0<*^b~JIxq?-D88c4krJG%FPr3^k|b>4y99O)RT3o5C~f$OZ2{&VcH zY-JuqIjN*9r~98s%x7^GZcIUnI=2`!I6V5Pfj<BFc=37a z+Bu)b=ie6?0T@#oy@F?R+DUnvj-z1|2RHw#uCoqmYx~|luEnjmdvSMncXxM(;_mM5 z1efCOZpEQU(c)GpuD^8NKW=;P_uZM5iOl|-b=G8`WF~t(&tzwO2qkPhHZOs+f3n?I z1n-sZX~sUtq=T>fDwy=UY>8I`;~E@YYMJ9O z43eactvjF@Qjlg^YjNSSMJCQ*8nda$l!T&W4O6I6?^&&Z;@;Iy&{IJ?qXO+8^x0z; ztQWU(q%z|$U*-hH)1m={sFk%S`z*^?=8rVX;t!gfVzcrhb$ug33Tht(!B-O~uqR0g zn>vQVyyb2`37+{N-`3f@aBghNiwwf5`7Ri9Tg?U486P^1x9C|+k=s>{AraIE=BkhwlLN3PLgo1tng>i6Tq#KPJP z`^ZmE$l3m$7^gaXKfa?RQ_Yx&|58k1`n}ltj#L{|XI+-AIs%Zgdurm@X$oOs&!9nv zScS=c!R#X7kzUA%*aMEon_?P+76|xJs6^9u>)e`iF!AxcuPFi|L!Qe7q+Sww-G^lC zbx918COY?X(B5(hQ*GzRDAPv$fuRK2cRp6SYef!Kq+#$q&#*q4-2rU_Z10V>k^X8T zd>-kJ(_Ask9`rjGTXH1t>9Dd(NnJ1dZ3~k+t+N*O>*oHX&u}H;iQTp+8R67blF2G! z{FqR%wUo!ONncQITn4-v`AE;4fUVPBxi<|g?KlspYSmekl3U?VBQE2`lVxUHPP7Rp z!EcO#q?v7_X5E6rLd}3UGEbX~AoBvqdT^bz8e{=opqo z(mt!TG}k9cjXBTs&(iG+sQ^W79J4R06l^G;`^{52zlSyfj6LQ_bUdbAEo%H5Q>VDBA-q8CT7 z|M9qPRt9VipNngRrF)nvqft5eQ4!tLgN^||>gOM*Diw1Orx?($1a#q$O)l?@J4&~E=&<`dBys`%0en|T7UL|Rq(Fus# z>`XhfFW$zLUCS6(iSr124obxrIMCu-o#oP zy9+uICACW14+SgXPd3%e&(c?CFWKdan%^gwK6TLmU3NLi&(aqJ78?8r|`UKK&f(QPuZ?ya`)tRShK050OfM`l|;A5{K!<% z1S7SNgYz-Gsk>SkPlKVk7Jsd{C)|jmgLczEX?| ziVx~BmifwEsa4-dT4;V6QgFCg3omys)(+QfP7QSX#x)adp%-}om?W{#dHR5^C&XalJbA!1T+2>)5WC3sa-x@PgY0>DIV5~O~?p!e1FRCw!#RJf8nw!nltRMZ^PJP zD1_j%#Feim;l(t3+f8>Kz?-uaXGgFhszR%$1W?PgE6|oCQXdT@#g-S$4FRwi}wJaEm>bxRF^R+ zm@W6cB4)u$jVPdKKKgV0q*Yh}yxUJWI@eu6(|bz$i?Ubh>1D1#Z&|ZACkL6^myJQ+ zgu0B(q3O~=fQF@DqpnT(%1m$tO%F!&T(n7~y4Qnckc6GB7IEp#@TD-uDuLPxMs)3~ zo9|Okdz+q*#A9Eu`CKr=ps#s*^IW;!E0dLWr5GDu^e6E0#8i5ePCIHrv`yOS_q&y;>{xIQu{I4jalk`L~oV?P+%pg=|8c5$RE#iGZn6ysNp%ui?_b+d} z>2-WbM<(ByS=*H|D>kR;+n6`q(N!27OH204m~KtN^ASR5!CZuDb2;0WYMt1n?`+&v zW;_XkDi{j$f!q0n2lPr+NX{RQ+h(d+=?yF|f7aA0!kEPL`oC)A2%Zh8-K6f6PyeVo z-frT50!N$glRyJHXz#p%S;I!lF_MuxQnPN!m(>R~7?G)7Tcirk8!xt& z59ADt0qivg_K?u*vs*)S?B!HrFzMxmo<`a>qTI%m^iq#OSB=OXECWeq65&tRH7~|3 z-DV#E{d3yU!g{g!#Jo$|P_eOJAo4;>vt|p@i^#4f{l+#-W>_{o%`LSQwl2Dp7^99< zUh7Vn*Wd>Lpz%NJW{k(V<@pyi2Dm_dm10R~HjBdiJ`pUA1}KXz5Y_N~2QRCPhS*g< z71?I-i7-C#q>^ZJj5m`^)!`=Zgswo$}Ud*Yy* zX~v)UNxEegV@~(65L@%4Fu@CRz>Ivu7%#u~tS+r1;dLIHXV)=iLmYW@sYX48@MMI{ zY65Clr2ZUavLl>PeEI2Ff?Wj#tH{CA0U}@ZDA7d}N;5(YeQiX=rgP9#f)U;iP*Z^< z=mN#(#P|OBvh;L4ys)vQl<1pZK_%JrS(j}`$I{czMeN9ukQ(lm)xbC7(~WsPziHO@ z=M#e*A>w^DyIQ1QxNZuU+PgRS?r3@@qD`ks+Kn7sHzZAB1Z93Ns9nOS9;-I~kG{L& zG%99!<&|b(*&VgDy((~F#{_oiZe>#;En);5hJBCQ==BeGx(IYdlU13j@B0z`ktDQP z$!t+D5zJrh76>leYMqa~?;s{PC)cSEYf6Wc)NM*Pu1ZGO_o0+lqnRNa-!JF?#{meN?6`o3k$K6CT+ zOhpCbklUlw>wT)Y=lbzhcy4NPIZMXe)&Q{N30LC_PrL!0OmeiPLdr+q!e0AywX+my zC(;r2#3&&uWg2hgoam#^7=Fs8GfNnEp5xRx-&ctxPQk7htB6r`Yh)bp<=e&=EsV)_ zL0FCMTdzgOFed%c=H|D7wm%8;wOF_Z-_ zFz(H;F+_Tc8xLvS50+V3%5DJg9w`eAqm&07&b+D+Fbxsi3*4!R*lVY*$MIf~Vm_zS z_7ybHU{wTYJxP!2$1fH*!hoi$5~?!=yRmWA6A)yoyq{?qqSxAWar;n+Wo!vDG`LDFRKrQ;w~?2M$U+E+ymE_|7@sVz+T zD%d_Q)Z{6rZI$y`K_Yxbkdqm$5vMD{iESOnQ6zFzqb0Sxb#?VP7#&-DOa3!6KUK6M z9Nk?_i`ee)3mmzb)(We7DNQQXijL|*WuD*ekDJv#RmJ+7=%4BC3P^zrs@woa{0MKc zePlV?#RY|ZOHQRilm|KL%Wm6q^KkX+EMN1B*kVD%=~>fQr9caR&=IL+ght`nv31wn3z>^|>3JtPCbSYrcUt6<%bn?+_-hgj3?9L4~$FfA}*8au_i#73`_n8W+Z*SWqP6_pW`=w96N=e_ma z7PduJHlX_Pn z%o&J-U(jydk(#ml9WQiD+Pi*eHA^=5(1?4E*V&U-4>o+sLHPA&ZxlH1z0d`oT*W98 z1)GJdpoOTdS{nl3joZ}swtizsVTKH<>h{Z?vAzTcj2>#ua>3+C#CuwTFTTu7gAr#Q zYG^pWj4QI}A$cx%lq|!SDVZfP?0%>CCdyyN^ObOveT^2KR^Z8W($VnY?n7!?BF=Yc z^n+tAtc|Pk5v13OSC?TLhl*k^raj;QK>7+Y=Yl|e%1PS2Ms7@_1^Ym|zo>wF)M2G! zAjU9`Atz((y2>`Z8P$%yGKpi)$L)!1>czf_hVtiyVG?{rpK-ewrDjE;qaEC~3nhn& zgkRly?|TB^#XY`eBaFT4UBTE!gxPZRwbnd#$*yszZ;cl)O7Om!R5PB3xFa(w#;}f|m2U zQREWOt737sA6z+9!zv$;5AnSvVAJZsl+95$|WK?O~VNLqZLxU_**U zuEyPt42Co;ye*Zhr`R-EL_)orK+H#r2%o~yx?oX1`2J-jZd0Hge)-J3NecCY;JTZA zLR{tKS20Un$W%5)PP%|e_F;)3dIatvXy&f+5E49*t9%HAn+iOpDEIKq2nANybCb4M zk+Q>{_U>?o@L>~qVt$(W?@KBTGX54CeR0xMOj={_)ZcwMzh>ibtSQqVJ4wb{WwiCf zxpjJDX0)0KOU;~yJlJYNF9=YFxqkO#%5w34OA}ZZJMMN|P$L8C<&g2z|8(_33hNk2 zwtw5W5KjF@jv)j813Miqq}-_e7scpM0jwqOZt>8mcRqiZW^Mta;b0LpDG%X-Wt5C< z@VwhYk6;F*NF0;HG?;HsD0r`)z^=Ngzk+m23Y*E7v_qUAIqEGmpeyRV)TBm+zd+k* z`wBHLO#3U=oI1OYx;Rm^`rx*Qk1z;!A0^!EMV2k{{8~LoKIQYMXrUiNFk8fo)i*kQ z9*i8X!@`R4#X8SiHs{&{?alG zWDye5YYo^lLu^Kp*Nr-nyw4F)T~SuAde=pA8@jP!AP5u^7En-z1f-!t)EK|Y>$EM_ zGz#%fo(~?^BRZZ8JxA!HrpanC_rXF)JPaWn2i+L?6%h!jhwjR~z-H`Ww~oM4aKVAt z@X?dAKo%i77mgKIEUf^3u6me7qX)`hXvS8M2j^*d$qre~1W@s_`AEc3rv&DX_>!lP z6@#PK16YPHk@qP%&gDex$w03f4`wx#co&P<*!k2yTNTFlwYom}TwNg}>R(k0QIx5= zIHX^K z8~%O~a9W;mCeKUI5)x^7NL;{WH^4EsPem)2KH3I$nc0JwtezYLcc~#ajXhyw`=HF} z@XIQ;yjo(cz33TjI2ONpwONM5;}!YlZd|a-PGM5GUY(%sAf^QVn~l5h(-3i@S{JQ` zHgoifn_hW8g*hsCcKv#@vdAT@+HD`oTPB~g13ED;?VU;?)JMhG_DA;yxiXf;2WRa$ z2X!VH(I*bOc)PvvQLD6H_vc6^eKPJ3lNKo)RSPpZjkd%{t5IYD)CH4#PDZrP9_ab{ z??(DaJ30_g0R_W5Mxo=>YGXWmnRNM@?S0BSJA8AQJR-78ivsz!8%elafmL@3K}{4| zSvcA#23-(=Y)^Pr5lN;!&CrfRgM3+B9cM0C;hG<8YCKrHXSz12iV*3H9ER=PdNc_t zZN)^z{B~luJHO0hnp*tOWA&iYTljQ?Yb8DZr8F`r9l@ujp2!}p4BTm8SsPqlD{RB4 zEsWnsra{C3IhO5GuZS!N8LSKV)AI)7rmeD~p{;3eq5m1Q{RjU3Le7=GPxSi8Xrdjl z$Iw9v!%ya(qrE2wZfun_P}5iOB@xA*kBT=~K}kM%D5Z8PkekwE`7S94 zn>3Z5^o0_Z#iZPah>aqP`5|NGZ^CuytIK0$zY!y~ACyq=MHS-3Dy;d$g*M8^%O5}y z>7xh5PDin5I)$1oz!t&M3pgn>HcV>I7C%Up@QGeCnbVwBy@vGPMss*GMy*qrCS(!? zpQ#1kWOZ!QNh_?eN-tjaxrm`1&}n}ubV@d`NMwtwpeMg`$Yu-_Y+{H(Iq?RI^GXlv zJ~Gn-yb%wTY_26ksX!%Edzk5hBnjnLN@&N&q{1@7s5uSSdyC38YJDqF(lhn6oZxQU zaWfPW98}D9Kgra6#)^a)U39I%sDNU4FUP_An)hw2RQVw)o}nf8P=x6#M8?C0I{a7f-OGRU*0 z1mPOBh0Rm|(R&*Pqr+^;5wmB4%>;&4=EjeFdBx8`CsMVf$|=4ZW`c>b)3J ziHMVG$*g;MhE&@Iy#OTo^gxdQR6meZLZ8=m!`e|^!xdM?oc@pso?<^+1z2-BtEgf# zs!|{?tl7Yel=UYk2dL< ztG?JyK#iMVh2q&-MkQejzvz)7$xwK{Ih3)ycFPQi|B45@o@k`rOmK}ZhWN^0R>A%M2+WAa$81$Q(U zKL3{^)Ec}~E0<))EKV2i z8#1wRgQqBHzDgr#`^Y|FQ9b|?)*NVLcy;z9+2;T!ZEG$;^uo5% zy$k8+(9Bi*@ro(DQvzHxdRbkXf84%bGZNvQ$dpJK7K>~dk1&mr2`s2dG@xm!{;3FM zMlKGuFVh%$n!N?@iabbieiA16YvP@25pLO<;*XyOvHqAx6G?n0&n8H;&>u#5@;Hol z$ylDj3|K$D*QxpbYBigqb$A&DCHuZ@p>f^na9GuRA8y!-aa~ohPFtQBVsDWX84MTqBpcU6r{oTjSzWx0T)ug+N zYd-p}x`m$c?IH2gAubbJ3AE?WlF#O1M84{gvSC*NCfgy*uGKfY$sm5uV_)mEFVvIq zq|lfy51nUpUG-B?KQRm5G$JENi!7T8Qve_+${e_(sYlL~Oj)o9@AcrWv^lf&DG<+5 zKlX;wo-|yFU!TADyL~8V=E-@yZ2@kM=roVCJm8#>7##^ijrI@dLpEq5 zS>%yQwCu_{Ijl#S0_Cv(CgyX&knW+EzCKFFa4@y-Q|$Y6EC2D;IZ@RoI$wn=_-jP{ zyk$-Ls{LZwF{#SU-io=|G+`L=tY{O4^P>JYV_vWqd^;mYdYdFV3_puk__RZK0=KR$o;BdOsd0>uO?O>QnHs(Sn*y zMU#vX4c|f?Ymz-G2K1i8%Lng-0bCh21tR}XBmT-tRfac*up>5kgInm!e1m8#)NB3-1*|dLjw}NRN#x~xxX`n8*d%}OnrZ=>SlOkw4gf+gkppeY84;-px z7KpKzAuunUNh7Q2Hedp)r_@l<4A!cO6w_<(7vWe{`_iB+LM5Tj54~E>=&`+umnvuF zpKNlD8hOU+v@V`a>JwLyEG#xgG;9D9Sx4DV!n zuQyyOAUqd;e)w?SyIIsiUl4M}4jIm<;j!MbaI9h9Cy&;n_5^V}o~54QJyrWj`QuE# zscdKaIpbh(q-rg^muwji>SStYMNO`!exrbJohCl2KK@u(W3hG@OeCs8$k{a4DQ_NW zC2A_hgv>fwT*;h3f3IWf`cEYH#{A|WW*a$%ped>y9&{X_$@j`8Un8q_pO0;_5$`Q^ z7p=IP`IhWdY!&0PRpPkT`^96aHoQYyY4}JW3{`d&re=3mjZe<^1l5=w;D)pT4o_zH z_NC&@sB*~XStE6$(+cCs5ZQ4tLZ#a7@W*LM`lqU7=hv@ScKLHkAI}Gw-!a2;jxenx z!auAU?lDV{9B)Ahpiq(;x^Y%>7G{hsIupiYyu#ks3Z67QJc-SzIX`K3p{&RZBm4~d zG3p74<~k~|old3zSkC`t4zYeU9s_q87}t%D&g$5kU~|3{(;G71>hGt0LXWld4&ZGF z5J=PMjoLNITzW{OS4nVWe>1GX^xzDjGcrsS(|Ez+*jG6a6;xLx&o=xu3ITl*2FZsg ztHOb-o$(!=($=!3>=I+UEya+-#j{bmoc?*aN{7l?br`9;F{2oBY@NG6%MOeat&Y55 z(KQRNlHG6#)$5|*%Y`#lLlwY@QL#jkJLwk?b25?AEC^1? zi9dzAi)|-u1xBQ3O^t0H?6cR%mwIUDq=(0ix0E-iR+7`XD!-ffXl0P(Afv*nSA7E- z^#fGnAl6-BK2g3sc4K9iONv7j=e zZ=KRlXY2hdJmZWAjvEZ!?@X`C^k2`jvX_qH<*LM_+;(F@#(^EH^bYM@+^&X)hMW3HkE%Oy6Je z*UQ4R+u)ekL`)KdF0b9FDy z&hh=R(jLrYi1r+Oz5b^Gy05&doThkC-`A7GLkcC&yG&8;BX{doF!PY%RCOIqyF75k zN8I{H(>fKF$y=H$NHCma--QPvwIr2a<}xFD{MEf@3248vBH9m#n?l)RNhd1&&mpx1xP zW4TiKCA=F(@QSgc;ay(JN_23?UDqG!j=aZP(Bq?0^y@s{G4Z&Ai9u$W>|lk1uJMAh zS)49+`TPa>y2oLlbNp%|=eMaG(8O&)b8{zyVPMNh#{UFTRkrlB`im+*QVp=od3U=tHh zj65C%mX7e}@~lgF65jPLZz1&glN^n)Z+Nrz`EJ87j!1h!m2NDjNTxsndyZ9|shYbvL5D4J?pF>Ve zRftYXUYtQrNM1@@OhuJmPW)}+Z%S2)s`$(Cm}L)eq7x_x2+W@V5F_9-dPipmYcmtq zKaafwoE4P$d^rewUk5k~?yp&Dz*p!^Y>ix89F1Hp|C~pXr7Eskrbo{MOt^&~1mt(_ z{|rT-F8CjkdqOTIR#u8e_GY&K5B4YMD=>j;epCl=;GtrG@w<`epRow!{u?A>Y2<8V z;%eqBYUFD4UtlLt{tvrHUR)YjM0H>hejAqkGpK-FO#cRoJJ`Gam-9O@35Jt|1mNU$ zU=aNS0Y2&={)?k(WoxGDY-I0Z?%-@^=KNpUZyPnZGCbI2SP+moV4(j+%OLrSX5z@o z!tuLZ>d!(|1J8@Md1LMcSdx2S{C!?uKK+;QkH+DjoZp$O+5@-5AcBB=0mk2)8_EC0 zVgAg-{O^2>fE{2f^}Xh1;t=>E;Q()eE-_Rmc0|K|M8C#-rCGYn`w7YK}xe^mxQ z_*$|xoc}*4T>qbB{uIvtyEt)Oe_{URefRGo|EW$1{M7w1 z^rrse{8x1UPtJ&R~q2vU!ecpz^5n!3HAF- RP=L2K;0n8>1g=?-{{seTn|J^K literal 0 HcmV?d00001 diff --git a/roguelike/impl/pom.xml b/roguelike/impl/pom.xml new file mode 100644 index 0000000..9724b40 --- /dev/null +++ b/roguelike/impl/pom.xml @@ -0,0 +1,21 @@ + + + 4.0.0 + + simiyutin + roguelike + 1.0-SNAPSHOT + + + net.trystan + ascii-panel + 1.1 + system + ${project.basedir}/libs/ascii-panel/asciiPanel.jar + + + + + \ No newline at end of file diff --git a/roguelike/impl/src/main/java/Game.java b/roguelike/impl/src/main/java/Game.java new file mode 100644 index 0000000..01de6e0 --- /dev/null +++ b/roguelike/impl/src/main/java/Game.java @@ -0,0 +1,5 @@ +/** + * Created by boris on 08.05.17. + */ +public class Game { +} diff --git a/roguelike/impl/src/main/java/Main.java b/roguelike/impl/src/main/java/Main.java new file mode 100644 index 0000000..7d15efb --- /dev/null +++ b/roguelike/impl/src/main/java/Main.java @@ -0,0 +1,11 @@ +/** + * Created by boris on 08.05.17. + */ +public class Main { + public static void main(String[] args) { + Game game = new Game(); + final int framerate = 60; + Scheduler scheduler = new Scheduler(framerate); + scheduler.schedule(game); + } +} diff --git a/roguelike/impl/src/main/java/Scheduler.java b/roguelike/impl/src/main/java/Scheduler.java new file mode 100644 index 0000000..f622ea2 --- /dev/null +++ b/roguelike/impl/src/main/java/Scheduler.java @@ -0,0 +1,53 @@ +import asciiPanel.AsciiPanel; +import io.Screen; +import io.StartScreen; + +import javax.swing.*; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +/** + * Created by boris on 08.05.17. + */ +public class Scheduler extends JFrame implements KeyListener { + private int framerate; + private AsciiPanel terminal; + private Screen screen; + + public Scheduler(int framerate) { + super(); + this.framerate = framerate; + this.terminal = new AsciiPanel(); + add(terminal); + pack(); + this.screen = new StartScreen(); + addKeyListener(this); + repaint(); + } + + public void schedule(Game game) { + + setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + setVisible(true); + } + + public void keyTyped(KeyEvent e) { + + } + + public void keyPressed(KeyEvent e) { + screen = screen.respondToUserInput(e); + repaint(); + } + + public void keyReleased(KeyEvent e) { + + } + + @Override + public void repaint() { + terminal.clear(); + screen.display(terminal); + super.repaint(); + } +} diff --git a/roguelike/impl/src/main/java/io/PlayScreen.java b/roguelike/impl/src/main/java/io/PlayScreen.java new file mode 100644 index 0000000..f9c8626 --- /dev/null +++ b/roguelike/impl/src/main/java/io/PlayScreen.java @@ -0,0 +1,18 @@ +package io; + +import asciiPanel.AsciiPanel; + +import java.awt.event.KeyEvent; + +/** + * Created by boris on 08.05.17. + */ +public class PlayScreen implements Screen { + public void display(AsciiPanel terminal) { + terminal.writeCenter("game started", 22); + } + + public Screen respondToUserInput(KeyEvent key) { + return this; + } +} diff --git a/roguelike/impl/src/main/java/io/Screen.java b/roguelike/impl/src/main/java/io/Screen.java new file mode 100644 index 0000000..fbd9633 --- /dev/null +++ b/roguelike/impl/src/main/java/io/Screen.java @@ -0,0 +1,13 @@ +package io; + +import asciiPanel.AsciiPanel; + +import java.awt.event.KeyEvent; + +/** + * Created by boris on 08.05.17. + */ +public interface Screen { + void display(AsciiPanel terminal); + Screen respondToUserInput(KeyEvent key); +} diff --git a/roguelike/impl/src/main/java/io/StartScreen.java b/roguelike/impl/src/main/java/io/StartScreen.java new file mode 100644 index 0000000..3dbfe8f --- /dev/null +++ b/roguelike/impl/src/main/java/io/StartScreen.java @@ -0,0 +1,19 @@ +package io; + +import asciiPanel.AsciiPanel; + +import java.awt.event.KeyEvent; + +/** + * Created by boris on 08.05.17. + */ +public class StartScreen implements Screen { + public void display(AsciiPanel terminal) { + final int onHeight = 22; + terminal.writeCenter("Press [enter] to start", onHeight); + } + + public Screen respondToUserInput(KeyEvent key) { + return key.getKeyCode() == KeyEvent.VK_ENTER ? new PlayScreen() : this; + } +} From 898333d6338a115f6844b8cd99ed4f5fb42636d3 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Mon, 8 May 2017 23:28:26 +0300 Subject: [PATCH 21/63] first world --- .gitignore | 2 + .../impl/src/main/java/io/PlayScreen.java | 18 ----- .../src/main/java/{ => roguelike}/Game.java | 2 + .../src/main/java/{ => roguelike}/Main.java | 5 +- .../main/java/{ => roguelike}/Scheduler.java | 17 ++--- .../src/main/java/roguelike/WorldFactory.java | 24 +++++++ .../src/main/java/roguelike/models/Tile.java | 30 +++++++++ .../src/main/java/roguelike/models/World.java | 38 +++++++++++ .../java/roguelike/screens/PlayScreen.java | 67 +++++++++++++++++++ .../{io => roguelike/screens}/Screen.java | 2 +- .../screens}/StartScreen.java | 2 +- 11 files changed, 177 insertions(+), 30 deletions(-) delete mode 100644 roguelike/impl/src/main/java/io/PlayScreen.java rename roguelike/impl/src/main/java/{ => roguelike}/Game.java (75%) rename roguelike/impl/src/main/java/{ => roguelike}/Main.java (66%) rename roguelike/impl/src/main/java/{ => roguelike}/Scheduler.java (83%) create mode 100644 roguelike/impl/src/main/java/roguelike/WorldFactory.java create mode 100644 roguelike/impl/src/main/java/roguelike/models/Tile.java create mode 100644 roguelike/impl/src/main/java/roguelike/models/World.java create mode 100644 roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java rename roguelike/impl/src/main/java/{io => roguelike/screens}/Screen.java (88%) rename roguelike/impl/src/main/java/{io => roguelike/screens}/StartScreen.java (94%) diff --git a/.gitignore b/.gitignore index 362bb5b..c35a209 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /**/.idea/ /**/build /**/*.vpp.* +/**/*.iml +/**/*.class diff --git a/roguelike/impl/src/main/java/io/PlayScreen.java b/roguelike/impl/src/main/java/io/PlayScreen.java deleted file mode 100644 index f9c8626..0000000 --- a/roguelike/impl/src/main/java/io/PlayScreen.java +++ /dev/null @@ -1,18 +0,0 @@ -package io; - -import asciiPanel.AsciiPanel; - -import java.awt.event.KeyEvent; - -/** - * Created by boris on 08.05.17. - */ -public class PlayScreen implements Screen { - public void display(AsciiPanel terminal) { - terminal.writeCenter("game started", 22); - } - - public Screen respondToUserInput(KeyEvent key) { - return this; - } -} diff --git a/roguelike/impl/src/main/java/Game.java b/roguelike/impl/src/main/java/roguelike/Game.java similarity index 75% rename from roguelike/impl/src/main/java/Game.java rename to roguelike/impl/src/main/java/roguelike/Game.java index 01de6e0..3a24758 100644 --- a/roguelike/impl/src/main/java/Game.java +++ b/roguelike/impl/src/main/java/roguelike/Game.java @@ -1,3 +1,5 @@ +package roguelike; + /** * Created by boris on 08.05.17. */ diff --git a/roguelike/impl/src/main/java/Main.java b/roguelike/impl/src/main/java/roguelike/Main.java similarity index 66% rename from roguelike/impl/src/main/java/Main.java rename to roguelike/impl/src/main/java/roguelike/Main.java index 7d15efb..274346f 100644 --- a/roguelike/impl/src/main/java/Main.java +++ b/roguelike/impl/src/main/java/roguelike/Main.java @@ -1,11 +1,12 @@ +package roguelike; + /** * Created by boris on 08.05.17. */ public class Main { public static void main(String[] args) { Game game = new Game(); - final int framerate = 60; - Scheduler scheduler = new Scheduler(framerate); + Scheduler scheduler = new Scheduler(); scheduler.schedule(game); } } diff --git a/roguelike/impl/src/main/java/Scheduler.java b/roguelike/impl/src/main/java/roguelike/Scheduler.java similarity index 83% rename from roguelike/impl/src/main/java/Scheduler.java rename to roguelike/impl/src/main/java/roguelike/Scheduler.java index f622ea2..58f57dc 100644 --- a/roguelike/impl/src/main/java/Scheduler.java +++ b/roguelike/impl/src/main/java/roguelike/Scheduler.java @@ -1,26 +1,27 @@ +package roguelike; + import asciiPanel.AsciiPanel; -import io.Screen; -import io.StartScreen; +import roguelike.screens.Screen; +import roguelike.screens.StartScreen; import javax.swing.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; -/** - * Created by boris on 08.05.17. - */ + public class Scheduler extends JFrame implements KeyListener { - private int framerate; private AsciiPanel terminal; private Screen screen; - public Scheduler(int framerate) { + public Scheduler() { super(); - this.framerate = framerate; + this.terminal = new AsciiPanel(); add(terminal); pack(); + this.screen = new StartScreen(); + addKeyListener(this); repaint(); } diff --git a/roguelike/impl/src/main/java/roguelike/WorldFactory.java b/roguelike/impl/src/main/java/roguelike/WorldFactory.java new file mode 100644 index 0000000..8a4e63f --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/WorldFactory.java @@ -0,0 +1,24 @@ +package roguelike; + +import roguelike.models.Tile; +import roguelike.models.World; + +/** + * Created by boris on 08.05.17. + */ +public class WorldFactory { + public static World getWorld() { + Tile[][] tiles = new Tile[100][100]; + for (int i = 0; i < 100; i++) { + for (int j = 0; j < 100; j++) { + tiles[i][j] = Tile.FLOOR; + } + } + + for (int i = 0; i < 100; i++) { + tiles[i][i] = Tile.WALL; + } + + return new World(tiles); + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/Tile.java b/roguelike/impl/src/main/java/roguelike/models/Tile.java new file mode 100644 index 0000000..6f98acc --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/Tile.java @@ -0,0 +1,30 @@ +package roguelike.models; + +import asciiPanel.AsciiPanel; + +import java.awt.*; + +/** + * Created by boris on 08.05.17. + */ +public enum Tile { + FLOOR('.', AsciiPanel.yellow), + WALL('#', AsciiPanel.yellow), + BOUNDS('x', AsciiPanel.brightBlack); + + private char glyph; + private Color color; + + Tile(char glyph, Color color) { + this.glyph = glyph; + this.color = color; + } + + public char getGlyph() { + return glyph; + } + + public Color getColor() { + return color; + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java new file mode 100644 index 0000000..57ab441 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -0,0 +1,38 @@ +package roguelike.models; + +import java.awt.*; + +/** + * Created by boris on 08.05.17. + */ +public class World { + private Tile[][] tiles; + private int width; + private int height; + + public World(Tile[][] tiles) { + this.tiles = tiles; + this.height = tiles.length; + this.width = tiles[0].length; + } + + public Tile getTile(int x, int y) { + return tiles[y][x]; + } + + public char getGlyph(int x, int y) { + return getTile(x, y).getGlyph(); + } + + public Color getColor(int x, int y) { + return getTile(x, y).getColor(); + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } +} diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java new file mode 100644 index 0000000..d987ba9 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -0,0 +1,67 @@ +package roguelike.screens; + +import asciiPanel.AsciiPanel; +import roguelike.WorldFactory; +import roguelike.models.World; + + +import java.awt.event.KeyEvent; + +/** + * Created by boris on 08.05.17. + */ +public class PlayScreen implements Screen { + + private World world; + private int centerX; + private int centerY; + private int screenWidth = 80; + private int screenHeight = 23; + + public PlayScreen() { + + world = WorldFactory.getWorld(); + centerX = world.getWidth() / 2; + centerY = world.getHeight() / 2; + } + + public void display(AsciiPanel terminal) { + int left = scrollLeft(); + int top = scrollTop(); + displayWorld(terminal, left, top); + } + + private int scrollLeft() { + return Math.max(0, Math.min(centerX - screenWidth / 2, world.getWidth() - screenWidth)); + } + + private int scrollTop() { + return Math.max(0, Math.min(centerY - screenHeight / 2, world.getHeight() - screenHeight)); + } + + private void scrollBy(int dx, int dy) { + centerX = Math.max(0, Math.min(centerX + dx, world.getWidth() - 1)); + centerY = Math.max(0, Math.min(centerY + dy, world.getHeight() - 1)); + } + + public Screen respondToUserInput(KeyEvent key) { + switch (key.getKeyCode()) { + case KeyEvent.VK_S: + scrollBy(0, 1); + break; + } + return this; + } + + public void displayWorld(AsciiPanel terminal, int left, int top) { + + for (int x = 0; x < screenWidth; x++) { + for (int y = 0; y < screenHeight; y++) { + int wx = x + left; + int wy = y + top; + + terminal.write(world.getGlyph(wx, wy), x, y, world.getColor(wx, wy)); + } + } + } +} diff --git a/roguelike/impl/src/main/java/io/Screen.java b/roguelike/impl/src/main/java/roguelike/screens/Screen.java similarity index 88% rename from roguelike/impl/src/main/java/io/Screen.java rename to roguelike/impl/src/main/java/roguelike/screens/Screen.java index fbd9633..6a172ce 100644 --- a/roguelike/impl/src/main/java/io/Screen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/Screen.java @@ -1,4 +1,4 @@ -package io; +package roguelike.screens; import asciiPanel.AsciiPanel; diff --git a/roguelike/impl/src/main/java/io/StartScreen.java b/roguelike/impl/src/main/java/roguelike/screens/StartScreen.java similarity index 94% rename from roguelike/impl/src/main/java/io/StartScreen.java rename to roguelike/impl/src/main/java/roguelike/screens/StartScreen.java index 3dbfe8f..7bc0f0c 100644 --- a/roguelike/impl/src/main/java/io/StartScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/StartScreen.java @@ -1,4 +1,4 @@ -package io; +package roguelike.screens; import asciiPanel.AsciiPanel; From 20848c6c3de1027b174d8a42713944b25ba7adac Mon Sep 17 00:00:00 2001 From: simiyutin Date: Tue, 9 May 2017 00:14:38 +0300 Subject: [PATCH 22/63] randomized world --- .../src/main/java/roguelike/WorldFactory.java | 24 ------- .../src/main/java/roguelike/models/World.java | 6 +- .../java/roguelike/models/WorldBuilder.java | 68 +++++++++++++++++++ .../java/roguelike/screens/PlayScreen.java | 13 +++- 4 files changed, 82 insertions(+), 29 deletions(-) delete mode 100644 roguelike/impl/src/main/java/roguelike/WorldFactory.java create mode 100644 roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java diff --git a/roguelike/impl/src/main/java/roguelike/WorldFactory.java b/roguelike/impl/src/main/java/roguelike/WorldFactory.java deleted file mode 100644 index 8a4e63f..0000000 --- a/roguelike/impl/src/main/java/roguelike/WorldFactory.java +++ /dev/null @@ -1,24 +0,0 @@ -package roguelike; - -import roguelike.models.Tile; -import roguelike.models.World; - -/** - * Created by boris on 08.05.17. - */ -public class WorldFactory { - public static World getWorld() { - Tile[][] tiles = new Tile[100][100]; - for (int i = 0; i < 100; i++) { - for (int j = 0; j < 100; j++) { - tiles[i][j] = Tile.FLOOR; - } - } - - for (int i = 0; i < 100; i++) { - tiles[i][i] = Tile.WALL; - } - - return new World(tiles); - } -} diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java index 57ab441..9b203a1 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -12,12 +12,12 @@ public class World { public World(Tile[][] tiles) { this.tiles = tiles; - this.height = tiles.length; - this.width = tiles[0].length; + this.width = tiles.length; + this.height = tiles[0].length; } public Tile getTile(int x, int y) { - return tiles[y][x]; + return tiles[x][y]; } public char getGlyph(int x, int y) { diff --git a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java new file mode 100644 index 0000000..aae5506 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java @@ -0,0 +1,68 @@ +package roguelike.models; + +import roguelike.models.Tile; +import roguelike.models.World; + +/** + * Created by boris on 08.05.17. + */ +public class WorldBuilder { + + private int width; + private int height; + private Tile[][] tiles; + + public WorldBuilder(int width, int height) { + this.width = width; + this.height = height; + this.tiles = new Tile[width][height]; + + } + + public World build() { + return new World(tiles); + } + + public WorldBuilder makeCaves() { + return randomizeTiles() + .smooth(8); + } + + private WorldBuilder randomizeTiles() { + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + tiles[x][y] = Math.random() < 0.5 ? Tile.FLOOR : Tile.WALL; + } + } + return this; + } + + private WorldBuilder smooth(int times) { + Tile[][] tiles2 = new Tile[width][height]; + for (int time = 0; time < times; time++) { + + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + int floors = 0; + int rocks = 0; + + for (int ox = -1; ox < 2; ox++) { + for (int oy = -1; oy < 2; oy++) { + if (x + ox < 0 || x + ox >= width || y + oy < 0 + || y + oy >= height) + continue; + + if (tiles[x + ox][y + oy] == Tile.FLOOR) + floors++; + else + rocks++; + } + } + tiles2[x][y] = floors >= rocks ? Tile.FLOOR : Tile.WALL; + } + } + tiles = tiles2; + } + return this; + } +} diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index d987ba9..17069f4 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -1,7 +1,7 @@ package roguelike.screens; import asciiPanel.AsciiPanel; -import roguelike.WorldFactory; +import roguelike.models.WorldBuilder; import roguelike.models.World; @@ -20,7 +20,7 @@ public class PlayScreen implements Screen { public PlayScreen() { - world = WorldFactory.getWorld(); + world = new WorldBuilder(100, 100).makeCaves().build(); centerX = world.getWidth() / 2; centerY = world.getHeight() / 2; } @@ -49,6 +49,15 @@ public Screen respondToUserInput(KeyEvent key) { case KeyEvent.VK_S: scrollBy(0, 1); break; + case KeyEvent.VK_W: + scrollBy(0, -1); + break; + case KeyEvent.VK_A: + scrollBy(-1, 0); + break; + case KeyEvent.VK_D: + scrollBy(1, 0); + break; } return this; } From 69094ae3b3a19b5294114b5bb9c39d886d019779 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Tue, 9 May 2017 00:20:07 +0300 Subject: [PATCH 23/63] display player --- .../impl/src/main/java/roguelike/screens/PlayScreen.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index 17069f4..b81115f 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -5,6 +5,7 @@ import roguelike.models.World; +import java.awt.*; import java.awt.event.KeyEvent; /** @@ -29,6 +30,7 @@ public void display(AsciiPanel terminal) { int left = scrollLeft(); int top = scrollTop(); displayWorld(terminal, left, top); + displayPlayer(terminal); } private int scrollLeft() { @@ -62,6 +64,10 @@ public Screen respondToUserInput(KeyEvent key) { return this; } + public void displayPlayer(AsciiPanel terminal) { + terminal.write('X', centerX - scrollLeft(), centerY - scrollTop(), Color.BLUE); + } + public void displayWorld(AsciiPanel terminal, int left, int top) { for (int x = 0; x < screenWidth; x++) { From 35c329a7ad23c3f66530585653a5798c78876528 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Tue, 9 May 2017 11:38:29 +0300 Subject: [PATCH 24/63] beings and player --- roguelike/impl/pom.xml | 16 ++++++ .../src/main/java/roguelike/models/Being.java | 56 +++++++++++++++++++ .../main/java/roguelike/models/Player.java | 16 ++++++ .../src/main/java/roguelike/models/Tile.java | 8 +++ .../src/main/java/roguelike/models/World.java | 22 +++++++- .../java/roguelike/screens/PlayScreen.java | 34 ++++++----- 6 files changed, 133 insertions(+), 19 deletions(-) create mode 100644 roguelike/impl/src/main/java/roguelike/models/Being.java create mode 100644 roguelike/impl/src/main/java/roguelike/models/Player.java diff --git a/roguelike/impl/pom.xml b/roguelike/impl/pom.xml index 9724b40..c3da1fc 100644 --- a/roguelike/impl/pom.xml +++ b/roguelike/impl/pom.xml @@ -7,6 +7,18 @@ simiyutin roguelike 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 1.8 + 1.8 + + + net.trystan @@ -18,4 +30,8 @@ + + + + \ No newline at end of file diff --git a/roguelike/impl/src/main/java/roguelike/models/Being.java b/roguelike/impl/src/main/java/roguelike/models/Being.java new file mode 100644 index 0000000..7806a3c --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/Being.java @@ -0,0 +1,56 @@ +package roguelike.models; + +import asciiPanel.AsciiPanel; + +import java.awt.*; +import java.util.Random; + +/** + * Created by boris on 09.05.17. + */ +public abstract class Being { + public int x; + public int y; + private int xDirection; + private int yDirection; + + protected char glyph; + protected Color color; + protected World world; + + Being(World world) { + this.world = world; + + Random randomGen = new Random(42); + + do { + + x = randomGen.nextInt(world.getWidth()); + y = randomGen.nextInt(world.getHeight()); + + } while (world.getTile(x, y) != Tile.FLOOR); + } + + public char getGlyph() { + return glyph; + } + + public Color getColor() { + return color; + } + + public void move(int dx, int dy) { + xDirection = Math.max(0, Math.min(x + dx, world.getWidth() - 1)); + yDirection = Math.max(0, Math.min(y + dy, world.getHeight() - 1)); + if (world.getTile(xDirection, yDirection).isWalkable()) { + x = xDirection; + y = yDirection; + } + } + + public void dig() { + if (world.getTile(xDirection, yDirection).isDiggable()) { + world.setTile(xDirection, yDirection, Tile.FLOOR); + } + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/Player.java b/roguelike/impl/src/main/java/roguelike/models/Player.java new file mode 100644 index 0000000..917ef3e --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/Player.java @@ -0,0 +1,16 @@ +package roguelike.models; + +import java.awt.*; + +/** + * Created by boris on 09.05.17. + */ +public class Player extends Being { + + public Player(World world) { + super(world); + + this.glyph = 'X'; + this.color = Color.BLUE; + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/Tile.java b/roguelike/impl/src/main/java/roguelike/models/Tile.java index 6f98acc..32adf2d 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Tile.java +++ b/roguelike/impl/src/main/java/roguelike/models/Tile.java @@ -27,4 +27,12 @@ public char getGlyph() { public Color getColor() { return color; } + + public boolean isWalkable() { + return this == FLOOR; + } + + public boolean isDiggable() { + return this == WALL; + } } diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java index 9b203a1..fabe1bf 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -1,6 +1,9 @@ package roguelike.models; -import java.awt.*; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.List; /** * Created by boris on 08.05.17. @@ -9,17 +12,26 @@ public class World { private Tile[][] tiles; private int width; private int height; + private Player player; + private List mobs; public World(Tile[][] tiles) { this.tiles = tiles; this.width = tiles.length; this.height = tiles[0].length; + + this.player = new Player(this); + this.mobs = new ArrayList<>(); } public Tile getTile(int x, int y) { return tiles[x][y]; } + public void setTile(int x, int y, Tile tile) { + tiles[x][y] = tile; + } + public char getGlyph(int x, int y) { return getTile(x, y).getGlyph(); } @@ -35,4 +47,12 @@ public int getWidth() { public int getHeight() { return height; } + + public Player getPlayer() { + return player; + } + + public List getMobs() { + return mobs; + } } diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index b81115f..49f684a 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -1,6 +1,7 @@ package roguelike.screens; import asciiPanel.AsciiPanel; +import roguelike.models.Player; import roguelike.models.WorldBuilder; import roguelike.models.World; @@ -14,58 +15,55 @@ public class PlayScreen implements Screen { private World world; - private int centerX; - private int centerY; + private Player player; private int screenWidth = 80; private int screenHeight = 23; public PlayScreen() { world = new WorldBuilder(100, 100).makeCaves().build(); - centerX = world.getWidth() / 2; - centerY = world.getHeight() / 2; + player = world.getPlayer(); } public void display(AsciiPanel terminal) { int left = scrollLeft(); int top = scrollTop(); displayWorld(terminal, left, top); - displayPlayer(terminal); + displayPlayer(terminal, left, top); } private int scrollLeft() { - return Math.max(0, Math.min(centerX - screenWidth / 2, world.getWidth() - screenWidth)); + return Math.max(0, Math.min(player.x - screenWidth / 2, world.getWidth() - screenWidth)); } private int scrollTop() { - return Math.max(0, Math.min(centerY - screenHeight / 2, world.getHeight() - screenHeight)); - } - - private void scrollBy(int dx, int dy) { - centerX = Math.max(0, Math.min(centerX + dx, world.getWidth() - 1)); - centerY = Math.max(0, Math.min(centerY + dy, world.getHeight() - 1)); + return Math.max(0, Math.min(player.y - screenHeight / 2, world.getHeight() - screenHeight)); } public Screen respondToUserInput(KeyEvent key) { switch (key.getKeyCode()) { case KeyEvent.VK_S: - scrollBy(0, 1); + player.move(0, 1); break; case KeyEvent.VK_W: - scrollBy(0, -1); + player.move(0, -1); break; case KeyEvent.VK_A: - scrollBy(-1, 0); + player.move(-1, 0); break; case KeyEvent.VK_D: - scrollBy(1, 0); + player.move(1, 0); + break; + case KeyEvent.VK_F: + player.dig(); break; } return this; } - public void displayPlayer(AsciiPanel terminal) { - terminal.write('X', centerX - scrollLeft(), centerY - scrollTop(), Color.BLUE); + public void displayPlayer(AsciiPanel terminal, int left, int top) { + Player p = world.getPlayer(); + terminal.write(p.getGlyph(), p.x - left, p.y - top, p.getColor()); } public void displayWorld(AsciiPanel terminal, int left, int top) { From 963710cecf5a5f4cbf18f474470f90476e685249 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Tue, 9 May 2017 12:27:04 +0300 Subject: [PATCH 25/63] mushrooms --- .../src/main/java/roguelike/models/Being.java | 4 +-- .../main/java/roguelike/models/Mushroom.java | 16 ++++++++++ .../src/main/java/roguelike/models/World.java | 3 +- .../java/roguelike/models/WorldBuilder.java | 32 +++++++++++++++++-- .../java/roguelike/screens/PlayScreen.java | 27 +++++++++++----- 5 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 roguelike/impl/src/main/java/roguelike/models/Mushroom.java diff --git a/roguelike/impl/src/main/java/roguelike/models/Being.java b/roguelike/impl/src/main/java/roguelike/models/Being.java index 7806a3c..ff97d8a 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Being.java +++ b/roguelike/impl/src/main/java/roguelike/models/Being.java @@ -18,7 +18,7 @@ public abstract class Being { protected Color color; protected World world; - Being(World world) { + public Being(World world) { this.world = world; Random randomGen = new Random(42); @@ -28,7 +28,7 @@ public abstract class Being { x = randomGen.nextInt(world.getWidth()); y = randomGen.nextInt(world.getHeight()); - } while (world.getTile(x, y) != Tile.FLOOR); + } while (world.getTile(x, y) != Tile.FLOOR || world.getMobs().stream().anyMatch(b -> b.x == x && b.y == y)); } public char getGlyph() { diff --git a/roguelike/impl/src/main/java/roguelike/models/Mushroom.java b/roguelike/impl/src/main/java/roguelike/models/Mushroom.java new file mode 100644 index 0000000..b5f907d --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/Mushroom.java @@ -0,0 +1,16 @@ +package roguelike.models; + +import java.awt.*; + +/** + * Created by boris on 09.05.17. + */ +public class Mushroom extends Being { + + public Mushroom(World world) { + super(world); + + this.glyph = 'T'; + this.color = Color.GREEN; + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java index fabe1bf..31787dc 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -20,8 +20,9 @@ public World(Tile[][] tiles) { this.width = tiles.length; this.height = tiles[0].length; - this.player = new Player(this); this.mobs = new ArrayList<>(); + this.player = new Player(this); + this.mobs.add(this.player); } public Tile getTile(int x, int y) { diff --git a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java index aae5506..800e345 100644 --- a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java +++ b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java @@ -3,6 +3,13 @@ import roguelike.models.Tile; import roguelike.models.World; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + /** * Created by boris on 08.05.17. */ @@ -11,16 +18,26 @@ public class WorldBuilder { private int width; private int height; private Tile[][] tiles; + private List> mobs; public WorldBuilder(int width, int height) { this.width = width; this.height = height; this.tiles = new Tile[width][height]; - + this.mobs = new ArrayList<>(); } public World build() { - return new World(tiles); + World world = new World(tiles); + for (Constructor c : mobs) { + try { + world.getMobs().add(c.newInstance(world)); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } + + return world; } public WorldBuilder makeCaves() { @@ -28,6 +45,17 @@ public WorldBuilder makeCaves() { .smooth(8); } + public WorldBuilder addMobs(Class clazz, int quantity) { + for (int i = 0; i < quantity; i++) { + try { + mobs.add(clazz.getConstructor(World.class)); + } catch (NoSuchMethodException ex) { + ex.printStackTrace(); + } + } + return this; + } + private WorldBuilder randomizeTiles() { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index 49f684a..bfd901a 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -1,9 +1,7 @@ package roguelike.screens; import asciiPanel.AsciiPanel; -import roguelike.models.Player; -import roguelike.models.WorldBuilder; -import roguelike.models.World; +import roguelike.models.*; import java.awt.*; @@ -21,7 +19,11 @@ public class PlayScreen implements Screen { public PlayScreen() { - world = new WorldBuilder(100, 100).makeCaves().build(); + world = new WorldBuilder(100, 100) + .makeCaves() + .addMobs(Mushroom.class, 10) + .build(); + player = world.getPlayer(); } @@ -29,7 +31,7 @@ public void display(AsciiPanel terminal) { int left = scrollLeft(); int top = scrollTop(); displayWorld(terminal, left, top); - displayPlayer(terminal, left, top); + displayMobs(terminal, left, top); } private int scrollLeft() { @@ -61,9 +63,18 @@ public Screen respondToUserInput(KeyEvent key) { return this; } - public void displayPlayer(AsciiPanel terminal, int left, int top) { - Player p = world.getPlayer(); - terminal.write(p.getGlyph(), p.x - left, p.y - top, p.getColor()); + public void displayMobs(AsciiPanel terminal, int left, int top) { + + for (Being b: world.getMobs()) { + writeSafe(terminal, b.getGlyph(), b.x - left, b.y - top, b.getColor()); + } + + } + + private void writeSafe(AsciiPanel terminal, char c, int x, int y, Color color) { + if (x > 0 && x < screenWidth && y > 0 && y < screenHeight) { + terminal.write(c, x, y, color); + } } public void displayWorld(AsciiPanel terminal, int left, int top) { From 368b3b928af691a4ee13546fb787dd6a382ecf13 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Tue, 9 May 2017 13:11:13 +0300 Subject: [PATCH 26/63] dead screen & health display --- .../src/main/java/roguelike/models/Being.java | 10 +++++++++ .../main/java/roguelike/models/Mushroom.java | 14 +++++++++++++ .../main/java/roguelike/models/Player.java | 5 +++++ .../src/main/java/roguelike/models/Tile.java | 17 ++++++++++----- .../src/main/java/roguelike/models/World.java | 3 +++ .../java/roguelike/screens/DeadScreen.java | 21 +++++++++++++++++++ .../java/roguelike/screens/PlayScreen.java | 9 ++++++-- .../main/java/roguelike/screens/Screen.java | 4 ++++ .../java/roguelike/screens/StartScreen.java | 6 ++++-- 9 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 roguelike/impl/src/main/java/roguelike/screens/DeadScreen.java diff --git a/roguelike/impl/src/main/java/roguelike/models/Being.java b/roguelike/impl/src/main/java/roguelike/models/Being.java index ff97d8a..6851d58 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Being.java +++ b/roguelike/impl/src/main/java/roguelike/models/Being.java @@ -17,9 +17,11 @@ public abstract class Being { protected char glyph; protected Color color; protected World world; + protected int health; public Being(World world) { this.world = world; + this.health = 100; Random randomGen = new Random(42); @@ -39,6 +41,10 @@ public Color getColor() { return color; } + public int getHealth() { + return health; + } + public void move(int dx, int dy) { xDirection = Math.max(0, Math.min(x + dx, world.getWidth() - 1)); yDirection = Math.max(0, Math.min(y + dy, world.getHeight() - 1)); @@ -46,6 +52,8 @@ public void move(int dx, int dy) { x = xDirection; y = yDirection; } + + respondToMove(); } public void dig() { @@ -53,4 +61,6 @@ public void dig() { world.setTile(xDirection, yDirection, Tile.FLOOR); } } + + protected void respondToMove() {} } diff --git a/roguelike/impl/src/main/java/roguelike/models/Mushroom.java b/roguelike/impl/src/main/java/roguelike/models/Mushroom.java index b5f907d..f1bb50b 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Mushroom.java +++ b/roguelike/impl/src/main/java/roguelike/models/Mushroom.java @@ -12,5 +12,19 @@ public Mushroom(World world) { this.glyph = 'T'; this.color = Color.GREEN; + poisonTiles(); + + } + + private void poisonTiles() { + for (int i = -2; i < 3; i++) { + for (int j = -2; j < 3; j++) { + int wx = x + i; + int wy = y + j; + if (i * i + j * j <= 5 && world.getTile(wx, wy) == Tile.FLOOR) { + world.setTile(wx, wy, Tile.POISONED_FLOOR); + } + } + } } } diff --git a/roguelike/impl/src/main/java/roguelike/models/Player.java b/roguelike/impl/src/main/java/roguelike/models/Player.java index 917ef3e..91a7d6d 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Player.java +++ b/roguelike/impl/src/main/java/roguelike/models/Player.java @@ -13,4 +13,9 @@ public Player(World world) { this.glyph = 'X'; this.color = Color.BLUE; } + + @Override + protected void respondToMove() { + health -= world.getTile(x, y).getHarmness(); + } } diff --git a/roguelike/impl/src/main/java/roguelike/models/Tile.java b/roguelike/impl/src/main/java/roguelike/models/Tile.java index 32adf2d..df60224 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Tile.java +++ b/roguelike/impl/src/main/java/roguelike/models/Tile.java @@ -8,16 +8,19 @@ * Created by boris on 08.05.17. */ public enum Tile { - FLOOR('.', AsciiPanel.yellow), - WALL('#', AsciiPanel.yellow), - BOUNDS('x', AsciiPanel.brightBlack); + FLOOR('.', AsciiPanel.yellow, 0), + POISONED_FLOOR('.', Color.GREEN, 5), + WALL('#', AsciiPanel.yellow, 0), + BOUNDS('x', AsciiPanel.brightBlack, 0); private char glyph; private Color color; + private int harmness; - Tile(char glyph, Color color) { + Tile(char glyph, Color color, int harmness) { this.glyph = glyph; this.color = color; + this.harmness = harmness; } public char getGlyph() { @@ -28,8 +31,12 @@ public Color getColor() { return color; } + public int getHarmness() { + return harmness; + } + public boolean isWalkable() { - return this == FLOOR; + return this == FLOOR || this == POISONED_FLOOR; } public boolean isDiggable() { diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java index 31787dc..9583809 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -26,6 +26,9 @@ public World(Tile[][] tiles) { } public Tile getTile(int x, int y) { + if (x < 0 || x > width - 1 || y < 0 || y > height - 1) { + return Tile.BOUNDS; + } return tiles[x][y]; } diff --git a/roguelike/impl/src/main/java/roguelike/screens/DeadScreen.java b/roguelike/impl/src/main/java/roguelike/screens/DeadScreen.java new file mode 100644 index 0000000..9e0d2e8 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/screens/DeadScreen.java @@ -0,0 +1,21 @@ +package roguelike.screens; + +import asciiPanel.AsciiPanel; + +import java.awt.event.KeyEvent; + +/** + * Created by boris on 09.05.17. + */ +public class DeadScreen implements Screen { + + @Override + public void display(AsciiPanel terminal) { + print(terminal, "You are dead"); + } + + @Override + public Screen respondToUserInput(KeyEvent key) { + return this; + } +} diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index bfd901a..a4b6098 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -15,7 +15,7 @@ public class PlayScreen implements Screen { private World world; private Player player; private int screenWidth = 80; - private int screenHeight = 23; + private int screenHeight = 24; public PlayScreen() { @@ -32,6 +32,7 @@ public void display(AsciiPanel terminal) { int top = scrollTop(); displayWorld(terminal, left, top); displayMobs(terminal, left, top); + displayHealth(terminal); } private int scrollLeft() { @@ -60,7 +61,7 @@ public Screen respondToUserInput(KeyEvent key) { player.dig(); break; } - return this; + return player.getHealth() > 0 ? this : new DeadScreen(); } public void displayMobs(AsciiPanel terminal, int left, int top) { @@ -77,6 +78,10 @@ private void writeSafe(AsciiPanel terminal, char c, int x, int y, Color color) { } } + public void displayHealth(AsciiPanel terminal) { + terminal.write(String.format("health: %s", player.getHealth()), 67, 1); + } + public void displayWorld(AsciiPanel terminal, int left, int top) { for (int x = 0; x < screenWidth; x++) { diff --git a/roguelike/impl/src/main/java/roguelike/screens/Screen.java b/roguelike/impl/src/main/java/roguelike/screens/Screen.java index 6a172ce..7a6b08b 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/Screen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/Screen.java @@ -10,4 +10,8 @@ public interface Screen { void display(AsciiPanel terminal); Screen respondToUserInput(KeyEvent key); + default void print(AsciiPanel terminal, String str) { + final int onHeight = 22; + terminal.writeCenter(str, onHeight); + } } diff --git a/roguelike/impl/src/main/java/roguelike/screens/StartScreen.java b/roguelike/impl/src/main/java/roguelike/screens/StartScreen.java index 7bc0f0c..0263be1 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/StartScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/StartScreen.java @@ -8,11 +8,13 @@ * Created by boris on 08.05.17. */ public class StartScreen implements Screen { + + @Override public void display(AsciiPanel terminal) { - final int onHeight = 22; - terminal.writeCenter("Press [enter] to start", onHeight); + print(terminal, "Press [enter] to start"); } + @Override public Screen respondToUserInput(KeyEvent key) { return key.getKeyCode() == KeyEvent.VK_ENTER ? new PlayScreen() : this; } From 1c0ab9536c7e94fad018a2a9bd295f6a71482cd4 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Wed, 10 May 2017 21:16:01 +0300 Subject: [PATCH 27/63] ai --- .../main/java/roguelike/RecurringTask.java | 20 ++++++++ .../src/main/java/roguelike/Scheduler.java | 7 ++- .../java/roguelike/models/ActiveBeing.java | 40 ++++++++++++++++ .../models/ArtificialIntelligence.java | 8 ++++ .../src/main/java/roguelike/models/Being.java | 25 ---------- .../src/main/java/roguelike/models/Ghost.java | 33 +++++++++++++ .../main/java/roguelike/models/Player.java | 7 +-- .../java/roguelike/models/PlayerState.java | 5 ++ .../src/main/java/roguelike/models/Tile.java | 12 ++--- .../java/roguelike/screens/PlayScreen.java | 5 +- .../main/java/roguelike/screens/Screen.java | 2 +- roguelike/impl/src/main/resources/todolist | 46 +++++++++++++++++++ 12 files changed, 172 insertions(+), 38 deletions(-) create mode 100644 roguelike/impl/src/main/java/roguelike/RecurringTask.java create mode 100644 roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java create mode 100644 roguelike/impl/src/main/java/roguelike/models/ArtificialIntelligence.java create mode 100644 roguelike/impl/src/main/java/roguelike/models/Ghost.java create mode 100644 roguelike/impl/src/main/java/roguelike/models/PlayerState.java create mode 100644 roguelike/impl/src/main/resources/todolist diff --git a/roguelike/impl/src/main/java/roguelike/RecurringTask.java b/roguelike/impl/src/main/java/roguelike/RecurringTask.java new file mode 100644 index 0000000..e3d3a7d --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/RecurringTask.java @@ -0,0 +1,20 @@ +package roguelike; + +import java.util.TimerTask; + +/** + * Created by boris on 10.05.17. + */ +public class RecurringTask { + private java.util.Timer timer; + + public RecurringTask(Runnable task, long period) { + this.timer = new java.util.Timer(true); + this.timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + task.run(); + } + }, 0, period); + } +} diff --git a/roguelike/impl/src/main/java/roguelike/Scheduler.java b/roguelike/impl/src/main/java/roguelike/Scheduler.java index 58f57dc..83e287c 100644 --- a/roguelike/impl/src/main/java/roguelike/Scheduler.java +++ b/roguelike/impl/src/main/java/roguelike/Scheduler.java @@ -5,13 +5,16 @@ import roguelike.screens.StartScreen; import javax.swing.*; +import javax.swing.Timer; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; +import java.util.*; public class Scheduler extends JFrame implements KeyListener { private AsciiPanel terminal; private Screen screen; + private RecurringTask task; public Scheduler() { super(); @@ -23,7 +26,9 @@ public Scheduler() { this.screen = new StartScreen(); addKeyListener(this); - repaint(); + + + task = new RecurringTask(this::repaint, 10); } public void schedule(Game game) { diff --git a/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java b/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java new file mode 100644 index 0000000..6cdb2ce --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java @@ -0,0 +1,40 @@ +package roguelike.models; + +/** + * Created by boris on 10.05.17. + */ +public abstract class ActiveBeing extends Being { + + private int xDirection; + private int yDirection; + + protected int health; + + public ActiveBeing(World world) { + super(world); + this.health = 100; + } + + public int getHealth() { + return health; + } + + public void move(int dx, int dy) { + xDirection = Math.max(0, Math.min(x + dx, world.getWidth() - 1)); + yDirection = Math.max(0, Math.min(y + dy, world.getHeight() - 1)); + if (world.getTile(xDirection, yDirection).isWalkable()) { + x = xDirection; + y = yDirection; + } + + getEnvironmentEffects(); + } + + public void act() { + if (world.getTile(xDirection, yDirection).isDiggable()) { + world.setTile(xDirection, yDirection, Tile.FLOOR); + } + } + + protected abstract void getEnvironmentEffects(); +} diff --git a/roguelike/impl/src/main/java/roguelike/models/ArtificialIntelligence.java b/roguelike/impl/src/main/java/roguelike/models/ArtificialIntelligence.java new file mode 100644 index 0000000..725d55f --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/ArtificialIntelligence.java @@ -0,0 +1,8 @@ +package roguelike.models; + +/** + * Created by boris on 10.05.17. + */ +public interface ArtificialIntelligence { + void move(); +} diff --git a/roguelike/impl/src/main/java/roguelike/models/Being.java b/roguelike/impl/src/main/java/roguelike/models/Being.java index 6851d58..d008b4f 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Being.java +++ b/roguelike/impl/src/main/java/roguelike/models/Being.java @@ -11,17 +11,13 @@ public abstract class Being { public int x; public int y; - private int xDirection; - private int yDirection; protected char glyph; protected Color color; protected World world; - protected int health; public Being(World world) { this.world = world; - this.health = 100; Random randomGen = new Random(42); @@ -41,26 +37,5 @@ public Color getColor() { return color; } - public int getHealth() { - return health; - } - - public void move(int dx, int dy) { - xDirection = Math.max(0, Math.min(x + dx, world.getWidth() - 1)); - yDirection = Math.max(0, Math.min(y + dy, world.getHeight() - 1)); - if (world.getTile(xDirection, yDirection).isWalkable()) { - x = xDirection; - y = yDirection; - } - - respondToMove(); - } - - public void dig() { - if (world.getTile(xDirection, yDirection).isDiggable()) { - world.setTile(xDirection, yDirection, Tile.FLOOR); - } - } - protected void respondToMove() {} } diff --git a/roguelike/impl/src/main/java/roguelike/models/Ghost.java b/roguelike/impl/src/main/java/roguelike/models/Ghost.java new file mode 100644 index 0000000..5bd4988 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/Ghost.java @@ -0,0 +1,33 @@ +package roguelike.models; + +import roguelike.RecurringTask; + +import java.awt.*; +import java.util.Random; + +/** + * Created by boris on 10.05.17. + */ +public class Ghost extends ActiveBeing implements ArtificialIntelligence { + + private RecurringTask task; + + public Ghost(World world) { + super(world); + + this.glyph = 'G'; + this.color = Color.cyan; + + task = new RecurringTask(this::move, 100); + } + + @Override + protected void getEnvironmentEffects() { + + } + + @Override + public void move() { + move(new Random().nextInt(3) - 1, new Random().nextInt(3) - 1); + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/Player.java b/roguelike/impl/src/main/java/roguelike/models/Player.java index 91a7d6d..751d3c2 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Player.java +++ b/roguelike/impl/src/main/java/roguelike/models/Player.java @@ -5,7 +5,7 @@ /** * Created by boris on 09.05.17. */ -public class Player extends Being { +public class Player extends ActiveBeing { public Player(World world) { super(world); @@ -15,7 +15,8 @@ public Player(World world) { } @Override - protected void respondToMove() { - health -= world.getTile(x, y).getHarmness(); + protected void getEnvironmentEffects() { + int deltaHealth = world.getTile(x, y).getDeltaHealth(); + health += deltaHealth; } } diff --git a/roguelike/impl/src/main/java/roguelike/models/PlayerState.java b/roguelike/impl/src/main/java/roguelike/models/PlayerState.java new file mode 100644 index 0000000..2b37e39 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/PlayerState.java @@ -0,0 +1,5 @@ +package roguelike.models; + +public enum PlayerState { + +} diff --git a/roguelike/impl/src/main/java/roguelike/models/Tile.java b/roguelike/impl/src/main/java/roguelike/models/Tile.java index df60224..9e24393 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Tile.java +++ b/roguelike/impl/src/main/java/roguelike/models/Tile.java @@ -9,18 +9,18 @@ */ public enum Tile { FLOOR('.', AsciiPanel.yellow, 0), - POISONED_FLOOR('.', Color.GREEN, 5), + POISONED_FLOOR('.', Color.GREEN, -5), WALL('#', AsciiPanel.yellow, 0), BOUNDS('x', AsciiPanel.brightBlack, 0); private char glyph; private Color color; - private int harmness; + private int deltaHealth; - Tile(char glyph, Color color, int harmness) { + Tile(char glyph, Color color, int deltaHealth) { this.glyph = glyph; this.color = color; - this.harmness = harmness; + this.deltaHealth = deltaHealth; } public char getGlyph() { @@ -31,8 +31,8 @@ public Color getColor() { return color; } - public int getHarmness() { - return harmness; + public int getDeltaHealth() { + return deltaHealth; } public boolean isWalkable() { diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index a4b6098..d921e3b 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -22,6 +22,7 @@ public PlayScreen() { world = new WorldBuilder(100, 100) .makeCaves() .addMobs(Mushroom.class, 10) + .addMobs(Ghost.class, 10) .build(); player = world.getPlayer(); @@ -57,8 +58,8 @@ public Screen respondToUserInput(KeyEvent key) { case KeyEvent.VK_D: player.move(1, 0); break; - case KeyEvent.VK_F: - player.dig(); + case KeyEvent.VK_ENTER: + player.act(); break; } return player.getHealth() > 0 ? this : new DeadScreen(); diff --git a/roguelike/impl/src/main/java/roguelike/screens/Screen.java b/roguelike/impl/src/main/java/roguelike/screens/Screen.java index 7a6b08b..5c6ca28 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/Screen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/Screen.java @@ -11,7 +11,7 @@ public interface Screen { void display(AsciiPanel terminal); Screen respondToUserInput(KeyEvent key); default void print(AsciiPanel terminal, String str) { - final int onHeight = 22; + final int onHeight = 18; terminal.writeCenter(str, onHeight); } } diff --git a/roguelike/impl/src/main/resources/todolist b/roguelike/impl/src/main/resources/todolist new file mode 100644 index 0000000..abc9b79 --- /dev/null +++ b/roguelike/impl/src/main/resources/todolist @@ -0,0 +1,46 @@ +1. Текст сообщения о том, что происходит (или нафиг?) + +2. AI +3. Призрак - гоняется за нами, если догоняет, то инвертирует наше управление. + После этого, все призраки от нас убегают, и чтобы вернуть управление назад, нам надо догнать и победить. + Они должны двигаться медленнее нас, но должны догонять, если мы копаем стены + +4. Добавить кирку, и ее здоровье, чтобы нельзя было вечно долбить + +4. Оружие, аптечки: + Дешевое оружие и аптечки раскиданы по карте, более дорогое оружие можно получить только у дракона. + При взятии нового оружия, старое пропадает + Интенсивностью отмечаем уровень оружия + +5. Дракон - когда наступаем на него, начинается бой, если побеждаем, то увеличиваем свой уровень . + Рядом с драконом лежит лут, но когда мы его забираем, то начинается драка, и нельзя уйти. + Драка такая - надо много раз нажать заданную клавишу. + +6. Урон от дракона и грибов зависит от их уровня + Следовательно, надо будет разработать формулу для подсчета этого урона. + +7. Переход на новые локации: + Есть телепорты, переходя на них, генерируется новая карта, с другим цветом (и более сложная?) + +8. Спрайты - держим буфер фильтров, которые наслоятся на следующие кадры анимации. + Когда отрисовываем кадр, считываем фильтр из буфера и отрисовываем поверх + + +ОБЯЗАТЕЛЬНЫЕ ЗАДАНИЯ: +1. Юнит - тесты +2. Логирование + + + + + + + + + + + + + + + From a0e49a7fe95ba6bffdc120af92c977540cdf4829 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Wed, 10 May 2017 23:26:23 +0300 Subject: [PATCH 28/63] ghosts can feel player --- .../impl/src/main/java/roguelike/Game.java | 7 ---- .../impl/src/main/java/roguelike/Main.java | 3 +- .../src/main/java/roguelike/Scheduler.java | 6 ++-- .../java/roguelike/models/ActiveBeing.java | 4 +-- .../src/main/java/roguelike/models/Ghost.java | 33 ++++++++++++++++++- .../main/java/roguelike/models/Player.java | 2 +- .../java/roguelike/models/PlayerState.java | 5 --- 7 files changed, 40 insertions(+), 20 deletions(-) delete mode 100644 roguelike/impl/src/main/java/roguelike/Game.java delete mode 100644 roguelike/impl/src/main/java/roguelike/models/PlayerState.java diff --git a/roguelike/impl/src/main/java/roguelike/Game.java b/roguelike/impl/src/main/java/roguelike/Game.java deleted file mode 100644 index 3a24758..0000000 --- a/roguelike/impl/src/main/java/roguelike/Game.java +++ /dev/null @@ -1,7 +0,0 @@ -package roguelike; - -/** - * Created by boris on 08.05.17. - */ -public class Game { -} diff --git a/roguelike/impl/src/main/java/roguelike/Main.java b/roguelike/impl/src/main/java/roguelike/Main.java index 274346f..050271d 100644 --- a/roguelike/impl/src/main/java/roguelike/Main.java +++ b/roguelike/impl/src/main/java/roguelike/Main.java @@ -5,8 +5,7 @@ */ public class Main { public static void main(String[] args) { - Game game = new Game(); Scheduler scheduler = new Scheduler(); - scheduler.schedule(game); + scheduler.schedule(); } } diff --git a/roguelike/impl/src/main/java/roguelike/Scheduler.java b/roguelike/impl/src/main/java/roguelike/Scheduler.java index 83e287c..ff2505e 100644 --- a/roguelike/impl/src/main/java/roguelike/Scheduler.java +++ b/roguelike/impl/src/main/java/roguelike/Scheduler.java @@ -31,21 +31,23 @@ public Scheduler() { task = new RecurringTask(this::repaint, 10); } - public void schedule(Game game) { - + public void schedule() { setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setVisible(true); } + @Override public void keyTyped(KeyEvent e) { } + @Override public void keyPressed(KeyEvent e) { screen = screen.respondToUserInput(e); repaint(); } + @Override public void keyReleased(KeyEvent e) { } diff --git a/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java b/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java index 6cdb2ce..90008ee 100644 --- a/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java +++ b/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java @@ -27,7 +27,7 @@ public void move(int dx, int dy) { y = yDirection; } - getEnvironmentEffects(); + interactWithEnvironment(); } public void act() { @@ -36,5 +36,5 @@ public void act() { } } - protected abstract void getEnvironmentEffects(); + protected abstract void interactWithEnvironment(); } diff --git a/roguelike/impl/src/main/java/roguelike/models/Ghost.java b/roguelike/impl/src/main/java/roguelike/models/Ghost.java index 5bd4988..2465e7f 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Ghost.java +++ b/roguelike/impl/src/main/java/roguelike/models/Ghost.java @@ -11,6 +11,7 @@ public class Ghost extends ActiveBeing implements ArtificialIntelligence { private RecurringTask task; + private final int SMELL_RANGE = 10; public Ghost(World world) { super(world); @@ -22,12 +23,42 @@ public Ghost(World world) { } @Override - protected void getEnvironmentEffects() { + protected void interactWithEnvironment() { } @Override public void move() { + + if (distToPlayer(x, y) < SMELL_RANGE) { + moveToPlayer(); + } else { + moveRandom(); + } + + } + + private void moveToPlayer() { + int dx = 0; + int dy = 0; + double minDist = Double.POSITIVE_INFINITY; + for (int i = -1; i < 2; i++) { + for (int j = -1; j < 2; j++) { + if (distToPlayer(x + i, y + j) < minDist) { + minDist = distToPlayer(x + i, y + j); + dx = i; + dy = j; + } + } + } + move(dx, dy); + } + + private void moveRandom() { move(new Random().nextInt(3) - 1, new Random().nextInt(3) - 1); } + + private double distToPlayer(int fromX, int fromY) { + return Math.hypot(fromX - world.getPlayer().x, fromY - world.getPlayer().y); + } } diff --git a/roguelike/impl/src/main/java/roguelike/models/Player.java b/roguelike/impl/src/main/java/roguelike/models/Player.java index 751d3c2..a5cb400 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Player.java +++ b/roguelike/impl/src/main/java/roguelike/models/Player.java @@ -15,7 +15,7 @@ public Player(World world) { } @Override - protected void getEnvironmentEffects() { + protected void interactWithEnvironment() { int deltaHealth = world.getTile(x, y).getDeltaHealth(); health += deltaHealth; } diff --git a/roguelike/impl/src/main/java/roguelike/models/PlayerState.java b/roguelike/impl/src/main/java/roguelike/models/PlayerState.java deleted file mode 100644 index 2b37e39..0000000 --- a/roguelike/impl/src/main/java/roguelike/models/PlayerState.java +++ /dev/null @@ -1,5 +0,0 @@ -package roguelike.models; - -public enum PlayerState { - -} From 800423c4880c3d9e9168951137528d934ab8354f Mon Sep 17 00:00:00 2001 From: simiyutin Date: Thu, 11 May 2017 00:04:17 +0300 Subject: [PATCH 29/63] ghost actions --- .../java/roguelike/models/ActiveBeing.java | 20 +++++++-- .../src/main/java/roguelike/models/Ghost.java | 45 +++++++++++++++++-- .../src/main/java/roguelike/models/World.java | 9 ++++ .../java/roguelike/screens/PlayScreen.java | 2 +- 4 files changed, 69 insertions(+), 7 deletions(-) diff --git a/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java b/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java index 90008ee..3fc6c5a 100644 --- a/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java +++ b/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java @@ -1,18 +1,24 @@ package roguelike.models; +import java.util.function.Function; + /** * Created by boris on 10.05.17. */ public abstract class ActiveBeing extends Being { - private int xDirection; - private int yDirection; + protected int xDirection; + protected int yDirection; protected int health; + + private PlayerEffects effect; + public ActiveBeing(World world) { super(world); this.health = 100; + this.effect = PlayerEffects.IDENTITY; } public int getHealth() { @@ -22,7 +28,7 @@ public int getHealth() { public void move(int dx, int dy) { xDirection = Math.max(0, Math.min(x + dx, world.getWidth() - 1)); yDirection = Math.max(0, Math.min(y + dy, world.getHeight() - 1)); - if (world.getTile(xDirection, yDirection).isWalkable()) { + if (world.getTile(xDirection, yDirection).isWalkable() && world.getMob(xDirection, yDirection) == null) { x = xDirection; y = yDirection; } @@ -36,5 +42,13 @@ public void act() { } } + public void setEffect(PlayerEffects effect) { + this.effect = effect; + } + + public PlayerEffects getEffect() { + return effect; + } + protected abstract void interactWithEnvironment(); } diff --git a/roguelike/impl/src/main/java/roguelike/models/Ghost.java b/roguelike/impl/src/main/java/roguelike/models/Ghost.java index 2465e7f..8bb46d6 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Ghost.java +++ b/roguelike/impl/src/main/java/roguelike/models/Ghost.java @@ -5,13 +5,19 @@ import java.awt.*; import java.util.Random; +import static roguelike.models.PlayerEffects.IDENTITY; +import static roguelike.models.PlayerEffects.INVERSED; + /** * Created by boris on 10.05.17. */ public class Ghost extends ActiveBeing implements ArtificialIntelligence { + private static boolean moveTo = true; + private RecurringTask task; - private final int SMELL_RANGE = 10; + private final int SMELL_RANGE = 15; + private boolean alive = true; public Ghost(World world) { super(world); @@ -24,14 +30,31 @@ public Ghost(World world) { @Override protected void interactWithEnvironment() { - + if (distToPlayer(x, y) == 1) { + PlayerEffects effect = world.getPlayer().getEffect(); + if (effect == INVERSED) { + world.getMobs().remove(this); + world.getPlayer().setEffect(IDENTITY); + alive = false; + } else { + world.getPlayer().setEffect(INVERSED); + } + moveTo = !moveTo; + } } @Override public void move() { + if (!alive) return; + if (distToPlayer(x, y) < SMELL_RANGE) { - moveToPlayer(); + if (moveTo) { + moveToPlayer(); + } else { + moveFromPlayer(); + } + } else { moveRandom(); } @@ -54,6 +77,22 @@ private void moveToPlayer() { move(dx, dy); } + private void moveFromPlayer() { + int dx = 0; + int dy = 0; + double maxDist = 0; + for (int i = -1; i < 2; i++) { + for (int j = -1; j < 2; j++) { + if (distToPlayer(x + i, y + j) > maxDist) { + maxDist = distToPlayer(x + i, y + j); + dx = i; + dy = j; + } + } + } + move(dx, dy); + } + private void moveRandom() { move(new Random().nextInt(3) - 1, new Random().nextInt(3) - 1); } diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java index 9583809..25d7631 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -59,4 +59,13 @@ public Player getPlayer() { public List getMobs() { return mobs; } + + public Being getMob(int x, int y) { + for (Being b : mobs) { + if (b.x == x && b.y == y) { + return b; + } + } + return null; + } } diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index d921e3b..65052eb 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -45,7 +45,7 @@ private int scrollTop() { } public Screen respondToUserInput(KeyEvent key) { - switch (key.getKeyCode()) { + switch (player.getEffect().apply(key.getKeyCode())) { case KeyEvent.VK_S: player.move(0, 1); break; From d3715ad5b0490bdedc44926a4e0cb9ae6796f7d3 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Thu, 11 May 2017 09:59:41 +0300 Subject: [PATCH 30/63] ghost effect --- .../java/roguelike/models/ActiveBeing.java | 6 ++- .../src/main/java/roguelike/models/Ghost.java | 8 ++-- .../java/roguelike/models/PlayerEffects.java | 37 +++++++++++++++++++ 3 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 roguelike/impl/src/main/java/roguelike/models/PlayerEffects.java diff --git a/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java b/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java index 3fc6c5a..6d936b6 100644 --- a/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java +++ b/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java @@ -28,7 +28,7 @@ public int getHealth() { public void move(int dx, int dy) { xDirection = Math.max(0, Math.min(x + dx, world.getWidth() - 1)); yDirection = Math.max(0, Math.min(y + dy, world.getHeight() - 1)); - if (world.getTile(xDirection, yDirection).isWalkable() && world.getMob(xDirection, yDirection) == null) { + if (canMove(xDirection, yDirection)) { x = xDirection; y = yDirection; } @@ -36,6 +36,10 @@ public void move(int dx, int dy) { interactWithEnvironment(); } + protected boolean canMove(int xTo, int yTo) { + return world.getTile(xTo, yTo).isWalkable() && world.getMob(xTo, yTo) == null; + } + public void act() { if (world.getTile(xDirection, yDirection).isDiggable()) { world.setTile(xDirection, yDirection, Tile.FLOOR); diff --git a/roguelike/impl/src/main/java/roguelike/models/Ghost.java b/roguelike/impl/src/main/java/roguelike/models/Ghost.java index 8bb46d6..8d0c4d6 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Ghost.java +++ b/roguelike/impl/src/main/java/roguelike/models/Ghost.java @@ -30,7 +30,7 @@ public Ghost(World world) { @Override protected void interactWithEnvironment() { - if (distToPlayer(x, y) == 1) { + if (distToPlayer(x, y) < 2) { PlayerEffects effect = world.getPlayer().getEffect(); if (effect == INVERSED) { world.getMobs().remove(this); @@ -47,7 +47,7 @@ protected void interactWithEnvironment() { public void move() { if (!alive) return; - + if (distToPlayer(x, y) < SMELL_RANGE) { if (moveTo) { moveToPlayer(); @@ -67,7 +67,7 @@ private void moveToPlayer() { double minDist = Double.POSITIVE_INFINITY; for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { - if (distToPlayer(x + i, y + j) < minDist) { + if (distToPlayer(x + i, y + j) < minDist && canMove(x + i, y + j)) { minDist = distToPlayer(x + i, y + j); dx = i; dy = j; @@ -83,7 +83,7 @@ private void moveFromPlayer() { double maxDist = 0; for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { - if (distToPlayer(x + i, y + j) > maxDist) { + if (distToPlayer(x + i, y + j) > maxDist && canMove(x + i, y + j)) { maxDist = distToPlayer(x + i, y + j); dx = i; dy = j; diff --git a/roguelike/impl/src/main/java/roguelike/models/PlayerEffects.java b/roguelike/impl/src/main/java/roguelike/models/PlayerEffects.java new file mode 100644 index 0000000..3981e41 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/PlayerEffects.java @@ -0,0 +1,37 @@ +package roguelike.models; + +import java.awt.event.KeyEvent; +import java.util.function.Function; + +/** + * Created by boris on 10.05.17. + */ +public enum PlayerEffects { + + IDENTITY(Function.identity()), + + INVERSED(key -> { + switch (key) { + case KeyEvent.VK_S: + return KeyEvent.VK_W; + case KeyEvent.VK_W: + return KeyEvent.VK_S; + case KeyEvent.VK_A: + return KeyEvent.VK_D; + case KeyEvent.VK_D: + return KeyEvent.VK_A; + default: + return 0; + } + }); + + private Function proxy; + + PlayerEffects(Function proxy) { + this.proxy = proxy; + } + + public Integer apply(Integer key) { + return proxy.apply(key); + } +} From 1a36c59525aeeebe0c1430a6861f80e1c18b1ce1 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Thu, 11 May 2017 12:38:32 +0300 Subject: [PATCH 31/63] messages --- .../src/main/java/roguelike/DelayedTask.java | 20 +++++++++++++++++++ .../main/java/roguelike/RecurringTask.java | 5 ++--- .../src/main/java/roguelike/Scheduler.java | 3 +-- .../src/main/java/roguelike/models/Ghost.java | 5 +++-- .../src/main/java/roguelike/models/World.java | 13 ++++++++++++ .../java/roguelike/screens/PlayScreen.java | 5 +++++ roguelike/impl/src/main/resources/todolist | 4 ++-- 7 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 roguelike/impl/src/main/java/roguelike/DelayedTask.java diff --git a/roguelike/impl/src/main/java/roguelike/DelayedTask.java b/roguelike/impl/src/main/java/roguelike/DelayedTask.java new file mode 100644 index 0000000..71fe303 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/DelayedTask.java @@ -0,0 +1,20 @@ +package roguelike; + +import java.util.Timer; +import java.util.TimerTask; + +/** + * Created by boris on 11.05.17. + */ +public class DelayedTask { + + public DelayedTask(Runnable task, long timeout) { + Timer timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + task.run(); + } + }, timeout); + } +} diff --git a/roguelike/impl/src/main/java/roguelike/RecurringTask.java b/roguelike/impl/src/main/java/roguelike/RecurringTask.java index e3d3a7d..92bd5f0 100644 --- a/roguelike/impl/src/main/java/roguelike/RecurringTask.java +++ b/roguelike/impl/src/main/java/roguelike/RecurringTask.java @@ -6,11 +6,10 @@ * Created by boris on 10.05.17. */ public class RecurringTask { - private java.util.Timer timer; public RecurringTask(Runnable task, long period) { - this.timer = new java.util.Timer(true); - this.timer.scheduleAtFixedRate(new TimerTask() { + java.util.Timer timer = new java.util.Timer(true); + timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { task.run(); diff --git a/roguelike/impl/src/main/java/roguelike/Scheduler.java b/roguelike/impl/src/main/java/roguelike/Scheduler.java index ff2505e..4d045f2 100644 --- a/roguelike/impl/src/main/java/roguelike/Scheduler.java +++ b/roguelike/impl/src/main/java/roguelike/Scheduler.java @@ -14,7 +14,6 @@ public class Scheduler extends JFrame implements KeyListener { private AsciiPanel terminal; private Screen screen; - private RecurringTask task; public Scheduler() { super(); @@ -28,7 +27,7 @@ public Scheduler() { addKeyListener(this); - task = new RecurringTask(this::repaint, 10); + new RecurringTask(this::repaint, 10); } public void schedule() { diff --git a/roguelike/impl/src/main/java/roguelike/models/Ghost.java b/roguelike/impl/src/main/java/roguelike/models/Ghost.java index 8d0c4d6..dca41cd 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Ghost.java +++ b/roguelike/impl/src/main/java/roguelike/models/Ghost.java @@ -15,7 +15,6 @@ public class Ghost extends ActiveBeing implements ArtificialIntelligence { private static boolean moveTo = true; - private RecurringTask task; private final int SMELL_RANGE = 15; private boolean alive = true; @@ -25,7 +24,7 @@ public Ghost(World world) { this.glyph = 'G'; this.color = Color.cyan; - task = new RecurringTask(this::move, 100); + new RecurringTask(this::move, 100); } @Override @@ -35,9 +34,11 @@ protected void interactWithEnvironment() { if (effect == INVERSED) { world.getMobs().remove(this); world.getPlayer().setEffect(IDENTITY); + world.setMessage("Controls back to normal"); alive = false; } else { world.getPlayer().setEffect(INVERSED); + world.setMessage("Controls inversed!"); } moveTo = !moveTo; } diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java index 25d7631..54f6fba 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -1,6 +1,8 @@ package roguelike.models; +import roguelike.DelayedTask; + import java.awt.Color; import java.util.ArrayList; import java.util.List; @@ -14,6 +16,17 @@ public class World { private int height; private Player player; private List mobs; + private String message = ""; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + //todo timeoutTask; + this.message = message; + new DelayedTask(() -> this.message = "", 1000); + } public World(Tile[][] tiles) { this.tiles = tiles; diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index 65052eb..4325b36 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -34,6 +34,7 @@ public void display(AsciiPanel terminal) { displayWorld(terminal, left, top); displayMobs(terminal, left, top); displayHealth(terminal); + displayMessage(terminal); } private int scrollLeft() { @@ -94,4 +95,8 @@ public void displayWorld(AsciiPanel terminal, int left, int top) { } } } + + private void displayMessage(AsciiPanel terminal) { + terminal.write(world.getMessage(), 40 - world.getMessage().length() / 2, 1); + } } diff --git a/roguelike/impl/src/main/resources/todolist b/roguelike/impl/src/main/resources/todolist index abc9b79..dd8ad3b 100644 --- a/roguelike/impl/src/main/resources/todolist +++ b/roguelike/impl/src/main/resources/todolist @@ -1,7 +1,7 @@ 1. Текст сообщения о том, что происходит (или нафиг?) -2. AI -3. Призрак - гоняется за нами, если догоняет, то инвертирует наше управление. +--2. AI +--3. Призрак - гоняется за нами, если догоняет, то инвертирует наше управление. После этого, все призраки от нас убегают, и чтобы вернуть управление назад, нам надо догнать и победить. Они должны двигаться медленнее нас, но должны догонять, если мы копаем стены From bcd7fbf15035d7c5dfb13f549f9233aeebacf0cf Mon Sep 17 00:00:00 2001 From: simiyutin Date: Thu, 11 May 2017 13:29:51 +0300 Subject: [PATCH 32/63] dummy Weapons --- .../src/main/java/roguelike/models/Being.java | 11 ++--- .../main/java/roguelike/models/LootItem.java | 26 ++++++++++++ .../main/java/roguelike/models/Player.java | 3 ++ .../main/java/roguelike/models/Position.java | 14 +++++++ .../main/java/roguelike/models/Weapon.java | 34 +++++++++++++++ .../java/roguelike/models/WeaponType.java | 41 +++++++++++++++++++ .../src/main/java/roguelike/models/World.java | 30 ++++++++++++++ .../java/roguelike/models/WorldBuilder.java | 18 ++++++++ .../java/roguelike/screens/PlayScreen.java | 9 ++++ 9 files changed, 178 insertions(+), 8 deletions(-) create mode 100644 roguelike/impl/src/main/java/roguelike/models/LootItem.java create mode 100644 roguelike/impl/src/main/java/roguelike/models/Position.java create mode 100644 roguelike/impl/src/main/java/roguelike/models/Weapon.java create mode 100644 roguelike/impl/src/main/java/roguelike/models/WeaponType.java diff --git a/roguelike/impl/src/main/java/roguelike/models/Being.java b/roguelike/impl/src/main/java/roguelike/models/Being.java index d008b4f..292f460 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Being.java +++ b/roguelike/impl/src/main/java/roguelike/models/Being.java @@ -19,14 +19,9 @@ public abstract class Being { public Being(World world) { this.world = world; - Random randomGen = new Random(42); - - do { - - x = randomGen.nextInt(world.getWidth()); - y = randomGen.nextInt(world.getHeight()); - - } while (world.getTile(x, y) != Tile.FLOOR || world.getMobs().stream().anyMatch(b -> b.x == x && b.y == y)); + Position position = world.getEmptyPosition(); + this.x = position.x; + this.y = position.y; } public char getGlyph() { diff --git a/roguelike/impl/src/main/java/roguelike/models/LootItem.java b/roguelike/impl/src/main/java/roguelike/models/LootItem.java new file mode 100644 index 0000000..8421be7 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/LootItem.java @@ -0,0 +1,26 @@ +package roguelike.models; + +/** + * Created by boris on 11.05.17. + */ +public class LootItem { + public int x; + public int y; + private Weapon weapon; + + public LootItem(Weapon weapon, World world) { + this.weapon = weapon; + + Position position = world.getEmptyPosition(); + this.x = position.x; + this.y = position.y; + } + + public Weapon getWeapon() { + return weapon; + } + + public void setWeapon(Weapon weapon) { + this.weapon = weapon; + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/Player.java b/roguelike/impl/src/main/java/roguelike/models/Player.java index a5cb400..3bb007a 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Player.java +++ b/roguelike/impl/src/main/java/roguelike/models/Player.java @@ -7,11 +7,14 @@ */ public class Player extends ActiveBeing { + private Weapon weapon; + public Player(World world) { super(world); this.glyph = 'X'; this.color = Color.BLUE; + this.weapon = WeaponType.HAND.getItem(); } @Override diff --git a/roguelike/impl/src/main/java/roguelike/models/Position.java b/roguelike/impl/src/main/java/roguelike/models/Position.java new file mode 100644 index 0000000..9ffaf0e --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/Position.java @@ -0,0 +1,14 @@ +package roguelike.models; + +/** + * Created by boris on 11.05.17. + */ +public class Position { + public int x; + public int y; + + public Position(int x, int y) { + this.x = x; + this.y = y; + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/Weapon.java b/roguelike/impl/src/main/java/roguelike/models/Weapon.java new file mode 100644 index 0000000..5533170 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/Weapon.java @@ -0,0 +1,34 @@ +package roguelike.models; + +import java.awt.*; + +/** + * Created by boris on 11.05.17. + */ +public class Weapon { + private WeaponType type; + private final int MAX_LEVEL = 10; + private int level; // 1 - 10 + + public Weapon(WeaponType type, int level) { + this.type = type; + this.level = level; + } + + public Color getColor() { + int brightness = 150 + level / MAX_LEVEL * 100; + return Color.getHSBColor(type.getHue(), 200, brightness); + } + + public char getGlyph() { + return type.getGlyph(); + } + + public int getLevel() { + return level; + } + + public static Weapon getRandomOfLevel(int level) { + return new Weapon(WeaponType.getRandom(), level); + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/WeaponType.java b/roguelike/impl/src/main/java/roguelike/models/WeaponType.java new file mode 100644 index 0000000..bfdbe87 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/WeaponType.java @@ -0,0 +1,41 @@ +package roguelike.models; + +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +/** + * Created by boris on 11.05.17. + */ +public enum WeaponType { + HAND('h', 1, 10), + SWORD('>', 10, 150); + + private char glyph; + private int hue; + private int harm; + + WeaponType(char glyph, int harm, int hue) { + this.glyph = glyph; + this.harm = harm; + this.hue = hue; + } + + public char getGlyph() { + return glyph; + } + + public int getHue() { + return hue; + } + + public Weapon getItem() { + return new Weapon(this, 1); + } + + public static WeaponType getRandom() { + List types = Arrays.asList(SWORD); + Integer ind = new Random().nextInt(types.size()); + return types.get(ind); + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java index 54f6fba..90e6ed2 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -6,6 +6,7 @@ import java.awt.Color; import java.util.ArrayList; import java.util.List; +import java.util.Random; /** * Created by boris on 08.05.17. @@ -17,6 +18,11 @@ public class World { private Player player; private List mobs; private String message = ""; + private List loot; + + public List getLoot() { + return loot; + } public String getMessage() { return message; @@ -34,8 +40,10 @@ public World(Tile[][] tiles) { this.height = tiles[0].length; this.mobs = new ArrayList<>(); + this.loot = new ArrayList<>(); this.player = new Player(this); this.mobs.add(this.player); + } public Tile getTile(int x, int y) { @@ -81,4 +89,26 @@ public Being getMob(int x, int y) { } return null; } + + public Position getEmptyPosition() { + Random randomGen = new Random(); + + int x; + int y; + + do { + + x = randomGen.nextInt(getWidth()); + y = randomGen.nextInt(getHeight()); + + } while (!isEmptyFloor(x, y)); + + return new Position(x, y); + } + + private boolean isEmptyFloor(int x, int y) { + return getTile(x, y) == Tile.FLOOR + && getMobs().stream().noneMatch(b -> b.x == x && b.y == y) + && getLoot().stream().noneMatch(b -> b.x == x && b.y == y); + } } diff --git a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java index 800e345..25cc192 100644 --- a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java +++ b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Random; import java.util.stream.Collectors; /** @@ -19,12 +20,14 @@ public class WorldBuilder { private int height; private Tile[][] tiles; private List> mobs; + private List loot; public WorldBuilder(int width, int height) { this.width = width; this.height = height; this.tiles = new Tile[width][height]; this.mobs = new ArrayList<>(); + this.loot = new ArrayList<>(); } public World build() { @@ -37,6 +40,10 @@ public World build() { } } + for (Weapon w : loot) { + world.getLoot().add(new LootItem(w, world)); //todo circular dependency + } + return world; } @@ -50,12 +57,23 @@ public WorldBuilder addMobs(Class clazz, int quantity) { try { mobs.add(clazz.getConstructor(World.class)); } catch (NoSuchMethodException ex) { + // todo log ex.printStackTrace(); } } return this; } + public WorldBuilder addLoot(int quantity) { + Random randGen = new Random(); + final int maxLevel = 2; + for (int i = 0; i < quantity; i++) { + Weapon weapon = Weapon.getRandomOfLevel(randGen.nextInt(maxLevel + 1)); + loot.add(weapon); + } + return this; + } + private WorldBuilder randomizeTiles() { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index 4325b36..131ddc9 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -23,6 +23,7 @@ public PlayScreen() { .makeCaves() .addMobs(Mushroom.class, 10) .addMobs(Ghost.class, 10) + .addLoot(15) .build(); player = world.getPlayer(); @@ -33,6 +34,7 @@ public void display(AsciiPanel terminal) { int top = scrollTop(); displayWorld(terminal, left, top); displayMobs(terminal, left, top); + displayLoot(terminal, left, top); displayHealth(terminal); displayMessage(terminal); } @@ -96,6 +98,13 @@ public void displayWorld(AsciiPanel terminal, int left, int top) { } } + public void displayLoot(AsciiPanel terminal, int left, int top) { + for (LootItem b: world.getLoot()) { + Weapon w = b.getWeapon(); + writeSafe(terminal, w.getGlyph(), b.x - left, b.y - top, w.getColor()); + } + } + private void displayMessage(AsciiPanel terminal) { terminal.write(world.getMessage(), 40 - world.getMessage().length() / 2, 1); } From b5efefb459104fa544a1ce66232a24026517d17c Mon Sep 17 00:00:00 2001 From: simiyutin Date: Thu, 11 May 2017 13:31:17 +0300 Subject: [PATCH 33/63] todo ++ --- roguelike/impl/src/main/resources/todolist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roguelike/impl/src/main/resources/todolist b/roguelike/impl/src/main/resources/todolist index dd8ad3b..3e1239b 100644 --- a/roguelike/impl/src/main/resources/todolist +++ b/roguelike/impl/src/main/resources/todolist @@ -1,4 +1,4 @@ -1. Текст сообщения о том, что происходит (или нафиг?) +--1. Текст сообщения о том, что происходит --2. AI --3. Призрак - гоняется за нами, если догоняет, то инвертирует наше управление. @@ -28,7 +28,7 @@ ОБЯЗАТЕЛЬНЫЕ ЗАДАНИЯ: 1. Юнит - тесты -2. Логирование +2. Логирование (например, исключений) From caa8823974001d17a9bde14effc0789e2d611179 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Thu, 11 May 2017 13:33:27 +0300 Subject: [PATCH 34/63] ++ todo --- roguelike/impl/src/main/resources/todolist | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/roguelike/impl/src/main/resources/todolist b/roguelike/impl/src/main/resources/todolist index 3e1239b..6b99768 100644 --- a/roguelike/impl/src/main/resources/todolist +++ b/roguelike/impl/src/main/resources/todolist @@ -10,7 +10,8 @@ 4. Оружие, аптечки: Дешевое оружие и аптечки раскиданы по карте, более дорогое оружие можно получить только у дракона. При взятии нового оружия, старое пропадает - Интенсивностью отмечаем уровень оружия + --Интенсивностью отмечаем уровень оружия + Отображать текущее оружие рядом со здоровьем 5. Дракон - когда наступаем на него, начинается бой, если побеждаем, то увеличиваем свой уровень . Рядом с драконом лежит лут, но когда мы его забираем, то начинается драка, и нельзя уйти. @@ -20,7 +21,8 @@ Следовательно, надо будет разработать формулу для подсчета этого урона. 7. Переход на новые локации: - Есть телепорты, переходя на них, генерируется новая карта, с другим цветом (и более сложная?) + Есть телепорты, переходя на них, генерируется новая карта, с другим цветом + (более сложная, то есть все существа там более высокого уровня) 8. Спрайты - держим буфер фильтров, которые наслоятся на следующие кадры анимации. Когда отрисовываем кадр, считываем фильтр из буфера и отрисовываем поверх @@ -31,6 +33,10 @@ 2. Логирование (например, исключений) +БАГИ: +1. Не работает в русской раскладке + + From 64611a6f95ce057927dad67cc5b70c8992f6805e Mon Sep 17 00:00:00 2001 From: simiyutin Date: Thu, 11 May 2017 14:34:33 +0300 Subject: [PATCH 35/63] dragon dummy --- .../main/java/roguelike/models/Mushroom.java | 30 ------------- .../src/main/java/roguelike/models/Tile.java | 3 +- .../src/main/java/roguelike/models/World.java | 3 ++ .../java/roguelike/models/WorldBuilder.java | 7 ++- .../roguelike/models/actions/Actions.java | 21 +++++++++ .../models/{ => beings}/ActiveBeing.java | 12 +++++- .../{ => beings}/ArtificialIntelligence.java | 2 +- .../roguelike/models/{ => beings}/Being.java | 4 +- .../java/roguelike/models/beings/Dragon.java | 43 +++++++++++++++++++ .../roguelike/models/{ => beings}/Ghost.java | 12 +++--- .../roguelike/models/beings/Mushroom.java | 26 +++++++++++ .../roguelike/models/{ => beings}/Player.java | 6 ++- .../models/{ => beings}/PlayerEffects.java | 2 +- .../models/{ => items}/LootItem.java | 5 ++- .../roguelike/models/{ => items}/Weapon.java | 2 +- .../models/{ => items}/WeaponType.java | 2 +- .../java/roguelike/screens/PlayScreen.java | 4 ++ roguelike/impl/src/main/resources/todolist | 1 + 18 files changed, 134 insertions(+), 51 deletions(-) delete mode 100644 roguelike/impl/src/main/java/roguelike/models/Mushroom.java create mode 100644 roguelike/impl/src/main/java/roguelike/models/actions/Actions.java rename roguelike/impl/src/main/java/roguelike/models/{ => beings}/ActiveBeing.java (84%) rename roguelike/impl/src/main/java/roguelike/models/{ => beings}/ArtificialIntelligence.java (75%) rename roguelike/impl/src/main/java/roguelike/models/{ => beings}/Being.java (85%) create mode 100644 roguelike/impl/src/main/java/roguelike/models/beings/Dragon.java rename roguelike/impl/src/main/java/roguelike/models/{ => beings}/Ghost.java (89%) create mode 100644 roguelike/impl/src/main/java/roguelike/models/beings/Mushroom.java rename roguelike/impl/src/main/java/roguelike/models/{ => beings}/Player.java (76%) rename roguelike/impl/src/main/java/roguelike/models/{ => beings}/PlayerEffects.java (95%) rename roguelike/impl/src/main/java/roguelike/models/{ => items}/LootItem.java (82%) rename roguelike/impl/src/main/java/roguelike/models/{ => items}/Weapon.java (95%) rename roguelike/impl/src/main/java/roguelike/models/{ => items}/WeaponType.java (96%) diff --git a/roguelike/impl/src/main/java/roguelike/models/Mushroom.java b/roguelike/impl/src/main/java/roguelike/models/Mushroom.java deleted file mode 100644 index f1bb50b..0000000 --- a/roguelike/impl/src/main/java/roguelike/models/Mushroom.java +++ /dev/null @@ -1,30 +0,0 @@ -package roguelike.models; - -import java.awt.*; - -/** - * Created by boris on 09.05.17. - */ -public class Mushroom extends Being { - - public Mushroom(World world) { - super(world); - - this.glyph = 'T'; - this.color = Color.GREEN; - poisonTiles(); - - } - - private void poisonTiles() { - for (int i = -2; i < 3; i++) { - for (int j = -2; j < 3; j++) { - int wx = x + i; - int wy = y + j; - if (i * i + j * j <= 5 && world.getTile(wx, wy) == Tile.FLOOR) { - world.setTile(wx, wy, Tile.POISONED_FLOOR); - } - } - } - } -} diff --git a/roguelike/impl/src/main/java/roguelike/models/Tile.java b/roguelike/impl/src/main/java/roguelike/models/Tile.java index 9e24393..84dde88 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Tile.java +++ b/roguelike/impl/src/main/java/roguelike/models/Tile.java @@ -10,6 +10,7 @@ public enum Tile { FLOOR('.', AsciiPanel.yellow, 0), POISONED_FLOOR('.', Color.GREEN, -5), + ENFLAMED_FLOOR('.', Color.RED, -5), WALL('#', AsciiPanel.yellow, 0), BOUNDS('x', AsciiPanel.brightBlack, 0); @@ -36,7 +37,7 @@ public int getDeltaHealth() { } public boolean isWalkable() { - return this == FLOOR || this == POISONED_FLOOR; + return this == FLOOR || this == POISONED_FLOOR || this == ENFLAMED_FLOOR; } public boolean isDiggable() { diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java index 90e6ed2..b7bf8a5 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -2,6 +2,9 @@ import roguelike.DelayedTask; +import roguelike.models.beings.Being; +import roguelike.models.beings.Player; +import roguelike.models.items.LootItem; import java.awt.Color; import java.util.ArrayList; diff --git a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java index 25cc192..4579640 100644 --- a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java +++ b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java @@ -1,15 +1,14 @@ package roguelike.models; -import roguelike.models.Tile; -import roguelike.models.World; +import roguelike.models.beings.Being; +import roguelike.models.items.LootItem; +import roguelike.models.items.Weapon; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.Random; -import java.util.stream.Collectors; /** * Created by boris on 08.05.17. diff --git a/roguelike/impl/src/main/java/roguelike/models/actions/Actions.java b/roguelike/impl/src/main/java/roguelike/models/actions/Actions.java new file mode 100644 index 0000000..314a07e --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/actions/Actions.java @@ -0,0 +1,21 @@ +package roguelike.models.actions; + +import roguelike.models.Tile; +import roguelike.models.World; + +/** + * Created by boris on 11.05.17. + */ +public class Actions { + public static void setTilesAround(World world, int x, int y, int radius, Tile tile) { + for (int i = -radius; i <= radius; i++) { + for (int j = -radius; j <= radius; j++) { + int wx = x + i; + int wy = y + j; + if (i * i + j * j <= radius * radius && world.getTile(wx, wy) == Tile.FLOOR) { + world.setTile(wx, wy, tile); + } + } + } + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java b/roguelike/impl/src/main/java/roguelike/models/beings/ActiveBeing.java similarity index 84% rename from roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java rename to roguelike/impl/src/main/java/roguelike/models/beings/ActiveBeing.java index 6d936b6..71104a5 100644 --- a/roguelike/impl/src/main/java/roguelike/models/ActiveBeing.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/ActiveBeing.java @@ -1,6 +1,9 @@ -package roguelike.models; +package roguelike.models.beings; -import java.util.function.Function; +import roguelike.models.Tile; +import roguelike.models.World; + +import java.util.Random; /** * Created by boris on 10.05.17. @@ -54,5 +57,10 @@ public PlayerEffects getEffect() { return effect; } + + protected void moveRandom() { + move(new Random().nextInt(3) - 1, new Random().nextInt(3) - 1); + } + protected abstract void interactWithEnvironment(); } diff --git a/roguelike/impl/src/main/java/roguelike/models/ArtificialIntelligence.java b/roguelike/impl/src/main/java/roguelike/models/beings/ArtificialIntelligence.java similarity index 75% rename from roguelike/impl/src/main/java/roguelike/models/ArtificialIntelligence.java rename to roguelike/impl/src/main/java/roguelike/models/beings/ArtificialIntelligence.java index 725d55f..939697f 100644 --- a/roguelike/impl/src/main/java/roguelike/models/ArtificialIntelligence.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/ArtificialIntelligence.java @@ -1,4 +1,4 @@ -package roguelike.models; +package roguelike.models.beings; /** * Created by boris on 10.05.17. diff --git a/roguelike/impl/src/main/java/roguelike/models/Being.java b/roguelike/impl/src/main/java/roguelike/models/beings/Being.java similarity index 85% rename from roguelike/impl/src/main/java/roguelike/models/Being.java rename to roguelike/impl/src/main/java/roguelike/models/beings/Being.java index 292f460..707ee30 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Being.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Being.java @@ -1,6 +1,8 @@ -package roguelike.models; +package roguelike.models.beings; import asciiPanel.AsciiPanel; +import roguelike.models.Position; +import roguelike.models.World; import java.awt.*; import java.util.Random; diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Dragon.java b/roguelike/impl/src/main/java/roguelike/models/beings/Dragon.java new file mode 100644 index 0000000..4aff441 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Dragon.java @@ -0,0 +1,43 @@ +package roguelike.models.beings; + +import roguelike.RecurringTask; +import roguelike.models.Tile; +import roguelike.models.World; +import roguelike.models.actions.Actions; + +import java.awt.*; + +/** + * Created by boris on 11.05.17. + */ +public class Dragon extends ActiveBeing implements ArtificialIntelligence { + public Dragon(World world) { + super(world); + + this.glyph = 'D'; + this.color = Color.RED; + enflameTiles(); + + new RecurringTask(this::move, 1000); + } + + @Override + public void move() { + moveRandom(); + } + + @Override + public void move(int dx, int dy) { + super.move(dx, dy); + enflameTiles(); + } + + @Override + protected void interactWithEnvironment() { + + } + + private void enflameTiles() { + Actions.setTilesAround(world, x, y, 0, Tile.ENFLAMED_FLOOR); + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/Ghost.java b/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java similarity index 89% rename from roguelike/impl/src/main/java/roguelike/models/Ghost.java rename to roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java index dca41cd..06860c9 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Ghost.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java @@ -1,12 +1,13 @@ -package roguelike.models; +package roguelike.models.beings; import roguelike.RecurringTask; +import roguelike.models.World; import java.awt.*; import java.util.Random; -import static roguelike.models.PlayerEffects.IDENTITY; -import static roguelike.models.PlayerEffects.INVERSED; +import static roguelike.models.beings.PlayerEffects.IDENTITY; +import static roguelike.models.beings.PlayerEffects.INVERSED; /** * Created by boris on 10.05.17. @@ -29,7 +30,7 @@ public Ghost(World world) { @Override protected void interactWithEnvironment() { - if (distToPlayer(x, y) < 2) { + if (distToPlayer(x, y) < 3) { PlayerEffects effect = world.getPlayer().getEffect(); if (effect == INVERSED) { world.getMobs().remove(this); @@ -94,9 +95,6 @@ private void moveFromPlayer() { move(dx, dy); } - private void moveRandom() { - move(new Random().nextInt(3) - 1, new Random().nextInt(3) - 1); - } private double distToPlayer(int fromX, int fromY) { return Math.hypot(fromX - world.getPlayer().x, fromY - world.getPlayer().y); diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Mushroom.java b/roguelike/impl/src/main/java/roguelike/models/beings/Mushroom.java new file mode 100644 index 0000000..e452d25 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Mushroom.java @@ -0,0 +1,26 @@ +package roguelike.models.beings; + +import roguelike.models.Tile; +import roguelike.models.World; +import roguelike.models.actions.Actions; + +import java.awt.*; + +/** + * Created by boris on 09.05.17. + */ +public class Mushroom extends Being { + + public Mushroom(World world) { + super(world); + + this.glyph = 'T'; + this.color = Color.GREEN; + poisonTiles(); + + } + + private void poisonTiles() { + Actions.setTilesAround(world, x, y, 3, Tile.POISONED_FLOOR); + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/Player.java b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java similarity index 76% rename from roguelike/impl/src/main/java/roguelike/models/Player.java rename to roguelike/impl/src/main/java/roguelike/models/beings/Player.java index 3bb007a..7e7787d 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Player.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java @@ -1,4 +1,8 @@ -package roguelike.models; +package roguelike.models.beings; + +import roguelike.models.items.Weapon; +import roguelike.models.items.WeaponType; +import roguelike.models.World; import java.awt.*; diff --git a/roguelike/impl/src/main/java/roguelike/models/PlayerEffects.java b/roguelike/impl/src/main/java/roguelike/models/beings/PlayerEffects.java similarity index 95% rename from roguelike/impl/src/main/java/roguelike/models/PlayerEffects.java rename to roguelike/impl/src/main/java/roguelike/models/beings/PlayerEffects.java index 3981e41..7e33054 100644 --- a/roguelike/impl/src/main/java/roguelike/models/PlayerEffects.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/PlayerEffects.java @@ -1,4 +1,4 @@ -package roguelike.models; +package roguelike.models.beings; import java.awt.event.KeyEvent; import java.util.function.Function; diff --git a/roguelike/impl/src/main/java/roguelike/models/LootItem.java b/roguelike/impl/src/main/java/roguelike/models/items/LootItem.java similarity index 82% rename from roguelike/impl/src/main/java/roguelike/models/LootItem.java rename to roguelike/impl/src/main/java/roguelike/models/items/LootItem.java index 8421be7..1219116 100644 --- a/roguelike/impl/src/main/java/roguelike/models/LootItem.java +++ b/roguelike/impl/src/main/java/roguelike/models/items/LootItem.java @@ -1,4 +1,7 @@ -package roguelike.models; +package roguelike.models.items; + +import roguelike.models.Position; +import roguelike.models.World; /** * Created by boris on 11.05.17. diff --git a/roguelike/impl/src/main/java/roguelike/models/Weapon.java b/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java similarity index 95% rename from roguelike/impl/src/main/java/roguelike/models/Weapon.java rename to roguelike/impl/src/main/java/roguelike/models/items/Weapon.java index 5533170..7c735b7 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Weapon.java +++ b/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java @@ -1,4 +1,4 @@ -package roguelike.models; +package roguelike.models.items; import java.awt.*; diff --git a/roguelike/impl/src/main/java/roguelike/models/WeaponType.java b/roguelike/impl/src/main/java/roguelike/models/items/WeaponType.java similarity index 96% rename from roguelike/impl/src/main/java/roguelike/models/WeaponType.java rename to roguelike/impl/src/main/java/roguelike/models/items/WeaponType.java index bfdbe87..d1e8e29 100644 --- a/roguelike/impl/src/main/java/roguelike/models/WeaponType.java +++ b/roguelike/impl/src/main/java/roguelike/models/items/WeaponType.java @@ -1,4 +1,4 @@ -package roguelike.models; +package roguelike.models.items; import java.util.Arrays; import java.util.List; diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index 131ddc9..2fad003 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -2,6 +2,9 @@ import asciiPanel.AsciiPanel; import roguelike.models.*; +import roguelike.models.beings.*; +import roguelike.models.items.LootItem; +import roguelike.models.items.Weapon; import java.awt.*; @@ -23,6 +26,7 @@ public PlayScreen() { .makeCaves() .addMobs(Mushroom.class, 10) .addMobs(Ghost.class, 10) + .addMobs(Dragon.class, 2) .addLoot(15) .build(); diff --git a/roguelike/impl/src/main/resources/todolist b/roguelike/impl/src/main/resources/todolist index 6b99768..17173fe 100644 --- a/roguelike/impl/src/main/resources/todolist +++ b/roguelike/impl/src/main/resources/todolist @@ -35,6 +35,7 @@ БАГИ: 1. Не работает в русской раскладке +2. В reversed состоянии не работает копание From b3f80e21f124fda60f8dcfe89d78dc7f0dacf306 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Thu, 11 May 2017 14:47:07 +0300 Subject: [PATCH 36/63] pick weapons --- .../impl/src/main/java/roguelike/models/World.java | 10 ++++++++++ .../main/java/roguelike/models/beings/Player.java | 8 ++++++++ .../src/main/java/roguelike/models/items/Weapon.java | 4 ++++ .../main/java/roguelike/models/items/WeaponType.java | 12 +++++++++--- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java index b7bf8a5..f7eb609 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -5,6 +5,7 @@ import roguelike.models.beings.Being; import roguelike.models.beings.Player; import roguelike.models.items.LootItem; +import roguelike.models.items.Weapon; import java.awt.Color; import java.util.ArrayList; @@ -93,6 +94,15 @@ public Being getMob(int x, int y) { return null; } + public LootItem getWeapon(int x, int y) { + for (LootItem b : loot) { + if (b.x == x && b.y == y) { + return b; + } + } + return null; + } + public Position getEmptyPosition() { Random randomGen = new Random(); diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java index 7e7787d..81fef25 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java @@ -1,5 +1,6 @@ package roguelike.models.beings; +import roguelike.models.items.LootItem; import roguelike.models.items.Weapon; import roguelike.models.items.WeaponType; import roguelike.models.World; @@ -25,5 +26,12 @@ public Player(World world) { protected void interactWithEnvironment() { int deltaHealth = world.getTile(x, y).getDeltaHealth(); health += deltaHealth; + + LootItem lootItem = world.getWeapon(x, y); + if (lootItem != null) { + weapon = lootItem.getWeapon(); + world.setMessage(String.format("picked %s", weapon.getName())); + world.getLoot().remove(lootItem); + } } } diff --git a/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java b/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java index 7c735b7..8058389 100644 --- a/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java +++ b/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java @@ -20,6 +20,10 @@ public Color getColor() { return Color.getHSBColor(type.getHue(), 200, brightness); } + public String getName() { // todo handle level name correlation + return type.getName() + String.format(" of level %d", level); + } + public char getGlyph() { return type.getGlyph(); } diff --git a/roguelike/impl/src/main/java/roguelike/models/items/WeaponType.java b/roguelike/impl/src/main/java/roguelike/models/items/WeaponType.java index d1e8e29..2babf65 100644 --- a/roguelike/impl/src/main/java/roguelike/models/items/WeaponType.java +++ b/roguelike/impl/src/main/java/roguelike/models/items/WeaponType.java @@ -8,19 +8,25 @@ * Created by boris on 11.05.17. */ public enum WeaponType { - HAND('h', 1, 10), - SWORD('>', 10, 150); + HAND('h', "hand", 1, 10), + SWORD('>', "sword", 10, 150); private char glyph; private int hue; private int harm; + private String name; - WeaponType(char glyph, int harm, int hue) { + WeaponType(char glyph, String name, int harm, int hue) { this.glyph = glyph; + this.name = name; this.harm = harm; this.hue = hue; } + public String getName() { + return name; + } + public char getGlyph() { return glyph; } From 74d19b8d62bf304e91a0512459e308a3d783525f Mon Sep 17 00:00:00 2001 From: simiyutin Date: Thu, 11 May 2017 21:57:27 +0300 Subject: [PATCH 37/63] battle --- .../src/main/java/roguelike/Scheduler.java | 11 ++- .../src/main/java/roguelike/models/World.java | 7 +- .../java/roguelike/models/actions/Action.java | 8 ++ .../java/roguelike/models/actions/Battle.java | 13 +++ .../models/actions/DragonBattle.java | 16 ++++ .../roguelike/models/beings/ActiveBeing.java | 48 +++++++--- .../java/roguelike/models/beings/Ghost.java | 8 +- .../java/roguelike/models/beings/Player.java | 87 +++++++++++++++++++ .../{PlayerEffects.java => SideEffect.java} | 6 +- .../java/roguelike/screens/DeadScreen.java | 5 ++ .../java/roguelike/screens/PlayScreen.java | 11 ++- .../main/java/roguelike/screens/Screen.java | 1 + .../java/roguelike/screens/StartScreen.java | 5 ++ 13 files changed, 201 insertions(+), 25 deletions(-) create mode 100644 roguelike/impl/src/main/java/roguelike/models/actions/Action.java create mode 100644 roguelike/impl/src/main/java/roguelike/models/actions/Battle.java create mode 100644 roguelike/impl/src/main/java/roguelike/models/actions/DragonBattle.java rename roguelike/impl/src/main/java/roguelike/models/beings/{PlayerEffects.java => SideEffect.java} (87%) diff --git a/roguelike/impl/src/main/java/roguelike/Scheduler.java b/roguelike/impl/src/main/java/roguelike/Scheduler.java index 4d045f2..2ba7c70 100644 --- a/roguelike/impl/src/main/java/roguelike/Scheduler.java +++ b/roguelike/impl/src/main/java/roguelike/Scheduler.java @@ -25,14 +25,17 @@ public Scheduler() { this.screen = new StartScreen(); addKeyListener(this); + setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + setVisible(true); + } - - new RecurringTask(this::repaint, 10); + public void run() { + screen = screen.updateState(); + repaint(); } public void schedule() { - setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - setVisible(true); + new RecurringTask(this::run, 10); } @Override diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java index f7eb609..cb8bf61 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -2,6 +2,7 @@ import roguelike.DelayedTask; +import roguelike.models.actions.Battle; import roguelike.models.beings.Being; import roguelike.models.beings.Player; import roguelike.models.items.LootItem; @@ -35,7 +36,11 @@ public String getMessage() { public void setMessage(String message) { //todo timeoutTask; this.message = message; - new DelayedTask(() -> this.message = "", 1000); + new DelayedTask(() -> { + if (this.message.equals(message)) { + this.message = ""; + } + }, 1000); } public World(Tile[][] tiles) { diff --git a/roguelike/impl/src/main/java/roguelike/models/actions/Action.java b/roguelike/impl/src/main/java/roguelike/models/actions/Action.java new file mode 100644 index 0000000..f769a46 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/actions/Action.java @@ -0,0 +1,8 @@ +package roguelike.models.actions; + +/** + * Created by boris on 11.05.17. + */ +public interface Action { + void act(); +} diff --git a/roguelike/impl/src/main/java/roguelike/models/actions/Battle.java b/roguelike/impl/src/main/java/roguelike/models/actions/Battle.java new file mode 100644 index 0000000..90aaaff --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/actions/Battle.java @@ -0,0 +1,13 @@ +package roguelike.models.actions; + +import roguelike.RecurringTask; +import roguelike.models.World; +import roguelike.models.beings.ActiveBeing; + +/** + * Created by boris on 11.05.17. + */ +public interface Battle { + + void doBattle(World world, ActiveBeing enemy); +} diff --git a/roguelike/impl/src/main/java/roguelike/models/actions/DragonBattle.java b/roguelike/impl/src/main/java/roguelike/models/actions/DragonBattle.java new file mode 100644 index 0000000..7835fef --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/actions/DragonBattle.java @@ -0,0 +1,16 @@ +package roguelike.models.actions; + +import roguelike.models.World; +import roguelike.models.beings.ActiveBeing; +import roguelike.models.beings.SideEffect; + +/** + * Created by boris on 11.05.17. + */ +public class DragonBattle implements Battle { + @Override + public void doBattle(World world, ActiveBeing enemy) { + + + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/ActiveBeing.java b/roguelike/impl/src/main/java/roguelike/models/beings/ActiveBeing.java index 71104a5..5fe4ce1 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/ActiveBeing.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/ActiveBeing.java @@ -1,6 +1,5 @@ package roguelike.models.beings; -import roguelike.models.Tile; import roguelike.models.World; import java.util.Random; @@ -14,21 +13,54 @@ public abstract class ActiveBeing extends Being { protected int yDirection; protected int health; + protected int level; + protected boolean immobilized; + protected boolean alive; - private PlayerEffects effect; + private SideEffect effect; public ActiveBeing(World world) { super(world); this.health = 100; - this.effect = PlayerEffects.IDENTITY; + this.effect = SideEffect.IDENTITY; + this.level = 1; + this.immobilized = false; + this.alive = true; + } + + public boolean isAlive() { + return alive; + } + + public void setAlive(boolean alive) { + this.alive = alive; + } + + public boolean isImmobilized() { + return immobilized; + } + + public void setImmobilized(boolean immobilized) { + this.immobilized = immobilized; + } + + public int getLevel() { + return level; } public int getHealth() { return health; } + public void setHealth(int health) { + this.health = health; + } + public void move(int dx, int dy) { + if (immobilized) { + return; + } xDirection = Math.max(0, Math.min(x + dx, world.getWidth() - 1)); yDirection = Math.max(0, Math.min(y + dy, world.getHeight() - 1)); if (canMove(xDirection, yDirection)) { @@ -43,17 +75,11 @@ protected boolean canMove(int xTo, int yTo) { return world.getTile(xTo, yTo).isWalkable() && world.getMob(xTo, yTo) == null; } - public void act() { - if (world.getTile(xDirection, yDirection).isDiggable()) { - world.setTile(xDirection, yDirection, Tile.FLOOR); - } - } - - public void setEffect(PlayerEffects effect) { + public void setEffect(SideEffect effect) { this.effect = effect; } - public PlayerEffects getEffect() { + public SideEffect getEffect() { return effect; } diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java b/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java index 06860c9..1e61edd 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java @@ -4,10 +4,9 @@ import roguelike.models.World; import java.awt.*; -import java.util.Random; -import static roguelike.models.beings.PlayerEffects.IDENTITY; -import static roguelike.models.beings.PlayerEffects.INVERSED; +import static roguelike.models.beings.SideEffect.IDENTITY; +import static roguelike.models.beings.SideEffect.INVERSED; /** * Created by boris on 10.05.17. @@ -17,7 +16,6 @@ public class Ghost extends ActiveBeing implements ArtificialIntelligence { private static boolean moveTo = true; private final int SMELL_RANGE = 15; - private boolean alive = true; public Ghost(World world) { super(world); @@ -31,7 +29,7 @@ public Ghost(World world) { @Override protected void interactWithEnvironment() { if (distToPlayer(x, y) < 3) { - PlayerEffects effect = world.getPlayer().getEffect(); + SideEffect effect = world.getPlayer().getEffect(); if (effect == INVERSED) { world.getMobs().remove(this); world.getPlayer().setEffect(IDENTITY); diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java index 81fef25..2882067 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java @@ -1,5 +1,11 @@ package roguelike.models.beings; +import roguelike.DelayedTask; +import roguelike.RecurringTask; +import roguelike.models.Tile; +import roguelike.models.actions.Action; +import roguelike.models.actions.Battle; +import roguelike.models.actions.DragonBattle; import roguelike.models.items.LootItem; import roguelike.models.items.Weapon; import roguelike.models.items.WeaponType; @@ -13,6 +19,7 @@ public class Player extends ActiveBeing { private Weapon weapon; + private Action action; public Player(World world) { super(world); @@ -20,6 +27,7 @@ public Player(World world) { this.glyph = 'X'; this.color = Color.BLUE; this.weapon = WeaponType.HAND.getItem(); + this.action = new RegularAction(); } @Override @@ -33,5 +41,84 @@ protected void interactWithEnvironment() { world.setMessage(String.format("picked %s", weapon.getName())); world.getLoot().remove(lootItem); } + + Being being = getMobNearMe(); + if (being != null) { + if (being instanceof Dragon) { // todo inheritance + world.setMessage("press [enter] to start battle with dragon"); + } + } + } + + public Being getMobNearMe() { + for (Being b : world.getMobs()) { + if (distTo(b.x, b.y) == 1) { + return b; + } + } + + return null; + } + + private double distTo(int toX, int toY) { + return Math.hypot(toX - x, toY - y); + } + + public void act() { + action.act(); + } + + private void startBattleWithDragon(Dragon dragon) { + setImmobilized(true); + dragon.setImmobilized(true); + action = new AttackingAction(dragon); + new RecurringTask(() -> { + if (dragon.isAlive()) { + int harm = dragon.getLevel(); + setHealth(health - harm); + } + }, 500); + } + + class RegularAction implements Action { + + @Override + public void act() { + if (world.getTile(xDirection, yDirection).isDiggable()) { + world.setTile(xDirection, yDirection, Tile.FLOOR); + } + + Being being = getMobNearMe(); + if (being != null) { + if (being instanceof Dragon) { // todo inheritance + startBattleWithDragon((Dragon) being); + } + } + } + } + + class AttackingAction implements Action { + private ActiveBeing enemy; + + public AttackingAction(ActiveBeing enemy) { + this.enemy = enemy; + } + + @Override + public void act() { + int harm = level * weapon.getLevel(); + int health = enemy.getHealth(); + enemy.setHealth(health - harm); + world.setMessage(String.format("enemy heath: %d", enemy.getHealth())); + if (enemy.getHealth() < 0) { + world.setMessage("You won!"); + weapon = Weapon.getRandomOfLevel(enemy.getLevel() + 2); + new DelayedTask(() -> world.setMessage(String.format("Obtained %s", weapon.getName())), 1000); + world.getMobs().remove(enemy); + enemy.setAlive(false); + setImmobilized(false); + action = new RegularAction(); + } + } } } diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/PlayerEffects.java b/roguelike/impl/src/main/java/roguelike/models/beings/SideEffect.java similarity index 87% rename from roguelike/impl/src/main/java/roguelike/models/beings/PlayerEffects.java rename to roguelike/impl/src/main/java/roguelike/models/beings/SideEffect.java index 7e33054..0838d14 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/PlayerEffects.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/SideEffect.java @@ -6,10 +6,12 @@ /** * Created by boris on 10.05.17. */ -public enum PlayerEffects { +public enum SideEffect { IDENTITY(Function.identity()), + IMMOBILIZED(key -> 0), + INVERSED(key -> { switch (key) { case KeyEvent.VK_S: @@ -27,7 +29,7 @@ public enum PlayerEffects { private Function proxy; - PlayerEffects(Function proxy) { + SideEffect(Function proxy) { this.proxy = proxy; } diff --git a/roguelike/impl/src/main/java/roguelike/screens/DeadScreen.java b/roguelike/impl/src/main/java/roguelike/screens/DeadScreen.java index 9e0d2e8..48d8710 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/DeadScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/DeadScreen.java @@ -18,4 +18,9 @@ public void display(AsciiPanel terminal) { public Screen respondToUserInput(KeyEvent key) { return this; } + + @Override + public Screen updateState() { + return this; + } } diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index 2fad003..b3a0c71 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -25,14 +25,15 @@ public PlayScreen() { world = new WorldBuilder(100, 100) .makeCaves() .addMobs(Mushroom.class, 10) - .addMobs(Ghost.class, 10) - .addMobs(Dragon.class, 2) + .addMobs(Ghost.class, 0) + .addMobs(Dragon.class, 100) .addLoot(15) .build(); player = world.getPlayer(); } + @Override public void display(AsciiPanel terminal) { int left = scrollLeft(); int top = scrollTop(); @@ -51,6 +52,7 @@ private int scrollTop() { return Math.max(0, Math.min(player.y - screenHeight / 2, world.getHeight() - screenHeight)); } + @Override public Screen respondToUserInput(KeyEvent key) { switch (player.getEffect().apply(key.getKeyCode())) { case KeyEvent.VK_S: @@ -69,6 +71,11 @@ public Screen respondToUserInput(KeyEvent key) { player.act(); break; } + return updateState(); + } + + @Override + public Screen updateState() { return player.getHealth() > 0 ? this : new DeadScreen(); } diff --git a/roguelike/impl/src/main/java/roguelike/screens/Screen.java b/roguelike/impl/src/main/java/roguelike/screens/Screen.java index 5c6ca28..52b1b74 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/Screen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/Screen.java @@ -10,6 +10,7 @@ public interface Screen { void display(AsciiPanel terminal); Screen respondToUserInput(KeyEvent key); + Screen updateState(); default void print(AsciiPanel terminal, String str) { final int onHeight = 18; terminal.writeCenter(str, onHeight); diff --git a/roguelike/impl/src/main/java/roguelike/screens/StartScreen.java b/roguelike/impl/src/main/java/roguelike/screens/StartScreen.java index 0263be1..490d710 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/StartScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/StartScreen.java @@ -18,4 +18,9 @@ public void display(AsciiPanel terminal) { public Screen respondToUserInput(KeyEvent key) { return key.getKeyCode() == KeyEvent.VK_ENTER ? new PlayScreen() : this; } + + @Override + public Screen updateState() { + return this; + } } From c8258cfb0b98b0668a10e52b299a6609872c74d7 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Thu, 11 May 2017 21:58:01 +0300 Subject: [PATCH 38/63] amend --- .../java/roguelike/models/actions/Battle.java | 13 ------------- .../roguelike/models/actions/DragonBattle.java | 16 ---------------- 2 files changed, 29 deletions(-) delete mode 100644 roguelike/impl/src/main/java/roguelike/models/actions/Battle.java delete mode 100644 roguelike/impl/src/main/java/roguelike/models/actions/DragonBattle.java diff --git a/roguelike/impl/src/main/java/roguelike/models/actions/Battle.java b/roguelike/impl/src/main/java/roguelike/models/actions/Battle.java deleted file mode 100644 index 90aaaff..0000000 --- a/roguelike/impl/src/main/java/roguelike/models/actions/Battle.java +++ /dev/null @@ -1,13 +0,0 @@ -package roguelike.models.actions; - -import roguelike.RecurringTask; -import roguelike.models.World; -import roguelike.models.beings.ActiveBeing; - -/** - * Created by boris on 11.05.17. - */ -public interface Battle { - - void doBattle(World world, ActiveBeing enemy); -} diff --git a/roguelike/impl/src/main/java/roguelike/models/actions/DragonBattle.java b/roguelike/impl/src/main/java/roguelike/models/actions/DragonBattle.java deleted file mode 100644 index 7835fef..0000000 --- a/roguelike/impl/src/main/java/roguelike/models/actions/DragonBattle.java +++ /dev/null @@ -1,16 +0,0 @@ -package roguelike.models.actions; - -import roguelike.models.World; -import roguelike.models.beings.ActiveBeing; -import roguelike.models.beings.SideEffect; - -/** - * Created by boris on 11.05.17. - */ -public class DragonBattle implements Battle { - @Override - public void doBattle(World world, ActiveBeing enemy) { - - - } -} From 0fe3905aee8aca4c7f15c2ecd6fbe5101f8b8c8b Mon Sep 17 00:00:00 2001 From: simiyutin Date: Thu, 11 May 2017 22:16:45 +0300 Subject: [PATCH 39/63] med aids --- .../src/main/java/roguelike/models/World.java | 13 ++++---- .../java/roguelike/models/WorldBuilder.java | 21 +++++++++---- .../java/roguelike/models/beings/Player.java | 20 +++++++------ .../java/roguelike/models/items/Item.java | 12 ++++++++ .../java/roguelike/models/items/MedAid.java | 30 +++++++++++++++++++ .../items/{LootItem.java => ThrownItem.java} | 16 +++++----- .../java/roguelike/models/items/Weapon.java | 2 +- .../java/roguelike/screens/PlayScreen.java | 13 ++++---- 8 files changed, 90 insertions(+), 37 deletions(-) create mode 100644 roguelike/impl/src/main/java/roguelike/models/items/Item.java create mode 100644 roguelike/impl/src/main/java/roguelike/models/items/MedAid.java rename roguelike/impl/src/main/java/roguelike/models/items/{LootItem.java => ThrownItem.java} (54%) diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java index cb8bf61..8388bfc 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -2,11 +2,9 @@ import roguelike.DelayedTask; -import roguelike.models.actions.Battle; import roguelike.models.beings.Being; import roguelike.models.beings.Player; -import roguelike.models.items.LootItem; -import roguelike.models.items.Weapon; +import roguelike.models.items.ThrownItem; import java.awt.Color; import java.util.ArrayList; @@ -23,9 +21,9 @@ public class World { private Player player; private List mobs; private String message = ""; - private List loot; + private List loot; - public List getLoot() { + public List getLoot() { return loot; } @@ -34,7 +32,6 @@ public String getMessage() { } public void setMessage(String message) { - //todo timeoutTask; this.message = message; new DelayedTask(() -> { if (this.message.equals(message)) { @@ -99,8 +96,8 @@ public Being getMob(int x, int y) { return null; } - public LootItem getWeapon(int x, int y) { - for (LootItem b : loot) { + public ThrownItem getItem(int x, int y) { + for (ThrownItem b : loot) { if (b.x == x && b.y == y) { return b; } diff --git a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java index 4579640..97f28ce 100644 --- a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java +++ b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java @@ -1,7 +1,9 @@ package roguelike.models; import roguelike.models.beings.Being; -import roguelike.models.items.LootItem; +import roguelike.models.items.Item; +import roguelike.models.items.MedAid; +import roguelike.models.items.ThrownItem; import roguelike.models.items.Weapon; import java.lang.reflect.Constructor; @@ -19,7 +21,7 @@ public class WorldBuilder { private int height; private Tile[][] tiles; private List> mobs; - private List loot; + private List loot; public WorldBuilder(int width, int height) { this.width = width; @@ -39,8 +41,8 @@ public World build() { } } - for (Weapon w : loot) { - world.getLoot().add(new LootItem(w, world)); //todo circular dependency + for (Item w : loot) { + world.getLoot().add(new ThrownItem(w, world)); //todo circular dependency } return world; @@ -63,7 +65,7 @@ public WorldBuilder addMobs(Class clazz, int quantity) { return this; } - public WorldBuilder addLoot(int quantity) { + public WorldBuilder addWeapons(int quantity) { Random randGen = new Random(); final int maxLevel = 2; for (int i = 0; i < quantity; i++) { @@ -73,6 +75,15 @@ public WorldBuilder addLoot(int quantity) { return this; } + public WorldBuilder addMedAids(int quantity) { + for (int i = 0; i < quantity; i++) { + MedAid medAid = new MedAid(); + loot.add(medAid); + } + + return this; + } + private WorldBuilder randomizeTiles() { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java index 2882067..0d0da25 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java @@ -4,11 +4,7 @@ import roguelike.RecurringTask; import roguelike.models.Tile; import roguelike.models.actions.Action; -import roguelike.models.actions.Battle; -import roguelike.models.actions.DragonBattle; -import roguelike.models.items.LootItem; -import roguelike.models.items.Weapon; -import roguelike.models.items.WeaponType; +import roguelike.models.items.*; import roguelike.models.World; import java.awt.*; @@ -35,11 +31,17 @@ protected void interactWithEnvironment() { int deltaHealth = world.getTile(x, y).getDeltaHealth(); health += deltaHealth; - LootItem lootItem = world.getWeapon(x, y); - if (lootItem != null) { - weapon = lootItem.getWeapon(); + ThrownItem thrownItem = world.getItem(x, y); + if (thrownItem != null) { + Item item = thrownItem.getItem(); + if (item instanceof Weapon) { + weapon = (Weapon) item; + } else if (item instanceof MedAid) { + health += ((MedAid) item).getValue(); + health = Math.min(health, 100); + } world.setMessage(String.format("picked %s", weapon.getName())); - world.getLoot().remove(lootItem); + world.getLoot().remove(thrownItem); } Being being = getMobNearMe(); diff --git a/roguelike/impl/src/main/java/roguelike/models/items/Item.java b/roguelike/impl/src/main/java/roguelike/models/items/Item.java new file mode 100644 index 0000000..23035d3 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/items/Item.java @@ -0,0 +1,12 @@ +package roguelike.models.items; + +import java.awt.*; + +/** + * Created by boris on 11.05.17. + */ +public interface Item { + Color getColor(); + String getName(); + char getGlyph(); +} diff --git a/roguelike/impl/src/main/java/roguelike/models/items/MedAid.java b/roguelike/impl/src/main/java/roguelike/models/items/MedAid.java new file mode 100644 index 0000000..bca1ce7 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/items/MedAid.java @@ -0,0 +1,30 @@ +package roguelike.models.items; + +import java.awt.*; + +/** + * Created by boris on 11.05.17. + */ +public class MedAid implements Item { + + private int value = 50; + + @Override + public Color getColor() { + return Color.GREEN; + } + + @Override + public String getName() { + return String.format("Med aid of value %d", value); + } + + @Override + public char getGlyph() { + return '+'; + } + + public int getValue() { + return value; + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/items/LootItem.java b/roguelike/impl/src/main/java/roguelike/models/items/ThrownItem.java similarity index 54% rename from roguelike/impl/src/main/java/roguelike/models/items/LootItem.java rename to roguelike/impl/src/main/java/roguelike/models/items/ThrownItem.java index 1219116..253d709 100644 --- a/roguelike/impl/src/main/java/roguelike/models/items/LootItem.java +++ b/roguelike/impl/src/main/java/roguelike/models/items/ThrownItem.java @@ -6,24 +6,24 @@ /** * Created by boris on 11.05.17. */ -public class LootItem { +public class ThrownItem { public int x; public int y; - private Weapon weapon; + private Item item; - public LootItem(Weapon weapon, World world) { - this.weapon = weapon; + public ThrownItem(Item item, World world) { + this.item = item; Position position = world.getEmptyPosition(); this.x = position.x; this.y = position.y; } - public Weapon getWeapon() { - return weapon; + public Item getItem() { + return item; } - public void setWeapon(Weapon weapon) { - this.weapon = weapon; + public void setItem(Item item) { + this.item = item; } } diff --git a/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java b/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java index 8058389..aa89eb6 100644 --- a/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java +++ b/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java @@ -5,7 +5,7 @@ /** * Created by boris on 11.05.17. */ -public class Weapon { +public class Weapon implements Item { private WeaponType type; private final int MAX_LEVEL = 10; private int level; // 1 - 10 diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index b3a0c71..2710106 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -3,8 +3,8 @@ import asciiPanel.AsciiPanel; import roguelike.models.*; import roguelike.models.beings.*; -import roguelike.models.items.LootItem; -import roguelike.models.items.Weapon; +import roguelike.models.items.Item; +import roguelike.models.items.ThrownItem; import java.awt.*; @@ -27,7 +27,8 @@ public PlayScreen() { .addMobs(Mushroom.class, 10) .addMobs(Ghost.class, 0) .addMobs(Dragon.class, 100) - .addLoot(15) + .addWeapons(15) + .addMedAids(10) .build(); player = world.getPlayer(); @@ -110,9 +111,9 @@ public void displayWorld(AsciiPanel terminal, int left, int top) { } public void displayLoot(AsciiPanel terminal, int left, int top) { - for (LootItem b: world.getLoot()) { - Weapon w = b.getWeapon(); - writeSafe(terminal, w.getGlyph(), b.x - left, b.y - top, w.getColor()); + for (ThrownItem b: world.getLoot()) { + Item item = b.getItem(); + writeSafe(terminal, item.getGlyph(), b.x - left, b.y - top, item.getColor()); } } From 573040b4dcad87ce5b4e2ba73856343efb456f44 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Thu, 11 May 2017 22:20:21 +0300 Subject: [PATCH 40/63] slightly tuned --- .../impl/src/main/java/roguelike/models/beings/Ghost.java | 2 +- .../impl/src/main/java/roguelike/models/beings/Player.java | 4 ++-- .../impl/src/main/java/roguelike/screens/PlayScreen.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java b/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java index 1e61edd..1f25b91 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java @@ -23,7 +23,7 @@ public Ghost(World world) { this.glyph = 'G'; this.color = Color.cyan; - new RecurringTask(this::move, 100); + new RecurringTask(this::move, 200); } @Override diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java index 0d0da25..7e984b7 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java @@ -40,7 +40,7 @@ protected void interactWithEnvironment() { health += ((MedAid) item).getValue(); health = Math.min(health, 100); } - world.setMessage(String.format("picked %s", weapon.getName())); + world.setMessage(String.format("picked %s", item.getName())); world.getLoot().remove(thrownItem); } @@ -111,7 +111,7 @@ public void act() { int harm = level * weapon.getLevel(); int health = enemy.getHealth(); enemy.setHealth(health - harm); - world.setMessage(String.format("enemy heath: %d", enemy.getHealth())); + world.setMessage(String.format("enemy health: %d", enemy.getHealth())); if (enemy.getHealth() < 0) { world.setMessage("You won!"); weapon = Weapon.getRandomOfLevel(enemy.getLevel() + 2); diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index 2710106..d62ed86 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -25,8 +25,8 @@ public PlayScreen() { world = new WorldBuilder(100, 100) .makeCaves() .addMobs(Mushroom.class, 10) - .addMobs(Ghost.class, 0) - .addMobs(Dragon.class, 100) + .addMobs(Ghost.class, 5) + .addMobs(Dragon.class, 15) .addWeapons(15) .addMedAids(10) .build(); From 73e396f3450056ae28c6f831dc2fefa4b123189d Mon Sep 17 00:00:00 2001 From: simiyutin Date: Thu, 11 May 2017 22:23:11 +0300 Subject: [PATCH 41/63] updated todo list --- roguelike/impl/src/main/resources/todolist | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/roguelike/impl/src/main/resources/todolist b/roguelike/impl/src/main/resources/todolist index 17173fe..9ac8365 100644 --- a/roguelike/impl/src/main/resources/todolist +++ b/roguelike/impl/src/main/resources/todolist @@ -8,21 +8,22 @@ 4. Добавить кирку, и ее здоровье, чтобы нельзя было вечно долбить 4. Оружие, аптечки: - Дешевое оружие и аптечки раскиданы по карте, более дорогое оружие можно получить только у дракона. - При взятии нового оружия, старое пропадает + --Дешевое оружие и аптечки раскиданы по карте, более дорогое оружие можно получить только у дракона. + --При взятии нового оружия, старое пропадает --Интенсивностью отмечаем уровень оружия Отображать текущее оружие рядом со здоровьем -5. Дракон - когда наступаем на него, начинается бой, если побеждаем, то увеличиваем свой уровень . - Рядом с драконом лежит лут, но когда мы его забираем, то начинается драка, и нельзя уйти. - Драка такая - надо много раз нажать заданную клавишу. +--5. --Дракон - когда наступаем на него, начинается бой, если побеждаем, то увеличиваем свой уровень . + --Рядом с драконом лежит лут, но когда мы его забираем, то начинается драка, и нельзя уйти. + --Драка такая - надо много раз нажать заданную клавишу. -6. Урон от дракона и грибов зависит от их уровня +--6. Урон от дракона и грибов зависит от их уровня Следовательно, надо будет разработать формулу для подсчета этого урона. 7. Переход на новые локации: Есть телепорты, переходя на них, генерируется новая карта, с другим цветом (более сложная, то есть все существа там более высокого уровня) + Телепорт появляется только после убивания всех драконов 8. Спрайты - держим буфер фильтров, которые наслоятся на следующие кадры анимации. Когда отрисовываем кадр, считываем фильтр из буфера и отрисовываем поверх From 04e7e22a4257dbccf6ffc5b13937d91a444b7fb6 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 13 May 2017 15:09:00 +0300 Subject: [PATCH 42/63] artefacts fix --- roguelike/impl/src/main/java/roguelike/Scheduler.java | 11 ++++++++++- .../impl/src/main/java/roguelike/models/World.java | 9 +++++++++ .../src/main/java/roguelike/screens/PlayScreen.java | 3 +++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/roguelike/impl/src/main/java/roguelike/Scheduler.java b/roguelike/impl/src/main/java/roguelike/Scheduler.java index 2ba7c70..13e969e 100644 --- a/roguelike/impl/src/main/java/roguelike/Scheduler.java +++ b/roguelike/impl/src/main/java/roguelike/Scheduler.java @@ -8,6 +8,7 @@ import javax.swing.Timer; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; +import java.lang.reflect.InvocationTargetException; import java.util.*; @@ -35,7 +36,15 @@ public void run() { } public void schedule() { - new RecurringTask(this::run, 10); + new RecurringTask(() -> { + try { + SwingUtilities.invokeAndWait(this::run); + } catch (InterruptedException e) { + e.printStackTrace(); // todo log + } catch (InvocationTargetException e) { + e.printStackTrace(); // todo log + } + }, 1000 / 60); } @Override diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java index 8388bfc..760e984 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -63,6 +63,15 @@ public void setTile(int x, int y, Tile tile) { tiles[x][y] = tile; } + public void printTiles() { + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + System.out.print(tiles[j][i].getGlyph() + " "); + } + System.out.println(); + } + } + public char getGlyph(int x, int y) { return getTile(x, y).getGlyph(); } diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index d62ed86..d478213 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -71,6 +71,9 @@ public Screen respondToUserInput(KeyEvent key) { case KeyEvent.VK_ENTER: player.act(); break; + case KeyEvent.VK_P: + world.printTiles(); + break; } return updateState(); } From 77c016fd47997e7f70aa324ad08926a26e413653 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 13 May 2017 15:36:32 +0300 Subject: [PATCH 43/63] minor updates --- .../src/main/java/roguelike/Scheduler.java | 23 +++++++++---------- .../java/roguelike/models/WorldBuilder.java | 4 ++-- .../java/roguelike/models/beings/Player.java | 6 +++++ .../java/roguelike/models/items/Weapon.java | 1 + .../java/roguelike/screens/DeadScreen.java | 10 ++++++-- .../java/roguelike/screens/PlayScreen.java | 5 ++-- 6 files changed, 31 insertions(+), 18 deletions(-) diff --git a/roguelike/impl/src/main/java/roguelike/Scheduler.java b/roguelike/impl/src/main/java/roguelike/Scheduler.java index 13e969e..e8a0d32 100644 --- a/roguelike/impl/src/main/java/roguelike/Scheduler.java +++ b/roguelike/impl/src/main/java/roguelike/Scheduler.java @@ -31,20 +31,20 @@ public Scheduler() { } public void run() { - screen = screen.updateState(); - repaint(); + try { + SwingUtilities.invokeAndWait(() -> { + screen = screen.updateState(); + repaint(); + }); + } catch (InterruptedException e) { + e.printStackTrace(); // todo log + } catch (InvocationTargetException e) { + e.printStackTrace(); // todo log + } } public void schedule() { - new RecurringTask(() -> { - try { - SwingUtilities.invokeAndWait(this::run); - } catch (InterruptedException e) { - e.printStackTrace(); // todo log - } catch (InvocationTargetException e) { - e.printStackTrace(); // todo log - } - }, 1000 / 60); + new RecurringTask(this::run, 1000 / 60); } @Override @@ -55,7 +55,6 @@ public void keyTyped(KeyEvent e) { @Override public void keyPressed(KeyEvent e) { screen = screen.respondToUserInput(e); - repaint(); } @Override diff --git a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java index 97f28ce..aaf2d4e 100644 --- a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java +++ b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java @@ -67,9 +67,9 @@ public WorldBuilder addMobs(Class clazz, int quantity) { public WorldBuilder addWeapons(int quantity) { Random randGen = new Random(); - final int maxLevel = 2; + final int maxLevel = 2; // todo global constant for (int i = 0; i < quantity; i++) { - Weapon weapon = Weapon.getRandomOfLevel(randGen.nextInt(maxLevel + 1)); + Weapon weapon = Weapon.getRandomOfLevel(1 + randGen.nextInt(maxLevel)); loot.add(weapon); } return this; diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java index 7e984b7..6b410b2 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java @@ -36,6 +36,8 @@ protected void interactWithEnvironment() { Item item = thrownItem.getItem(); if (item instanceof Weapon) { weapon = (Weapon) item; + world.getLoot().removeIf(w -> + w.getItem() instanceof Weapon && ((Weapon) w.getItem()).getLevel() <= weapon.getLevel()); } else if (item instanceof MedAid) { health += ((MedAid) item).getValue(); health = Math.min(health, 100); @@ -82,6 +84,10 @@ private void startBattleWithDragon(Dragon dragon) { }, 500); } + public Weapon getWeapon() { + return weapon; + } + class RegularAction implements Action { @Override diff --git a/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java b/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java index aa89eb6..bd3cdba 100644 --- a/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java +++ b/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java @@ -21,6 +21,7 @@ public Color getColor() { } public String getName() { // todo handle level name correlation + if (type == WeaponType.HAND) return type.getName(); return type.getName() + String.format(" of level %d", level); } diff --git a/roguelike/impl/src/main/java/roguelike/screens/DeadScreen.java b/roguelike/impl/src/main/java/roguelike/screens/DeadScreen.java index 48d8710..f555799 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/DeadScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/DeadScreen.java @@ -11,12 +11,18 @@ public class DeadScreen implements Screen { @Override public void display(AsciiPanel terminal) { - print(terminal, "You are dead"); + print(terminal, "You are dead. Retry? [enter]"); + } @Override public Screen respondToUserInput(KeyEvent key) { - return this; + switch (key.getKeyCode()) { + case KeyEvent.VK_ENTER: + return new PlayScreen(); + default: + return this; + } } @Override diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index d478213..dd65c7a 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -27,7 +27,7 @@ public PlayScreen() { .addMobs(Mushroom.class, 10) .addMobs(Ghost.class, 5) .addMobs(Dragon.class, 15) - .addWeapons(15) + .addWeapons(5) .addMedAids(10) .build(); @@ -98,7 +98,8 @@ private void writeSafe(AsciiPanel terminal, char c, int x, int y, Color color) { } public void displayHealth(AsciiPanel terminal) { - terminal.write(String.format("health: %s", player.getHealth()), 67, 1); + terminal.write(String.format("health: %s", player.getHealth()), 2, 1); + terminal.write(String.format("weapon: %s", player.getWeapon().getName()), 2, 2); } public void displayWorld(AsciiPanel terminal, int left, int top) { From 104018d4a7ce75aefb626abddfe331b0ed6706d9 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 13 May 2017 15:36:59 +0300 Subject: [PATCH 44/63] amend --- .../impl/src/main/java/roguelike/screens/PlayScreen.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index dd65c7a..b4b0ff1 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -41,7 +41,7 @@ public void display(AsciiPanel terminal) { displayWorld(terminal, left, top); displayMobs(terminal, left, top); displayLoot(terminal, left, top); - displayHealth(terminal); + displayInfo(terminal); displayMessage(terminal); } @@ -97,7 +97,7 @@ private void writeSafe(AsciiPanel terminal, char c, int x, int y, Color color) { } } - public void displayHealth(AsciiPanel terminal) { + public void displayInfo(AsciiPanel terminal) { terminal.write(String.format("health: %s", player.getHealth()), 2, 1); terminal.write(String.format("weapon: %s", player.getWeapon().getName()), 2, 2); } From 0b90e56e329ad4421fe557dce54505d0604e9957 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 13 May 2017 17:05:18 +0300 Subject: [PATCH 45/63] Z level --- .../src/main/java/roguelike/models/Tile.java | 17 ++-- .../src/main/java/roguelike/models/World.java | 91 ++++++++++++------- .../java/roguelike/models/WorldBuilder.java | 9 ++ .../java/roguelike/models/beings/Player.java | 19 ++++ .../roguelike/models/beings/SideEffect.java | 2 - .../roguelike/models/items/WorldFactory.java | 26 ++++++ .../java/roguelike/screens/PlayScreen.java | 32 +++---- 7 files changed, 138 insertions(+), 58 deletions(-) create mode 100644 roguelike/impl/src/main/java/roguelike/models/items/WorldFactory.java diff --git a/roguelike/impl/src/main/java/roguelike/models/Tile.java b/roguelike/impl/src/main/java/roguelike/models/Tile.java index 84dde88..d60f9d5 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Tile.java +++ b/roguelike/impl/src/main/java/roguelike/models/Tile.java @@ -8,20 +8,23 @@ * Created by boris on 08.05.17. */ public enum Tile { - FLOOR('.', AsciiPanel.yellow, 0), - POISONED_FLOOR('.', Color.GREEN, -5), - ENFLAMED_FLOOR('.', Color.RED, -5), - WALL('#', AsciiPanel.yellow, 0), - BOUNDS('x', AsciiPanel.brightBlack, 0); + FLOOR('.', AsciiPanel.yellow, 0, true), + POISONED_FLOOR('.', Color.GREEN, -5, true), + ENFLAMED_FLOOR('.', Color.RED, -5, true), + WALL('#', AsciiPanel.yellow, 0, false), + Z_TELEPORT('Z', AsciiPanel.brightMagenta, 0, true), + BOUNDS('x', AsciiPanel.brightBlack, 0, false); private char glyph; private Color color; private int deltaHealth; + private boolean isWalkable; - Tile(char glyph, Color color, int deltaHealth) { + Tile(char glyph, Color color, int deltaHealth, boolean isWalkable) { this.glyph = glyph; this.color = color; this.deltaHealth = deltaHealth; + this.isWalkable = isWalkable; } public char getGlyph() { @@ -37,7 +40,7 @@ public int getDeltaHealth() { } public boolean isWalkable() { - return this == FLOOR || this == POISONED_FLOOR || this == ENFLAMED_FLOOR; + return isWalkable; } public boolean isDiggable() { diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java index 760e984..2fc5a1b 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -15,58 +15,64 @@ * Created by boris on 08.05.17. */ public class World { - private Tile[][] tiles; - private int width; - private int height; - private Player player; - private List mobs; - private String message = ""; - private List loot; + + private WorldData d; public List getLoot() { - return loot; + return d.loot; + } + + public int getMinLevel() { + return d.minLevel; + } + + public void setMinLevel(int minLevel) { + this.d.minLevel = minLevel; } public String getMessage() { - return message; + return d.message; } public void setMessage(String message) { - this.message = message; + this.d.message = message; new DelayedTask(() -> { - if (this.message.equals(message)) { - this.message = ""; + if (this.d.message.equals(message)) { + this.d.message = ""; } }, 1000); } public World(Tile[][] tiles) { - this.tiles = tiles; - this.width = tiles.length; - this.height = tiles[0].length; - - this.mobs = new ArrayList<>(); - this.loot = new ArrayList<>(); - this.player = new Player(this); - this.mobs.add(this.player); + this.d = new WorldData(); + this.d.tiles = tiles; + this.d.width = tiles.length; + this.d.height = tiles[0].length; + this.d.mobs = new ArrayList<>(); + this.d.loot = new ArrayList<>(); + this.d.minLevel = 1; + this.d.player = new Player(this); +// this.d.mobs.add(this.d.player); } + + public Tile getTile(int x, int y) { - if (x < 0 || x > width - 1 || y < 0 || y > height - 1) { + if (x < 0 || x > getWidth() - 1 || y < 0 || y > getHeight() - 1) { return Tile.BOUNDS; } - return tiles[x][y]; + return d.tiles[x][y]; } public void setTile(int x, int y, Tile tile) { - tiles[x][y] = tile; + d.tiles[x][y] = tile; } public void printTiles() { - for (int i = 0; i < width; i++) { - for (int j = 0; j < height; j++) { - System.out.print(tiles[j][i].getGlyph() + " "); + for (int i = 0; i < d.width; i++) { + for (int j = 0; j < d.height; j++) { + System.out.print(d.tiles[j][i].getGlyph() + " "); } System.out.println(); } @@ -81,23 +87,23 @@ public Color getColor(int x, int y) { } public int getWidth() { - return width; + return d.width; } public int getHeight() { - return height; + return d.height; } public Player getPlayer() { - return player; + return d.player; } public List getMobs() { - return mobs; + return d.mobs; } public Being getMob(int x, int y) { - for (Being b : mobs) { + for (Being b : getMobs()) { if (b.x == x && b.y == y) { return b; } @@ -106,7 +112,7 @@ public Being getMob(int x, int y) { } public ThrownItem getItem(int x, int y) { - for (ThrownItem b : loot) { + for (ThrownItem b : getLoot()) { if (b.x == x && b.y == y) { return b; } @@ -130,9 +136,30 @@ public Position getEmptyPosition() { return new Position(x, y); } + public void setPlayer(Player player) { + d.player = player; + } + + public void swapData(World other) { + d = other.d; + } + + + private boolean isEmptyFloor(int x, int y) { return getTile(x, y) == Tile.FLOOR && getMobs().stream().noneMatch(b -> b.x == x && b.y == y) && getLoot().stream().noneMatch(b -> b.x == x && b.y == y); } + + private static class WorldData { + private Tile[][] tiles; + private int width; + private int height; + private Player player; + private List mobs; + private String message = ""; + private List loot; + private int minLevel; + } } diff --git a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java index aaf2d4e..6e52e73 100644 --- a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java +++ b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java @@ -22,6 +22,7 @@ public class WorldBuilder { private Tile[][] tiles; private List> mobs; private List loot; + private int minLevel; public WorldBuilder(int width, int height) { this.width = width; @@ -29,6 +30,7 @@ public WorldBuilder(int width, int height) { this.tiles = new Tile[width][height]; this.mobs = new ArrayList<>(); this.loot = new ArrayList<>(); + this.minLevel = 1; } public World build() { @@ -45,9 +47,16 @@ public World build() { world.getLoot().add(new ThrownItem(w, world)); //todo circular dependency } + world.setMinLevel(minLevel); + return world; } + public WorldBuilder ofMinLevel(int level) { + this.minLevel = level; + return this; + } + public WorldBuilder makeCaves() { return randomizeTiles() .smooth(8); diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java index 6b410b2..bd79185 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java @@ -2,6 +2,7 @@ import roguelike.DelayedTask; import roguelike.RecurringTask; +import roguelike.models.Position; import roguelike.models.Tile; import roguelike.models.actions.Action; import roguelike.models.items.*; @@ -52,6 +53,19 @@ protected void interactWithEnvironment() { world.setMessage("press [enter] to start battle with dragon"); } } + + if (world.getTile(x, y) == Tile.Z_TELEPORT) { + zlevel(); + } + } + + public void zlevel() { + World newWorld = WorldFactory.getOfMinLevel(world.getMinLevel() + 1); + Position pos = newWorld.getEmptyPosition(); + x = pos.x; + y = pos.y; + newWorld.setPlayer(this); + world.swapData(newWorld); } public Being getMobNearMe() { @@ -126,6 +140,11 @@ public void act() { enemy.setAlive(false); setImmobilized(false); action = new RegularAction(); + if (world.getMobs().stream().noneMatch(m -> m instanceof Dragon)) { + world.setMessage("Killed last dragon. Find Z tile to proceed to next level"); + Position position = world.getEmptyPosition(); + world.setTile(position.x, position.y, Tile.Z_TELEPORT); + } } } } diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/SideEffect.java b/roguelike/impl/src/main/java/roguelike/models/beings/SideEffect.java index 0838d14..e6c01d6 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/SideEffect.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/SideEffect.java @@ -10,8 +10,6 @@ public enum SideEffect { IDENTITY(Function.identity()), - IMMOBILIZED(key -> 0), - INVERSED(key -> { switch (key) { case KeyEvent.VK_S: diff --git a/roguelike/impl/src/main/java/roguelike/models/items/WorldFactory.java b/roguelike/impl/src/main/java/roguelike/models/items/WorldFactory.java new file mode 100644 index 0000000..e272d22 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/models/items/WorldFactory.java @@ -0,0 +1,26 @@ +package roguelike.models.items; + +import roguelike.models.World; +import roguelike.models.WorldBuilder; +import roguelike.models.beings.Dragon; +import roguelike.models.beings.Ghost; +import roguelike.models.beings.Mushroom; + +/** + * Created by boris on 13.05.17. + */ +public class WorldFactory { + public static World getOfMinLevel(int level) { + World result = new WorldBuilder(100, 100) + .ofMinLevel(level) + .makeCaves() + .addMobs(Mushroom.class, 10) + .addMobs(Ghost.class, 0) + .addMobs(Dragon.class, 1) + .addWeapons(5) + .addMedAids(10) + .build(); + + return result; + } +} diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index b4b0ff1..13b0b44 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -5,6 +5,7 @@ import roguelike.models.beings.*; import roguelike.models.items.Item; import roguelike.models.items.ThrownItem; +import roguelike.models.items.WorldFactory; import java.awt.*; @@ -16,22 +17,12 @@ public class PlayScreen implements Screen { private World world; - private Player player; private int screenWidth = 80; private int screenHeight = 24; public PlayScreen() { - world = new WorldBuilder(100, 100) - .makeCaves() - .addMobs(Mushroom.class, 10) - .addMobs(Ghost.class, 5) - .addMobs(Dragon.class, 15) - .addWeapons(5) - .addMedAids(10) - .build(); - - player = world.getPlayer(); + world = WorldFactory.getOfMinLevel(1); } @Override @@ -46,15 +37,16 @@ public void display(AsciiPanel terminal) { } private int scrollLeft() { - return Math.max(0, Math.min(player.x - screenWidth / 2, world.getWidth() - screenWidth)); + return Math.max(0, Math.min(world.getPlayer().x - screenWidth / 2, world.getWidth() - screenWidth)); } private int scrollTop() { - return Math.max(0, Math.min(player.y - screenHeight / 2, world.getHeight() - screenHeight)); + return Math.max(0, Math.min(world.getPlayer().y - screenHeight / 2, world.getHeight() - screenHeight)); } @Override public Screen respondToUserInput(KeyEvent key) { + Player player = world.getPlayer(); switch (player.getEffect().apply(key.getKeyCode())) { case KeyEvent.VK_S: player.move(0, 1); @@ -74,13 +66,16 @@ public Screen respondToUserInput(KeyEvent key) { case KeyEvent.VK_P: world.printTiles(); break; + case KeyEvent.VK_Z: + world.getPlayer().zlevel(); + break; } return updateState(); } @Override public Screen updateState() { - return player.getHealth() > 0 ? this : new DeadScreen(); + return world.getPlayer().getHealth() > 0 ? this : new DeadScreen(); } public void displayMobs(AsciiPanel terminal, int left, int top) { @@ -89,6 +84,9 @@ public void displayMobs(AsciiPanel terminal, int left, int top) { writeSafe(terminal, b.getGlyph(), b.x - left, b.y - top, b.getColor()); } + Player p = world.getPlayer(); + writeSafe(terminal, p.getGlyph(), p.x - left, p.y - top, p.getColor()); + } private void writeSafe(AsciiPanel terminal, char c, int x, int y, Color color) { @@ -98,8 +96,8 @@ private void writeSafe(AsciiPanel terminal, char c, int x, int y, Color color) { } public void displayInfo(AsciiPanel terminal) { - terminal.write(String.format("health: %s", player.getHealth()), 2, 1); - terminal.write(String.format("weapon: %s", player.getWeapon().getName()), 2, 2); + terminal.write(String.format("health: %s", world.getPlayer().getHealth()), 1, 1); + terminal.write(String.format("weapon: %s", world.getPlayer().getWeapon().getName()), 1, 2); } public void displayWorld(AsciiPanel terminal, int left, int top) { @@ -122,6 +120,6 @@ public void displayLoot(AsciiPanel terminal, int left, int top) { } private void displayMessage(AsciiPanel terminal) { - terminal.write(world.getMessage(), 40 - world.getMessage().length() / 2, 1); + terminal.write(world.getMessage(), 40 - world.getMessage().length() / 2, 5); } } From 3edc211222ca0029f3e669b69bea7214dc053731 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 13 May 2017 17:22:32 +0300 Subject: [PATCH 46/63] level --- .../impl/src/main/java/roguelike/models/WorldBuilder.java | 5 +++-- .../src/main/java/roguelike/models/beings/ActiveBeing.java | 2 +- .../impl/src/main/java/roguelike/models/beings/Player.java | 3 ++- .../impl/src/main/java/roguelike/screens/PlayScreen.java | 5 +++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java index 6e52e73..b2c25f4 100644 --- a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java +++ b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java @@ -35,6 +35,8 @@ public WorldBuilder(int width, int height) { public World build() { World world = new World(tiles); + world.setMinLevel(minLevel); + for (Constructor c : mobs) { try { world.getMobs().add(c.newInstance(world)); @@ -76,9 +78,8 @@ public WorldBuilder addMobs(Class clazz, int quantity) { public WorldBuilder addWeapons(int quantity) { Random randGen = new Random(); - final int maxLevel = 2; // todo global constant for (int i = 0; i < quantity; i++) { - Weapon weapon = Weapon.getRandomOfLevel(1 + randGen.nextInt(maxLevel)); + Weapon weapon = Weapon.getRandomOfLevel(minLevel + randGen.nextInt(2)); loot.add(weapon); } return this; diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/ActiveBeing.java b/roguelike/impl/src/main/java/roguelike/models/beings/ActiveBeing.java index 5fe4ce1..50d11fa 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/ActiveBeing.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/ActiveBeing.java @@ -24,7 +24,7 @@ public ActiveBeing(World world) { super(world); this.health = 100; this.effect = SideEffect.IDENTITY; - this.level = 1; + this.level = world.getMinLevel(); this.immobilized = false; this.alive = true; } diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java index bd79185..539959d 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java @@ -30,7 +30,7 @@ public Player(World world) { @Override protected void interactWithEnvironment() { int deltaHealth = world.getTile(x, y).getDeltaHealth(); - health += deltaHealth; + health += deltaHealth * level; ThrownItem thrownItem = world.getItem(x, y); if (thrownItem != null) { @@ -60,6 +60,7 @@ protected void interactWithEnvironment() { } public void zlevel() { + level++; World newWorld = WorldFactory.getOfMinLevel(world.getMinLevel() + 1); Position pos = newWorld.getEmptyPosition(); x = pos.x; diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index 13b0b44..3598311 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -96,8 +96,9 @@ private void writeSafe(AsciiPanel terminal, char c, int x, int y, Color color) { } public void displayInfo(AsciiPanel terminal) { - terminal.write(String.format("health: %s", world.getPlayer().getHealth()), 1, 1); - terminal.write(String.format("weapon: %s", world.getPlayer().getWeapon().getName()), 1, 2); + terminal.write(String.format("level: %s", world.getPlayer().getLevel()), 1, 1); + terminal.write(String.format("health: %s", world.getPlayer().getHealth()), 1, 2); + terminal.write(String.format("weapon: %s", world.getPlayer().getWeapon().getName()), 1, 3); } public void displayWorld(AsciiPanel terminal, int left, int top) { From f02c56bb103220e577deeef1051d7416b4903167 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 13 May 2017 17:43:21 +0300 Subject: [PATCH 47/63] random colors on new level --- .../java/roguelike/RandomColorGenerator.java | 19 +++++++++++++++++++ .../src/main/java/roguelike/models/Tile.java | 4 ++++ .../src/main/java/roguelike/models/World.java | 3 +-- .../java/roguelike/models/WorldBuilder.java | 6 ++++++ .../java/roguelike/models/beings/Being.java | 2 +- .../java/roguelike/models/beings/Player.java | 6 +++--- .../java/roguelike/screens/PlayScreen.java | 8 ++++---- 7 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 roguelike/impl/src/main/java/roguelike/RandomColorGenerator.java diff --git a/roguelike/impl/src/main/java/roguelike/RandomColorGenerator.java b/roguelike/impl/src/main/java/roguelike/RandomColorGenerator.java new file mode 100644 index 0000000..8c60944 --- /dev/null +++ b/roguelike/impl/src/main/java/roguelike/RandomColorGenerator.java @@ -0,0 +1,19 @@ +package roguelike; + +import java.awt.*; +import java.util.Random; + +/** + * Created by boris on 13.05.17. + */ +public class RandomColorGenerator { + private final Random randomGen = new Random(42); + + public Color getColor() { + return Color.getHSBColor(getComponent(), 0.8f, 0.4f); + } + + private float getComponent() { + return (float) randomGen.nextDouble(); + } +} diff --git a/roguelike/impl/src/main/java/roguelike/models/Tile.java b/roguelike/impl/src/main/java/roguelike/models/Tile.java index d60f9d5..72d7882 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Tile.java +++ b/roguelike/impl/src/main/java/roguelike/models/Tile.java @@ -27,6 +27,10 @@ public enum Tile { this.isWalkable = isWalkable; } + public void setColor(Color color) { + this.color = color; + } + public char getGlyph() { return glyph; } diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java index 2fc5a1b..89696db 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -53,7 +53,6 @@ public World(Tile[][] tiles) { this.d.loot = new ArrayList<>(); this.d.minLevel = 1; this.d.player = new Player(this); -// this.d.mobs.add(this.d.player); } @@ -140,7 +139,7 @@ public void setPlayer(Player player) { d.player = player; } - public void swapData(World other) { + public void moveDataFrom(World other) { d = other.d; } diff --git a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java index b2c25f4..69f22bf 100644 --- a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java +++ b/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java @@ -1,11 +1,13 @@ package roguelike.models; +import roguelike.RandomColorGenerator; import roguelike.models.beings.Being; import roguelike.models.items.Item; import roguelike.models.items.MedAid; import roguelike.models.items.ThrownItem; import roguelike.models.items.Weapon; +import java.awt.*; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; @@ -23,6 +25,7 @@ public class WorldBuilder { private List> mobs; private List loot; private int minLevel; + private static final RandomColorGenerator colorGen = new RandomColorGenerator();; public WorldBuilder(int width, int height) { this.width = width; @@ -36,6 +39,9 @@ public WorldBuilder(int width, int height) { public World build() { World world = new World(tiles); world.setMinLevel(minLevel); + Color color = colorGen.getColor(); + Tile.FLOOR.setColor(color); + Tile.WALL.setColor(color); for (Constructor c : mobs) { try { diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Being.java b/roguelike/impl/src/main/java/roguelike/models/beings/Being.java index 707ee30..d8d94bf 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Being.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Being.java @@ -16,7 +16,7 @@ public abstract class Being { protected char glyph; protected Color color; - protected World world; + protected final World world; public Being(World world) { this.world = world; diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java index 539959d..f18423e 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java @@ -55,18 +55,18 @@ protected void interactWithEnvironment() { } if (world.getTile(x, y) == Tile.Z_TELEPORT) { - zlevel(); + levelUp(); } } - public void zlevel() { + public void levelUp() { level++; World newWorld = WorldFactory.getOfMinLevel(world.getMinLevel() + 1); Position pos = newWorld.getEmptyPosition(); x = pos.x; y = pos.y; newWorld.setPlayer(this); - world.swapData(newWorld); + world.moveDataFrom(newWorld); } public Being getMobNearMe() { diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java index 3598311..b1f16da 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java @@ -16,9 +16,9 @@ */ public class PlayScreen implements Screen { - private World world; - private int screenWidth = 80; - private int screenHeight = 24; + private final World world; + private final int screenWidth = 80; + private final int screenHeight = 24; public PlayScreen() { @@ -67,7 +67,7 @@ public Screen respondToUserInput(KeyEvent key) { world.printTiles(); break; case KeyEvent.VK_Z: - world.getPlayer().zlevel(); + world.getPlayer().levelUp(); break; } return updateState(); From 217eebe470421541071ad1fc33b2df1ac8e44e51 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 13 May 2017 18:14:20 +0300 Subject: [PATCH 48/63] refactor --- .../src/main/java/roguelike/Scheduler.java | 3 +-- .../src/main/java/roguelike/models/World.java | 14 ++++++++++++- .../roguelike/models/actions/Actions.java | 21 ------------------- .../java/roguelike/models/beings/Dragon.java | 5 ++--- .../java/roguelike/models/beings/Ghost.java | 2 +- .../roguelike/models/beings/Mushroom.java | 3 +-- .../java/roguelike/models/beings/Player.java | 6 +++--- .../roguelike/models/items/WorldFactory.java | 2 +- .../{models/actions => util}/Action.java | 2 +- .../roguelike/{ => util}/DelayedTask.java | 2 +- .../{ => util}/RandomColorGenerator.java | 2 +- .../roguelike/{ => util}/RecurringTask.java | 2 +- .../{models => util}/WorldBuilder.java | 5 +++-- roguelike/impl/src/main/resources/todolist | 20 +++++++++--------- 14 files changed, 39 insertions(+), 50 deletions(-) delete mode 100644 roguelike/impl/src/main/java/roguelike/models/actions/Actions.java rename roguelike/impl/src/main/java/roguelike/{models/actions => util}/Action.java (71%) rename roguelike/impl/src/main/java/roguelike/{ => util}/DelayedTask.java (94%) rename roguelike/impl/src/main/java/roguelike/{ => util}/RandomColorGenerator.java (93%) rename roguelike/impl/src/main/java/roguelike/{ => util}/RecurringTask.java (94%) rename roguelike/impl/src/main/java/roguelike/{models => util}/WorldBuilder.java (97%) diff --git a/roguelike/impl/src/main/java/roguelike/Scheduler.java b/roguelike/impl/src/main/java/roguelike/Scheduler.java index e8a0d32..ff527a4 100644 --- a/roguelike/impl/src/main/java/roguelike/Scheduler.java +++ b/roguelike/impl/src/main/java/roguelike/Scheduler.java @@ -3,13 +3,12 @@ import asciiPanel.AsciiPanel; import roguelike.screens.Screen; import roguelike.screens.StartScreen; +import roguelike.util.RecurringTask; import javax.swing.*; -import javax.swing.Timer; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.lang.reflect.InvocationTargetException; -import java.util.*; public class Scheduler extends JFrame implements KeyListener { diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/roguelike/models/World.java index 89696db..0d91d84 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/roguelike/models/World.java @@ -1,7 +1,7 @@ package roguelike.models; -import roguelike.DelayedTask; +import roguelike.util.DelayedTask; import roguelike.models.beings.Being; import roguelike.models.beings.Player; import roguelike.models.items.ThrownItem; @@ -151,6 +151,18 @@ && getMobs().stream().noneMatch(b -> b.x == x && b.y == y) && getLoot().stream().noneMatch(b -> b.x == x && b.y == y); } + public void setTilesAround(int x, int y, int radius, Tile tile) { + for (int i = -radius; i <= radius; i++) { + for (int j = -radius; j <= radius; j++) { + int wx = x + i; + int wy = y + j; + if (i * i + j * j <= radius * radius && getTile(wx, wy) == Tile.FLOOR) { + setTile(wx, wy, tile); + } + } + } + } + private static class WorldData { private Tile[][] tiles; private int width; diff --git a/roguelike/impl/src/main/java/roguelike/models/actions/Actions.java b/roguelike/impl/src/main/java/roguelike/models/actions/Actions.java deleted file mode 100644 index 314a07e..0000000 --- a/roguelike/impl/src/main/java/roguelike/models/actions/Actions.java +++ /dev/null @@ -1,21 +0,0 @@ -package roguelike.models.actions; - -import roguelike.models.Tile; -import roguelike.models.World; - -/** - * Created by boris on 11.05.17. - */ -public class Actions { - public static void setTilesAround(World world, int x, int y, int radius, Tile tile) { - for (int i = -radius; i <= radius; i++) { - for (int j = -radius; j <= radius; j++) { - int wx = x + i; - int wy = y + j; - if (i * i + j * j <= radius * radius && world.getTile(wx, wy) == Tile.FLOOR) { - world.setTile(wx, wy, tile); - } - } - } - } -} diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Dragon.java b/roguelike/impl/src/main/java/roguelike/models/beings/Dragon.java index 4aff441..2f119e4 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Dragon.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Dragon.java @@ -1,9 +1,8 @@ package roguelike.models.beings; -import roguelike.RecurringTask; +import roguelike.util.RecurringTask; import roguelike.models.Tile; import roguelike.models.World; -import roguelike.models.actions.Actions; import java.awt.*; @@ -38,6 +37,6 @@ protected void interactWithEnvironment() { } private void enflameTiles() { - Actions.setTilesAround(world, x, y, 0, Tile.ENFLAMED_FLOOR); + world.setTilesAround(x, y, 0, Tile.ENFLAMED_FLOOR); } } diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java b/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java index 1f25b91..3afc3a8 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java @@ -1,6 +1,6 @@ package roguelike.models.beings; -import roguelike.RecurringTask; +import roguelike.util.RecurringTask; import roguelike.models.World; import java.awt.*; diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Mushroom.java b/roguelike/impl/src/main/java/roguelike/models/beings/Mushroom.java index e452d25..6caf51d 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Mushroom.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Mushroom.java @@ -2,7 +2,6 @@ import roguelike.models.Tile; import roguelike.models.World; -import roguelike.models.actions.Actions; import java.awt.*; @@ -21,6 +20,6 @@ public Mushroom(World world) { } private void poisonTiles() { - Actions.setTilesAround(world, x, y, 3, Tile.POISONED_FLOOR); + world.setTilesAround(x, y, 3, Tile.POISONED_FLOOR); } } diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java index f18423e..eb74c28 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/roguelike/models/beings/Player.java @@ -1,10 +1,10 @@ package roguelike.models.beings; -import roguelike.DelayedTask; -import roguelike.RecurringTask; +import roguelike.util.DelayedTask; +import roguelike.util.RecurringTask; import roguelike.models.Position; import roguelike.models.Tile; -import roguelike.models.actions.Action; +import roguelike.util.Action; import roguelike.models.items.*; import roguelike.models.World; diff --git a/roguelike/impl/src/main/java/roguelike/models/items/WorldFactory.java b/roguelike/impl/src/main/java/roguelike/models/items/WorldFactory.java index e272d22..6a5575c 100644 --- a/roguelike/impl/src/main/java/roguelike/models/items/WorldFactory.java +++ b/roguelike/impl/src/main/java/roguelike/models/items/WorldFactory.java @@ -1,7 +1,7 @@ package roguelike.models.items; import roguelike.models.World; -import roguelike.models.WorldBuilder; +import roguelike.util.WorldBuilder; import roguelike.models.beings.Dragon; import roguelike.models.beings.Ghost; import roguelike.models.beings.Mushroom; diff --git a/roguelike/impl/src/main/java/roguelike/models/actions/Action.java b/roguelike/impl/src/main/java/roguelike/util/Action.java similarity index 71% rename from roguelike/impl/src/main/java/roguelike/models/actions/Action.java rename to roguelike/impl/src/main/java/roguelike/util/Action.java index f769a46..c8ecf05 100644 --- a/roguelike/impl/src/main/java/roguelike/models/actions/Action.java +++ b/roguelike/impl/src/main/java/roguelike/util/Action.java @@ -1,4 +1,4 @@ -package roguelike.models.actions; +package roguelike.util; /** * Created by boris on 11.05.17. diff --git a/roguelike/impl/src/main/java/roguelike/DelayedTask.java b/roguelike/impl/src/main/java/roguelike/util/DelayedTask.java similarity index 94% rename from roguelike/impl/src/main/java/roguelike/DelayedTask.java rename to roguelike/impl/src/main/java/roguelike/util/DelayedTask.java index 71fe303..e281b22 100644 --- a/roguelike/impl/src/main/java/roguelike/DelayedTask.java +++ b/roguelike/impl/src/main/java/roguelike/util/DelayedTask.java @@ -1,4 +1,4 @@ -package roguelike; +package roguelike.util; import java.util.Timer; import java.util.TimerTask; diff --git a/roguelike/impl/src/main/java/roguelike/RandomColorGenerator.java b/roguelike/impl/src/main/java/roguelike/util/RandomColorGenerator.java similarity index 93% rename from roguelike/impl/src/main/java/roguelike/RandomColorGenerator.java rename to roguelike/impl/src/main/java/roguelike/util/RandomColorGenerator.java index 8c60944..22c7376 100644 --- a/roguelike/impl/src/main/java/roguelike/RandomColorGenerator.java +++ b/roguelike/impl/src/main/java/roguelike/util/RandomColorGenerator.java @@ -1,4 +1,4 @@ -package roguelike; +package roguelike.util; import java.awt.*; import java.util.Random; diff --git a/roguelike/impl/src/main/java/roguelike/RecurringTask.java b/roguelike/impl/src/main/java/roguelike/util/RecurringTask.java similarity index 94% rename from roguelike/impl/src/main/java/roguelike/RecurringTask.java rename to roguelike/impl/src/main/java/roguelike/util/RecurringTask.java index 92bd5f0..44ba64b 100644 --- a/roguelike/impl/src/main/java/roguelike/RecurringTask.java +++ b/roguelike/impl/src/main/java/roguelike/util/RecurringTask.java @@ -1,4 +1,4 @@ -package roguelike; +package roguelike.util; import java.util.TimerTask; diff --git a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java b/roguelike/impl/src/main/java/roguelike/util/WorldBuilder.java similarity index 97% rename from roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java rename to roguelike/impl/src/main/java/roguelike/util/WorldBuilder.java index 69f22bf..39a5de6 100644 --- a/roguelike/impl/src/main/java/roguelike/models/WorldBuilder.java +++ b/roguelike/impl/src/main/java/roguelike/util/WorldBuilder.java @@ -1,6 +1,7 @@ -package roguelike.models; +package roguelike.util; -import roguelike.RandomColorGenerator; +import roguelike.models.Tile; +import roguelike.models.World; import roguelike.models.beings.Being; import roguelike.models.items.Item; import roguelike.models.items.MedAid; diff --git a/roguelike/impl/src/main/resources/todolist b/roguelike/impl/src/main/resources/todolist index 9ac8365..4070c86 100644 --- a/roguelike/impl/src/main/resources/todolist +++ b/roguelike/impl/src/main/resources/todolist @@ -2,16 +2,13 @@ --2. AI --3. Призрак - гоняется за нами, если догоняет, то инвертирует наше управление. - После этого, все призраки от нас убегают, и чтобы вернуть управление назад, нам надо догнать и победить. - Они должны двигаться медленнее нас, но должны догонять, если мы копаем стены + После этого, все призраки от нас убегают, и чтобы вернуть управление назад, нам надо догнать. -4. Добавить кирку, и ее здоровье, чтобы нельзя было вечно долбить - -4. Оружие, аптечки: +--4. Оружие, аптечки: --Дешевое оружие и аптечки раскиданы по карте, более дорогое оружие можно получить только у дракона. --При взятии нового оружия, старое пропадает --Интенсивностью отмечаем уровень оружия - Отображать текущее оружие рядом со здоровьем + --Отображать текущее оружие рядом со здоровьем --5. --Дракон - когда наступаем на него, начинается бой, если побеждаем, то увеличиваем свой уровень . --Рядом с драконом лежит лут, но когда мы его забираем, то начинается драка, и нельзя уйти. @@ -20,14 +17,16 @@ --6. Урон от дракона и грибов зависит от их уровня Следовательно, надо будет разработать формулу для подсчета этого урона. -7. Переход на новые локации: - Есть телепорты, переходя на них, генерируется новая карта, с другим цветом - (более сложная, то есть все существа там более высокого уровня) - Телепорт появляется только после убивания всех драконов +--7. Переход на новые локации: + --Есть телепорты, переходя на них, генерируется новая карта, с другим цветом + --(более сложная, то есть все существа там более высокого уровня) + --Телепорт появляется только после убивания всех драконов 8. Спрайты - держим буфер фильтров, которые наслоятся на следующие кадры анимации. Когда отрисовываем кадр, считываем фильтр из буфера и отрисовываем поверх +9. Туториал, в виде текста на отделном экране и по нажатию кнопки + ОБЯЗАТЕЛЬНЫЕ ЗАДАНИЯ: 1. Юнит - тесты @@ -37,6 +36,7 @@ БАГИ: 1. Не работает в русской раскладке 2. В reversed состоянии не работает копание +3. После победы над драконом можно поднять меч более низкого уровня From 329c0a2d68197a4740d930e6ebcd7cd51dc57919 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 13 May 2017 18:17:25 +0300 Subject: [PATCH 49/63] reverse domain name --- .../{ => com/simiyutin/au}/roguelike/Main.java | 2 +- .../simiyutin/au}/roguelike/Scheduler.java | 8 ++++---- .../au}/roguelike/models/Position.java | 2 +- .../simiyutin/au}/roguelike/models/Tile.java | 2 +- .../simiyutin/au}/roguelike/models/World.java | 10 +++++----- .../roguelike/models/beings/ActiveBeing.java | 4 ++-- .../models/beings/ArtificialIntelligence.java | 2 +- .../au}/roguelike/models/beings/Being.java | 8 +++----- .../au}/roguelike/models/beings/Dragon.java | 8 ++++---- .../au}/roguelike/models/beings/Ghost.java | 10 +++++----- .../au}/roguelike/models/beings/Mushroom.java | 6 +++--- .../au}/roguelike/models/beings/Player.java | 18 +++++++++--------- .../roguelike/models/beings/SideEffect.java | 2 +- .../au}/roguelike/models/items/Item.java | 2 +- .../au}/roguelike/models/items/MedAid.java | 2 +- .../au}/roguelike/models/items/ThrownItem.java | 6 +++--- .../au}/roguelike/models/items/Weapon.java | 2 +- .../au}/roguelike/models/items/WeaponType.java | 2 +- .../roguelike/models/items/WorldFactory.java | 12 ++++++------ .../au}/roguelike/screens/DeadScreen.java | 2 +- .../au}/roguelike/screens/PlayScreen.java | 12 ++++++------ .../au}/roguelike/screens/Screen.java | 2 +- .../au}/roguelike/screens/StartScreen.java | 2 +- .../simiyutin/au}/roguelike/util/Action.java | 2 +- .../au}/roguelike/util/DelayedTask.java | 2 +- .../roguelike/util/RandomColorGenerator.java | 2 +- .../au}/roguelike/util/RecurringTask.java | 2 +- .../au}/roguelike/util/WorldBuilder.java | 18 +++++++++--------- 28 files changed, 75 insertions(+), 77 deletions(-) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/Main.java (84%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/Scheduler.java (87%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/Position.java (81%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/Tile.java (96%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/World.java (93%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/beings/ActiveBeing.java (95%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/beings/ArtificialIntelligence.java (67%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/beings/Being.java (77%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/beings/Dragon.java (77%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/beings/Ghost.java (88%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/beings/Mushroom.java (70%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/beings/Player.java (91%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/beings/SideEffect.java (93%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/items/Item.java (75%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/items/MedAid.java (90%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/items/ThrownItem.java (75%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/items/Weapon.java (94%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/items/WeaponType.java (94%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/models/items/WorldFactory.java (60%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/screens/DeadScreen.java (93%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/screens/PlayScreen.java (92%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/screens/Screen.java (89%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/screens/StartScreen.java (91%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/util/Action.java (67%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/util/DelayedTask.java (90%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/util/RandomColorGenerator.java (89%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/util/RecurringTask.java (90%) rename roguelike/impl/src/main/java/{ => com/simiyutin/au}/roguelike/util/WorldBuilder.java (90%) diff --git a/roguelike/impl/src/main/java/roguelike/Main.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Main.java similarity index 84% rename from roguelike/impl/src/main/java/roguelike/Main.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Main.java index 050271d..0f2ccb1 100644 --- a/roguelike/impl/src/main/java/roguelike/Main.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Main.java @@ -1,4 +1,4 @@ -package roguelike; +package com.simiyutin.au.roguelike; /** * Created by boris on 08.05.17. diff --git a/roguelike/impl/src/main/java/roguelike/Scheduler.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Scheduler.java similarity index 87% rename from roguelike/impl/src/main/java/roguelike/Scheduler.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Scheduler.java index ff527a4..edc2d30 100644 --- a/roguelike/impl/src/main/java/roguelike/Scheduler.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Scheduler.java @@ -1,9 +1,9 @@ -package roguelike; +package com.simiyutin.au.roguelike; import asciiPanel.AsciiPanel; -import roguelike.screens.Screen; -import roguelike.screens.StartScreen; -import roguelike.util.RecurringTask; +import com.simiyutin.au.roguelike.screens.Screen; +import com.simiyutin.au.roguelike.screens.StartScreen; +import com.simiyutin.au.roguelike.util.RecurringTask; import javax.swing.*; import java.awt.event.KeyEvent; diff --git a/roguelike/impl/src/main/java/roguelike/models/Position.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Position.java similarity index 81% rename from roguelike/impl/src/main/java/roguelike/models/Position.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Position.java index 9ffaf0e..22c2e6c 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Position.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Position.java @@ -1,4 +1,4 @@ -package roguelike.models; +package com.simiyutin.au.roguelike.models; /** * Created by boris on 11.05.17. diff --git a/roguelike/impl/src/main/java/roguelike/models/Tile.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Tile.java similarity index 96% rename from roguelike/impl/src/main/java/roguelike/models/Tile.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Tile.java index 72d7882..0f94282 100644 --- a/roguelike/impl/src/main/java/roguelike/models/Tile.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Tile.java @@ -1,4 +1,4 @@ -package roguelike.models; +package com.simiyutin.au.roguelike.models; import asciiPanel.AsciiPanel; diff --git a/roguelike/impl/src/main/java/roguelike/models/World.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java similarity index 93% rename from roguelike/impl/src/main/java/roguelike/models/World.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java index 0d91d84..8616e7a 100644 --- a/roguelike/impl/src/main/java/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java @@ -1,10 +1,10 @@ -package roguelike.models; +package com.simiyutin.au.roguelike.models; -import roguelike.util.DelayedTask; -import roguelike.models.beings.Being; -import roguelike.models.beings.Player; -import roguelike.models.items.ThrownItem; +import com.simiyutin.au.roguelike.util.DelayedTask; +import com.simiyutin.au.roguelike.models.beings.Being; +import com.simiyutin.au.roguelike.models.beings.Player; +import com.simiyutin.au.roguelike.models.items.ThrownItem; import java.awt.Color; import java.util.ArrayList; diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/ActiveBeing.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java similarity index 95% rename from roguelike/impl/src/main/java/roguelike/models/beings/ActiveBeing.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java index 50d11fa..e0843bf 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/ActiveBeing.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java @@ -1,6 +1,6 @@ -package roguelike.models.beings; +package com.simiyutin.au.roguelike.models.beings; -import roguelike.models.World; +import com.simiyutin.au.roguelike.models.World; import java.util.Random; diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/ArtificialIntelligence.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ArtificialIntelligence.java similarity index 67% rename from roguelike/impl/src/main/java/roguelike/models/beings/ArtificialIntelligence.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ArtificialIntelligence.java index 939697f..72023dc 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/ArtificialIntelligence.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ArtificialIntelligence.java @@ -1,4 +1,4 @@ -package roguelike.models.beings; +package com.simiyutin.au.roguelike.models.beings; /** * Created by boris on 10.05.17. diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Being.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Being.java similarity index 77% rename from roguelike/impl/src/main/java/roguelike/models/beings/Being.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Being.java index d8d94bf..17cbef9 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Being.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Being.java @@ -1,11 +1,9 @@ -package roguelike.models.beings; +package com.simiyutin.au.roguelike.models.beings; -import asciiPanel.AsciiPanel; -import roguelike.models.Position; -import roguelike.models.World; +import com.simiyutin.au.roguelike.models.Position; +import com.simiyutin.au.roguelike.models.World; import java.awt.*; -import java.util.Random; /** * Created by boris on 09.05.17. diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Dragon.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java similarity index 77% rename from roguelike/impl/src/main/java/roguelike/models/beings/Dragon.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java index 2f119e4..99faa0d 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Dragon.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java @@ -1,8 +1,8 @@ -package roguelike.models.beings; +package com.simiyutin.au.roguelike.models.beings; -import roguelike.util.RecurringTask; -import roguelike.models.Tile; -import roguelike.models.World; +import com.simiyutin.au.roguelike.util.RecurringTask; +import com.simiyutin.au.roguelike.models.Tile; +import com.simiyutin.au.roguelike.models.World; import java.awt.*; diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Ghost.java similarity index 88% rename from roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Ghost.java index 3afc3a8..e2eeca7 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Ghost.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Ghost.java @@ -1,12 +1,12 @@ -package roguelike.models.beings; +package com.simiyutin.au.roguelike.models.beings; -import roguelike.util.RecurringTask; -import roguelike.models.World; +import com.simiyutin.au.roguelike.util.RecurringTask; +import com.simiyutin.au.roguelike.models.World; import java.awt.*; -import static roguelike.models.beings.SideEffect.IDENTITY; -import static roguelike.models.beings.SideEffect.INVERSED; +import static com.simiyutin.au.roguelike.models.beings.SideEffect.IDENTITY; +import static com.simiyutin.au.roguelike.models.beings.SideEffect.INVERSED; /** * Created by boris on 10.05.17. diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Mushroom.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Mushroom.java similarity index 70% rename from roguelike/impl/src/main/java/roguelike/models/beings/Mushroom.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Mushroom.java index 6caf51d..c7ce451 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Mushroom.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Mushroom.java @@ -1,7 +1,7 @@ -package roguelike.models.beings; +package com.simiyutin.au.roguelike.models.beings; -import roguelike.models.Tile; -import roguelike.models.World; +import com.simiyutin.au.roguelike.models.Tile; +import com.simiyutin.au.roguelike.models.World; import java.awt.*; diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java similarity index 91% rename from roguelike/impl/src/main/java/roguelike/models/beings/Player.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java index eb74c28..e534e05 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java @@ -1,12 +1,12 @@ -package roguelike.models.beings; - -import roguelike.util.DelayedTask; -import roguelike.util.RecurringTask; -import roguelike.models.Position; -import roguelike.models.Tile; -import roguelike.util.Action; -import roguelike.models.items.*; -import roguelike.models.World; +package com.simiyutin.au.roguelike.models.beings; + +import com.simiyutin.au.roguelike.util.DelayedTask; +import com.simiyutin.au.roguelike.util.RecurringTask; +import com.simiyutin.au.roguelike.models.Position; +import com.simiyutin.au.roguelike.models.Tile; +import com.simiyutin.au.roguelike.util.Action; +import com.simiyutin.au.roguelike.models.items.*; +import com.simiyutin.au.roguelike.models.World; import java.awt.*; diff --git a/roguelike/impl/src/main/java/roguelike/models/beings/SideEffect.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/SideEffect.java similarity index 93% rename from roguelike/impl/src/main/java/roguelike/models/beings/SideEffect.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/SideEffect.java index e6c01d6..1fbb2d4 100644 --- a/roguelike/impl/src/main/java/roguelike/models/beings/SideEffect.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/SideEffect.java @@ -1,4 +1,4 @@ -package roguelike.models.beings; +package com.simiyutin.au.roguelike.models.beings; import java.awt.event.KeyEvent; import java.util.function.Function; diff --git a/roguelike/impl/src/main/java/roguelike/models/items/Item.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Item.java similarity index 75% rename from roguelike/impl/src/main/java/roguelike/models/items/Item.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Item.java index 23035d3..876ed57 100644 --- a/roguelike/impl/src/main/java/roguelike/models/items/Item.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Item.java @@ -1,4 +1,4 @@ -package roguelike.models.items; +package com.simiyutin.au.roguelike.models.items; import java.awt.*; diff --git a/roguelike/impl/src/main/java/roguelike/models/items/MedAid.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/MedAid.java similarity index 90% rename from roguelike/impl/src/main/java/roguelike/models/items/MedAid.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/MedAid.java index bca1ce7..6e60b52 100644 --- a/roguelike/impl/src/main/java/roguelike/models/items/MedAid.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/MedAid.java @@ -1,4 +1,4 @@ -package roguelike.models.items; +package com.simiyutin.au.roguelike.models.items; import java.awt.*; diff --git a/roguelike/impl/src/main/java/roguelike/models/items/ThrownItem.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/ThrownItem.java similarity index 75% rename from roguelike/impl/src/main/java/roguelike/models/items/ThrownItem.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/ThrownItem.java index 253d709..8266740 100644 --- a/roguelike/impl/src/main/java/roguelike/models/items/ThrownItem.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/ThrownItem.java @@ -1,7 +1,7 @@ -package roguelike.models.items; +package com.simiyutin.au.roguelike.models.items; -import roguelike.models.Position; -import roguelike.models.World; +import com.simiyutin.au.roguelike.models.Position; +import com.simiyutin.au.roguelike.models.World; /** * Created by boris on 11.05.17. diff --git a/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java similarity index 94% rename from roguelike/impl/src/main/java/roguelike/models/items/Weapon.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java index bd3cdba..fa5ee70 100644 --- a/roguelike/impl/src/main/java/roguelike/models/items/Weapon.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java @@ -1,4 +1,4 @@ -package roguelike.models.items; +package com.simiyutin.au.roguelike.models.items; import java.awt.*; diff --git a/roguelike/impl/src/main/java/roguelike/models/items/WeaponType.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WeaponType.java similarity index 94% rename from roguelike/impl/src/main/java/roguelike/models/items/WeaponType.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WeaponType.java index 2babf65..6447bf6 100644 --- a/roguelike/impl/src/main/java/roguelike/models/items/WeaponType.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WeaponType.java @@ -1,4 +1,4 @@ -package roguelike.models.items; +package com.simiyutin.au.roguelike.models.items; import java.util.Arrays; import java.util.List; diff --git a/roguelike/impl/src/main/java/roguelike/models/items/WorldFactory.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WorldFactory.java similarity index 60% rename from roguelike/impl/src/main/java/roguelike/models/items/WorldFactory.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WorldFactory.java index 6a5575c..d630c88 100644 --- a/roguelike/impl/src/main/java/roguelike/models/items/WorldFactory.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WorldFactory.java @@ -1,10 +1,10 @@ -package roguelike.models.items; +package com.simiyutin.au.roguelike.models.items; -import roguelike.models.World; -import roguelike.util.WorldBuilder; -import roguelike.models.beings.Dragon; -import roguelike.models.beings.Ghost; -import roguelike.models.beings.Mushroom; +import com.simiyutin.au.roguelike.models.World; +import com.simiyutin.au.roguelike.util.WorldBuilder; +import com.simiyutin.au.roguelike.models.beings.Dragon; +import com.simiyutin.au.roguelike.models.beings.Ghost; +import com.simiyutin.au.roguelike.models.beings.Mushroom; /** * Created by boris on 13.05.17. diff --git a/roguelike/impl/src/main/java/roguelike/screens/DeadScreen.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/DeadScreen.java similarity index 93% rename from roguelike/impl/src/main/java/roguelike/screens/DeadScreen.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/DeadScreen.java index f555799..6b0cdea 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/DeadScreen.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/DeadScreen.java @@ -1,4 +1,4 @@ -package roguelike.screens; +package com.simiyutin.au.roguelike.screens; import asciiPanel.AsciiPanel; diff --git a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java similarity index 92% rename from roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java index b1f16da..870764b 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java @@ -1,11 +1,11 @@ -package roguelike.screens; +package com.simiyutin.au.roguelike.screens; import asciiPanel.AsciiPanel; -import roguelike.models.*; -import roguelike.models.beings.*; -import roguelike.models.items.Item; -import roguelike.models.items.ThrownItem; -import roguelike.models.items.WorldFactory; +import com.simiyutin.au.roguelike.models.*; +import com.simiyutin.au.roguelike.models.beings.*; +import com.simiyutin.au.roguelike.models.items.Item; +import com.simiyutin.au.roguelike.models.items.ThrownItem; +import com.simiyutin.au.roguelike.models.items.WorldFactory; import java.awt.*; diff --git a/roguelike/impl/src/main/java/roguelike/screens/Screen.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/Screen.java similarity index 89% rename from roguelike/impl/src/main/java/roguelike/screens/Screen.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/Screen.java index 52b1b74..e8abe44 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/Screen.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/Screen.java @@ -1,4 +1,4 @@ -package roguelike.screens; +package com.simiyutin.au.roguelike.screens; import asciiPanel.AsciiPanel; diff --git a/roguelike/impl/src/main/java/roguelike/screens/StartScreen.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/StartScreen.java similarity index 91% rename from roguelike/impl/src/main/java/roguelike/screens/StartScreen.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/StartScreen.java index 490d710..02e5d4b 100644 --- a/roguelike/impl/src/main/java/roguelike/screens/StartScreen.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/StartScreen.java @@ -1,4 +1,4 @@ -package roguelike.screens; +package com.simiyutin.au.roguelike.screens; import asciiPanel.AsciiPanel; diff --git a/roguelike/impl/src/main/java/roguelike/util/Action.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/Action.java similarity index 67% rename from roguelike/impl/src/main/java/roguelike/util/Action.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/Action.java index c8ecf05..ca6dad9 100644 --- a/roguelike/impl/src/main/java/roguelike/util/Action.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/Action.java @@ -1,4 +1,4 @@ -package roguelike.util; +package com.simiyutin.au.roguelike.util; /** * Created by boris on 11.05.17. diff --git a/roguelike/impl/src/main/java/roguelike/util/DelayedTask.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/DelayedTask.java similarity index 90% rename from roguelike/impl/src/main/java/roguelike/util/DelayedTask.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/DelayedTask.java index e281b22..51c7611 100644 --- a/roguelike/impl/src/main/java/roguelike/util/DelayedTask.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/DelayedTask.java @@ -1,4 +1,4 @@ -package roguelike.util; +package com.simiyutin.au.roguelike.util; import java.util.Timer; import java.util.TimerTask; diff --git a/roguelike/impl/src/main/java/roguelike/util/RandomColorGenerator.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomColorGenerator.java similarity index 89% rename from roguelike/impl/src/main/java/roguelike/util/RandomColorGenerator.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomColorGenerator.java index 22c7376..0e4aa22 100644 --- a/roguelike/impl/src/main/java/roguelike/util/RandomColorGenerator.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomColorGenerator.java @@ -1,4 +1,4 @@ -package roguelike.util; +package com.simiyutin.au.roguelike.util; import java.awt.*; import java.util.Random; diff --git a/roguelike/impl/src/main/java/roguelike/util/RecurringTask.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RecurringTask.java similarity index 90% rename from roguelike/impl/src/main/java/roguelike/util/RecurringTask.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RecurringTask.java index 44ba64b..c51dd98 100644 --- a/roguelike/impl/src/main/java/roguelike/util/RecurringTask.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RecurringTask.java @@ -1,4 +1,4 @@ -package roguelike.util; +package com.simiyutin.au.roguelike.util; import java.util.TimerTask; diff --git a/roguelike/impl/src/main/java/roguelike/util/WorldBuilder.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java similarity index 90% rename from roguelike/impl/src/main/java/roguelike/util/WorldBuilder.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java index 39a5de6..2b29119 100644 --- a/roguelike/impl/src/main/java/roguelike/util/WorldBuilder.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java @@ -1,12 +1,12 @@ -package roguelike.util; - -import roguelike.models.Tile; -import roguelike.models.World; -import roguelike.models.beings.Being; -import roguelike.models.items.Item; -import roguelike.models.items.MedAid; -import roguelike.models.items.ThrownItem; -import roguelike.models.items.Weapon; +package com.simiyutin.au.roguelike.util; + +import com.simiyutin.au.roguelike.models.Tile; +import com.simiyutin.au.roguelike.models.World; +import com.simiyutin.au.roguelike.models.beings.Being; +import com.simiyutin.au.roguelike.models.items.Item; +import com.simiyutin.au.roguelike.models.items.MedAid; +import com.simiyutin.au.roguelike.models.items.ThrownItem; +import com.simiyutin.au.roguelike.models.items.Weapon; import java.awt.*; import java.lang.reflect.Constructor; From 1bcf16897ccb674378928a8cb2154a3a4d34a344 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sat, 13 May 2017 18:30:26 +0300 Subject: [PATCH 50/63] refactor --- .../simiyutin/au/roguelike/models/World.java | 49 +++++++++---------- .../roguelike/models/beings/ActiveBeing.java | 15 +++--- .../au/roguelike/models/beings/Dragon.java | 1 + .../au/roguelike/models/beings/Player.java | 45 ++++++++--------- .../au/roguelike/models/items/ThrownItem.java | 4 -- .../au/roguelike/models/items/Weapon.java | 4 ++ .../au/roguelike/models/items/WeaponType.java | 4 ++ .../au/roguelike/screens/PlayScreen.java | 48 +++++++++--------- ...rator.java => RandomBGColorGenerator.java} | 2 +- .../au/roguelike/util/WorldBuilder.java | 2 +- .../{models/items => util}/WorldFactory.java | 2 +- 11 files changed, 88 insertions(+), 88 deletions(-) rename roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/{RandomColorGenerator.java => RandomBGColorGenerator.java} (90%) rename roguelike/impl/src/main/java/com/simiyutin/au/roguelike/{models/items => util}/WorldFactory.java (93%) diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java index 8616e7a..c01ad24 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java @@ -18,6 +18,18 @@ public class World { private WorldData d; + public World(Tile[][] tiles) { + this.d = new WorldData(); + this.d.tiles = tiles; + this.d.width = tiles.length; + this.d.height = tiles[0].length; + + this.d.mobs = new ArrayList<>(); + this.d.loot = new ArrayList<>(); + this.d.minLevel = 1; + this.d.player = new Player(this); + } + public List getLoot() { return d.loot; } @@ -43,20 +55,6 @@ public void setMessage(String message) { }, 1000); } - public World(Tile[][] tiles) { - this.d = new WorldData(); - this.d.tiles = tiles; - this.d.width = tiles.length; - this.d.height = tiles[0].length; - - this.d.mobs = new ArrayList<>(); - this.d.loot = new ArrayList<>(); - this.d.minLevel = 1; - this.d.player = new Player(this); - } - - - public Tile getTile(int x, int y) { if (x < 0 || x > getWidth() - 1 || y < 0 || y > getHeight() - 1) { return Tile.BOUNDS; @@ -139,18 +137,6 @@ public void setPlayer(Player player) { d.player = player; } - public void moveDataFrom(World other) { - d = other.d; - } - - - - private boolean isEmptyFloor(int x, int y) { - return getTile(x, y) == Tile.FLOOR - && getMobs().stream().noneMatch(b -> b.x == x && b.y == y) - && getLoot().stream().noneMatch(b -> b.x == x && b.y == y); - } - public void setTilesAround(int x, int y, int radius, Tile tile) { for (int i = -radius; i <= radius; i++) { for (int j = -radius; j <= radius; j++) { @@ -163,6 +149,17 @@ public void setTilesAround(int x, int y, int radius, Tile tile) { } } + public void moveDataFrom(World other) { + d = other.d; + } + + + private boolean isEmptyFloor(int x, int y) { + return getTile(x, y) == Tile.FLOOR + && getMobs().stream().noneMatch(b -> b.x == x && b.y == y) + && getLoot().stream().noneMatch(b -> b.x == x && b.y == y); + } + private static class WorldData { private Tile[][] tiles; private int width; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java index e0843bf..413b0a0 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java @@ -11,13 +11,10 @@ public abstract class ActiveBeing extends Being { protected int xDirection; protected int yDirection; - protected int health; protected int level; protected boolean immobilized; - protected boolean alive; - private SideEffect effect; public ActiveBeing(World world) { @@ -62,7 +59,7 @@ public void move(int dx, int dy) { return; } xDirection = Math.max(0, Math.min(x + dx, world.getWidth() - 1)); - yDirection = Math.max(0, Math.min(y + dy, world.getHeight() - 1)); + yDirection = Math.max(0, Math.min(y + dy, world.getHeight() - 1)); if (canMove(xDirection, yDirection)) { x = xDirection; y = yDirection; @@ -71,18 +68,18 @@ public void move(int dx, int dy) { interactWithEnvironment(); } + public SideEffect getEffect() { + return effect; + } + protected boolean canMove(int xTo, int yTo) { return world.getTile(xTo, yTo).isWalkable() && world.getMob(xTo, yTo) == null; } - public void setEffect(SideEffect effect) { + protected void setEffect(SideEffect effect) { this.effect = effect; } - public SideEffect getEffect() { - return effect; - } - protected void moveRandom() { move(new Random().nextInt(3) - 1, new Random().nextInt(3) - 1); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java index 99faa0d..3331874 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java @@ -10,6 +10,7 @@ * Created by boris on 11.05.17. */ public class Dragon extends ActiveBeing implements ArtificialIntelligence { + public Dragon(World world) { super(world); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java index e534e05..1f0e352 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java @@ -7,6 +7,7 @@ import com.simiyutin.au.roguelike.util.Action; import com.simiyutin.au.roguelike.models.items.*; import com.simiyutin.au.roguelike.models.World; +import com.simiyutin.au.roguelike.util.WorldFactory; import java.awt.*; @@ -27,6 +28,24 @@ public Player(World world) { this.action = new RegularAction(); } + public void levelUp() { + level++; + World newWorld = WorldFactory.getOfMinLevel(world.getMinLevel() + 1); + Position pos = newWorld.getEmptyPosition(); + x = pos.x; + y = pos.y; + newWorld.setPlayer(this); + world.moveDataFrom(newWorld); + } + + public void act() { + action.act(); + } + + public Weapon getWeapon() { + return weapon; + } + @Override protected void interactWithEnvironment() { int deltaHealth = world.getTile(x, y).getDeltaHealth(); @@ -59,17 +78,7 @@ protected void interactWithEnvironment() { } } - public void levelUp() { - level++; - World newWorld = WorldFactory.getOfMinLevel(world.getMinLevel() + 1); - Position pos = newWorld.getEmptyPosition(); - x = pos.x; - y = pos.y; - newWorld.setPlayer(this); - world.moveDataFrom(newWorld); - } - - public Being getMobNearMe() { + private Being getMobNearMe() { for (Being b : world.getMobs()) { if (distTo(b.x, b.y) == 1) { return b; @@ -79,14 +88,6 @@ public Being getMobNearMe() { return null; } - private double distTo(int toX, int toY) { - return Math.hypot(toX - x, toY - y); - } - - public void act() { - action.act(); - } - private void startBattleWithDragon(Dragon dragon) { setImmobilized(true); dragon.setImmobilized(true); @@ -99,8 +100,8 @@ private void startBattleWithDragon(Dragon dragon) { }, 500); } - public Weapon getWeapon() { - return weapon; + private double distTo(int toX, int toY) { + return Math.hypot(toX - x, toY - y); } class RegularAction implements Action { @@ -129,7 +130,7 @@ public AttackingAction(ActiveBeing enemy) { @Override public void act() { - int harm = level * weapon.getLevel(); + int harm = level * weapon.getLevel() + weapon.getHarm(); int health = enemy.getHealth(); enemy.setHealth(health - harm); world.setMessage(String.format("enemy health: %d", enemy.getHealth())); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/ThrownItem.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/ThrownItem.java index 8266740..c8efef5 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/ThrownItem.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/ThrownItem.java @@ -22,8 +22,4 @@ public ThrownItem(Item item, World world) { public Item getItem() { return item; } - - public void setItem(Item item) { - this.item = item; - } } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java index fa5ee70..1c371af 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java @@ -25,6 +25,10 @@ public String getName() { // todo handle level name correlation return type.getName() + String.format(" of level %d", level); } + public int getHarm() { + return type.getHarm(); + } + public char getGlyph() { return type.getGlyph(); } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WeaponType.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WeaponType.java index 6447bf6..3fe544a 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WeaponType.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WeaponType.java @@ -31,6 +31,10 @@ public char getGlyph() { return glyph; } + public int getHarm() { + return harm; + } + public int getHue() { return hue; } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java index 870764b..bebfc82 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java @@ -5,7 +5,7 @@ import com.simiyutin.au.roguelike.models.beings.*; import com.simiyutin.au.roguelike.models.items.Item; import com.simiyutin.au.roguelike.models.items.ThrownItem; -import com.simiyutin.au.roguelike.models.items.WorldFactory; +import com.simiyutin.au.roguelike.util.WorldFactory; import java.awt.*; @@ -36,14 +36,6 @@ public void display(AsciiPanel terminal) { displayMessage(terminal); } - private int scrollLeft() { - return Math.max(0, Math.min(world.getPlayer().x - screenWidth / 2, world.getWidth() - screenWidth)); - } - - private int scrollTop() { - return Math.max(0, Math.min(world.getPlayer().y - screenHeight / 2, world.getHeight() - screenHeight)); - } - @Override public Screen respondToUserInput(KeyEvent key) { Player player = world.getPlayer(); @@ -78,7 +70,7 @@ public Screen updateState() { return world.getPlayer().getHealth() > 0 ? this : new DeadScreen(); } - public void displayMobs(AsciiPanel terminal, int left, int top) { + private void displayMobs(AsciiPanel terminal, int left, int top) { for (Being b: world.getMobs()) { writeSafe(terminal, b.getGlyph(), b.x - left, b.y - top, b.getColor()); @@ -89,19 +81,7 @@ public void displayMobs(AsciiPanel terminal, int left, int top) { } - private void writeSafe(AsciiPanel terminal, char c, int x, int y, Color color) { - if (x > 0 && x < screenWidth && y > 0 && y < screenHeight) { - terminal.write(c, x, y, color); - } - } - - public void displayInfo(AsciiPanel terminal) { - terminal.write(String.format("level: %s", world.getPlayer().getLevel()), 1, 1); - terminal.write(String.format("health: %s", world.getPlayer().getHealth()), 1, 2); - terminal.write(String.format("weapon: %s", world.getPlayer().getWeapon().getName()), 1, 3); - } - - public void displayWorld(AsciiPanel terminal, int left, int top) { + private void displayWorld(AsciiPanel terminal, int left, int top) { for (int x = 0; x < screenWidth; x++) { for (int y = 0; y < screenHeight; y++) { @@ -113,7 +93,7 @@ public void displayWorld(AsciiPanel terminal, int left, int top) { } } - public void displayLoot(AsciiPanel terminal, int left, int top) { + private void displayLoot(AsciiPanel terminal, int left, int top) { for (ThrownItem b: world.getLoot()) { Item item = b.getItem(); writeSafe(terminal, item.getGlyph(), b.x - left, b.y - top, item.getColor()); @@ -123,4 +103,24 @@ public void displayLoot(AsciiPanel terminal, int left, int top) { private void displayMessage(AsciiPanel terminal) { terminal.write(world.getMessage(), 40 - world.getMessage().length() / 2, 5); } + + private void displayInfo(AsciiPanel terminal) { + terminal.write(String.format("level: %s", world.getPlayer().getLevel()), 1, 1); + terminal.write(String.format("health: %s", world.getPlayer().getHealth()), 1, 2); + terminal.write(String.format("weapon: %s", world.getPlayer().getWeapon().getName()), 1, 3); + } + + private int scrollTop() { + return Math.max(0, Math.min(world.getPlayer().y - screenHeight / 2, world.getHeight() - screenHeight)); + } + + private int scrollLeft() { + return Math.max(0, Math.min(world.getPlayer().x - screenWidth / 2, world.getWidth() - screenWidth)); + } + + private void writeSafe(AsciiPanel terminal, char c, int x, int y, Color color) { + if (x > 0 && x < screenWidth && y > 0 && y < screenHeight) { + terminal.write(c, x, y, color); + } + } } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomColorGenerator.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomBGColorGenerator.java similarity index 90% rename from roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomColorGenerator.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomBGColorGenerator.java index 0e4aa22..6225d14 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomColorGenerator.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomBGColorGenerator.java @@ -6,7 +6,7 @@ /** * Created by boris on 13.05.17. */ -public class RandomColorGenerator { +public class RandomBGColorGenerator { private final Random randomGen = new Random(42); public Color getColor() { diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java index 2b29119..1539740 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java @@ -26,7 +26,7 @@ public class WorldBuilder { private List> mobs; private List loot; private int minLevel; - private static final RandomColorGenerator colorGen = new RandomColorGenerator();; + private static final RandomBGColorGenerator colorGen = new RandomBGColorGenerator();; public WorldBuilder(int width, int height) { this.width = width; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WorldFactory.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java similarity index 93% rename from roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WorldFactory.java rename to roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java index d630c88..106e08f 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WorldFactory.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java @@ -1,4 +1,4 @@ -package com.simiyutin.au.roguelike.models.items; +package com.simiyutin.au.roguelike.util; import com.simiyutin.au.roguelike.models.World; import com.simiyutin.au.roguelike.util.WorldBuilder; From 27f93074b83e9568810a69eb3b92d39de326ac50 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sun, 14 May 2017 00:32:29 +0300 Subject: [PATCH 51/63] tests --- roguelike/impl/pom.xml | 5 + .../simiyutin/au/roguelike/models/World.java | 6 +- .../roguelike/models/beings/ActiveBeing.java | 11 +- .../au/roguelike/models/beings/Dragon.java | 9 +- .../au/roguelike/models/beings/Ghost.java | 13 +- .../au/roguelike/models/beings/Player.java | 6 +- .../roguelike/models/beings/SideEffect.java | 2 +- .../au/roguelike/screens/PlayScreen.java | 2 +- .../au/roguelike/util/WorldBuilder.java | 32 +++- .../au/roguelike/util/WorldFactory.java | 14 +- .../com/simiyutin/au/roguelike/MobsTests.java | 176 ++++++++++++++++++ .../au/roguelike/WorldBuilderTests.java | 102 ++++++++++ .../simiyutin/au/roguelike/WorldTests.java | 37 ++++ 13 files changed, 381 insertions(+), 34 deletions(-) create mode 100644 roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java create mode 100644 roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldBuilderTests.java create mode 100644 roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldTests.java diff --git a/roguelike/impl/pom.xml b/roguelike/impl/pom.xml index c3da1fc..0e3818f 100644 --- a/roguelike/impl/pom.xml +++ b/roguelike/impl/pom.xml @@ -27,6 +27,11 @@ system ${project.basedir}/libs/ascii-panel/asciiPanel.jar + + junit + junit + 4.12 + diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java index c01ad24..f028c19 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java @@ -30,7 +30,7 @@ public World(Tile[][] tiles) { this.d.player = new Player(this); } - public List getLoot() { + public List getItems() { return d.loot; } @@ -109,7 +109,7 @@ public Being getMob(int x, int y) { } public ThrownItem getItem(int x, int y) { - for (ThrownItem b : getLoot()) { + for (ThrownItem b : getItems()) { if (b.x == x && b.y == y) { return b; } @@ -157,7 +157,7 @@ public void moveDataFrom(World other) { private boolean isEmptyFloor(int x, int y) { return getTile(x, y) == Tile.FLOOR && getMobs().stream().noneMatch(b -> b.x == x && b.y == y) - && getLoot().stream().noneMatch(b -> b.x == x && b.y == y); + && getItems().stream().noneMatch(b -> b.x == x && b.y == y); } private static class WorldData { diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java index 413b0a0..e83124f 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java @@ -34,10 +34,6 @@ public void setAlive(boolean alive) { this.alive = alive; } - public boolean isImmobilized() { - return immobilized; - } - public void setImmobilized(boolean immobilized) { this.immobilized = immobilized; } @@ -72,18 +68,17 @@ public SideEffect getEffect() { return effect; } - protected boolean canMove(int xTo, int yTo) { + public boolean canMove(int xTo, int yTo) { return world.getTile(xTo, yTo).isWalkable() && world.getMob(xTo, yTo) == null; } + public abstract void interactWithEnvironment(); + protected void setEffect(SideEffect effect) { this.effect = effect; } - protected void moveRandom() { move(new Random().nextInt(3) - 1, new Random().nextInt(3) - 1); } - - protected abstract void interactWithEnvironment(); } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java index 3331874..699713a 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java @@ -11,6 +11,8 @@ */ public class Dragon extends ActiveBeing implements ArtificialIntelligence { + public static boolean isSelfActing = true; + public Dragon(World world) { super(world); @@ -18,7 +20,10 @@ public Dragon(World world) { this.color = Color.RED; enflameTiles(); - new RecurringTask(this::move, 1000); + + if (isSelfActing) { + new RecurringTask(this::move, 1000); + } } @Override @@ -33,7 +38,7 @@ public void move(int dx, int dy) { } @Override - protected void interactWithEnvironment() { + public void interactWithEnvironment() { } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Ghost.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Ghost.java index e2eeca7..d091133 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Ghost.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Ghost.java @@ -15,7 +15,9 @@ public class Ghost extends ActiveBeing implements ArtificialIntelligence { private static boolean moveTo = true; - private final int SMELL_RANGE = 15; + public static final int SMELL_RANGE = 15; + public static final int TRIGGER_RANGE = 3; + public static boolean isSelfActing = true; public Ghost(World world) { super(world); @@ -23,12 +25,14 @@ public Ghost(World world) { this.glyph = 'G'; this.color = Color.cyan; - new RecurringTask(this::move, 200); + if (isSelfActing) { + new RecurringTask(this::move, 200); + } } @Override - protected void interactWithEnvironment() { - if (distToPlayer(x, y) < 3) { + public void interactWithEnvironment() { + if (distToPlayer(x, y) < TRIGGER_RANGE) { SideEffect effect = world.getPlayer().getEffect(); if (effect == INVERSED) { world.getMobs().remove(this); @@ -54,7 +58,6 @@ public void move() { } else { moveFromPlayer(); } - } else { moveRandom(); } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java index 1f0e352..0cc2dda 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java @@ -47,7 +47,7 @@ public Weapon getWeapon() { } @Override - protected void interactWithEnvironment() { + public void interactWithEnvironment() { int deltaHealth = world.getTile(x, y).getDeltaHealth(); health += deltaHealth * level; @@ -56,14 +56,14 @@ protected void interactWithEnvironment() { Item item = thrownItem.getItem(); if (item instanceof Weapon) { weapon = (Weapon) item; - world.getLoot().removeIf(w -> + world.getItems().removeIf(w -> w.getItem() instanceof Weapon && ((Weapon) w.getItem()).getLevel() <= weapon.getLevel()); } else if (item instanceof MedAid) { health += ((MedAid) item).getValue(); health = Math.min(health, 100); } world.setMessage(String.format("picked %s", item.getName())); - world.getLoot().remove(thrownItem); + world.getItems().remove(thrownItem); } Being being = getMobNearMe(); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/SideEffect.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/SideEffect.java index 1fbb2d4..037e447 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/SideEffect.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/SideEffect.java @@ -21,7 +21,7 @@ public enum SideEffect { case KeyEvent.VK_D: return KeyEvent.VK_A; default: - return 0; + return key; } }); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java index bebfc82..7d4347f 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java @@ -94,7 +94,7 @@ private void displayWorld(AsciiPanel terminal, int left, int top) { } private void displayLoot(AsciiPanel terminal, int left, int top) { - for (ThrownItem b: world.getLoot()) { + for (ThrownItem b: world.getItems()) { Item item = b.getItem(); writeSafe(terminal, item.getGlyph(), b.x - left, b.y - top, item.getColor()); } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java index 1539740..a5e37df 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java @@ -31,10 +31,15 @@ public class WorldBuilder { public WorldBuilder(int width, int height) { this.width = width; this.height = height; + this.tiles = new Tile[width][height]; + fillWithFloor(); + this.mobs = new ArrayList<>(); this.loot = new ArrayList<>(); this.minLevel = 1; + + } public World build() { @@ -53,7 +58,7 @@ public World build() { } for (Item w : loot) { - world.getLoot().add(new ThrownItem(w, world)); //todo circular dependency + world.getItems().add(new ThrownItem(w, world)); //todo circular dependency } world.setMinLevel(minLevel); @@ -61,14 +66,15 @@ public World build() { return world; } - public WorldBuilder ofMinLevel(int level) { - this.minLevel = level; + public WorldBuilder withCaves() { + randomizeTiles(); + smooth(8); return this; } - public WorldBuilder makeCaves() { - return randomizeTiles() - .smooth(8); + public WorldBuilder ofMinLevel(int level) { + this.minLevel = level; + return this; } public WorldBuilder addMobs(Class clazz, int quantity) { @@ -101,16 +107,15 @@ public WorldBuilder addMedAids(int quantity) { return this; } - private WorldBuilder randomizeTiles() { + private void randomizeTiles() { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { tiles[x][y] = Math.random() < 0.5 ? Tile.FLOOR : Tile.WALL; } } - return this; } - private WorldBuilder smooth(int times) { + private void smooth(int times) { Tile[][] tiles2 = new Tile[width][height]; for (int time = 0; time < times; time++) { @@ -136,6 +141,13 @@ private WorldBuilder smooth(int times) { } tiles = tiles2; } - return this; + } + + private void fillWithFloor() { + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + tiles[i][j] = Tile.FLOOR; + } + } } } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java index 106e08f..ab0e17a 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java @@ -13,7 +13,19 @@ public class WorldFactory { public static World getOfMinLevel(int level) { World result = new WorldBuilder(100, 100) .ofMinLevel(level) - .makeCaves() + .addMobs(Mushroom.class, 10) + .addMobs(Ghost.class, 10) + .addMobs(Dragon.class, 5) + .addWeapons(5) + .addMedAids(10) + .build(); + + return result; + } + + public static World getTestConfig(int level) { + World result = new WorldBuilder(100, 100) + .ofMinLevel(level) .addMobs(Mushroom.class, 10) .addMobs(Ghost.class, 0) .addMobs(Dragon.class, 1) diff --git a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java new file mode 100644 index 0000000..97a1d27 --- /dev/null +++ b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java @@ -0,0 +1,176 @@ +package com.simiyutin.au.roguelike; + +import com.simiyutin.au.roguelike.models.Tile; +import com.simiyutin.au.roguelike.models.World; +import com.simiyutin.au.roguelike.models.beings.*; +import com.simiyutin.au.roguelike.models.items.MedAid; +import com.simiyutin.au.roguelike.models.items.ThrownItem; +import com.simiyutin.au.roguelike.models.items.Weapon; +import com.simiyutin.au.roguelike.models.items.WeaponType; +import com.simiyutin.au.roguelike.util.WorldBuilder; +import org.junit.Test; + +import static java.lang.Thread.sleep; +import static junit.framework.TestCase.assertFalse; +import static junit.framework.TestCase.assertTrue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.CoreMatchers.is; + +/** + * Created by boris on 13.05.17. + */ +public class MobsTests { + + private World world; + private Player player; + + @Test + public void testAlive() { + init(); + assertTrue(player.isAlive()); + } + + @Test + public void testCanMove() { + init(); + world.setTile(50, 51, Tile.WALL); + assertFalse(player.canMove(50, 51)); + } + + @Test + public void testMove() { + init(); + int prevX = player.x; + player.move(1, 0); + assertThat(player.x, is(prevX + 1)); + } + + @Test + public void testMoveToPoisonedFloor() { + init(); + world.setTile(50, 51, Tile.POISONED_FLOOR); + int healthBefore = player.getHealth(); + player.move(0, 1); + assertTrue(player.getHealth() < healthBefore); + } + + @Test + public void testMoveOverEdge() { + init(); + player.x = 0; + player.y = 0; + player.move(-1, 0); + assertThat(player.x, is(0)); + } + + @Test + public void testMoveImmobilized() { + init(); + player.setImmobilized(true); + int prevX = player.x; + player.move(1, 0); + assertThat(player.x, is(prevX)); + + } + + @Test + public void testAct() { + init(); + world.setTile(50, 51, Tile.WALL); + player.move(0, 1); + player.act(); + assertThat(world.getTile(50, 51), is(Tile.FLOOR)); + } + + @Test + public void testGhost() { + init(); + Ghost.isSelfActing = false; + Ghost ghost = new Ghost(world); + world.getMobs().add(ghost); + ghost.x = 50 + Ghost.TRIGGER_RANGE; + ghost.y = 50; + ghost.interactWithEnvironment(); + assertThat(player.getEffect(), is(SideEffect.IDENTITY)); + ghost.x--; + ghost.interactWithEnvironment(); + assertThat(player.getEffect(), is(SideEffect.INVERSED)); + + ghost.interactWithEnvironment(); + assertThat(player.getEffect(), is(SideEffect.IDENTITY)); + assertTrue(world.getMobs().isEmpty()); + assertFalse(ghost.isAlive()); + } + + @Test + public void testDragon() throws InterruptedException { + init(); + Dragon dragon = new Dragon(world); + world.getMobs().add(dragon); + dragon.x = 50; + dragon.y = 51; + + int dragonHealthBefore = dragon.getHealth(); + int playerHealthBefore = player.getHealth(); + + player.act(); + sleep(1000); + player.act(); + + assertTrue(player.getHealth() < playerHealthBefore); + assertTrue(dragon.getHealth() < dragonHealthBefore); + + } + + @Test + public void testMushroom() { + init(); + Mushroom mushroom = new Mushroom(world); + int healthBefore = player.getHealth(); + player.x = mushroom.x; + player.y = mushroom.y + 1; + assertThat(world.getTile(player.x, player.y), is(Tile.POISONED_FLOOR)); + player.move(1, 0); + assertTrue(player.getHealth() < healthBefore); + } + + @Test + public void testPickUpWeapon() { + init(); + ThrownItem sword = new ThrownItem(new Weapon(WeaponType.SWORD, 1), world); + world.getItems().add(sword); + player.x = sword.x; + player.y = sword.y; + + player.interactWithEnvironment(); + assertThat(player.getWeapon() , is(sword.getItem())); + assertTrue(world.getItems().isEmpty()); + } + + @Test + public void testPickUpMed() { + init(); + ThrownItem medAidPos = new ThrownItem(new MedAid(), world); + MedAid medAid = ((MedAid) medAidPos.getItem()); + + world.getItems().add(medAidPos); + player.x = medAidPos.x; + player.y = medAidPos.y; + int prevHealth = player.getHealth(); + player.setHealth(player.getHealth() - medAid.getValue() - 10); + player.interactWithEnvironment(); + + assertThat(player.getHealth(), is(prevHealth - 10)); + assertTrue(world.getItems().isEmpty()); + } + + + private void init() { + world = new WorldBuilder(100, 100) + .build(); + + player = world.getPlayer(); + player.x = 50; + player.y = 50; + } +} diff --git a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldBuilderTests.java b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldBuilderTests.java new file mode 100644 index 0000000..5702e6d --- /dev/null +++ b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldBuilderTests.java @@ -0,0 +1,102 @@ +package com.simiyutin.au.roguelike; + +import com.simiyutin.au.roguelike.models.World; +import com.simiyutin.au.roguelike.models.beings.*; +import com.simiyutin.au.roguelike.models.items.Item; +import com.simiyutin.au.roguelike.models.items.MedAid; +import com.simiyutin.au.roguelike.models.items.ThrownItem; +import com.simiyutin.au.roguelike.models.items.Weapon; +import com.simiyutin.au.roguelike.util.WorldBuilder; +import org.hamcrest.CoreMatchers; +import org.junit.Test; +import sun.java2d.pipe.hw.AccelDeviceEventListener; + +import java.util.stream.Collectors; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +public class WorldBuilderTests { + + @Test + public void testSimple() { + World world = new WorldBuilder(100, 100).build(); + assertThat(world.getHeight(), is(100)); + assertThat(world.getWidth(), is(100)); + assertTrue(world.getItems().isEmpty()); + assertTrue(world.getMobs().isEmpty()); + assertTrue(world.getPlayer().isAlive()); + assertThat(world.getPlayer().getWeapon(), CoreMatchers.notNullValue()); + } + + + + @Test + public void testMobs() { + World world = new WorldBuilder(100, 100) + .withCaves() + .addMobs(Mushroom.class, 10) + .addMobs(Ghost.class, 10) + .addMobs(Dragon.class, 10) + .build(); + + assertThat(world.getMobs().stream().filter(m -> m instanceof Mushroom).count(), is(10L)); + assertThat(world.getMobs().stream().filter(m -> m instanceof Ghost).count(), is(10L)); + assertThat(world.getMobs().stream().filter(m -> m instanceof Dragon).count(), is(10L)); + } + + @Test + public void testMinLevel() { + World world = new WorldBuilder(100, 100) + .withCaves() + .ofMinLevel(10) + .addMobs(Mushroom.class, 10) + .addMobs(Ghost.class, 10) + .addMobs(Dragon.class, 10) + .addWeapons(10) + .build(); + + assertThat(world.getMinLevel(), is(10)); + + for (Being mob : world.getMobs()) { + if (mob instanceof ActiveBeing) { + assertTrue(((ActiveBeing) mob).getLevel() >= world.getMinLevel()); + } + } + + for (ThrownItem item : world.getItems()) { + if (item.getItem() instanceof Weapon) { + Weapon w = ((Weapon) item.getItem()); + assertTrue(w.getLevel() >= world.getMinLevel()); + } + } + } + + + @Test + public void testWeapons() { + World world = new WorldBuilder(100, 100) + .withCaves() + .addWeapons(10) + .build(); + + assertThat(world.getItems().stream().map(ThrownItem::getItem).filter(i -> i instanceof Weapon).count(), is(10L)); + + for (Item item : world.getItems().stream().map(ThrownItem::getItem).filter(i -> i instanceof Weapon).collect(Collectors.toList())) { + Weapon weapon = (Weapon) item; + assertTrue(weapon.getLevel() >= world.getMinLevel()); + } + } + + @Test + public void testMedAids() { + World world = new WorldBuilder(100, 100) + .withCaves() + .addWeapons(10) + .addMedAids(10) + .build(); + + assertThat(world.getItems().stream().map(ThrownItem::getItem).filter(i -> i instanceof MedAid).count(), is(10L)); + } +} diff --git a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldTests.java b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldTests.java new file mode 100644 index 0000000..5c55d66 --- /dev/null +++ b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldTests.java @@ -0,0 +1,37 @@ +package com.simiyutin.au.roguelike; + +import com.simiyutin.au.roguelike.models.Position; +import com.simiyutin.au.roguelike.models.Tile; +import com.simiyutin.au.roguelike.models.World; +import com.simiyutin.au.roguelike.models.beings.Ghost; +import com.simiyutin.au.roguelike.util.WorldBuilder; +import com.simiyutin.au.roguelike.util.WorldFactory; +import javafx.geometry.Pos; +import org.hamcrest.CoreMatchers; +import org.junit.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertTrue; + +/** + * Created by boris on 13.05.17. + */ +public class WorldTests { + + @Test + public void testEmptyPosition() { + World world = new WorldBuilder(100, 100) + .withCaves() + .addMedAids(50) + .addWeapons(50) + .addMobs(Ghost.class, 100) + .build(); + + for (int i = 0; i < 10000; i++) { + Position position = world.getEmptyPosition(); + assertTrue(world.getMob(position.x, position.y) == null); + assertTrue(world.getItem(position.x, position.y) == null); + assertTrue(world.getTile(position.x, position.y) == Tile.FLOOR); + } + } +} From a30e7631b1946d0870049be5897fdf2f2b8925b7 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sun, 14 May 2017 00:53:19 +0300 Subject: [PATCH 52/63] logging --- roguelike/impl/pom.xml | 10 ++++++++++ .../main/java/com/simiyutin/au/roguelike/Main.java | 6 ++++++ .../java/com/simiyutin/au/roguelike/Scheduler.java | 10 ++++++---- .../simiyutin/au/roguelike/util/WorldBuilder.java | 12 ++++++++---- roguelike/impl/src/main/resources/log4j2.xml | 13 +++++++++++++ 5 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 roguelike/impl/src/main/resources/log4j2.xml diff --git a/roguelike/impl/pom.xml b/roguelike/impl/pom.xml index 0e3818f..b675edf 100644 --- a/roguelike/impl/pom.xml +++ b/roguelike/impl/pom.xml @@ -32,6 +32,16 @@ junit 4.12 + + org.apache.logging.log4j + log4j-api + 2.8.1 + + + org.apache.logging.log4j + log4j-core + 2.8.1 + diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Main.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Main.java index 0f2ccb1..bee5963 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Main.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Main.java @@ -1,11 +1,17 @@ package com.simiyutin.au.roguelike; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + /** * Created by boris on 08.05.17. */ public class Main { + private static final Logger LOGGER = LogManager.getLogger(Main.class); + public static void main(String[] args) { Scheduler scheduler = new Scheduler(); scheduler.schedule(); + LOGGER.trace("application started"); } } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Scheduler.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Scheduler.java index edc2d30..0908d06 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Scheduler.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Scheduler.java @@ -4,6 +4,8 @@ import com.simiyutin.au.roguelike.screens.Screen; import com.simiyutin.au.roguelike.screens.StartScreen; import com.simiyutin.au.roguelike.util.RecurringTask; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import javax.swing.*; import java.awt.event.KeyEvent; @@ -15,6 +17,8 @@ public class Scheduler extends JFrame implements KeyListener { private AsciiPanel terminal; private Screen screen; + private static final Logger LOGGER = LogManager.getLogger(Scheduler.class); + public Scheduler() { super(); @@ -35,10 +39,8 @@ public void run() { screen = screen.updateState(); repaint(); }); - } catch (InterruptedException e) { - e.printStackTrace(); // todo log - } catch (InvocationTargetException e) { - e.printStackTrace(); // todo log + } catch (InterruptedException | InvocationTargetException e) { + LOGGER.error(e); } } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java index a5e37df..ed75e6d 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java @@ -1,5 +1,6 @@ package com.simiyutin.au.roguelike.util; +import com.simiyutin.au.roguelike.Main; import com.simiyutin.au.roguelike.models.Tile; import com.simiyutin.au.roguelike.models.World; import com.simiyutin.au.roguelike.models.beings.Being; @@ -7,6 +8,8 @@ import com.simiyutin.au.roguelike.models.items.MedAid; import com.simiyutin.au.roguelike.models.items.ThrownItem; import com.simiyutin.au.roguelike.models.items.Weapon; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.awt.*; import java.lang.reflect.Constructor; @@ -26,7 +29,9 @@ public class WorldBuilder { private List> mobs; private List loot; private int minLevel; - private static final RandomBGColorGenerator colorGen = new RandomBGColorGenerator();; + private static final RandomBGColorGenerator colorGen = new RandomBGColorGenerator(); + + private static final Logger LOGGER = LogManager.getLogger(WorldBuilder.class); public WorldBuilder(int width, int height) { this.width = width; @@ -53,7 +58,7 @@ public World build() { try { world.getMobs().add(c.newInstance(world)); } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); + LOGGER.error(e); } } @@ -82,8 +87,7 @@ public WorldBuilder addMobs(Class clazz, int quantity) { try { mobs.add(clazz.getConstructor(World.class)); } catch (NoSuchMethodException ex) { - // todo log - ex.printStackTrace(); + LOGGER.error(ex); } } return this; diff --git a/roguelike/impl/src/main/resources/log4j2.xml b/roguelike/impl/src/main/resources/log4j2.xml new file mode 100644 index 0000000..12f2d3f --- /dev/null +++ b/roguelike/impl/src/main/resources/log4j2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file From 7c2383eca06c1967fa4a34d4723f81e20de8dc58 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sun, 14 May 2017 00:56:35 +0300 Subject: [PATCH 53/63] fix --- .../main/java/com/simiyutin/au/roguelike/util/WorldFactory.java | 2 ++ roguelike/impl/src/main/resources/todolist | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java index ab0e17a..e94a066 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java @@ -12,6 +12,7 @@ public class WorldFactory { public static World getOfMinLevel(int level) { World result = new WorldBuilder(100, 100) + .withCaves() .ofMinLevel(level) .addMobs(Mushroom.class, 10) .addMobs(Ghost.class, 10) @@ -25,6 +26,7 @@ public static World getOfMinLevel(int level) { public static World getTestConfig(int level) { World result = new WorldBuilder(100, 100) + .withCaves() .ofMinLevel(level) .addMobs(Mushroom.class, 10) .addMobs(Ghost.class, 0) diff --git a/roguelike/impl/src/main/resources/todolist b/roguelike/impl/src/main/resources/todolist index 4070c86..9c3cfab 100644 --- a/roguelike/impl/src/main/resources/todolist +++ b/roguelike/impl/src/main/resources/todolist @@ -35,7 +35,7 @@ БАГИ: 1. Не работает в русской раскладке -2. В reversed состоянии не работает копание +--2. В reversed состоянии не работает копание 3. После победы над драконом можно поднять меч более низкого уровня From c8d3450bbfc2ed3d6ed3b0952d4dc9a2fe7a1939 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sun, 14 May 2017 02:18:56 +0300 Subject: [PATCH 54/63] building fix --- .gitignore | 1 + roguelike/impl/pom.xml | 47 ++++++++++++++---- .../ascii-panel/1.1/ascii-panel-1.1.jar} | Bin .../ascii-panel/1.1/ascii-panel-1.1.pom | 9 ++++ .../ascii-panel/maven-metadata-local.xml | 12 +++++ .../com/simiyutin/au/roguelike/MobsTests.java | 2 +- .../au/roguelike/WorldBuilderTests.java | 1 - .../simiyutin/au/roguelike/WorldTests.java | 4 -- 8 files changed, 61 insertions(+), 15 deletions(-) rename roguelike/impl/{libs/ascii-panel/asciiPanel.jar => repo/net/trystan/ascii-panel/1.1/ascii-panel-1.1.jar} (100%) create mode 100644 roguelike/impl/repo/net/trystan/ascii-panel/1.1/ascii-panel-1.1.pom create mode 100644 roguelike/impl/repo/net/trystan/ascii-panel/maven-metadata-local.xml diff --git a/.gitignore b/.gitignore index c35a209..26673c0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /**/*.vpp.* /**/*.iml /**/*.class +/**/target/ diff --git a/roguelike/impl/pom.xml b/roguelike/impl/pom.xml index b675edf..4a8acd9 100644 --- a/roguelike/impl/pom.xml +++ b/roguelike/impl/pom.xml @@ -7,6 +7,7 @@ simiyutin roguelike 1.0-SNAPSHOT + @@ -17,15 +18,49 @@ 1.8 1.8 - + + + org.apache.maven.plugins + maven-jar-plugin + 3.0.2 + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.0.0 + + + jar-with-dependencies + + + + com.simiyutin.au.roguelike.Main + + + + + + package + + single + + + + + + + + my-local-repo + file://${project.basedir}/repo + + net.trystan ascii-panel 1.1 - system - ${project.basedir}/libs/ascii-panel/asciiPanel.jar junit @@ -43,10 +78,4 @@ 2.8.1 - - - - - - \ No newline at end of file diff --git a/roguelike/impl/libs/ascii-panel/asciiPanel.jar b/roguelike/impl/repo/net/trystan/ascii-panel/1.1/ascii-panel-1.1.jar similarity index 100% rename from roguelike/impl/libs/ascii-panel/asciiPanel.jar rename to roguelike/impl/repo/net/trystan/ascii-panel/1.1/ascii-panel-1.1.jar diff --git a/roguelike/impl/repo/net/trystan/ascii-panel/1.1/ascii-panel-1.1.pom b/roguelike/impl/repo/net/trystan/ascii-panel/1.1/ascii-panel-1.1.pom new file mode 100644 index 0000000..054d201 --- /dev/null +++ b/roguelike/impl/repo/net/trystan/ascii-panel/1.1/ascii-panel-1.1.pom @@ -0,0 +1,9 @@ + + + 4.0.0 + net.trystan + ascii-panel + 1.1 + POM was created from install:install-file + diff --git a/roguelike/impl/repo/net/trystan/ascii-panel/maven-metadata-local.xml b/roguelike/impl/repo/net/trystan/ascii-panel/maven-metadata-local.xml new file mode 100644 index 0000000..316bbe9 --- /dev/null +++ b/roguelike/impl/repo/net/trystan/ascii-panel/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + net.trystan + ascii-panel + + 1.1 + + 1.1 + + 20170513231215 + + diff --git a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java index 97a1d27..6d452c1 100644 --- a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java +++ b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java @@ -13,8 +13,8 @@ import static java.lang.Thread.sleep; import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertTrue; -import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; /** * Created by boris on 13.05.17. diff --git a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldBuilderTests.java b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldBuilderTests.java index 5702e6d..9ed7f67 100644 --- a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldBuilderTests.java +++ b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldBuilderTests.java @@ -9,7 +9,6 @@ import com.simiyutin.au.roguelike.util.WorldBuilder; import org.hamcrest.CoreMatchers; import org.junit.Test; -import sun.java2d.pipe.hw.AccelDeviceEventListener; import java.util.stream.Collectors; diff --git a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldTests.java b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldTests.java index 5c55d66..fd349ab 100644 --- a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldTests.java +++ b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldTests.java @@ -5,12 +5,8 @@ import com.simiyutin.au.roguelike.models.World; import com.simiyutin.au.roguelike.models.beings.Ghost; import com.simiyutin.au.roguelike.util.WorldBuilder; -import com.simiyutin.au.roguelike.util.WorldFactory; -import javafx.geometry.Pos; -import org.hamcrest.CoreMatchers; import org.junit.Test; -import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertTrue; /** From 5bb68c9d0465abf8ea8fccbb83775876f9c12adb Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sun, 14 May 2017 02:38:26 +0300 Subject: [PATCH 55/63] more logging + refactor --- .../java/com/simiyutin/au/roguelike/Main.java | 7 +++---- .../au/roguelike/models/Position.java | 4 +--- .../simiyutin/au/roguelike/models/Tile.java | 4 +--- .../simiyutin/au/roguelike/models/World.java | 4 +--- .../roguelike/models/beings/ActiveBeing.java | 4 +--- .../models/beings/ArtificialIntelligence.java | 4 +--- .../au/roguelike/models/beings/Being.java | 4 +--- .../au/roguelike/models/beings/Dragon.java | 4 +--- .../au/roguelike/models/beings/Ghost.java | 4 +--- .../au/roguelike/models/beings/Mushroom.java | 4 +--- .../au/roguelike/models/beings/Player.java | 21 ++++++++++++------- .../roguelike/models/beings/SideEffect.java | 4 +--- .../au/roguelike/models/items/Item.java | 4 +--- .../au/roguelike/models/items/MedAid.java | 4 +--- .../au/roguelike/models/items/ThrownItem.java | 4 +--- .../au/roguelike/models/items/Weapon.java | 4 +--- .../au/roguelike/models/items/WeaponType.java | 4 +--- .../au/roguelike/screens/DeadScreen.java | 15 +++++++++---- .../au/roguelike/screens/PlayScreen.java | 11 ++++++---- .../au/roguelike/screens/Screen.java | 4 +--- .../au/roguelike/screens/StartScreen.java | 12 ++++++++--- .../simiyutin/au/roguelike/util/Action.java | 4 +--- .../au/roguelike/util/DelayedTask.java | 4 +--- .../util/RandomBGColorGenerator.java | 4 +--- .../au/roguelike/util/RecurringTask.java | 4 +--- .../au/roguelike/util/WorldBuilder.java | 5 +---- .../au/roguelike/util/WorldFactory.java | 4 +--- 27 files changed, 66 insertions(+), 89 deletions(-) diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Main.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Main.java index bee5963..ff0dbc1 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Main.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Main.java @@ -3,15 +3,14 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -/** - * Created by boris on 08.05.17. - */ + public class Main { private static final Logger LOGGER = LogManager.getLogger(Main.class); public static void main(String[] args) { + LOGGER.trace("application started"); Scheduler scheduler = new Scheduler(); + LOGGER.trace("start scheduling"); scheduler.schedule(); - LOGGER.trace("application started"); } } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Position.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Position.java index 22c2e6c..5fcfa20 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Position.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Position.java @@ -1,8 +1,6 @@ package com.simiyutin.au.roguelike.models; -/** - * Created by boris on 11.05.17. - */ + public class Position { public int x; public int y; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Tile.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Tile.java index 0f94282..ce79dca 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Tile.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Tile.java @@ -4,9 +4,7 @@ import java.awt.*; -/** - * Created by boris on 08.05.17. - */ + public enum Tile { FLOOR('.', AsciiPanel.yellow, 0, true), POISONED_FLOOR('.', Color.GREEN, -5, true), diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java index f028c19..6b969a3 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java @@ -11,9 +11,7 @@ import java.util.List; import java.util.Random; -/** - * Created by boris on 08.05.17. - */ + public class World { private WorldData d; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java index e83124f..7c256f0 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java @@ -4,9 +4,7 @@ import java.util.Random; -/** - * Created by boris on 10.05.17. - */ + public abstract class ActiveBeing extends Being { protected int xDirection; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ArtificialIntelligence.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ArtificialIntelligence.java index 72023dc..c0e7924 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ArtificialIntelligence.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ArtificialIntelligence.java @@ -1,8 +1,6 @@ package com.simiyutin.au.roguelike.models.beings; -/** - * Created by boris on 10.05.17. - */ + public interface ArtificialIntelligence { void move(); } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Being.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Being.java index 17cbef9..cb34242 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Being.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Being.java @@ -5,9 +5,7 @@ import java.awt.*; -/** - * Created by boris on 09.05.17. - */ + public abstract class Being { public int x; public int y; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java index 699713a..c71619d 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java @@ -6,9 +6,7 @@ import java.awt.*; -/** - * Created by boris on 11.05.17. - */ + public class Dragon extends ActiveBeing implements ArtificialIntelligence { public static boolean isSelfActing = true; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Ghost.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Ghost.java index d091133..7a25a74 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Ghost.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Ghost.java @@ -8,9 +8,7 @@ import static com.simiyutin.au.roguelike.models.beings.SideEffect.IDENTITY; import static com.simiyutin.au.roguelike.models.beings.SideEffect.INVERSED; -/** - * Created by boris on 10.05.17. - */ + public class Ghost extends ActiveBeing implements ArtificialIntelligence { private static boolean moveTo = true; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Mushroom.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Mushroom.java index c7ce451..e489f89 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Mushroom.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Mushroom.java @@ -5,9 +5,7 @@ import java.awt.*; -/** - * Created by boris on 09.05.17. - */ + public class Mushroom extends Being { public Mushroom(World world) { diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java index 0cc2dda..aab14f1 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java @@ -1,24 +1,26 @@ package com.simiyutin.au.roguelike.models.beings; -import com.simiyutin.au.roguelike.util.DelayedTask; -import com.simiyutin.au.roguelike.util.RecurringTask; import com.simiyutin.au.roguelike.models.Position; import com.simiyutin.au.roguelike.models.Tile; -import com.simiyutin.au.roguelike.util.Action; -import com.simiyutin.au.roguelike.models.items.*; import com.simiyutin.au.roguelike.models.World; +import com.simiyutin.au.roguelike.models.items.*; +import com.simiyutin.au.roguelike.util.Action; +import com.simiyutin.au.roguelike.util.DelayedTask; +import com.simiyutin.au.roguelike.util.RecurringTask; import com.simiyutin.au.roguelike.util.WorldFactory; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.awt.*; -/** - * Created by boris on 09.05.17. - */ + public class Player extends ActiveBeing { private Weapon weapon; private Action action; + private static final Logger LOGGER = LogManager.getLogger(Player.class); + public Player(World world) { super(world); @@ -36,6 +38,7 @@ public void levelUp() { y = pos.y; newWorld.setPlayer(this); world.moveDataFrom(newWorld); + LOGGER.trace("player level upped"); } public void act() { @@ -55,10 +58,12 @@ public void interactWithEnvironment() { if (thrownItem != null) { Item item = thrownItem.getItem(); if (item instanceof Weapon) { + LOGGER.trace(String.format("picked up weapon: %s", item.getName())); weapon = (Weapon) item; world.getItems().removeIf(w -> w.getItem() instanceof Weapon && ((Weapon) w.getItem()).getLevel() <= weapon.getLevel()); } else if (item instanceof MedAid) { + LOGGER.trace("picked up med aid"); health += ((MedAid) item).getValue(); health = Math.min(health, 100); } @@ -92,6 +97,7 @@ private void startBattleWithDragon(Dragon dragon) { setImmobilized(true); dragon.setImmobilized(true); action = new AttackingAction(dragon); + LOGGER.trace("started battle with dragon"); new RecurringTask(() -> { if (dragon.isAlive()) { int harm = dragon.getLevel(); @@ -136,6 +142,7 @@ public void act() { world.setMessage(String.format("enemy health: %d", enemy.getHealth())); if (enemy.getHealth() < 0) { world.setMessage("You won!"); + LOGGER.trace("player won battle with dragon"); weapon = Weapon.getRandomOfLevel(enemy.getLevel() + 2); new DelayedTask(() -> world.setMessage(String.format("Obtained %s", weapon.getName())), 1000); world.getMobs().remove(enemy); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/SideEffect.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/SideEffect.java index 037e447..06c9c10 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/SideEffect.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/SideEffect.java @@ -3,9 +3,7 @@ import java.awt.event.KeyEvent; import java.util.function.Function; -/** - * Created by boris on 10.05.17. - */ + public enum SideEffect { IDENTITY(Function.identity()), diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Item.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Item.java index 876ed57..5057d34 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Item.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Item.java @@ -2,9 +2,7 @@ import java.awt.*; -/** - * Created by boris on 11.05.17. - */ + public interface Item { Color getColor(); String getName(); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/MedAid.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/MedAid.java index 6e60b52..985ac07 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/MedAid.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/MedAid.java @@ -2,9 +2,7 @@ import java.awt.*; -/** - * Created by boris on 11.05.17. - */ + public class MedAid implements Item { private int value = 50; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/ThrownItem.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/ThrownItem.java index c8efef5..5d736da 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/ThrownItem.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/ThrownItem.java @@ -3,9 +3,7 @@ import com.simiyutin.au.roguelike.models.Position; import com.simiyutin.au.roguelike.models.World; -/** - * Created by boris on 11.05.17. - */ + public class ThrownItem { public int x; public int y; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java index 1c371af..25b4a49 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java @@ -2,9 +2,7 @@ import java.awt.*; -/** - * Created by boris on 11.05.17. - */ + public class Weapon implements Item { private WeaponType type; private final int MAX_LEVEL = 10; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WeaponType.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WeaponType.java index 3fe544a..ea17f50 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WeaponType.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WeaponType.java @@ -4,9 +4,7 @@ import java.util.List; import java.util.Random; -/** - * Created by boris on 11.05.17. - */ + public enum WeaponType { HAND('h', "hand", 1, 10), SWORD('>', "sword", 10, 150); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/DeadScreen.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/DeadScreen.java index 6b0cdea..0b0f616 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/DeadScreen.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/DeadScreen.java @@ -1,24 +1,31 @@ package com.simiyutin.au.roguelike.screens; import asciiPanel.AsciiPanel; +import com.simiyutin.au.roguelike.Main; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.awt.event.KeyEvent; -/** - * Created by boris on 09.05.17. - */ + public class DeadScreen implements Screen { + private static final Logger LOGGER = LogManager.getLogger(DeadScreen.class); + + public DeadScreen() { + LOGGER.trace("player died"); + } + @Override public void display(AsciiPanel terminal) { print(terminal, "You are dead. Retry? [enter]"); - } @Override public Screen respondToUserInput(KeyEvent key) { switch (key.getKeyCode()) { case KeyEvent.VK_ENTER: + LOGGER.trace("player pressed retry button"); return new PlayScreen(); default: return this; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java index 7d4347f..d550db3 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java @@ -1,28 +1,31 @@ package com.simiyutin.au.roguelike.screens; import asciiPanel.AsciiPanel; +import com.simiyutin.au.roguelike.Main; import com.simiyutin.au.roguelike.models.*; import com.simiyutin.au.roguelike.models.beings.*; import com.simiyutin.au.roguelike.models.items.Item; import com.simiyutin.au.roguelike.models.items.ThrownItem; import com.simiyutin.au.roguelike.util.WorldFactory; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.awt.*; import java.awt.event.KeyEvent; -/** - * Created by boris on 08.05.17. - */ + public class PlayScreen implements Screen { private final World world; private final int screenWidth = 80; private final int screenHeight = 24; + private static final Logger LOGGER = LogManager.getLogger(PlayScreen.class); - public PlayScreen() { + public PlayScreen() { world = WorldFactory.getOfMinLevel(1); + LOGGER.trace("Game screen created"); } @Override diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/Screen.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/Screen.java index e8abe44..227376c 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/Screen.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/Screen.java @@ -4,9 +4,7 @@ import java.awt.event.KeyEvent; -/** - * Created by boris on 08.05.17. - */ + public interface Screen { void display(AsciiPanel terminal); Screen respondToUserInput(KeyEvent key); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/StartScreen.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/StartScreen.java index 02e5d4b..d2ade3e 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/StartScreen.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/StartScreen.java @@ -1,14 +1,20 @@ package com.simiyutin.au.roguelike.screens; import asciiPanel.AsciiPanel; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.awt.event.KeyEvent; -/** - * Created by boris on 08.05.17. - */ + public class StartScreen implements Screen { + private static final Logger LOGGER = LogManager.getLogger(StartScreen.class); + + public StartScreen() { + LOGGER.trace("start screen showed"); + } + @Override public void display(AsciiPanel terminal) { print(terminal, "Press [enter] to start"); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/Action.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/Action.java index ca6dad9..ed17fc9 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/Action.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/Action.java @@ -1,8 +1,6 @@ package com.simiyutin.au.roguelike.util; -/** - * Created by boris on 11.05.17. - */ + public interface Action { void act(); } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/DelayedTask.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/DelayedTask.java index 51c7611..91444af 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/DelayedTask.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/DelayedTask.java @@ -3,9 +3,7 @@ import java.util.Timer; import java.util.TimerTask; -/** - * Created by boris on 11.05.17. - */ + public class DelayedTask { public DelayedTask(Runnable task, long timeout) { diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomBGColorGenerator.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomBGColorGenerator.java index 6225d14..ebeb94e 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomBGColorGenerator.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomBGColorGenerator.java @@ -3,9 +3,7 @@ import java.awt.*; import java.util.Random; -/** - * Created by boris on 13.05.17. - */ + public class RandomBGColorGenerator { private final Random randomGen = new Random(42); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RecurringTask.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RecurringTask.java index c51dd98..5e90621 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RecurringTask.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RecurringTask.java @@ -2,9 +2,7 @@ import java.util.TimerTask; -/** - * Created by boris on 10.05.17. - */ + public class RecurringTask { public RecurringTask(Runnable task, long period) { diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java index ed75e6d..b7d46fc 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java @@ -1,6 +1,5 @@ package com.simiyutin.au.roguelike.util; -import com.simiyutin.au.roguelike.Main; import com.simiyutin.au.roguelike.models.Tile; import com.simiyutin.au.roguelike.models.World; import com.simiyutin.au.roguelike.models.beings.Being; @@ -18,9 +17,7 @@ import java.util.List; import java.util.Random; -/** - * Created by boris on 08.05.17. - */ + public class WorldBuilder { private int width; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java index e94a066..c09e5ac 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java @@ -6,9 +6,7 @@ import com.simiyutin.au.roguelike.models.beings.Ghost; import com.simiyutin.au.roguelike.models.beings.Mushroom; -/** - * Created by boris on 13.05.17. - */ + public class WorldFactory { public static World getOfMinLevel(int level) { World result = new WorldBuilder(100, 100) From 2a82807b214f36d21454dfe371a39001b79c2b77 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sun, 14 May 2017 15:20:24 +0300 Subject: [PATCH 56/63] ++ --- roguelike/impl/src/main/resources/todolist | 10 ++++++---- .../java/com/simiyutin/au/roguelike/WorldTests.java | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/roguelike/impl/src/main/resources/todolist b/roguelike/impl/src/main/resources/todolist index 9c3cfab..6a9ccf6 100644 --- a/roguelike/impl/src/main/resources/todolist +++ b/roguelike/impl/src/main/resources/todolist @@ -29,14 +29,16 @@ ОБЯЗАТЕЛЬНЫЕ ЗАДАНИЯ: -1. Юнит - тесты -2. Логирование (например, исключений) +--1. Юнит - тесты +--2. Логирование (например, исключений) БАГИ: -1. Не работает в русской раскладке +--1. Не работает в русской раскладке --2. В reversed состоянии не работает копание -3. После победы над драконом можно поднять меч более низкого уровня +--3. После победы над драконом можно поднять меч более низкого уровня +4. ConcurrentModificationException. хорошо воспроизводится на тесте testEmptyPosition + diff --git a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldTests.java b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldTests.java index fd349ab..344cbe2 100644 --- a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldTests.java +++ b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldTests.java @@ -23,7 +23,7 @@ public void testEmptyPosition() { .addMobs(Ghost.class, 100) .build(); - for (int i = 0; i < 10000; i++) { + for (int i = 0; i < 100000; i++) { Position position = world.getEmptyPosition(); assertTrue(world.getMob(position.x, position.y) == null); assertTrue(world.getItem(position.x, position.y) == null); From 01b84605eba3f3a3f25c07e23302b359f7f68364 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sun, 14 May 2017 15:35:17 +0300 Subject: [PATCH 57/63] Create README.md --- roguelike/impl/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 roguelike/impl/README.md diff --git a/roguelike/impl/README.md b/roguelike/impl/README.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/roguelike/impl/README.md @@ -0,0 +1 @@ + From 5d3244803060e48b0e3c52bb61da2bb48ee957f4 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sun, 14 May 2017 15:50:04 +0300 Subject: [PATCH 58/63] Update README.md --- roguelike/impl/README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/roguelike/impl/README.md b/roguelike/impl/README.md index 8b13789..91d36a5 100644 --- a/roguelike/impl/README.md +++ b/roguelike/impl/README.md @@ -1 +1,14 @@ - +## ROGUELIKE +### Управление +1. Передвижение: клавиши A, W, S, D +2. В стенах можно копать ходы - для этого надо стоя рядом с ней шагнуть в ее сторону еще раз и нажать [enter] +### Мобы +1. Гриб (M): Статический моб, отравляет территорию вокруг себя. +2. Призрак (G): Когда оказывается рядом с игроком, начинает за ним гнаться, и если догоняет, то инвертирует клавиши управления и начинает убегать. Если после этого игрок догоняет призрака, то призрак исчезает и управление возвращается к исходному. +3. Дракон (D): Случайно блуждает по карте, поджигая за собой пол. Можно сразиться с драконом, встав рядом, и зажав [enter], и получить от него оружие более высокого уровня (но это не точно). После победы над всеми драконами на уровне открывается переход на новый уровень (Z), который надо найти на карте. +### Предметы +По карте разбросаны: +* Аптечки +* Оружие +### Уровни +Каждый новый уровень отличается от предыдущего количеством урона, которое игрок наносит драконам или получает при схватках и хождении по отравленным или подожженным тайлам. При этом максимальный уровень здоровья и его количество, восстанавливаемое одной аптечкой не изменяются. From edfb7e9fe013b93f16259a303965d4524c041c21 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sun, 28 May 2017 01:40:04 +0300 Subject: [PATCH 59/63] inventory --- roguelike/arch/roguelike_class_diagram.vpp | Bin 686080 -> 701440 bytes roguelike/impl/pom.xml | 11 +++- .../au/roguelike/models/beings/Player.java | 56 ++++++++++++++++-- .../au/roguelike/models/items/Weapon.java | 26 +++++++- .../au/roguelike/screens/PlayScreen.java | 12 ++-- roguelike/impl/src/main/resources/log4j2.xml | 2 +- 6 files changed, 91 insertions(+), 16 deletions(-) diff --git a/roguelike/arch/roguelike_class_diagram.vpp b/roguelike/arch/roguelike_class_diagram.vpp index bc48460c1c1364b657a400ba6bec9d833be9d484..bfe5c632ab2af53edf01539ca811ba876f867fa3 100644 GIT binary patch delta 15273 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 delta 2091 zcmZvde{9r67QnwVZ+82g0opB4S7aBq+bylot_Ljy)PR)+ihyEUq{L#aAhfkDEiG*2 zM=7=x@W3lf+v!!{DwZE|+?{r72ctw3xd_3FUNMI`6~a%6{R0yuM(S~I)+I5K&3?Y~ z=FQBT_kC~Pd>g(S-*Dr>meKJkmPPj>TP(|(jCgjYWssD2p5G6QOtOfI&nJn}m+6tS z*g$wv^%+X7i#;~;jTr)`aJuys+=g550}Q}5xCr0CIp~Lf!KrY3=3x>(^Waa!k^FJf zdw&m~nlL4mgnIJb!}Wd5aGms&*mfEWTB&FQeXzzM$w&Z6ingY2^kzI&lXkd6R6{4k zsmD^pan;`eKgUu+?O`}6=dzjhDSg@>VbCV^h_sTy=d-%k8S$X+I*>kdH=Vr}Er^xs6 z;g$>%kd-ZO$lDtpC#iCJ{RHBbW%Vn_n()8t)5(y~U2n)Sj6s;_V+rs$9a1Wcaohq1 zP<;`?16wxP5li1kp1tANU9$;Eme0tEBt>qOjifp}v{lfsd;H&sJfSA~3u4gS8V5cW zk-OIDCv<=gLJE8V8{sYGIz%4{`!Z{&ba%RCeWxqIj)Nq!a#clDapjA_x{C6c@vxZ4 z#L97U-0R;qvaT(xi)hwGX_a$|MW#SHhH!`avkUgbyq`b9QE@9rJr)l+y7Cj=O-zK& zsq_)hk6u_`mT9&fv)^|=z*Ks*NVBb`mk-ni>z^H(wP4p}!ojSW7ClXuSnpUf(SC-S z|2&j)>-?JuZb#n9W%_sL2>&DhY8Iv@|i`wbRpeAPtyOA zAIWF*CNOviN?|{I5%#D3mB<+wp2fL?3VY&X9RCL-VM)9mZ0e7#Sz3sKps(d;tH z&E5EC&E1aXZfA3MOkcOnTnE_^&JMDpc9)Zo(-t|cMI9U`@^st0Nb1#zEs$~F?2hbR ze$4;U)h3>l9I~jJ9MVJI=DP{4h*47U3cGQ+)48~LeO%aAd4Z7CeI&O6e*^ zSMXm*u&;#U8!SFh&QsezuyOb(AB6UDfl>#0NS61#&9U;!w4)BQr|*2o32Q%UGg7Bn zlZd<~eQ5}$Ix1I6%yU#O{}vAf$|jSoniZN@t<3T)N@ex&QQDg$t^%pmEE~=A)G`}SE1yP5s+zu!W9_N3 zef)0mIYPK@tqujmHZa#iq`=qdP->*#%_IHwDwHNp#7&)?k>(RT@|!ksvYwMJG>s%y zVPY3?w6vjkSzhT{_1t(dMz*YS>BGJJ8Bpx=U+vWE(B~ZY$^DX#R%6fd0^{^XnYC(! ze)TM018UA(FSo)AuEwq zMZXC@<(%RUN6&%jwj3p3Z}&BL&4;ZZh-QOqpWaZpso{WlD80Ql6brQ?Hx4!lB*2 REw(+TW>L9Uvm;_K=KnZ_No)WB diff --git a/roguelike/impl/pom.xml b/roguelike/impl/pom.xml index 4a8acd9..d7ae642 100644 --- a/roguelike/impl/pom.xml +++ b/roguelike/impl/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 @@ -77,5 +77,12 @@ log4j-core 2.8.1 + + + com.google.guava + guava + 22.0 + + \ No newline at end of file diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java index aab14f1..b464cb0 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java @@ -1,5 +1,6 @@ package com.simiyutin.au.roguelike.models.beings; +import com.google.common.collect.Iterators; import com.simiyutin.au.roguelike.models.Position; import com.simiyutin.au.roguelike.models.Tile; import com.simiyutin.au.roguelike.models.World; @@ -12,21 +13,26 @@ import org.apache.logging.log4j.Logger; import java.awt.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; public class Player extends ActiveBeing { + private static final Logger LOGGER = LogManager.getLogger(Player.class); private Weapon weapon; + private Iterator weaponIterator; private Action action; - private static final Logger LOGGER = LogManager.getLogger(Player.class); - public Player(World world) { super(world); this.glyph = 'X'; this.color = Color.BLUE; this.weapon = WeaponType.HAND.getItem(); + this.weaponIterator = Iterators.cycle(this.weapon); this.action = new RegularAction(); } @@ -49,6 +55,45 @@ public Weapon getWeapon() { return weapon; } + public void changeWeapon() { + weapon = weaponIterator.next(); + } + + private void addWeapon(Weapon newWeapon) { + java.util.List a = new ArrayList<>(); + a.add(1); + a.add(2); + + java.util.List b = new ArrayList<>(); + a.add(3); + a.add(4); + + Iterator it = Iterators.concat(a.iterator(), b.iterator()); + + while (it.hasNext()) { + System.out.println(it.next()); + } + + Set weapons = linearizeWeapons(); + weapons.add(newWeapon); + + weaponIterator = Iterators.cycle(weapons); + } + + private Set linearizeWeapons() { + Set list = new HashSet<>(); + Weapon fst = weaponIterator.next(); + + list.add(fst); + Weapon next = weaponIterator.next(); + while (next != fst) { + list.add(next); + next = weaponIterator.next(); + } + + return list; + } + @Override public void interactWithEnvironment() { int deltaHealth = world.getTile(x, y).getDeltaHealth(); @@ -59,7 +104,7 @@ public void interactWithEnvironment() { Item item = thrownItem.getItem(); if (item instanceof Weapon) { LOGGER.trace(String.format("picked up weapon: %s", item.getName())); - weapon = (Weapon) item; + addWeapon((Weapon) item); world.getItems().removeIf(w -> w.getItem() instanceof Weapon && ((Weapon) w.getItem()).getLevel() <= weapon.getLevel()); } else if (item instanceof MedAid) { @@ -143,8 +188,9 @@ public void act() { if (enemy.getHealth() < 0) { world.setMessage("You won!"); LOGGER.trace("player won battle with dragon"); - weapon = Weapon.getRandomOfLevel(enemy.getLevel() + 2); - new DelayedTask(() -> world.setMessage(String.format("Obtained %s", weapon.getName())), 1000); + Weapon newWeapon = Weapon.getRandomOfLevel(enemy.getLevel() + 2); + addWeapon(newWeapon); + new DelayedTask(() -> world.setMessage(String.format("Obtained %s", newWeapon.getName())), 1000); world.getMobs().remove(enemy); enemy.setAlive(false); setImmobilized(false); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java index 25b4a49..2af9b9d 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java @@ -4,8 +4,8 @@ public class Weapon implements Item { - private WeaponType type; private final int MAX_LEVEL = 10; + private WeaponType type; private int level; // 1 - 10 public Weapon(WeaponType type, int level) { @@ -13,6 +13,10 @@ public Weapon(WeaponType type, int level) { this.level = level; } + public static Weapon getRandomOfLevel(int level) { + return new Weapon(WeaponType.getRandom(), level); + } + public Color getColor() { int brightness = 150 + level / MAX_LEVEL * 100; return Color.getHSBColor(type.getHue(), 200, brightness); @@ -35,7 +39,23 @@ public int getLevel() { return level; } - public static Weapon getRandomOfLevel(int level) { - return new Weapon(WeaponType.getRandom(), level); + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Weapon weapon = (Weapon) o; + + if (MAX_LEVEL != weapon.MAX_LEVEL) return false; + if (level != weapon.level) return false; + return type == weapon.type; + } + + @Override + public int hashCode() { + int result = type != null ? type.hashCode() : 0; + result = 31 * result + MAX_LEVEL; + result = 31 * result + level; + return result; } } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java index d550db3..434c9b5 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java @@ -1,26 +1,25 @@ package com.simiyutin.au.roguelike.screens; import asciiPanel.AsciiPanel; -import com.simiyutin.au.roguelike.Main; -import com.simiyutin.au.roguelike.models.*; -import com.simiyutin.au.roguelike.models.beings.*; +import com.simiyutin.au.roguelike.models.World; +import com.simiyutin.au.roguelike.models.beings.Being; +import com.simiyutin.au.roguelike.models.beings.Player; import com.simiyutin.au.roguelike.models.items.Item; import com.simiyutin.au.roguelike.models.items.ThrownItem; import com.simiyutin.au.roguelike.util.WorldFactory; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; - import java.awt.*; import java.awt.event.KeyEvent; public class PlayScreen implements Screen { + private static final Logger LOGGER = LogManager.getLogger(PlayScreen.class); private final World world; private final int screenWidth = 80; private final int screenHeight = 24; - private static final Logger LOGGER = LogManager.getLogger(PlayScreen.class); public PlayScreen() { @@ -64,6 +63,9 @@ public Screen respondToUserInput(KeyEvent key) { case KeyEvent.VK_Z: world.getPlayer().levelUp(); break; + case KeyEvent.VK_I: + world.getPlayer().changeWeapon(); + break; } return updateState(); } diff --git a/roguelike/impl/src/main/resources/log4j2.xml b/roguelike/impl/src/main/resources/log4j2.xml index 12f2d3f..58b0db9 100644 --- a/roguelike/impl/src/main/resources/log4j2.xml +++ b/roguelike/impl/src/main/resources/log4j2.xml @@ -1,5 +1,5 @@ - + From 4251b1a1b8b0e6788c8cfd284b097badba9481b9 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sun, 28 May 2017 01:58:35 +0300 Subject: [PATCH 60/63] Update README.md --- roguelike/impl/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/roguelike/impl/README.md b/roguelike/impl/README.md index 91d36a5..0d9c317 100644 --- a/roguelike/impl/README.md +++ b/roguelike/impl/README.md @@ -2,6 +2,7 @@ ### Управление 1. Передвижение: клавиши A, W, S, D 2. В стенах можно копать ходы - для этого надо стоя рядом с ней шагнуть в ее сторону еще раз и нажать [enter] +3. Смена оружия: клавиша I ### Мобы 1. Гриб (M): Статический моб, отравляет территорию вокруг себя. 2. Призрак (G): Когда оказывается рядом с игроком, начинает за ним гнаться, и если догоняет, то инвертирует клавиши управления и начинает убегать. Если после этого игрок догоняет призрака, то призрак исчезает и управление возвращается к исходному. From 9e0f6c7ddd3c561eb13af3c951b29e60adf52431 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sun, 28 May 2017 02:01:46 +0300 Subject: [PATCH 61/63] trash code removed --- .../au/roguelike/models/beings/Player.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java index b464cb0..866296a 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java @@ -13,7 +13,6 @@ import org.apache.logging.log4j.Logger; import java.awt.*; -import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.Set; @@ -60,20 +59,6 @@ public void changeWeapon() { } private void addWeapon(Weapon newWeapon) { - java.util.List a = new ArrayList<>(); - a.add(1); - a.add(2); - - java.util.List b = new ArrayList<>(); - a.add(3); - a.add(4); - - Iterator it = Iterators.concat(a.iterator(), b.iterator()); - - while (it.hasNext()) { - System.out.println(it.next()); - } - Set weapons = linearizeWeapons(); weapons.add(newWeapon); From 99ed175cceda4121b2cacb375791f53a6026caed Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sun, 28 May 2017 12:17:50 +0300 Subject: [PATCH 62/63] comments --- .../com/simiyutin/au/roguelike/Scheduler.java | 13 ++-- .../simiyutin/au/roguelike/models/Action.java | 9 +++ .../au/roguelike/models/Position.java | 3 + .../simiyutin/au/roguelike/models/Tile.java | 16 +++-- .../simiyutin/au/roguelike/models/World.java | 60 +++++++++++++++---- .../roguelike/models/beings/ActiveBeing.java | 17 ++++-- .../models/beings/ArtificialIntelligence.java | 3 + .../au/roguelike/models/beings/Being.java | 6 +- .../au/roguelike/models/beings/Dragon.java | 14 +++-- .../au/roguelike/models/beings/Ghost.java | 9 ++- .../au/roguelike/models/beings/Mushroom.java | 3 + .../au/roguelike/models/beings/Player.java | 27 +++++++-- .../roguelike/models/beings/SideEffect.java | 3 + .../au/roguelike/models/items/Item.java | 5 ++ .../au/roguelike/models/items/MedAid.java | 6 ++ .../au/roguelike/models/items/ThrownItem.java | 3 + .../au/roguelike/models/items/Weapon.java | 9 +++ .../au/roguelike/models/items/WeaponType.java | 18 ++++-- .../au/roguelike/screens/DeadScreen.java | 4 +- .../au/roguelike/screens/PlayScreen.java | 7 ++- .../au/roguelike/screens/Screen.java | 19 ++++++ .../au/roguelike/screens/StartScreen.java | 3 + .../simiyutin/au/roguelike/util/Action.java | 6 -- .../au/roguelike/util/DelayedTask.java | 3 + .../util/RandomBGColorGenerator.java | 3 + .../au/roguelike/util/RecurringTask.java | 3 + .../au/roguelike/util/WorldBuilder.java | 25 ++++++-- .../au/roguelike/util/WorldFactory.java | 25 +++----- .../com/simiyutin/au/roguelike/MobsTests.java | 8 +-- .../au/roguelike/WorldBuilderTests.java | 10 ++-- 30 files changed, 256 insertions(+), 84 deletions(-) create mode 100644 roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Action.java delete mode 100644 roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/Action.java diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Scheduler.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Scheduler.java index 0908d06..8ebd91c 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Scheduler.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/Scheduler.java @@ -13,12 +13,14 @@ import java.lang.reflect.InvocationTargetException; +/** + * Routes user input to current Screen object, iterates Screen periodically and repaints it. + */ public class Scheduler extends JFrame implements KeyListener { + private static final Logger LOGGER = LogManager.getLogger(Scheduler.class); private AsciiPanel terminal; private Screen screen; - private static final Logger LOGGER = LogManager.getLogger(Scheduler.class); - public Scheduler() { super(); @@ -33,7 +35,7 @@ public Scheduler() { setVisible(true); } - public void run() { + private void iterate() { try { SwingUtilities.invokeAndWait(() -> { screen = screen.updateState(); @@ -44,8 +46,11 @@ public void run() { } } + /** + * Begin iterating state. + */ public void schedule() { - new RecurringTask(this::run, 1000 / 60); + new RecurringTask(this::iterate, 1000 / 60); } @Override diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Action.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Action.java new file mode 100644 index 0000000..ab04de0 --- /dev/null +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Action.java @@ -0,0 +1,9 @@ +package com.simiyutin.au.roguelike.models; + + +/** + * Action that player object will do after human player pressed [enter] + */ +public interface Action { + void act(); +} diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Position.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Position.java index 5fcfa20..fc574f2 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Position.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Position.java @@ -1,6 +1,9 @@ package com.simiyutin.au.roguelike.models; +/** + * Position itself. + */ public class Position { public int x; public int y; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Tile.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Tile.java index ce79dca..8640ba7 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Tile.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/Tile.java @@ -5,10 +5,13 @@ import java.awt.*; +/** + * Describes tiles the world can be built from. + */ public enum Tile { FLOOR('.', AsciiPanel.yellow, 0, true), POISONED_FLOOR('.', Color.GREEN, -5, true), - ENFLAMED_FLOOR('.', Color.RED, -5, true), + INFLAMED_FLOOR('.', Color.RED, -5, true), WALL('#', AsciiPanel.yellow, 0, false), Z_TELEPORT('Z', AsciiPanel.brightMagenta, 0, true), BOUNDS('x', AsciiPanel.brightBlack, 0, false); @@ -25,10 +28,6 @@ public enum Tile { this.isWalkable = isWalkable; } - public void setColor(Color color) { - this.color = color; - } - public char getGlyph() { return glyph; } @@ -37,6 +36,13 @@ public Color getColor() { return color; } + public void setColor(Color color) { + this.color = color; + } + + /** + * @return amount of health that will be applied to player's health after stepping onto tile. + */ public int getDeltaHealth() { return deltaHealth; } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java index 6b969a3..855838a 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/World.java @@ -1,17 +1,20 @@ package com.simiyutin.au.roguelike.models; -import com.simiyutin.au.roguelike.util.DelayedTask; import com.simiyutin.au.roguelike.models.beings.Being; import com.simiyutin.au.roguelike.models.beings.Player; import com.simiyutin.au.roguelike.models.items.ThrownItem; +import com.simiyutin.au.roguelike.util.DelayedTask; -import java.awt.Color; +import java.awt.*; import java.util.ArrayList; import java.util.List; import java.util.Random; +/** + * Holds map, player, mobs and loot. + */ public class World { private WorldData d; @@ -23,15 +26,18 @@ public World(Tile[][] tiles) { this.d.height = tiles[0].length; this.d.mobs = new ArrayList<>(); - this.d.loot = new ArrayList<>(); + this.d.thrownItems = new ArrayList<>(); this.d.minLevel = 1; this.d.player = new Player(this); } - public List getItems() { - return d.loot; + public List getThrownItems() { + return d.thrownItems; } + /** + * minLevel defines minimum level of items and mobs. + */ public int getMinLevel() { return d.minLevel; } @@ -40,6 +46,9 @@ public void setMinLevel(int minLevel) { this.d.minLevel = minLevel; } + /** + * @return message that will be displayed on top of a screen. + */ public String getMessage() { return d.message; } @@ -53,6 +62,9 @@ public void setMessage(String message) { }, 1000); } + /** + * @return Tile at given position. + */ public Tile getTile(int x, int y) { if (x < 0 || x > getWidth() - 1 || y < 0 || y > getHeight() - 1) { return Tile.BOUNDS; @@ -64,6 +76,9 @@ public void setTile(int x, int y, Tile tile) { d.tiles[x][y] = tile; } + /** + * Print current map co console. + */ public void printTiles() { for (int i = 0; i < d.width; i++) { for (int j = 0; j < d.height; j++) { @@ -73,10 +88,16 @@ public void printTiles() { } } + /** + * @return glyph of the tile at given position. + */ public char getGlyph(int x, int y) { return getTile(x, y).getGlyph(); } + /** + * @return color of the tile at given position. + */ public Color getColor(int x, int y) { return getTile(x, y).getColor(); } @@ -93,10 +114,17 @@ public Player getPlayer() { return d.player; } + public void setPlayer(Player player) { + d.player = player; + } + public List getMobs() { return d.mobs; } + /** + * @return mob at given position. (except player) + */ public Being getMob(int x, int y) { for (Being b : getMobs()) { if (b.x == x && b.y == y) { @@ -106,8 +134,11 @@ public Being getMob(int x, int y) { return null; } + /** + * @return thrown item at given position. + */ public ThrownItem getItem(int x, int y) { - for (ThrownItem b : getItems()) { + for (ThrownItem b : getThrownItems()) { if (b.x == x && b.y == y) { return b; } @@ -115,6 +146,9 @@ public ThrownItem getItem(int x, int y) { return null; } + /** + * @return walkable position free of mobs. + */ public Position getEmptyPosition() { Random randomGen = new Random(); @@ -131,10 +165,9 @@ public Position getEmptyPosition() { return new Position(x, y); } - public void setPlayer(Player player) { - d.player = player; - } - + /** + * Set all tiles in given radius to given type. + */ public void setTilesAround(int x, int y, int radius, Tile tile) { for (int i = -radius; i <= radius; i++) { for (int j = -radius; j <= radius; j++) { @@ -147,6 +180,9 @@ public void setTilesAround(int x, int y, int radius, Tile tile) { } } + /** + * move data from another world to current. + */ public void moveDataFrom(World other) { d = other.d; } @@ -155,7 +191,7 @@ public void moveDataFrom(World other) { private boolean isEmptyFloor(int x, int y) { return getTile(x, y) == Tile.FLOOR && getMobs().stream().noneMatch(b -> b.x == x && b.y == y) - && getItems().stream().noneMatch(b -> b.x == x && b.y == y); + && getThrownItems().stream().noneMatch(b -> b.x == x && b.y == y); } private static class WorldData { @@ -165,7 +201,7 @@ private static class WorldData { private Player player; private List mobs; private String message = ""; - private List loot; + private List thrownItems; private int minLevel; } } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java index 7c256f0..e8b1c43 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ActiveBeing.java @@ -5,6 +5,9 @@ import java.util.Random; +/** + * Beings that can move and interact with environment + */ public abstract class ActiveBeing extends Being { protected int xDirection; @@ -48,6 +51,9 @@ public void setHealth(int health) { this.health = health; } + /** + * Try to move being by given delta + */ public void move(int dx, int dy) { if (immobilized) { return; @@ -66,16 +72,19 @@ public SideEffect getEffect() { return effect; } + protected void setEffect(SideEffect effect) { + this.effect = effect; + } + + /** + * Check if map at given position is walkable and free from other mobs + */ public boolean canMove(int xTo, int yTo) { return world.getTile(xTo, yTo).isWalkable() && world.getMob(xTo, yTo) == null; } public abstract void interactWithEnvironment(); - protected void setEffect(SideEffect effect) { - this.effect = effect; - } - protected void moveRandom() { move(new Random().nextInt(3) - 1, new Random().nextInt(3) - 1); } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ArtificialIntelligence.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ArtificialIntelligence.java index c0e7924..1122d92 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ArtificialIntelligence.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/ArtificialIntelligence.java @@ -1,6 +1,9 @@ package com.simiyutin.au.roguelike.models.beings; +/** + * Specifies way for AI to act + */ public interface ArtificialIntelligence { void move(); } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Being.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Being.java index cb34242..5232f53 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Being.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Being.java @@ -6,13 +6,15 @@ import java.awt.*; +/** + * Base being class. This beings can only exist at given position/ + */ public abstract class Being { + protected final World world; public int x; public int y; - protected char glyph; protected Color color; - protected final World world; public Being(World world) { this.world = world; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java index c71619d..7ac590b 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Dragon.java @@ -1,12 +1,16 @@ package com.simiyutin.au.roguelike.models.beings; -import com.simiyutin.au.roguelike.util.RecurringTask; import com.simiyutin.au.roguelike.models.Tile; import com.simiyutin.au.roguelike.models.World; +import com.simiyutin.au.roguelike.util.RecurringTask; import java.awt.*; +/** + * Walking mob with AI. It moves randomly, inflames floor below. When getting close, player can attack dragon, + * and if wins, gets weapon. + */ public class Dragon extends ActiveBeing implements ArtificialIntelligence { public static boolean isSelfActing = true; @@ -16,7 +20,7 @@ public Dragon(World world) { this.glyph = 'D'; this.color = Color.RED; - enflameTiles(); + inflameTiles(); if (isSelfActing) { @@ -32,7 +36,7 @@ public void move() { @Override public void move(int dx, int dy) { super.move(dx, dy); - enflameTiles(); + inflameTiles(); } @Override @@ -40,7 +44,7 @@ public void interactWithEnvironment() { } - private void enflameTiles() { - world.setTilesAround(x, y, 0, Tile.ENFLAMED_FLOOR); + private void inflameTiles() { + world.setTilesAround(x, y, 0, Tile.INFLAMED_FLOOR); } } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Ghost.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Ghost.java index 7a25a74..ae0df25 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Ghost.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Ghost.java @@ -1,7 +1,7 @@ package com.simiyutin.au.roguelike.models.beings; -import com.simiyutin.au.roguelike.util.RecurringTask; import com.simiyutin.au.roguelike.models.World; +import com.simiyutin.au.roguelike.util.RecurringTask; import java.awt.*; @@ -9,13 +9,16 @@ import static com.simiyutin.au.roguelike.models.beings.SideEffect.INVERSED; +/** + * Walking mob with AI. It moves randomly, if smells player, chases him. + * On success, Ghost inverts controls of a player and starts to run away. So do all other Ghosts on the map . + */ public class Ghost extends ActiveBeing implements ArtificialIntelligence { - private static boolean moveTo = true; - public static final int SMELL_RANGE = 15; public static final int TRIGGER_RANGE = 3; public static boolean isSelfActing = true; + private static boolean moveTo = true; public Ghost(World world) { super(world); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Mushroom.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Mushroom.java index e489f89..7f4ab47 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Mushroom.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Mushroom.java @@ -6,6 +6,9 @@ import java.awt.*; +/** + * Static being. Poisons tiles around self and does nothing else. + */ public class Mushroom extends Being { public Mushroom(World world) { diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java index 866296a..99ca8f6 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java @@ -1,11 +1,11 @@ package com.simiyutin.au.roguelike.models.beings; import com.google.common.collect.Iterators; +import com.simiyutin.au.roguelike.models.Action; import com.simiyutin.au.roguelike.models.Position; import com.simiyutin.au.roguelike.models.Tile; import com.simiyutin.au.roguelike.models.World; import com.simiyutin.au.roguelike.models.items.*; -import com.simiyutin.au.roguelike.util.Action; import com.simiyutin.au.roguelike.util.DelayedTask; import com.simiyutin.au.roguelike.util.RecurringTask; import com.simiyutin.au.roguelike.util.WorldFactory; @@ -18,6 +18,9 @@ import java.util.Set; +/** + * Player himself. Can move around, pick up weapons and health packs, dig through walls and attack dragons. + */ public class Player extends ActiveBeing { private static final Logger LOGGER = LogManager.getLogger(Player.class); @@ -35,9 +38,13 @@ public Player(World world) { this.action = new RegularAction(); } + + /** + * Each level of player is followed by world of incremented level. + */ public void levelUp() { level++; - World newWorld = WorldFactory.getOfMinLevel(world.getMinLevel() + 1); + World newWorld = WorldFactory.getDefaultConfigurationOfMinLevel(world.getMinLevel() + 1); Position pos = newWorld.getEmptyPosition(); x = pos.x; y = pos.y; @@ -46,6 +53,10 @@ public void levelUp() { LOGGER.trace("player level upped"); } + + /** + * Do something on pressing [enter] key. "something" is taken from context. + */ public void act() { action.act(); } @@ -67,8 +78,8 @@ private void addWeapon(Weapon newWeapon) { private Set linearizeWeapons() { Set list = new HashSet<>(); - Weapon fst = weaponIterator.next(); + Weapon fst = weaponIterator.next(); list.add(fst); Weapon next = weaponIterator.next(); while (next != fst) { @@ -90,7 +101,7 @@ public void interactWithEnvironment() { if (item instanceof Weapon) { LOGGER.trace(String.format("picked up weapon: %s", item.getName())); addWeapon((Weapon) item); - world.getItems().removeIf(w -> + world.getThrownItems().removeIf(w -> w.getItem() instanceof Weapon && ((Weapon) w.getItem()).getLevel() <= weapon.getLevel()); } else if (item instanceof MedAid) { LOGGER.trace("picked up med aid"); @@ -98,7 +109,7 @@ public void interactWithEnvironment() { health = Math.min(health, 100); } world.setMessage(String.format("picked %s", item.getName())); - world.getItems().remove(thrownItem); + world.getThrownItems().remove(thrownItem); } Being being = getMobNearMe(); @@ -140,6 +151,9 @@ private double distTo(int toX, int toY) { return Math.hypot(toX - x, toY - y); } + /** + * Describes how to act in normal mode. + */ class RegularAction implements Action { @Override @@ -157,6 +171,9 @@ public void act() { } } + /** + * Describes how to act in attacking mode. + */ class AttackingAction implements Action { private ActiveBeing enemy; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/SideEffect.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/SideEffect.java index 06c9c10..e3874b8 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/SideEffect.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/SideEffect.java @@ -4,6 +4,9 @@ import java.util.function.Function; +/** + * Entity that maps user input to one of predefined profiles. + */ public enum SideEffect { IDENTITY(Function.identity()), diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Item.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Item.java index 5057d34..ef0601c 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Item.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Item.java @@ -3,8 +3,13 @@ import java.awt.*; +/** + * Some object that can be useful for player. + */ public interface Item { Color getColor(); + String getName(); + char getGlyph(); } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/MedAid.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/MedAid.java index 985ac07..07a5134 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/MedAid.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/MedAid.java @@ -3,6 +3,9 @@ import java.awt.*; +/** + * Health pack. + */ public class MedAid implements Item { private int value = 50; @@ -22,6 +25,9 @@ public char getGlyph() { return '+'; } + /** + * @return how much health player will recover after picking this medAid up. + */ public int getValue() { return value; } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/ThrownItem.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/ThrownItem.java index 5d736da..c23a083 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/ThrownItem.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/ThrownItem.java @@ -4,6 +4,9 @@ import com.simiyutin.au.roguelike.models.World; +/** + * Wrapper around Item that holds position on the map. + */ public class ThrownItem { public int x; public int y; diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java index 2af9b9d..2047869 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/Weapon.java @@ -3,6 +3,9 @@ import java.awt.*; +/** + * Weapon itself. + */ public class Weapon implements Item { private final int MAX_LEVEL = 10; private WeaponType type; @@ -13,6 +16,9 @@ public Weapon(WeaponType type, int level) { this.level = level; } + /** + * Get weapon of random type of given level. + */ public static Weapon getRandomOfLevel(int level) { return new Weapon(WeaponType.getRandom(), level); } @@ -27,6 +33,9 @@ public String getName() { // todo handle level name correlation return type.getName() + String.format(" of level %d", level); } + /** + * @return measure of harm this weapon can damage. + */ public int getHarm() { return type.getHarm(); } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WeaponType.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WeaponType.java index ea17f50..1caa7e9 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WeaponType.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/items/WeaponType.java @@ -5,6 +5,9 @@ import java.util.Random; +/** + * Specifies glyph, color and initial damage of weapon of given type. + */ public enum WeaponType { HAND('h', "hand", 1, 10), SWORD('>', "sword", 10, 150); @@ -21,6 +24,15 @@ public enum WeaponType { this.hue = hue; } + /** + * @return random weapon except "HAND" + */ + public static WeaponType getRandom() { + List types = Arrays.asList(SWORD); + Integer ind = new Random().nextInt(types.size()); + return types.get(ind); + } + public String getName() { return name; } @@ -40,10 +52,4 @@ public int getHue() { public Weapon getItem() { return new Weapon(this, 1); } - - public static WeaponType getRandom() { - List types = Arrays.asList(SWORD); - Integer ind = new Random().nextInt(types.size()); - return types.get(ind); - } } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/DeadScreen.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/DeadScreen.java index 0b0f616..af3857d 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/DeadScreen.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/DeadScreen.java @@ -1,13 +1,15 @@ package com.simiyutin.au.roguelike.screens; import asciiPanel.AsciiPanel; -import com.simiyutin.au.roguelike.Main; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.awt.event.KeyEvent; +/** + * "You are dead. Retry?" screen + */ public class DeadScreen implements Screen { private static final Logger LOGGER = LogManager.getLogger(DeadScreen.class); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java index 434c9b5..567cf5c 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/PlayScreen.java @@ -14,6 +14,9 @@ import java.awt.event.KeyEvent; +/** + * Main screen where all the business takes place. + */ public class PlayScreen implements Screen { private static final Logger LOGGER = LogManager.getLogger(PlayScreen.class); @@ -23,7 +26,7 @@ public class PlayScreen implements Screen { public PlayScreen() { - world = WorldFactory.getOfMinLevel(1); + world = WorldFactory.getDefaultConfigurationOfMinLevel(1); LOGGER.trace("Game screen created"); } @@ -99,7 +102,7 @@ private void displayWorld(AsciiPanel terminal, int left, int top) { } private void displayLoot(AsciiPanel terminal, int left, int top) { - for (ThrownItem b: world.getItems()) { + for (ThrownItem b : world.getThrownItems()) { Item item = b.getItem(); writeSafe(terminal, item.getGlyph(), b.x - left, b.y - top, item.getColor()); } diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/Screen.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/Screen.java index 227376c..82823d9 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/Screen.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/Screen.java @@ -5,10 +5,29 @@ import java.awt.event.KeyEvent; +/** + * Representation of the game is split into screens. + * Each of them has its purpose, can be drawn, and reacts to user input. + */ public interface Screen { + /** + * print screen representation to terminal + */ void display(AsciiPanel terminal); + + /** + * Change state according to user input and return self. + */ Screen respondToUserInput(KeyEvent key); + + /** + * Change state according to time passed and return self. + */ Screen updateState(); + + /** + * Print message to terminal + */ default void print(AsciiPanel terminal, String str) { final int onHeight = 18; terminal.writeCenter(str, onHeight); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/StartScreen.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/StartScreen.java index d2ade3e..7406ff0 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/StartScreen.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/screens/StartScreen.java @@ -7,6 +7,9 @@ import java.awt.event.KeyEvent; +/** + * "Press [enter] to start" screen. + */ public class StartScreen implements Screen { private static final Logger LOGGER = LogManager.getLogger(StartScreen.class); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/Action.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/Action.java deleted file mode 100644 index ed17fc9..0000000 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/Action.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.simiyutin.au.roguelike.util; - - -public interface Action { - void act(); -} diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/DelayedTask.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/DelayedTask.java index 91444af..a6f0d4d 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/DelayedTask.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/DelayedTask.java @@ -4,6 +4,9 @@ import java.util.TimerTask; +/** + * Runnable with delayed start. + */ public class DelayedTask { public DelayedTask(Runnable task, long timeout) { diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomBGColorGenerator.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomBGColorGenerator.java index ebeb94e..a5fd9ab 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomBGColorGenerator.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RandomBGColorGenerator.java @@ -4,6 +4,9 @@ import java.util.Random; +/** + * Generates color from preset color range. + */ public class RandomBGColorGenerator { private final Random randomGen = new Random(42); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RecurringTask.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RecurringTask.java index 5e90621..646e7ec 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RecurringTask.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/RecurringTask.java @@ -3,6 +3,9 @@ import java.util.TimerTask; +/** + * Runnable with period of repetition. + */ public class RecurringTask { public RecurringTask(Runnable task, long period) { diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java index b7d46fc..08b1064 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldBuilder.java @@ -18,17 +18,19 @@ import java.util.Random; +/** + * Builds world. (!) + */ public class WorldBuilder { + private static final RandomBGColorGenerator colorGen = new RandomBGColorGenerator(); + private static final Logger LOGGER = LogManager.getLogger(WorldBuilder.class); private int width; private int height; private Tile[][] tiles; private List> mobs; private List loot; private int minLevel; - private static final RandomBGColorGenerator colorGen = new RandomBGColorGenerator(); - - private static final Logger LOGGER = LogManager.getLogger(WorldBuilder.class); public WorldBuilder(int width, int height) { this.width = width; @@ -60,7 +62,7 @@ public World build() { } for (Item w : loot) { - world.getItems().add(new ThrownItem(w, world)); //todo circular dependency + world.getThrownItems().add(new ThrownItem(w, world)); //todo circular dependency } world.setMinLevel(minLevel); @@ -68,17 +70,26 @@ public World build() { return world; } + /** + * Add random caves to world. + */ public WorldBuilder withCaves() { randomizeTiles(); smooth(8); return this; } + /** + * Set minimum level of mobs and items. + */ public WorldBuilder ofMinLevel(int level) { this.minLevel = level; return this; } + /** + * Add mobs of given class and given quantity. + */ public WorldBuilder addMobs(Class clazz, int quantity) { for (int i = 0; i < quantity; i++) { try { @@ -90,6 +101,9 @@ public WorldBuilder addMobs(Class clazz, int quantity) { return this; } + /** + * Add random weapons of given quantity. + */ public WorldBuilder addWeapons(int quantity) { Random randGen = new Random(); for (int i = 0; i < quantity; i++) { @@ -99,6 +113,9 @@ public WorldBuilder addWeapons(int quantity) { return this; } + /** + * Add medAids of given quantity. + */ public WorldBuilder addMedAids(int quantity) { for (int i = 0; i < quantity; i++) { MedAid medAid = new MedAid(); diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java index c09e5ac..ae861c5 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/util/WorldFactory.java @@ -1,34 +1,27 @@ package com.simiyutin.au.roguelike.util; import com.simiyutin.au.roguelike.models.World; -import com.simiyutin.au.roguelike.util.WorldBuilder; import com.simiyutin.au.roguelike.models.beings.Dragon; import com.simiyutin.au.roguelike.models.beings.Ghost; import com.simiyutin.au.roguelike.models.beings.Mushroom; +/** + * Default World configurations. + */ public class WorldFactory { - public static World getOfMinLevel(int level) { - World result = new WorldBuilder(100, 100) - .withCaves() - .ofMinLevel(level) - .addMobs(Mushroom.class, 10) - .addMobs(Ghost.class, 10) - .addMobs(Dragon.class, 5) - .addWeapons(5) - .addMedAids(10) - .build(); - return result; - } - public static World getTestConfig(int level) { + /** + * Default configuration used in game. + */ + public static World getDefaultConfigurationOfMinLevel(int level) { World result = new WorldBuilder(100, 100) .withCaves() .ofMinLevel(level) .addMobs(Mushroom.class, 10) - .addMobs(Ghost.class, 0) - .addMobs(Dragon.class, 1) + .addMobs(Ghost.class, 10) + .addMobs(Dragon.class, 5) .addWeapons(5) .addMedAids(10) .build(); diff --git a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java index 6d452c1..4f09364 100644 --- a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java +++ b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java @@ -138,13 +138,13 @@ public void testMushroom() { public void testPickUpWeapon() { init(); ThrownItem sword = new ThrownItem(new Weapon(WeaponType.SWORD, 1), world); - world.getItems().add(sword); + world.getThrownItems().add(sword); player.x = sword.x; player.y = sword.y; player.interactWithEnvironment(); assertThat(player.getWeapon() , is(sword.getItem())); - assertTrue(world.getItems().isEmpty()); + assertTrue(world.getThrownItems().isEmpty()); } @Test @@ -153,7 +153,7 @@ public void testPickUpMed() { ThrownItem medAidPos = new ThrownItem(new MedAid(), world); MedAid medAid = ((MedAid) medAidPos.getItem()); - world.getItems().add(medAidPos); + world.getThrownItems().add(medAidPos); player.x = medAidPos.x; player.y = medAidPos.y; int prevHealth = player.getHealth(); @@ -161,7 +161,7 @@ public void testPickUpMed() { player.interactWithEnvironment(); assertThat(player.getHealth(), is(prevHealth - 10)); - assertTrue(world.getItems().isEmpty()); + assertTrue(world.getThrownItems().isEmpty()); } diff --git a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldBuilderTests.java b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldBuilderTests.java index 9ed7f67..34dfd65 100644 --- a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldBuilderTests.java +++ b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/WorldBuilderTests.java @@ -23,7 +23,7 @@ public void testSimple() { World world = new WorldBuilder(100, 100).build(); assertThat(world.getHeight(), is(100)); assertThat(world.getWidth(), is(100)); - assertTrue(world.getItems().isEmpty()); + assertTrue(world.getThrownItems().isEmpty()); assertTrue(world.getMobs().isEmpty()); assertTrue(world.getPlayer().isAlive()); assertThat(world.getPlayer().getWeapon(), CoreMatchers.notNullValue()); @@ -64,7 +64,7 @@ public void testMinLevel() { } } - for (ThrownItem item : world.getItems()) { + for (ThrownItem item : world.getThrownItems()) { if (item.getItem() instanceof Weapon) { Weapon w = ((Weapon) item.getItem()); assertTrue(w.getLevel() >= world.getMinLevel()); @@ -80,9 +80,9 @@ public void testWeapons() { .addWeapons(10) .build(); - assertThat(world.getItems().stream().map(ThrownItem::getItem).filter(i -> i instanceof Weapon).count(), is(10L)); + assertThat(world.getThrownItems().stream().map(ThrownItem::getItem).filter(i -> i instanceof Weapon).count(), is(10L)); - for (Item item : world.getItems().stream().map(ThrownItem::getItem).filter(i -> i instanceof Weapon).collect(Collectors.toList())) { + for (Item item : world.getThrownItems().stream().map(ThrownItem::getItem).filter(i -> i instanceof Weapon).collect(Collectors.toList())) { Weapon weapon = (Weapon) item; assertTrue(weapon.getLevel() >= world.getMinLevel()); } @@ -96,6 +96,6 @@ public void testMedAids() { .addMedAids(10) .build(); - assertThat(world.getItems().stream().map(ThrownItem::getItem).filter(i -> i instanceof MedAid).count(), is(10L)); + assertThat(world.getThrownItems().stream().map(ThrownItem::getItem).filter(i -> i instanceof MedAid).count(), is(10L)); } } From 784f155203bdeeffe93753c26b9046501b9e12e4 Mon Sep 17 00:00:00 2001 From: simiyutin Date: Sun, 28 May 2017 12:31:17 +0300 Subject: [PATCH 63/63] weapon loop improved --- .../au/roguelike/models/beings/Player.java | 22 ++++++++++--------- .../com/simiyutin/au/roguelike/MobsTests.java | 6 ++--- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java index 99ca8f6..210051a 100644 --- a/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java +++ b/roguelike/impl/src/main/java/com/simiyutin/au/roguelike/models/beings/Player.java @@ -13,9 +13,9 @@ import org.apache.logging.log4j.Logger; import java.awt.*; -import java.util.HashSet; +import java.util.ArrayList; import java.util.Iterator; -import java.util.Set; +import java.util.List; /** @@ -70,19 +70,21 @@ public void changeWeapon() { } private void addWeapon(Weapon newWeapon) { - Set weapons = linearizeWeapons(); - weapons.add(newWeapon); - + List weapons = linearizeWeapons(); + if (!weapons.contains(newWeapon)) { + weapons.add(newWeapon); + } weaponIterator = Iterators.cycle(weapons); + changeWeapon(); } - private Set linearizeWeapons() { - Set list = new HashSet<>(); + private List linearizeWeapons() { + List list = new ArrayList<>(); + - Weapon fst = weaponIterator.next(); - list.add(fst); + list.add(weapon); Weapon next = weaponIterator.next(); - while (next != fst) { + while (next != weapon) { list.add(next); next = weaponIterator.next(); } diff --git a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java index 4f09364..d758fa4 100644 --- a/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java +++ b/roguelike/impl/src/test/java/com/simiyutin/au/roguelike/MobsTests.java @@ -11,8 +11,7 @@ import org.junit.Test; import static java.lang.Thread.sleep; -import static junit.framework.TestCase.assertFalse; -import static junit.framework.TestCase.assertTrue; +import static junit.framework.TestCase.*; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -143,7 +142,8 @@ public void testPickUpWeapon() { player.y = sword.y; player.interactWithEnvironment(); - assertThat(player.getWeapon() , is(sword.getItem())); + player.changeWeapon(); + assertEquals(sword.getItem(), player.getWeapon()); assertTrue(world.getThrownItems().isEmpty()); }