Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/nrw-abitur-list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
type: minor
---

Add an NRW version of the library, `scratch-<version>-nrw-all.jar`, for courses that use the classes of the NRW Zentralabitur. In it, `Stage.find`, `Stage.getAll` and `Sprite.getTouchingSprites` return the Abitur's `List` instead of `java.util.List`, so students can write `List<Gegner> gegner = find(Gegner.class);`. `List.java` from the Abitur classes has to be in the project's default package. The normal JAR is unchanged.
11 changes: 10 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,15 @@ jobs:
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}

- name: Build fat jar
- name: Build NRW jar
# The NRW build returns the List of the NRW Zentralabitur from find,
# getAll and getTouchingSprites. It is only offered as a download, and
# the next step cleans target/, so the jars are put aside first.
run: |
mvn -B clean package -Pall,nrw
mkdir -p dist
cp target/*-nrw-all.jar target/*-nrw-sources.jar dist/

# Tests already ran as part of the deploy step above; skip them here
# to avoid paying for the full suite twice in the same job.
run: mvn -B clean package -Pall -DskipTests
Expand All @@ -66,6 +74,7 @@ jobs:
body: ${{ github.event.pull_request.body || format('Automated release of version {0}', env.VERSION) }}
files: |
target/*.jar
dist/*.jar

- name: Delete changeset branch
run: |
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ keeping the same mental model (Window / Stage / Sprite, costumes, backdrops, bro
- `mvn test` — run the JUnit 5 test suite (152 tests)
- `mvn clean package` — build the JAR
- `mvn clean package -Pall` — build a standalone JAR with all dependencies shaded in (maven-shade-plugin)
- `mvn clean package -Pall,nrw` — build the NRW Abitur version (`target/scratch-<version>-nrw-all.jar`), in which `find`, `getAll` and `getTouchingSprites` return the `List` of the NRW Zentralabitur. The sources are rewritten from the `// nrw-standard-begin` / `// nrw:` markers in `Stage.java` and `Sprite.java` by `src/tools/java/variants/NrwVariant.java`; tests, examples and docs are skipped in that build
- `mvn deploy -Pcentral` — release to Maven Central (GPG signing + central-publishing-maven-plugin); not something to run casually
- `./build.sh` — full doc site build: copies CHANGELOG into the docs book, regenerates reference GIFs from `src/examples/java/reference`, substitutes the version into docs, then runs `npx hyperbook build` inside `docs/`
- `cd docs && npx hyperbook dev` — run the documentation site locally
Expand Down
168 changes: 168 additions & 0 deletions docs/book/abitur-nrw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
---
name: Abiturklassen NRW
index: 5
---

# Abiturklassen NRW

In North Rhine-Westphalia the Zentralabitur in computer science comes with its
own classes: `List`, `Queue`, `Stack`, `BinaryTree`, `BinarySearchTree`,
`ComparableContent`, `Graph`, `Vertex`, `Edge`, `DatabaseConnector` and
`QueryResult`. Students work with them throughout the Oberstufe, and they are the
classes the Abitur tasks are written against.

You can use them together with Scratch for Java. The Abiturklassen then hold the
sprites of your game, for example all the enemies on the stage in a `List`.

## Two versions of Scratch for Java

Scratch for Java comes in two versions. They differ in three methods, which hand
you a list of sprites:

| JAR | `find`, `getAll` and `getTouchingSprites` return |
| ------------------------------- | ------------------------------------------------ |
| `scratch-<version>-all.jar` | Java's own `java.util.List` |
| `scratch-<version>-nrw-all.jar` | the `List` of the Abiturklassen |

Everything else is the same in both. If your course uses the Abiturklassen, take
the NRW version from the [Download](/download) page.

## Setting up a project

1. Download `scratch-<version>-nrw-all.jar` from the [Download](/download) page
and add it to your project, the same way as described in [Setup](/setup). In
BlueJ, for example, put it into the `+libs` folder of your project.
2. Get the Abiturklassen. QUA-LiS NRW publishes them on the Lehrplannavigator as
[Implementationen von Klassen für das Zentralabitur ab 2018](https://lehrplannavigator.nrw.de/system/files/media/document/file/2020-03-11_implementationen_von_klassen_fuer_das_zentralabitur_ab_2018.zip)
(ZIP). Your teacher may also hand them out.
3. Copy the `.java` files you need into your project, next to your own classes.
`List.java` is the one Scratch for Java needs. Take the others as your course
uses them. `Graph.java` needs `List.java`, and `DatabaseConnector.java` needs
`Queue.java` and `QueryResult.java`.

A BlueJ project then looks like this:

```text
MeinSpiel/
+libs/
scratch-<version>-nrw-all.jar
List.java <- from the Abiturklassen
Queue.java <- from the Abiturklassen, if you use it
MyStage.java <- your classes
Gegner.java
Muenze.java
```

Do not put the Abiturklassen into a package, and do not put them into `+libs`.
They have to sit next to your own classes. Do not change the files either. Use
them exactly as they come.

## Using the List

With the NRW version, write the Abitur's `List` on the left, and the sprites come
back in it.

In a stage, `find` gives you all sprites of one class:

```java
List<Gegner> gegner = find(Gegner.class);
gegner.toFirst();
while (gegner.hasAccess()) {
gegner.getContent().changeY(-5);
gegner.next();
}
```

`getAll` gives you every sprite on the stage:

```java
List<Sprite> alle = getAll();
alle.toFirst();
while (alle.hasAccess()) {
alle.getContent().hide();
alle.next();
}
```

In a sprite, `getTouchingSprites` gives you the sprites it is touching right now:

```java
List<Muenze> muenzen = getTouchingSprites(Muenze.class);
muenzen.toFirst();
while (muenzen.hasAccess()) {
getStage().remove(muenzen.getContent());
muenzen.next();
}
```

Each call returns a new list. Adding to it or removing from it does not add
sprites to the stage or remove them. Use `add` and `remove` on the stage for that,
as in the last example.

## Using the other Abiturklassen

The other Abiturklassen need nothing special. Create them yourself and put sprites
into them like any other object. A `Queue` lets enemies take turns, for example:

```java
Queue<Gegner> warteschlange = new Queue<>();

List<Gegner> gegner = find(Gegner.class);
gegner.toFirst();
while (gegner.hasAccess()) {
warteschlange.enqueue(gegner.getContent());
gegner.next();
}

// later, whenever it is the next enemy's turn
Gegner amZug = warteschlange.front();
warteschlange.dequeue();
amZug.move(20);
warteschlange.enqueue(amZug);
```

## How it works

The Abiturklassen are **not** part of Scratch for Java. The NRW version only
expects a class called `List` in your project. Whenever `find`, `getAll` or
`getTouchingSprites` is called, it looks that class up, creates an empty list
with `new List()`, adds the sprites with `append`, and hands the list to you.

That is why `List.java` has to be in your project, and why it works with the files
exactly as QUA-LiS publishes them. It is always your copy of the Abiturklassen
that is used, never a different one.

## Troubleshooting

**`incompatible types: java.util.List<…> cannot be converted to List<…>`**

You are using the normal JAR. Replace it with `scratch-<version>-nrw-all.jar`.

**`There is no class List in your project.`**

`List.java` is missing, is in a package, or is in `+libs`. Copy it next to your
own classes.

**`var` does not work**

`var gegner = find(Gegner.class);` does not tell Java which list you want. Write
the type out: `List<Gegner> gegner = find(Gegner.class);`.

**The examples in the reference do not compile**

The examples in the reference are written for the normal version, for example
`find(Coin.class).size()`. With the NRW version, walk through the list with
`toFirst`, `hasAccess` and `next` instead.

## Using the Abiturklassen with the normal version

You can also keep the normal JAR and still use the Abiturklassen for everything
else. Then `find`, `getAll` and `getTouchingSprites` return Java's list. The
name `List` means the Abitur's list, so write Java's list with its full name:

```java
java.util.List<Gegner> gegner = find(Gegner.class);
for (Gegner g : gegner) {
g.hide();
}
```
10 changes: 10 additions & 0 deletions docs/book/download.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ If you also need the JavaDoc, i.e., the documentation of the classes, it can be

It is best to add all three JAR files so that autocomplete and documentation lookup work correctly in your IDE.

### NRW Abitur version

If your course uses the classes of the NRW Zentralabitur, there is a version in
which `find`, `getAll` and `getTouchingSprites` return their `List`. See
[Abiturklassen NRW](/abitur-nrw).

::download[All Operating Systems (NRW)]{src="https://github.com/openpatch/scratch-for-java/releases/latest/download/scratch-{{VERSION}}-nrw-all.jar"}

::download[Sources (NRW)]{src="https://github.com/openpatch/scratch-for-java/releases/latest/download/scratch-{{VERSION}}-nrw-sources.jar"}

## Maven Central

```xml
Expand Down
6 changes: 6 additions & 0 deletions docs/book/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ index: 2

# Setup

:::alert{info}
Does your course use the Abiturklassen of the NRW Zentralabitur (`List`, `Queue`,
`Graph`, …)? Then read [Abiturklassen NRW](/abitur-nrw) first. There is a version
of Scratch for Java made for them.
:::

## VS Code (Recommended)

First make sure you have the Java Extension Pack installed. You can find it in the Extensions view by searching for `redhat.java`.
Expand Down
79 changes: 77 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
<libs.jackson>3.2.1</libs.jackson>
<libs.junit>5.11.4</libs.junit>
<libs.imagecomparison>4.4.0</libs.imagecomparison>
<!-- The nrw profile compiles a rewritten copy of the sources instead. -->
<scratch.sourceDirectory>src/main/java</scratch.sourceDirectory>
<scratch.allClassifier>all</scratch.allClassifier>
</properties>

<dependencies>
Expand Down Expand Up @@ -221,7 +224,7 @@
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>all</shadedClassifierName>
<shadedClassifierName>${scratch.allClassifier}</shadedClassifierName>
<transformers>
<!--
Merges META-INF/services instead of letting one jar
Expand All @@ -239,9 +242,80 @@
</plugins>
</build>
</profile>

<!--
The NRW build: find, getAll and getTouchingSprites return the List
of the NRW Zentralabitur instead of java.util.List. The sources are
rewritten by src/tools/java/variants/NrwVariant.java and compiled in
place of src/main/java. Examples, tests and the documentation are
written against the normal build, so they are left out.

mvn clean package -Pall,nrw -> target/scratch-<version>-nrw-all.jar
-->
<profile>
<id>nrw</id>
<properties>
<scratch.sourceDirectory>${project.build.directory}/nrw-sources</scratch.sourceDirectory>
<scratch.allClassifier>nrw-all</scratch.allClassifier>
<maven.test.skip>true</maven.test.skip>
<maven.javadoc.skip>true</maven.javadoc.skip>
</properties>
<build>
<finalName>${project.artifactId}-${project.version}-nrw</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>generate-nrw-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>${java.home}/bin/java</executable>
<workingDirectory>${project.basedir}</workingDirectory>
<arguments>
<argument>src/tools/java/variants/NrwVariant.java</argument>
<argument>src/main/java</argument>
<argument>${project.build.directory}/nrw-sources</argument>
</arguments>
</configuration>
</execution>
<execution>
<id>generate-asset-pages</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-examples-source</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<executions>
<execution>
<id>clean-reference-docs</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>

<build>
<sourceDirectory>${scratch.sourceDirectory}</sourceDirectory>
<plugins>
<!-- Compiler -->
<plugin>
Expand All @@ -265,6 +339,7 @@
<exclude>demos/**</exclude>
<exclude>reference/**</exclude>
<exclude>tools/**</exclude>
<exclude>variants/**</exclude>
</excludes>
</configuration>
</plugin>
Expand Down Expand Up @@ -434,7 +509,7 @@
</tag>
</tags>
<excludePackageNames>
demos.*:demos:reference.*:reference,doclets.*:doclets,docs.*:docs
demos.*:demos:reference.*:reference,doclets.*:doclets,docs.*:docs,variants.*:variants
</excludePackageNames>
<doclint>all,-missing</doclint>
</configuration>
Expand Down
Loading
Loading