From 726ffb866e3ba147b4abee3f4657de440e5241f8 Mon Sep 17 00:00:00 2001 From: Victor Date: Thu, 15 Nov 2018 18:32:59 +0200 Subject: [PATCH] Initial --- pom.xml | 42 + src/main/java/com/annimon/GroupCollector.java | 294 +++ src/main/java/com/annimon/Issue88.java | 66 + src/main/java/com/annimon/Merger.java | 144 ++ src/main/java/com/annimon/Tester.java | 90 + .../inputstreamtostring/SourceLoader.java | 70 + .../SourceLoaderBechmarks.java | 64 + .../streambenchmark/IndexedBenchmarks.java | 70 + .../annimon/streambenchmark/IndexedInt.java | 24 + .../streambenchmark/LsaStreamBenchmarks.java | 124 ++ .../SlidingWindowBenchmarks.java | 110 + .../StreamCountBenchmarks.java | 96 + .../streambenchmark/StreamMapBenchmarks.java | 94 + .../streambenchmark/StreamSumBenchmarks.java | 96 + .../stringempty/StringLengthBenchmarks.java | 68 + src/main/resources/pipes.own | 1948 +++++++++++++++++ 16 files changed, 3400 insertions(+) create mode 100644 pom.xml create mode 100644 src/main/java/com/annimon/GroupCollector.java create mode 100644 src/main/java/com/annimon/Issue88.java create mode 100644 src/main/java/com/annimon/Merger.java create mode 100644 src/main/java/com/annimon/Tester.java create mode 100644 src/main/java/com/annimon/inputstreamtostring/SourceLoader.java create mode 100644 src/main/java/com/annimon/inputstreamtostring/SourceLoaderBechmarks.java create mode 100644 src/main/java/com/annimon/streambenchmark/IndexedBenchmarks.java create mode 100644 src/main/java/com/annimon/streambenchmark/IndexedInt.java create mode 100644 src/main/java/com/annimon/streambenchmark/LsaStreamBenchmarks.java create mode 100644 src/main/java/com/annimon/streambenchmark/SlidingWindowBenchmarks.java create mode 100644 src/main/java/com/annimon/streambenchmark/StreamCountBenchmarks.java create mode 100644 src/main/java/com/annimon/streambenchmark/StreamMapBenchmarks.java create mode 100644 src/main/java/com/annimon/streambenchmark/StreamSumBenchmarks.java create mode 100644 src/main/java/com/annimon/stringempty/StringLengthBenchmarks.java create mode 100644 src/main/resources/pipes.own diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..66cc110 --- /dev/null +++ b/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + com.annimon + PerformanceBenchmark + 1.0-SNAPSHOT + jar + + + org.openjdk.jmh + jmh-core + 1.10.1 + + + org.openjdk.jmh + jmh-generator-annprocess + 1.10.1 + + + + com.annimon + stream + 1.1.4 + jar + + + ${project.groupId} + stream + 1.1.6 + + + + UTF-8 + 1.8 + 1.8 + + PerformanceBenchmark + \ No newline at end of file diff --git a/src/main/java/com/annimon/GroupCollector.java b/src/main/java/com/annimon/GroupCollector.java new file mode 100644 index 0000000..c151c41 --- /dev/null +++ b/src/main/java/com/annimon/GroupCollector.java @@ -0,0 +1,294 @@ +package com.annimon; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class GroupCollector { + + private final Function groupClassifier; + private final List> collectors; + private Optional, R>> finalFinisher; + + public static GroupCollector groupBy(Function classifier) { + return new GroupCollector<>(classifier); + } + + public GroupCollector(Function groupClassifier) { + this.groupClassifier = groupClassifier; + collectors = new ArrayList<>(); + finalFinisher = Optional.empty(); + } + + public GroupCollector add(Collector e) { + collectors.add(e); + return this; + } + + public GroupCollector addAll(Collection> c) { + collectors.addAll(c); + return this; + } + + public GroupCollector finishWith(BiFunction, R> finalFinisher) { + this.finalFinisher = Optional.ofNullable(finalFinisher); + return this; + } + + public Collector collect(Collector finalCollector) { + @SuppressWarnings("unchecked") + final Collector, List> chainCollector = Collector.of(() -> collectors.stream() + .map(Collector::supplier) + .map(Supplier::get) + .collect(Collectors.toList()), + (list, e) -> { + IntStream.range(0, collectors.size()).forEach( + i -> ((BiConsumer) collectors.get(i).accumulator()).accept(list.get(i), e) + ); + }, + (l1, l2) -> { + IntStream.range(0, collectors.size()).forEach( + i -> l1.set(i, ((BinaryOperator) collectors.get(i).combiner()).apply(l1.get(i), l2.get(i))) + ); + return l1; + }, + list -> { + IntStream.range(0, collectors.size()).forEach( + i -> list.set(i, ((Function) collectors.get(i).finisher()).apply(list.get(i))) + ); + return list; + } + ); + + final Collector>> groupingBy = Collectors + .groupingBy(groupClassifier, chainCollector); + + return Collectors.collectingAndThen(groupingBy, map -> map.entrySet().stream() + .map(e -> finalFinisher.get().apply(e.getKey(), e.getValue())) + .collect(finalCollector) + ); + } +} +// +//package com.annimon.stream; +// +//import com.annimon.stream.function.BiConsumer; +//import com.annimon.stream.function.BiFunction; +//import com.annimon.stream.function.Consumer; +//import com.annimon.stream.function.Function; +//import com.annimon.stream.function.Supplier; +//import com.annimon.stream.function.ToDoubleFunction; +//import com.annimon.stream.function.ToIntFunction; +//import java.util.ArrayList; +//import java.util.Arrays; +//import java.util.Collection; +//import java.util.List; +//import java.util.Map; +// +//public class GroupCollector { +// +// private final Function groupClassifier; +// private final List> collectors; +// private Optional, R>> finalFinisher; +// +// public static GroupCollector groupBy(Function classifier) { +// return new GroupCollector(classifier); +// } +// +// public GroupCollector(Function groupClassifier) { +// this.groupClassifier = groupClassifier; +// collectors = new ArrayList>(); +// finalFinisher = Optional.empty(); +// } +// +// public GroupCollector add(Collector e) { +// collectors.add(e); +// return this; +// } +// +// public GroupCollector addAll(Collection> c) { +// collectors.addAll(c); +// return this; +// } +// +// public GroupCollector finishWith(BiFunction, R> finalFinisher) { +// this.finalFinisher = Optional.ofNullable(finalFinisher); +// return this; +// } +// +// public Collector collect(final Collector finalCollector) { +// @SuppressWarnings("unchecked") +// final Collector, List> chainCollector = new Collector, List>() { +// +// @Override +// public Supplier> supplier() { +// return new Supplier>() { +// @Override +// public List get() { +// return Stream.of(collectors) +// .map(new Function, Object>() { +// @Override +// public Object apply(Collector collector) { +// return collector.supplier().get(); +// } +// }) +// .collect(Collectors.toList()); +// } +// }; +// } +// +// @Override +// public BiConsumer, T> accumulator() { +// return new BiConsumer, T>() { +// @Override +// public void accept(final List list, final T value) { +// Stream.of(collectors) +// .indexed() +// .forEach(new Consumer>>() { +// @Override +// public void accept(IntPair> p) { +// ((BiConsumer) collectors.get(p.getFirst()).accumulator()) +// .accept(list.get(p.getFirst()), value); +// } +// }); +// } +// }; +// } +// +// @Override +// public Function, List> finisher() { +// return new Function, List>() { +// @Override +// public List apply(final List list) { +// Stream.of(collectors) +// .indexed() +// .forEach(new Consumer>>() { +// @Override +// public void accept(IntPair> p) { +// final int i = p.getFirst(); +// list.set(i, ((Function) collectors.get(i).finisher()) +// .apply(list.get(i))); +// } +// }); +// return list; +// } +// }; +// } +// }; +// +// final Collector>> groupingBy = Collectors +// .groupingBy(groupClassifier, chainCollector); +// +// return Collectors.collectingAndThen(groupingBy, new Function>, U>() { +// @Override +// public U apply(Map> map) { +// return Stream.of(map.entrySet()) +// .map(new Function>, R>() { +// @Override +// public R apply(Map.Entry> e) { +// return finalFinisher.get().apply(e.getKey(), e.getValue()); +// } +// }) +// .collect(finalCollector); +// } +// }); +// } +// +// static class Data { +// String key; +// int value, count; +// double average; +// +// Data(String key, int value, int count) { +// this(key, value, count, 0d); +// } +// +// Data(String key, int value, int count, double average) { +// this.key = key; +// this.value = value; +// this.count = count; +// this.average = average; +// } +// +// public Data setKey(String key) { +// this.key = key; +// return this; +// } +// +// public String getKey() { +// return key; +// } +// +// public int getValue() { +// return value; +// } +// +// public int getCount() { +// return count; +// } +// +// public double getAverage() { +// return average; +// } +// +// @Override +// public String toString() { +// return "Data{" + "key=" + key + ", value=" + value + ", count=" + count + ", average=" + average + '}'; +// } +// } +// +// public static void main(String[] args) { +// List data = Arrays.asList( +// new Data("3228-hc43", 100, 400, 21.0), +// new Data("6759-4330", 123, 67, 10.4), +// new Data("a3f5-ac2g", 363, 13, 13), +// new Data("3228-hc43", 404, 819, 3.14), +// new Data("a3f5-ac2g", 3228, 66, 18), +// new Data("3228-hc43", 119, 42, -18.5) +// ); +// List grouped = Stream.of(data) +// .collect(GroupCollector.groupBy(new Function() { +// @Override +// public String apply(Data t) { +// return t.getKey(); +// } +// }) +// .add(Collectors.summingInt(new ToIntFunction() { +// @Override +// public int applyAsInt(Data t) { +// return t.getValue(); +// } +// })) +// .add(Collectors.summingInt(new ToIntFunction() { +// @Override +// public int applyAsInt(Data t) { +// return t.getCount(); +// } +// })) +// .add(Collectors.averagingDouble(new ToDoubleFunction() { +// @Override +// public double applyAsDouble(Data t) { +// return t.getAverage(); +// } +// })) +// .finishWith(new BiFunction, Data>() { +// @Override +// public Data apply(String k, List v) { +// return new Data(k, (Integer) v.get(0), (Integer) v.get(1), (Double) v.get(2)); +// } +// }) +// .collect(Collectors.toList())); +// System.out.println(grouped); +// } +//} + diff --git a/src/main/java/com/annimon/Issue88.java b/src/main/java/com/annimon/Issue88.java new file mode 100644 index 0000000..8402ff2 --- /dev/null +++ b/src/main/java/com/annimon/Issue88.java @@ -0,0 +1,66 @@ +package com.annimon; + +import com.annimon.stream.Stream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public final class Issue88 { + + public static void main(String[] args) { + final List ansTypes = Arrays.asList(AnswerType.values()); + + Stream stream1 = Stream.range(0, 4) + .flatMap(i -> Stream.of(new ChatQuestion())); + Stream stream2 = Stream.zip( + Stream.range(0, 4) + .flatMap(i -> Stream.of(new ChatAnswer())), + Stream.of(ansTypes), + (value1, value2) -> { + value1.setAnswerType(value2); + return value1; + }); + + final List chatQuestions = new ArrayList<>(); + Stream.zip(stream1, stream2, (value1, value2) -> { + value1.getAnswers().add(value2); + return value1; + }).forEach(chatQuestion -> chatQuestions.add(chatQuestion)); + + Stream.of(chatQuestions).forEach(System.out::println); + } + + private static class ChatQuestion { + + private final List answers; + + public ChatQuestion() { + this.answers = new ArrayList<>(); + } + + public List getAnswers() { + return answers; + } + + @Override + public String toString() { + return "ChatQuestion: " + answers.toString(); + } + } + + private static class ChatAnswer { + + private AnswerType answerType; + + public void setAnswerType(AnswerType type) { + this.answerType = type; + } + + @Override + public String toString() { + return "ChatAnswer{" + "answerType=" + answerType + '}'; + } + } + + private enum AnswerType { TYPE1, TYPE2, TYPE3, TYPE4 }; +} diff --git a/src/main/java/com/annimon/Merger.java b/src/main/java/com/annimon/Merger.java new file mode 100644 index 0000000..979abf5 --- /dev/null +++ b/src/main/java/com/annimon/Merger.java @@ -0,0 +1,144 @@ +package com.annimon; + +import java.util.Arrays; +import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public final class Merger { + + static class Data { + String key; + int value, count; + double average; + + Data(String key, int value, int count) { + this(key, value, count, 0d); + } + + Data(String key, int value, int count, double average) { + this.key = key; + this.value = value; + this.count = count; + this.average = average; + } + + public Data setKey(String key) { + this.key = key; + return this; + } + + public String getKey() { + return key; + } + + public int getValue() { + return value; + } + + public int getCount() { + return count; + } + + public double getAverage() { + return average; + } + + @Override + public String toString() { + return "Data{" + "key=" + key + ", value=" + value + ", count=" + count + ", average=" + average + '}'; + } + } + + public static void main(String[] args) { + List data = Arrays.asList( + new Data("3228-hc43", 100, 400, 21.0), + new Data("6759-4330", 123, 67, 10.4), + new Data("a3f5-ac2g", 363, 13, 13), + new Data("3228-hc43", 404, 819, 3.14), + new Data("a3f5-ac2g", 3228, 66, 18), + new Data("3228-hc43", 119, 42, -18.5) + ); + + System.out.println("1"); + data.stream() + .collect(Collectors.groupingBy(Data::getKey)) + .entrySet().stream() + .map(entry -> entry.getValue().stream() + .reduce(new Data(entry.getKey(), 0, 0), (t, u) -> { + t.value += u.value; + t.count += u.count; + return t; + })) + .forEach(System.out::println); + + System.out.println("2"); + data.stream() + .collect(Collectors.collectingAndThen( + Collectors.groupingBy(Data::getKey), + grouped -> grouped.entrySet().stream() + .map(entry -> entry.getValue().stream() + .reduce(new Data(entry.getKey(), 0, 0), (t, u) -> { + t.value += u.value; + t.count += u.count; + return t; + } + ) + ))) + .forEach(System.out::println); + + System.out.println("3"); + data.stream() + .collect(Collectors.groupingBy(Data::getKey, chain( + v -> new Data("", (Integer) v.get(0), (Integer) v.get(1), (Double) v.get(2)), + Collectors.summingInt(Data::getValue), + Collectors.summingInt(Data::getCount), + Collectors.averagingDouble(Data::getAverage) + ))) + .entrySet().stream() + .map(entry -> entry.getValue().setKey(entry.getKey())) + .forEach(System.out::println); + + System.out.println("4"); + data.stream() + .collect(GroupCollector.groupBy(Data::getKey) + .add(Collectors.summingInt(Data::getValue)) + .add(Collectors.summingInt(Data::getCount)) + .add(Collectors.averagingDouble(Data::getAverage)) + .finishWith((k, v) -> new Data(k, (Integer) v.get(0), (Integer) v.get(1), (Double) v.get(2))) + .collect(Collectors.toList())) + .forEach(System.out::println); + } + + public static Collector chain(Function, R> finalFinisher, Collector... collectors) { + final Function, List> finisher = list -> { + IntStream.range(0, collectors.length).forEach( + i -> list.set(i, ((Function) collectors[i].finisher()).apply(list.get(i))) + ); + return list; + }; + @SuppressWarnings("unchecked") + Collector, R> result = Collector.of(() -> Arrays.stream(collectors) + .map(Collector::supplier) + .map(Supplier::get) + .collect(Collectors.toList()), + (list, e) -> { + IntStream.range(0, collectors.length).forEach( + i -> ((BiConsumer) collectors[i].accumulator()).accept(list.get(i), e) + ); + }, + (l1, l2) -> { + IntStream.range(0, collectors.length).forEach( + i -> l1.set(i, ((BinaryOperator) collectors[i].combiner()).apply(l1.get(i), l2.get(i))) + ); + return l1; + }, + finisher.andThen(finalFinisher)); + return result; + } +} diff --git a/src/main/java/com/annimon/Tester.java b/src/main/java/com/annimon/Tester.java new file mode 100644 index 0000000..02d1c53 --- /dev/null +++ b/src/main/java/com/annimon/Tester.java @@ -0,0 +1,90 @@ +package com.annimon; + + +import com.annimon.stream.IntPair; +import com.annimon.stream.IntStream; +import com.annimon.stream.Stream; +import com.annimon.stream.function.Predicate; +import java.util.Arrays; +import java.util.stream.DoubleStream; + + +public final class Tester { + + public static void main(String[] args) { + double dv = DoubleStream.empty().flatMap(d -> DoubleStream.of(d)).iterator().nextDouble(); + System.out.println(dv); + + int[] input = { 1, 2, 3, 4, 0, 5, 6, 7, 8, 9}; + int[] expected = { 5, 6, 7, 8, 9, 0, 1, 2, 3, 4}; + + int[] actual = IntStream.of(input) + .boxed() + .chunkBy(x -> x == 0) + .filter(list -> list.size() != 1 || list.get(0) == 0) + .indexed() + .sortBy(p -> -p.getFirst()) + .flatMap(p -> Stream.of(p.getSecond())) + .mapToInt(i -> i) + .peek(System.out::print) + .toArray(); + System.out.println(); + System.out.println(Arrays.equals(actual, expected)); + + final String inputString = "aabaa"; + final int length = inputString.length(); + IntStream.range(0, length / 2) + .mapToObj(i -> new char[] { + inputString.charAt(i), + inputString.charAt(length - i - 1) + }) + .allMatch(arr -> arr[0] == arr[1]); + + + /*double[][] input = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}}; + Stream.of(input) + .flatMap(arr -> IntStream.range(0, arr.length).mapToObj(i -> arr[i])) + .forEach(System.out::println);*/ + + int[][] data = { + {9, 95, 959,9585,9595}, + {0,7,8,9,79,80,87,89,98,797,798,879,897,899,979} + }; + Stream.of(data) + .map(arr -> IntStream.of(arr) + .sorted(Tester::compare) + .toArray() + ) + .map(Arrays::toString) + .forEach(System.out::println); + } + + private static int compare(int a, int b) { + double rankA = rank(a); + double rankB = rank(b); + int cmp = Double.compare(rankA, rankB); + if (cmp == 0) { + return -Integer.compare( + Integer.toString(a).length(), + Integer.toString(b).length() + ); + } + return -cmp; + } + + private static double rank(int x) { + String str = Integer.toString(x); + double sum = str.charAt(0) - '0'; + for (int i = 1; i < str.length(); i++) { + char ch0 = str.charAt(i - 1); + char ch1 = str.charAt(i); + double weight = 1.0 / (Math.pow(10, i + 1) * (double)(ch1 - '0' + 1)); + if (ch0 < ch1) { + sum += weight; + } else if (ch0 > ch1) { + sum -= weight; + } + } + return sum; + } +} diff --git a/src/main/java/com/annimon/inputstreamtostring/SourceLoader.java b/src/main/java/com/annimon/inputstreamtostring/SourceLoader.java new file mode 100644 index 0000000..053d4b3 --- /dev/null +++ b/src/main/java/com/annimon/inputstreamtostring/SourceLoader.java @@ -0,0 +1,70 @@ +package com.annimon.inputstreamtostring; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +public final class SourceLoader { + + public static String readSourceBufferedReader(String name) throws IOException { + InputStream is = SourceLoader.class.getResourceAsStream(name); + if (is != null) return readStreamBufferedReader(is); + + is = new FileInputStream(name); + return readStreamBufferedReader(is); + } + + public static String readSourceBuffer(String name) throws IOException { + InputStream is = SourceLoader.class.getResourceAsStream(name); + if (is != null) return readStreamBuffer(is); + + is = new FileInputStream(name); + return readStreamBuffer(is); + } + + public static String readSourceBAOS(String name) throws IOException { + InputStream is = SourceLoader.class.getResourceAsStream(name); + if (is != null) return readStreamBAOS(is); + + is = new FileInputStream(name); + return readStreamBAOS(is); + } + + private static String readStreamBufferedReader(InputStream is) throws IOException { + final StringBuilder text = new StringBuilder(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"))) { + String line; + while ((line = reader.readLine()) != null) { + text.append(line); + text.append(System.lineSeparator()); + } + } + return text.toString(); + } + + private static String readStreamBuffer(InputStream is) throws IOException { + final StringBuilder text = new StringBuilder(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"))) { + final char[] buffer = new char[1024]; + int readed; + while ((readed = reader.read(buffer)) != -1) { + text.append(buffer, 0, readed); + } + } + return text.toString(); + } + + private static String readStreamBAOS(InputStream is) throws IOException { + final ByteArrayOutputStream result = new ByteArrayOutputStream(); + final byte[] buffer = new byte[1024]; + int length; + while ((length = is.read(buffer)) != -1) { + result.write(buffer, 0, length); + } + is.close(); + return result.toString("UTF-8"); + } +} diff --git a/src/main/java/com/annimon/inputstreamtostring/SourceLoaderBechmarks.java b/src/main/java/com/annimon/inputstreamtostring/SourceLoaderBechmarks.java new file mode 100644 index 0000000..a60c12d --- /dev/null +++ b/src/main/java/com/annimon/inputstreamtostring/SourceLoaderBechmarks.java @@ -0,0 +1,64 @@ +package com.annimon.inputstreamtostring; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Benchmark) +public class SourceLoaderBechmarks { + + private static final String RES_PATH = "/pipes.own"; + private static final String FILE_PATH = "C:/Users/aNNiMON/Documents/NetBeansProjects/_TUTORIALS/OwnLang/program.own"; + + @Benchmark + public void bufferedReaderFromResources() throws IOException { + SourceLoader.readSourceBufferedReader(RES_PATH); + } + + @Benchmark + public void bufferFromResources() throws IOException { + SourceLoader.readSourceBuffer(RES_PATH); + } + + @Benchmark + public void baosFromResources() throws IOException { + SourceLoader.readSourceBAOS(RES_PATH); + } + + @Benchmark + public void bufferedReaderFromFile() throws IOException { + SourceLoader.readSourceBufferedReader(FILE_PATH); + } + + @Benchmark + public void bufferFromFile() throws IOException { + SourceLoader.readSourceBuffer(FILE_PATH); + } + + @Benchmark + public void baosFromFile() throws IOException { + SourceLoader.readSourceBAOS(FILE_PATH); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(SourceLoaderBechmarks.class.getSimpleName()) + .warmupIterations(2) + .measurementIterations(3) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/main/java/com/annimon/streambenchmark/IndexedBenchmarks.java b/src/main/java/com/annimon/streambenchmark/IndexedBenchmarks.java new file mode 100644 index 0000000..bbcf270 --- /dev/null +++ b/src/main/java/com/annimon/streambenchmark/IndexedBenchmarks.java @@ -0,0 +1,70 @@ +package com.annimon.streambenchmark; + +import com.annimon.stream.function.IntBinaryOperator; +import com.annimon.stream.function.ToIntFunction; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Benchmark) +public class IndexedBenchmarks { + private static final int SIZE = 10000000; + private int[] input; + + @Setup + public void setup() { + input = new int[SIZE]; + for (int i = 0; i < SIZE; i++) { + if (i < SIZE / 2) { + input[i] = i; + } else { + input[i] = i - SIZE; + } + } + } + + @Benchmark + public long indexedObject() { + ToIntFunction mapper = idx -> idx.index() + idx.value(); + int index = 0; + long sum = 0; + for (int value : input) { + IndexedInt idx = IndexedInt.of(value, index++); + sum += mapper.applyAsInt(idx); + } + return sum; + } + + @Benchmark + public long indexedInts() { + IntBinaryOperator mapper = (index, value) -> index + value; + int index = 0; + long sum = 0; + for (int value : input) { + sum += mapper.applyAsInt(index++, value); + } + return sum; + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(IndexedBenchmarks.class.getSimpleName()) + .warmupIterations(3) + .measurementIterations(5) + .forks(2) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/main/java/com/annimon/streambenchmark/IndexedInt.java b/src/main/java/com/annimon/streambenchmark/IndexedInt.java new file mode 100644 index 0000000..de13244 --- /dev/null +++ b/src/main/java/com/annimon/streambenchmark/IndexedInt.java @@ -0,0 +1,24 @@ +package com.annimon.streambenchmark; + +public final class IndexedInt { + + private final int index; + private final int value; + + public static IndexedInt of(int index, int value) { + return new IndexedInt(index, value); + } + + private IndexedInt(int index, int value) { + this.index = index; + this.value = value; + } + + public int index() { + return index; + } + + public int value() { + return value; + } +} diff --git a/src/main/java/com/annimon/streambenchmark/LsaStreamBenchmarks.java b/src/main/java/com/annimon/streambenchmark/LsaStreamBenchmarks.java new file mode 100644 index 0000000..1053093 --- /dev/null +++ b/src/main/java/com/annimon/streambenchmark/LsaStreamBenchmarks.java @@ -0,0 +1,124 @@ +package com.annimon.streambenchmark; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.IntStream; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Benchmark) +public class LsaStreamBenchmarks { + + volatile int counts = 9999999; + int[] array = new int[counts]; + volatile List list = new ArrayList<>(counts); + + @Setup + public void setup() { + populate(list); + } + + public void populate(List list) { + for (int i = 0; i < counts; i++) { + if (i < counts / 2) { + array[i] = i; + list.add(i, i); + } else { + array[i] = i - counts; + list.add(i, i - counts); + } + } + } + + @Benchmark + public int forSumIntegers() { + int result = 0; + for (int i = 0; i < array.length; i++) { + result += array[i]; + } + return result; + } + + @Benchmark + public int forEachSumIntegers() { + int result = 0; + for (int value : array) { + result += value; + } + return result; + } + + @Benchmark + public int forEachSumIntegersList() { + int result = 0; + for (int value : list) { + result += value; + } + return result; + } + + @Benchmark + public int javaIntStreamSumIntegersWithReduce() { + int result = java.util.stream.IntStream.of(array) + .reduce(0, (a, b) -> a + b); + return result; + } + + @Benchmark + public int javaIntStreamSumIntegers() { + int result = java.util.stream.IntStream.of(array) + .sum(); + return result; + } + + @Benchmark + public int javaStreamSumIntegers() { + int result = list.stream() + .reduce(0, (a, b) -> a + b); + return result; + } + + @Benchmark + public int lsaStreamSumIntegers() { + int result = com.annimon.stream.Stream.of(list) + .reduce(0, (a, b) -> a + b); + return result; + } + + @Benchmark + public int lsaIntStreamSumIntegersWithReduce() { + int result = com.annimon.stream.IntStream.of(array) + .reduce(0, (a, b) -> a + b); + return result; + } + + @Benchmark + public int lsaIntStreamSumIntegers() { + int result = com.annimon.stream.IntStream.of(array) + .sum(); + return result; + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(LsaStreamBenchmarks.class.getSimpleName()) + .warmupIterations(3) + .measurementIterations(5) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/main/java/com/annimon/streambenchmark/SlidingWindowBenchmarks.java b/src/main/java/com/annimon/streambenchmark/SlidingWindowBenchmarks.java new file mode 100644 index 0000000..3e57110 --- /dev/null +++ b/src/main/java/com/annimon/streambenchmark/SlidingWindowBenchmarks.java @@ -0,0 +1,110 @@ +package com.annimon.streambenchmark; + +import com.annimon.stream.Stream; +import com.annimon.stream.function.Function; +import com.annimon.stream.function.Supplier; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Benchmark) +public class SlidingWindowBenchmarks { + + volatile int counts = 9999999; + + @Param({"1", "5", "10", "20", "40", "80", "150", "400", "800"}) + public int windowSizeParam; + + @Benchmark + public long slidingWindowLinkedList() { + return Stream.range(0, counts) + .custom(new SlidingWindow<>(windowSizeParam, 10, LinkedList::new)) + .count(); + } + + @Benchmark + public long slidingWindowArrayDeque() { + return Stream.range(0, counts) + .custom(new SlidingWindow<>(windowSizeParam, 10, ArrayDeque::new)) + .count(); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(SlidingWindowBenchmarks.class.getSimpleName()) + .warmupIterations(3) + .measurementIterations(5) + .forks(1) + .build(); + + new Runner(opt).run(); + } + + private static class SlidingWindow implements Function, Stream>> { + + private final int windowSize, stepWidth; + private final Supplier> supplier; + + public SlidingWindow(int windowSize, int stepWidth, Supplier> supplier) { + this.windowSize = windowSize; + this.stepWidth = stepWidth; + this.supplier = supplier; + } + + @Override + public Stream> apply(Stream t) { + final Iterator iterator = t.getIterator(); + return Stream.of(new Iterator>() { + private final Queue queue = supplier.get(); + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public List next() { + int i = queue.size(); + while (i < windowSize && iterator.hasNext()) { + queue.offer(iterator.next()); + i++; + } + + // the elements that are currently in the queue are the elements of our current window + List list = new ArrayList(queue); + + // remove stepWidth elements from the queue + int queueSize = queue.size(); + for (int j = 0; j < stepWidth && j < queueSize; j++) { + queue.poll(); + } + + // if the stepWidth is greater than the windowSize, skip (stepWidth - windowSize) elements + for (int j = windowSize; j < stepWidth && iterator.hasNext(); j++) { + iterator.next(); + } + + return list; + } + }); + } + } +} diff --git a/src/main/java/com/annimon/streambenchmark/StreamCountBenchmarks.java b/src/main/java/com/annimon/streambenchmark/StreamCountBenchmarks.java new file mode 100644 index 0000000..af71f99 --- /dev/null +++ b/src/main/java/com/annimon/streambenchmark/StreamCountBenchmarks.java @@ -0,0 +1,96 @@ +package com.annimon.streambenchmark; + +import com.annimon.stream.Stream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Benchmark) +public class StreamCountBenchmarks { + volatile int counts = 9999999; + volatile List values = new ArrayList<>(counts); + + @Setup + public void setup() { + populate(values); + } + + public void populate(List list) { + for (int i = 0; i < counts; i++) { + if (i < counts / 2) { + list.add(i, i); + } else { + list.add(i, i - counts); + } + } + + } + + @Benchmark + public long iteratorCountIntegers() { + long result = 0; + Iterator ite = values.iterator(); + while (ite.hasNext()) { + result++; + ite.next(); + } + return result; + } + + @Benchmark + public long fooEachCountIntegers() { + long result = 0; + for (Integer value : values) { + result++; + } + return result; + } + + @Benchmark + public long parallelCountIntegers() { + long result = values.parallelStream() + .count(); + return result; + + } + + @Benchmark + public long sequentialCountIntegers() { + long result = values.stream() + .count(); + return result; + + } + + @Benchmark + public long lsaCountIntegers() { + long result = Stream.of(values.iterator()) + .count(); + return result; + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(StreamCountBenchmarks.class.getSimpleName()) + .warmupIterations(3) + .measurementIterations(5) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/main/java/com/annimon/streambenchmark/StreamMapBenchmarks.java b/src/main/java/com/annimon/streambenchmark/StreamMapBenchmarks.java new file mode 100644 index 0000000..3e29147 --- /dev/null +++ b/src/main/java/com/annimon/streambenchmark/StreamMapBenchmarks.java @@ -0,0 +1,94 @@ +package com.annimon.streambenchmark; + +import com.annimon.stream.Stream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Benchmark) +public class StreamMapBenchmarks { + volatile int counts = 9999999; + volatile List values = new ArrayList<>(counts); + + @Setup + public void setup() { + populate(values); + } + + public void populate(List list) { + for (int i = 0; i < counts; i++) { + if (i < counts / 2) { + list.add(i, i); + } else { + list.add(i, i - counts); + } + } + + } + + @Benchmark + public void iteratorMapIntegers() { + long count = 0; + Iterator ite = values.iterator(); + while (ite.hasNext()) { + count++; + Integer value = ite.next(); + value = -value; + } + } + + @Benchmark + public void fooEachMapIntegers() { + long count = 0; + for (Integer value : values) { + count++; + value = -value; + } + } + + @Benchmark + public void parallelMapIntegers() { + values.parallelStream() + .map(i -> -i) + .count(); + } + + @Benchmark + public void sequentialMapIntegers() { + values.stream() + .map(i -> -i) + .count(); + } + + @Benchmark + public void lsaMapIntegers() { + Stream.of(values.iterator()) + .map(i -> -i) + .count(); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(StreamMapBenchmarks.class.getSimpleName()) + .warmupIterations(3) + .measurementIterations(5) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/main/java/com/annimon/streambenchmark/StreamSumBenchmarks.java b/src/main/java/com/annimon/streambenchmark/StreamSumBenchmarks.java new file mode 100644 index 0000000..dee7e10 --- /dev/null +++ b/src/main/java/com/annimon/streambenchmark/StreamSumBenchmarks.java @@ -0,0 +1,96 @@ +package com.annimon.streambenchmark; + +import com.annimon.stream.Stream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.OptionalInt; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Benchmark) +public class StreamSumBenchmarks { + volatile int counts = 9999999; + volatile List values = new ArrayList<>(counts); + + @Setup + public void setup() { + populate(values); + } + + public void populate(List list) { + for (int i = 0; i < counts; i++) { + if (i < counts / 2) { + list.add(i, i); + } else { + list.add(i, i - counts); + } + } + + } + + @Benchmark + public int iteratorSumIntegers() { + int result = 0; + Iterator ite = values.iterator(); + while (ite.hasNext()) { + result += ite.next(); + } + return result; + } + + @Benchmark + public int fooEachSumIntegers() { + int result = 0; + for (Integer value : values) { + result += value; + } + return result; + } + + @Benchmark + public int parallelSumIntegers() { + int result = values.parallelStream() + .reduce(0, (a, b) -> a + b); + return result; + + } + + @Benchmark + public int sequentialSumIntegers() { + int result = values.stream() + .reduce(0, (a, b) -> a + b); + return result; + + } + + @Benchmark + public int lsaSumIntegers() { + int result = Stream.of(values.iterator()) + .reduce(0, (a, b) -> a + b); + return result; + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(StreamSumBenchmarks.class.getSimpleName()) + .warmupIterations(0) + .measurementIterations(1) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/main/java/com/annimon/stringempty/StringLengthBenchmarks.java b/src/main/java/com/annimon/stringempty/StringLengthBenchmarks.java new file mode 100644 index 0000000..d4816d0 --- /dev/null +++ b/src/main/java/com/annimon/stringempty/StringLengthBenchmarks.java @@ -0,0 +1,68 @@ +package com.annimon.stringempty; + +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Benchmark) +public class StringLengthBenchmarks { + + String str = ""; + + @Benchmark + public void lengthEqZero() { + for(long k = 0; k < 1_000L; k++) + for(long j = 0; j < 1_000L; j++) + for(long i = 0; i < 1_000L; i++) + if (str.length() == 0) { + } + } + + @Benchmark + public void lengthGtZero() { + for(long k = 0; k < 1_000L; k++) + for(long j = 0; j < 1_000L; j++) + for(long i = 0; i < 1_000L; i++) + if (str.length() > 0) { + } + } + + @Benchmark + public void lengthLtZero() { + for(long k = 0; k < 1_000L; k++) + for(long j = 0; j < 1_000L; j++) + for(long i = 0; i < 1_000L; i++) + if (str.length() < 0) { + } + } + + @Benchmark + public void isEmpty() { + for(long k = 0; k < 1_000L; k++) + for(long j = 0; j < 1_000L; j++) + for(long i = 0; i < 1_000L; i++) + if (str.isEmpty()) { + } + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(StringLengthBenchmarks.class.getSimpleName()) + .warmupIterations(3) + .measurementIterations(5) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/main/resources/pipes.own b/src/main/resources/pipes.own new file mode 100644 index 0000000..e3dcf4d --- /dev/null +++ b/src/main/resources/pipes.own @@ -0,0 +1,1948 @@ +use "std" +use "canvas" + +///------------------------------------- +/// PIPES CELL +///------------------------------------- +CELL_START = 0 +HORIZONTAL = 0 +VERTICAL = 1 +LEFT_TO_DOWN = 2 +LEFT_TO_UP = 3 +RIGHT_TO_UP = 4 +RIGHT_TO_DOWN = 5 +CROSS = 6 +CELL_LAST = 6 + +// лево, право, верх, низ +HorizontalCell = [1,1,0,0] +VerticalCell = [0,0,1,1] +LeftToDownCell = [1,0,0,1] +LeftToUpCell = [1,0,1,0] +RightToUpCell = [0,1,1,0] +RightToDownCell = [0,1,0,1] +CrossCell = [1,1,1,1] + +support = [ + HorizontalCell, VerticalCell, + LeftToDownCell, LeftToUpCell, + RightToUpCell, RightToDownCell, + CrossCell +] + + +def draw(v, cellSize) { + c2 = cellSize / 2 + match v { + case HORIZONTAL : fillRect(0, c2 - 2, cellSize, 4) + case VERTICAL : fillRect(c2 - 2, 0, 4, cellSize) + case LEFT_TO_DOWN : { + fillRect(0, c2 - 2, c2, 4) + fillRect(c2 - 2, c2 - 2, 4, c2 + 2) + } + case LEFT_TO_UP : { + fillRect(0, c2 - 2, c2, 4) + fillRect(c2 - 2, c2 - 2, 4, c2 + 2) + } + case RIGHT_TO_UP : { + fillRect(c2 - 2, c2 - 2, c2 + 2, 4) + fillRect(c2 - 2, 0, 4, c2 + 2) + } + case RIGHT_TO_DOWN : { + fillRect(c2 - 2, c2 - 2, c2 + 2, 4) + fillRect(c2 - 2, c2 - 2, 4, c2 + 2) + } + case CROSS : { + fillRect(c2 - 2, 0, 4, cellSize) + fillRect(0, c2 - 2, cellSize, 4) + } + } +} + +def supportLeft(v) = support[v][0] +def supportRight(v) = support[v][1] +def supportUp(v) = support[v][2] +def supportDown(v) = support[v][3] +///------------------------------------- + + +///------------------------------------- +/// PIPES BOARD +///------------------------------------- +SIZE = 10 + +// Создаём игровое поле +board = newarray(SIZE, SIZE) + +def createBoard() { + for i=0, i CELL_LAST ? CELL_START : nextType +} + +def isFinished() { + // Стартовая труба должна иметь левую точку соприкосновения + if (!supportLeft(board[0][0])) return 0 + // А конечная труба - правую + if (!supportRight(board[SIZE - 1][SIZE - 1])) return 0 + + visited = newarray(SIZE, SIZE) + return isConnected(0, 0, visited) +} + +def isConnected(curX, curY, visited) { + // Если достигли конечной ячейки - выходим. + if ( (curX == SIZE - 1) && (curY == SIZE - 1) ) return 1 + + // Если уже посещали - выходим. + if (visited[curX][curY]) return 0 + // Отмечаем посещение. + visited[curX][curY] = 1 + current = board[curX][curY] + if ( supportLeft(current) && (curX > 0) && (supportRight(board[curX - 1][curY])) ) { + if (isConnected(curX - 1, curY, visited)) return 1 + } + if ( supportRight(current) && (curX < SIZE - 1) && (supportLeft(board[curX + 1][curY])) ) { + if (isConnected(curX + 1, curY, visited)) return 1 + } + if ( supportUp(current) && (curY > 0) && (supportDown(board[curX][curY - 1])) ) { + if (isConnected(curX, curY - 1, visited)) return 1 + } + if ( supportDown(current) && (curY < SIZE - 1) && (supportUp(board[curX][curY + 1])) ) { + if (isConnected(curX, curY + 1, visited)) return 1 + } + return 0 +} +///------------------------------------- + + +///------------------------------------- +/// PIPES MAIN +///------------------------------------- +translateX = 0 translateY = 0 +/* frect с поддержкой translate*/ +def fillRect(x,y,w,h) { + frect(translateX+x, translateY+y, w, h) +} + +// JAVA ME +// showcanvas() +// JAVA SE +WIDTH = 480 HEIGHT = 480 +window("Pipes", WIDTH, HEIGHT) +cellSize = WIDTH / SIZE +createBoard() + +// курсор +curX = 0 +curY = 0 + +run = 1 +while run { + //key = gameaction(keypressed()) + key = keypressed() + if (key == VK_LEFT && curX > 0) curX-- + else if (key == VK_RIGHT && curX < SIZE - 1) curX++ + else if (key == VK_UP && curY > 0) curY-- + else if (key == VK_DOWN && curY < SIZE - 1) curY++ + else if key == VK_FIRE switchCell(curX,curY) + else if key == 48 run = 0 + + // фон + color(isFinished() ? #00FF00 : #FFFFFF) + frect(0,0,WIDTH,HEIGHT) + // курсор + color(#4444FF) + frect(curX*cellSize, curY*cellSize, cellSize, cellSize) + for (i=0, i CELL_LAST ? CELL_START : nextType +} + +def isFinished() { + // Стартовая труба должна иметь левую точку соприкосновения + if (!supportLeft(board[0][0])) return 0 + // А конечная труба - правую + if (!supportRight(board[SIZE - 1][SIZE - 1])) return 0 + + visited = newarray(SIZE, SIZE) + return isConnected(0, 0, visited) +} + +def isConnected(curX, curY, visited) { + // Если достигли конечной ячейки - выходим. + if ( (curX == SIZE - 1) && (curY == SIZE - 1) ) return 1 + + // Если уже посещали - выходим. + if (visited[curX][curY]) return 0 + // Отмечаем посещение. + visited[curX][curY] = 1 + current = board[curX][curY] + if ( supportLeft(current) && (curX > 0) && (supportRight(board[curX - 1][curY])) ) { + if (isConnected(curX - 1, curY, visited)) return 1 + } + if ( supportRight(current) && (curX < SIZE - 1) && (supportLeft(board[curX + 1][curY])) ) { + if (isConnected(curX + 1, curY, visited)) return 1 + } + if ( supportUp(current) && (curY > 0) && (supportDown(board[curX][curY - 1])) ) { + if (isConnected(curX, curY - 1, visited)) return 1 + } + if ( supportDown(current) && (curY < SIZE - 1) && (supportUp(board[curX][curY + 1])) ) { + if (isConnected(curX, curY + 1, visited)) return 1 + } + return 0 +} +///------------------------------------- + + +///------------------------------------- +/// PIPES MAIN +///------------------------------------- +translateX = 0 translateY = 0 +/* frect с поддержкой translate*/ +def fillRect(x,y,w,h) { + frect(translateX+x, translateY+y, w, h) +} + +// JAVA ME +// showcanvas() +// JAVA SE +WIDTH = 480 HEIGHT = 480 +window("Pipes", WIDTH, HEIGHT) +cellSize = WIDTH / SIZE +createBoard() + +// курсор +curX = 0 +curY = 0 + +run = 1 +while run { + //key = gameaction(keypressed()) + key = keypressed() + if (key == VK_LEFT && curX > 0) curX-- + else if (key == VK_RIGHT && curX < SIZE - 1) curX++ + else if (key == VK_UP && curY > 0) curY-- + else if (key == VK_DOWN && curY < SIZE - 1) curY++ + else if key == VK_FIRE switchCell(curX,curY) + else if key == 48 run = 0 + + // фон + color(isFinished() ? #00FF00 : #FFFFFF) + frect(0,0,WIDTH,HEIGHT) + // курсор + color(#4444FF) + frect(curX*cellSize, curY*cellSize, cellSize, cellSize) + for (i=0, i CELL_LAST ? CELL_START : nextType +} + +def isFinished() { + // Стартовая труба должна иметь левую точку соприкосновения + if (!supportLeft(board[0][0])) return 0 + // А конечная труба - правую + if (!supportRight(board[SIZE - 1][SIZE - 1])) return 0 + + visited = newarray(SIZE, SIZE) + return isConnected(0, 0, visited) +} + +def isConnected(curX, curY, visited) { + // Если достигли конечной ячейки - выходим. + if ( (curX == SIZE - 1) && (curY == SIZE - 1) ) return 1 + + // Если уже посещали - выходим. + if (visited[curX][curY]) return 0 + // Отмечаем посещение. + visited[curX][curY] = 1 + current = board[curX][curY] + if ( supportLeft(current) && (curX > 0) && (supportRight(board[curX - 1][curY])) ) { + if (isConnected(curX - 1, curY, visited)) return 1 + } + if ( supportRight(current) && (curX < SIZE - 1) && (supportLeft(board[curX + 1][curY])) ) { + if (isConnected(curX + 1, curY, visited)) return 1 + } + if ( supportUp(current) && (curY > 0) && (supportDown(board[curX][curY - 1])) ) { + if (isConnected(curX, curY - 1, visited)) return 1 + } + if ( supportDown(current) && (curY < SIZE - 1) && (supportUp(board[curX][curY + 1])) ) { + if (isConnected(curX, curY + 1, visited)) return 1 + } + return 0 +} +///------------------------------------- + + +///------------------------------------- +/// PIPES MAIN +///------------------------------------- +translateX = 0 translateY = 0 +/* frect с поддержкой translate*/ +def fillRect(x,y,w,h) { + frect(translateX+x, translateY+y, w, h) +} + +// JAVA ME +// showcanvas() +// JAVA SE +WIDTH = 480 HEIGHT = 480 +window("Pipes", WIDTH, HEIGHT) +cellSize = WIDTH / SIZE +createBoard() + +// курсор +curX = 0 +curY = 0 + +run = 1 +while run { + //key = gameaction(keypressed()) + key = keypressed() + if (key == VK_LEFT && curX > 0) curX-- + else if (key == VK_RIGHT && curX < SIZE - 1) curX++ + else if (key == VK_UP && curY > 0) curY-- + else if (key == VK_DOWN && curY < SIZE - 1) curY++ + else if key == VK_FIRE switchCell(curX,curY) + else if key == 48 run = 0 + + // фон + color(isFinished() ? #00FF00 : #FFFFFF) + frect(0,0,WIDTH,HEIGHT) + // курсор + color(#4444FF) + frect(curX*cellSize, curY*cellSize, cellSize, cellSize) + for (i=0, i CELL_LAST ? CELL_START : nextType +} + +def isFinished() { + // Стартовая труба должна иметь левую точку соприкосновения + if (!supportLeft(board[0][0])) return 0 + // А конечная труба - правую + if (!supportRight(board[SIZE - 1][SIZE - 1])) return 0 + + visited = newarray(SIZE, SIZE) + return isConnected(0, 0, visited) +} + +def isConnected(curX, curY, visited) { + // Если достигли конечной ячейки - выходим. + if ( (curX == SIZE - 1) && (curY == SIZE - 1) ) return 1 + + // Если уже посещали - выходим. + if (visited[curX][curY]) return 0 + // Отмечаем посещение. + visited[curX][curY] = 1 + current = board[curX][curY] + if ( supportLeft(current) && (curX > 0) && (supportRight(board[curX - 1][curY])) ) { + if (isConnected(curX - 1, curY, visited)) return 1 + } + if ( supportRight(current) && (curX < SIZE - 1) && (supportLeft(board[curX + 1][curY])) ) { + if (isConnected(curX + 1, curY, visited)) return 1 + } + if ( supportUp(current) && (curY > 0) && (supportDown(board[curX][curY - 1])) ) { + if (isConnected(curX, curY - 1, visited)) return 1 + } + if ( supportDown(current) && (curY < SIZE - 1) && (supportUp(board[curX][curY + 1])) ) { + if (isConnected(curX, curY + 1, visited)) return 1 + } + return 0 +} +///------------------------------------- + + +///------------------------------------- +/// PIPES MAIN +///------------------------------------- +translateX = 0 translateY = 0 +/* frect с поддержкой translate*/ +def fillRect(x,y,w,h) { + frect(translateX+x, translateY+y, w, h) +} + +// JAVA ME +// showcanvas() +// JAVA SE +WIDTH = 480 HEIGHT = 480 +window("Pipes", WIDTH, HEIGHT) +cellSize = WIDTH / SIZE +createBoard() + +// курсор +curX = 0 +curY = 0 + +run = 1 +while run { + //key = gameaction(keypressed()) + key = keypressed() + if (key == VK_LEFT && curX > 0) curX-- + else if (key == VK_RIGHT && curX < SIZE - 1) curX++ + else if (key == VK_UP && curY > 0) curY-- + else if (key == VK_DOWN && curY < SIZE - 1) curY++ + else if key == VK_FIRE switchCell(curX,curY) + else if key == 48 run = 0 + + // фон + color(isFinished() ? #00FF00 : #FFFFFF) + frect(0,0,WIDTH,HEIGHT) + // курсор + color(#4444FF) + frect(curX*cellSize, curY*cellSize, cellSize, cellSize) + for (i=0, i CELL_LAST ? CELL_START : nextType +} + +def isFinished() { + // Стартовая труба должна иметь левую точку соприкосновения + if (!supportLeft(board[0][0])) return 0 + // А конечная труба - правую + if (!supportRight(board[SIZE - 1][SIZE - 1])) return 0 + + visited = newarray(SIZE, SIZE) + return isConnected(0, 0, visited) +} + +def isConnected(curX, curY, visited) { + // Если достигли конечной ячейки - выходим. + if ( (curX == SIZE - 1) && (curY == SIZE - 1) ) return 1 + + // Если уже посещали - выходим. + if (visited[curX][curY]) return 0 + // Отмечаем посещение. + visited[curX][curY] = 1 + current = board[curX][curY] + if ( supportLeft(current) && (curX > 0) && (supportRight(board[curX - 1][curY])) ) { + if (isConnected(curX - 1, curY, visited)) return 1 + } + if ( supportRight(current) && (curX < SIZE - 1) && (supportLeft(board[curX + 1][curY])) ) { + if (isConnected(curX + 1, curY, visited)) return 1 + } + if ( supportUp(current) && (curY > 0) && (supportDown(board[curX][curY - 1])) ) { + if (isConnected(curX, curY - 1, visited)) return 1 + } + if ( supportDown(current) && (curY < SIZE - 1) && (supportUp(board[curX][curY + 1])) ) { + if (isConnected(curX, curY + 1, visited)) return 1 + } + return 0 +} +///------------------------------------- + + +///------------------------------------- +/// PIPES MAIN +///------------------------------------- +translateX = 0 translateY = 0 +/* frect с поддержкой translate*/ +def fillRect(x,y,w,h) { + frect(translateX+x, translateY+y, w, h) +} + +// JAVA ME +// showcanvas() +// JAVA SE +WIDTH = 480 HEIGHT = 480 +window("Pipes", WIDTH, HEIGHT) +cellSize = WIDTH / SIZE +createBoard() + +// курсор +curX = 0 +curY = 0 + +run = 1 +while run { + //key = gameaction(keypressed()) + key = keypressed() + if (key == VK_LEFT && curX > 0) curX-- + else if (key == VK_RIGHT && curX < SIZE - 1) curX++ + else if (key == VK_UP && curY > 0) curY-- + else if (key == VK_DOWN && curY < SIZE - 1) curY++ + else if key == VK_FIRE switchCell(curX,curY) + else if key == 48 run = 0 + + // фон + color(isFinished() ? #00FF00 : #FFFFFF) + frect(0,0,WIDTH,HEIGHT) + // курсор + color(#4444FF) + frect(curX*cellSize, curY*cellSize, cellSize, cellSize) + for (i=0, i CELL_LAST ? CELL_START : nextType +} + +def isFinished() { + // Стартовая труба должна иметь левую точку соприкосновения + if (!supportLeft(board[0][0])) return 0 + // А конечная труба - правую + if (!supportRight(board[SIZE - 1][SIZE - 1])) return 0 + + visited = newarray(SIZE, SIZE) + return isConnected(0, 0, visited) +} + +def isConnected(curX, curY, visited) { + // Если достигли конечной ячейки - выходим. + if ( (curX == SIZE - 1) && (curY == SIZE - 1) ) return 1 + + // Если уже посещали - выходим. + if (visited[curX][curY]) return 0 + // Отмечаем посещение. + visited[curX][curY] = 1 + current = board[curX][curY] + if ( supportLeft(current) && (curX > 0) && (supportRight(board[curX - 1][curY])) ) { + if (isConnected(curX - 1, curY, visited)) return 1 + } + if ( supportRight(current) && (curX < SIZE - 1) && (supportLeft(board[curX + 1][curY])) ) { + if (isConnected(curX + 1, curY, visited)) return 1 + } + if ( supportUp(current) && (curY > 0) && (supportDown(board[curX][curY - 1])) ) { + if (isConnected(curX, curY - 1, visited)) return 1 + } + if ( supportDown(current) && (curY < SIZE - 1) && (supportUp(board[curX][curY + 1])) ) { + if (isConnected(curX, curY + 1, visited)) return 1 + } + return 0 +} +///------------------------------------- + + +///------------------------------------- +/// PIPES MAIN +///------------------------------------- +translateX = 0 translateY = 0 +/* frect с поддержкой translate*/ +def fillRect(x,y,w,h) { + frect(translateX+x, translateY+y, w, h) +} + +// JAVA ME +// showcanvas() +// JAVA SE +WIDTH = 480 HEIGHT = 480 +window("Pipes", WIDTH, HEIGHT) +cellSize = WIDTH / SIZE +createBoard() + +// курсор +curX = 0 +curY = 0 + +run = 1 +while run { + //key = gameaction(keypressed()) + key = keypressed() + if (key == VK_LEFT && curX > 0) curX-- + else if (key == VK_RIGHT && curX < SIZE - 1) curX++ + else if (key == VK_UP && curY > 0) curY-- + else if (key == VK_DOWN && curY < SIZE - 1) curY++ + else if key == VK_FIRE switchCell(curX,curY) + else if key == 48 run = 0 + + // фон + color(isFinished() ? #00FF00 : #FFFFFF) + frect(0,0,WIDTH,HEIGHT) + // курсор + color(#4444FF) + frect(curX*cellSize, curY*cellSize, cellSize, cellSize) + for (i=0, i CELL_LAST ? CELL_START : nextType +} + +def isFinished() { + // Стартовая труба должна иметь левую точку соприкосновения + if (!supportLeft(board[0][0])) return 0 + // А конечная труба - правую + if (!supportRight(board[SIZE - 1][SIZE - 1])) return 0 + + visited = newarray(SIZE, SIZE) + return isConnected(0, 0, visited) +} + +def isConnected(curX, curY, visited) { + // Если достигли конечной ячейки - выходим. + if ( (curX == SIZE - 1) && (curY == SIZE - 1) ) return 1 + + // Если уже посещали - выходим. + if (visited[curX][curY]) return 0 + // Отмечаем посещение. + visited[curX][curY] = 1 + current = board[curX][curY] + if ( supportLeft(current) && (curX > 0) && (supportRight(board[curX - 1][curY])) ) { + if (isConnected(curX - 1, curY, visited)) return 1 + } + if ( supportRight(current) && (curX < SIZE - 1) && (supportLeft(board[curX + 1][curY])) ) { + if (isConnected(curX + 1, curY, visited)) return 1 + } + if ( supportUp(current) && (curY > 0) && (supportDown(board[curX][curY - 1])) ) { + if (isConnected(curX, curY - 1, visited)) return 1 + } + if ( supportDown(current) && (curY < SIZE - 1) && (supportUp(board[curX][curY + 1])) ) { + if (isConnected(curX, curY + 1, visited)) return 1 + } + return 0 +} +///------------------------------------- + + +///------------------------------------- +/// PIPES MAIN +///------------------------------------- +translateX = 0 translateY = 0 +/* frect с поддержкой translate*/ +def fillRect(x,y,w,h) { + frect(translateX+x, translateY+y, w, h) +} + +// JAVA ME +// showcanvas() +// JAVA SE +WIDTH = 480 HEIGHT = 480 +window("Pipes", WIDTH, HEIGHT) +cellSize = WIDTH / SIZE +createBoard() + +// курсор +curX = 0 +curY = 0 + +run = 1 +while run { + //key = gameaction(keypressed()) + key = keypressed() + if (key == VK_LEFT && curX > 0) curX-- + else if (key == VK_RIGHT && curX < SIZE - 1) curX++ + else if (key == VK_UP && curY > 0) curY-- + else if (key == VK_DOWN && curY < SIZE - 1) curY++ + else if key == VK_FIRE switchCell(curX,curY) + else if key == 48 run = 0 + + // фон + color(isFinished() ? #00FF00 : #FFFFFF) + frect(0,0,WIDTH,HEIGHT) + // курсор + color(#4444FF) + frect(curX*cellSize, curY*cellSize, cellSize, cellSize) + for (i=0, i CELL_LAST ? CELL_START : nextType +} + +def isFinished() { + // Стартовая труба должна иметь левую точку соприкосновения + if (!supportLeft(board[0][0])) return 0 + // А конечная труба - правую + if (!supportRight(board[SIZE - 1][SIZE - 1])) return 0 + + visited = newarray(SIZE, SIZE) + return isConnected(0, 0, visited) +} + +def isConnected(curX, curY, visited) { + // Если достигли конечной ячейки - выходим. + if ( (curX == SIZE - 1) && (curY == SIZE - 1) ) return 1 + + // Если уже посещали - выходим. + if (visited[curX][curY]) return 0 + // Отмечаем посещение. + visited[curX][curY] = 1 + current = board[curX][curY] + if ( supportLeft(current) && (curX > 0) && (supportRight(board[curX - 1][curY])) ) { + if (isConnected(curX - 1, curY, visited)) return 1 + } + if ( supportRight(current) && (curX < SIZE - 1) && (supportLeft(board[curX + 1][curY])) ) { + if (isConnected(curX + 1, curY, visited)) return 1 + } + if ( supportUp(current) && (curY > 0) && (supportDown(board[curX][curY - 1])) ) { + if (isConnected(curX, curY - 1, visited)) return 1 + } + if ( supportDown(current) && (curY < SIZE - 1) && (supportUp(board[curX][curY + 1])) ) { + if (isConnected(curX, curY + 1, visited)) return 1 + } + return 0 +} +///------------------------------------- + + +///------------------------------------- +/// PIPES MAIN +///------------------------------------- +translateX = 0 translateY = 0 +/* frect с поддержкой translate*/ +def fillRect(x,y,w,h) { + frect(translateX+x, translateY+y, w, h) +} + +// JAVA ME +// showcanvas() +// JAVA SE +WIDTH = 480 HEIGHT = 480 +window("Pipes", WIDTH, HEIGHT) +cellSize = WIDTH / SIZE +createBoard() + +// курсор +curX = 0 +curY = 0 + +run = 1 +while run { + //key = gameaction(keypressed()) + key = keypressed() + if (key == VK_LEFT && curX > 0) curX-- + else if (key == VK_RIGHT && curX < SIZE - 1) curX++ + else if (key == VK_UP && curY > 0) curY-- + else if (key == VK_DOWN && curY < SIZE - 1) curY++ + else if key == VK_FIRE switchCell(curX,curY) + else if key == 48 run = 0 + + // фон + color(isFinished() ? #00FF00 : #FFFFFF) + frect(0,0,WIDTH,HEIGHT) + // курсор + color(#4444FF) + frect(curX*cellSize, curY*cellSize, cellSize, cellSize) + for (i=0, i CELL_LAST ? CELL_START : nextType +} + +def isFinished() { + // Стартовая труба должна иметь левую точку соприкосновения + if (!supportLeft(board[0][0])) return 0 + // А конечная труба - правую + if (!supportRight(board[SIZE - 1][SIZE - 1])) return 0 + + visited = newarray(SIZE, SIZE) + return isConnected(0, 0, visited) +} + +def isConnected(curX, curY, visited) { + // Если достигли конечной ячейки - выходим. + if ( (curX == SIZE - 1) && (curY == SIZE - 1) ) return 1 + + // Если уже посещали - выходим. + if (visited[curX][curY]) return 0 + // Отмечаем посещение. + visited[curX][curY] = 1 + current = board[curX][curY] + if ( supportLeft(current) && (curX > 0) && (supportRight(board[curX - 1][curY])) ) { + if (isConnected(curX - 1, curY, visited)) return 1 + } + if ( supportRight(current) && (curX < SIZE - 1) && (supportLeft(board[curX + 1][curY])) ) { + if (isConnected(curX + 1, curY, visited)) return 1 + } + if ( supportUp(current) && (curY > 0) && (supportDown(board[curX][curY - 1])) ) { + if (isConnected(curX, curY - 1, visited)) return 1 + } + if ( supportDown(current) && (curY < SIZE - 1) && (supportUp(board[curX][curY + 1])) ) { + if (isConnected(curX, curY + 1, visited)) return 1 + } + return 0 +} +///------------------------------------- + + +///------------------------------------- +/// PIPES MAIN +///------------------------------------- +translateX = 0 translateY = 0 +/* frect с поддержкой translate*/ +def fillRect(x,y,w,h) { + frect(translateX+x, translateY+y, w, h) +} + +// JAVA ME +// showcanvas() +// JAVA SE +WIDTH = 480 HEIGHT = 480 +window("Pipes", WIDTH, HEIGHT) +cellSize = WIDTH / SIZE +createBoard() + +// курсор +curX = 0 +curY = 0 + +run = 1 +while run { + //key = gameaction(keypressed()) + key = keypressed() + if (key == VK_LEFT && curX > 0) curX-- + else if (key == VK_RIGHT && curX < SIZE - 1) curX++ + else if (key == VK_UP && curY > 0) curY-- + else if (key == VK_DOWN && curY < SIZE - 1) curY++ + else if key == VK_FIRE switchCell(curX,curY) + else if key == 48 run = 0 + + // фон + color(isFinished() ? #00FF00 : #FFFFFF) + frect(0,0,WIDTH,HEIGHT) + // курсор + color(#4444FF) + frect(curX*cellSize, curY*cellSize, cellSize, cellSize) + for (i=0, i CELL_LAST ? CELL_START : nextType +} + +def isFinished() { + // Стартовая труба должна иметь левую точку соприкосновения + if (!supportLeft(board[0][0])) return 0 + // А конечная труба - правую + if (!supportRight(board[SIZE - 1][SIZE - 1])) return 0 + + visited = newarray(SIZE, SIZE) + return isConnected(0, 0, visited) +} + +def isConnected(curX, curY, visited) { + // Если достигли конечной ячейки - выходим. + if ( (curX == SIZE - 1) && (curY == SIZE - 1) ) return 1 + + // Если уже посещали - выходим. + if (visited[curX][curY]) return 0 + // Отмечаем посещение. + visited[curX][curY] = 1 + current = board[curX][curY] + if ( supportLeft(current) && (curX > 0) && (supportRight(board[curX - 1][curY])) ) { + if (isConnected(curX - 1, curY, visited)) return 1 + } + if ( supportRight(current) && (curX < SIZE - 1) && (supportLeft(board[curX + 1][curY])) ) { + if (isConnected(curX + 1, curY, visited)) return 1 + } + if ( supportUp(current) && (curY > 0) && (supportDown(board[curX][curY - 1])) ) { + if (isConnected(curX, curY - 1, visited)) return 1 + } + if ( supportDown(current) && (curY < SIZE - 1) && (supportUp(board[curX][curY + 1])) ) { + if (isConnected(curX, curY + 1, visited)) return 1 + } + return 0 +} +///------------------------------------- + + +///------------------------------------- +/// PIPES MAIN +///------------------------------------- +translateX = 0 translateY = 0 +/* frect с поддержкой translate*/ +def fillRect(x,y,w,h) { + frect(translateX+x, translateY+y, w, h) +} + +// JAVA ME +// showcanvas() +// JAVA SE +WIDTH = 480 HEIGHT = 480 +window("Pipes", WIDTH, HEIGHT) +cellSize = WIDTH / SIZE +createBoard() + +// курсор +curX = 0 +curY = 0 + +run = 1 +while run { + //key = gameaction(keypressed()) + key = keypressed() + if (key == VK_LEFT && curX > 0) curX-- + else if (key == VK_RIGHT && curX < SIZE - 1) curX++ + else if (key == VK_UP && curY > 0) curY-- + else if (key == VK_DOWN && curY < SIZE - 1) curY++ + else if key == VK_FIRE switchCell(curX,curY) + else if key == 48 run = 0 + + // фон + color(isFinished() ? #00FF00 : #FFFFFF) + frect(0,0,WIDTH,HEIGHT) + // курсор + color(#4444FF) + frect(curX*cellSize, curY*cellSize, cellSize, cellSize) + for (i=0, i CELL_LAST ? CELL_START : nextType +} + +def isFinished() { + // Стартовая труба должна иметь левую точку соприкосновения + if (!supportLeft(board[0][0])) return 0 + // А конечная труба - правую + if (!supportRight(board[SIZE - 1][SIZE - 1])) return 0 + + visited = newarray(SIZE, SIZE) + return isConnected(0, 0, visited) +} + +def isConnected(curX, curY, visited) { + // Если достигли конечной ячейки - выходим. + if ( (curX == SIZE - 1) && (curY == SIZE - 1) ) return 1 + + // Если уже посещали - выходим. + if (visited[curX][curY]) return 0 + // Отмечаем посещение. + visited[curX][curY] = 1 + current = board[curX][curY] + if ( supportLeft(current) && (curX > 0) && (supportRight(board[curX - 1][curY])) ) { + if (isConnected(curX - 1, curY, visited)) return 1 + } + if ( supportRight(current) && (curX < SIZE - 1) && (supportLeft(board[curX + 1][curY])) ) { + if (isConnected(curX + 1, curY, visited)) return 1 + } + if ( supportUp(current) && (curY > 0) && (supportDown(board[curX][curY - 1])) ) { + if (isConnected(curX, curY - 1, visited)) return 1 + } + if ( supportDown(current) && (curY < SIZE - 1) && (supportUp(board[curX][curY + 1])) ) { + if (isConnected(curX, curY + 1, visited)) return 1 + } + return 0 +} +///------------------------------------- + + +///------------------------------------- +/// PIPES MAIN +///------------------------------------- +translateX = 0 translateY = 0 +/* frect с поддержкой translate*/ +def fillRect(x,y,w,h) { + frect(translateX+x, translateY+y, w, h) +} + +// JAVA ME +// showcanvas() +// JAVA SE +WIDTH = 480 HEIGHT = 480 +window("Pipes", WIDTH, HEIGHT) +cellSize = WIDTH / SIZE +createBoard() + +// курсор +curX = 0 +curY = 0 + +run = 1 +while run { + //key = gameaction(keypressed()) + key = keypressed() + if (key == VK_LEFT && curX > 0) curX-- + else if (key == VK_RIGHT && curX < SIZE - 1) curX++ + else if (key == VK_UP && curY > 0) curY-- + else if (key == VK_DOWN && curY < SIZE - 1) curY++ + else if key == VK_FIRE switchCell(curX,curY) + else if key == 48 run = 0 + + // фон + color(isFinished() ? #00FF00 : #FFFFFF) + frect(0,0,WIDTH,HEIGHT) + // курсор + color(#4444FF) + frect(curX*cellSize, curY*cellSize, cellSize, cellSize) + for (i=0, i