terryebdon / trk21 Goto Github PK
View Code? Open in Web Editor NEWA Groovy version of the 1973 BASIC-PLUS program TREK.BAS, originally written on a PDP-11 running RSTS/E
License: Apache License 2.0
A Groovy version of the 1973 BASIC-PLUS program TREK.BAS, originally written on a PDP-11 running RSTS/E
License: Apache License 2.0
Trek.positionKlingons() is badly named. It does far more than its name implies, and the actual positioning of enemies occurs in trek.positionEnemy(). The commented-out code should also be removed.
This looks like an off-by-one error:
assert key > 0 && key < devices.size()
| | | | | | |
6 true| 6 | | 6
at net.ebdon.trk21.DamageControl.inflictDamage(DamageControl.groovy:121)
i.e. it should be <= device.size()
. It would be better to use a Range for
this, e.g.
assert key in 1..devices.size()
The wrapper method was added as part of an earlier refactoring. The wrapper is not needed, and can be eliminated with Remove Middle Man. The corresponding configuration option, in TrekGameConfig, can also be removed.
Firing a torpedo should:
Note: Some of these items may be implemented as part of issue #3.
junit.framework.AssertionFailedError: course: 8.999999, warpFactor: 0.125
...
at net.ebdon.trk21.ShipVectorTest.testRandomGoodValues(ShipVectorTest.groovy:33)
The testGame() method is very slow, e.g. nearly two and a quarter seconds on an old laptop.
See also issue #18, as I suspect it has the same cause. i.e. Trek is a sub-class of LoggingBase.
jcenter is now obsolete. This breaks clean builds, as the dependencies will no longer download.
Prerequisite for Issue #47.
When "test playing" the game it would save time if the tester could bypass the guess-work required to navigate to a particular sector or quadrant, without resorting to a scientific calculator. A "cheat" or "wizard" mode should be implemented to allow access to this feature. it should be possible to enable and disable the feature via cofinguration.
The quadrant setup code is should be moved out of Trek,groovy, as the Trek class is far too large. Extracting this setup code would make app easier to test and maintain.
Most interaction is localised, but there are some significant ommisions. Resolving these will require some changes to the UI interface classes. The test classes will also need changes, to consistently verify resource bundle usage and not depend on unlocalised messages.
DamageControl holds a reference to the Trek.damage map. This map is directly referenced by:
The damage map should be a private member of DamageControl.
Most of the long range scanning logic is in the main Trek class. It would make more sense for this functionality to be in its own class.
A separate log configuration for test was added by issue #16. The two log configurations are now completely independent of each other. However some configuration is now duplicated, e.g. the log file location and file pattern. It should be possible to move common configuration into a single file.
See also issue #33.
In order to extract the Repositioner class from Trek the new class was given a
reference to Trek. This has resulted in Repositioner being too dependent on
Trek.
The JaCoCo plugin was applied to the build to address issue #19 - Report test coverage. While this works well it is extremely slow. This is apparently due to the instrumentation and analysis (particularly the latter), even when a HTML report is not generated.
C:\projects\Trk21>gradlew test --rerun-tasks
> Task :test
BUILD SUCCESSFUL in 55s
5 actionable tasks: 5 executed
C:\projects\Trk21>gradlew test --rerun-tasks
> Task :test
BUILD SUCCESSFUL in 2m 7s
5 actionable tasks: 5 executed
This method currently has a complexoty value of 33, which is far too high.
See also #24 - Trek.isValid() is overly complex.
When docked the star base will always protect the ship from enemy fire and top-up the ship's energy. Under which circumstances should a docked ship's energy be exhausted?
STARDATE: 2608 CONDITION: DOCKED
QUADRANT: 5 - 7 SECTOR: 5 - 7
ENERGY: 3000 PHOTON TORPEDOS: 10
KLINGONS: 19
Command: p
Number of units to fire: 3000
Phasers locked in on target. Energy available 3000
1137 unit hit on Enemy ship No. 1 at sector 3 - 2
Enemy ship destroyed!
3000 unit hit on Enemy ship No. 2 at sector 6 - 8
Enemy ship destroyed!
987 unit hit on Enemy ship No. 3 at sector 8 - 1
Enemy ship destroyed!
It is stardate 2608
Your ship has been destroyed after 8 years.
Your civilisation will be conquered.
There are still 16 enemy ships.
You are dead.
This should be possible with the Commons Logging Bridge.
The Language resource bundle is located via ClasspathResourceManager
. This should not be needed; it would be better to use ResourceBundle.getBundle
It's possible that the existing code is not respecting the user's locale settings. ๐
See also: #33
Trying to travel through a star base is shown as an impact. Stopping next to a base is docking. But the ship is always docked after an impact. This is possibly confusing.
---------------
. . . . * . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . *
. E . . . . . B
. . . . . . . .
---------------
STARDATE: 2414 CONDITION: GREEN
QUADRANT: 2 - 7 SECTOR: 2 - 7
ENERGY: 877 PHOTON TORPEDOS: 10
KLINGONS: 21
Command: c
Course (1-8.99999): 1
Warp Factor (0-12): 1
Ship blocked by base at sector [7, 8] == 8 - 7
---------------
. . . . * . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . *
. . . . . . E B
. . . . . . . .
---------------
STARDATE: 2415 CONDITION: DOCKED
QUADRANT: 2 - 7 SECTOR: 7 - 7
ENERGY: 3000 PHOTON TORPEDOS: 10
KLINGONS: 21
Use a static code analyser, e.g. CodeNarc, to improve code quality.
The original code performs a short range scan after a course move. My Groovy code does not do this automatically; it should.
Output from original code, running on an emulated PDP-11 via SIMH V39-0
COMMAND? C
COURSE (1-8.99999)? 1
WARP FACTOR (0-12)? 3
---------------
* . * . . . . .
. . . . . . . .
. . E * . . . .
. . . . . . . .
. . . . . . . .
. . B * . . . .
. . . . . . . .
. . . . . . . .
---------------
STARDATE: 3501 CONDITION: YELLOW
QUADRANT: 4 - 6 SECTOR: 3 - 3
ENERGY: 2976 PHOTON TORPEDOS: 10
KLINGONS: 21
COMMAND? ^C
Ready
Code of the form:
log.<level> sprintf( template, args )
Can often be replaced with:
log.<level> template, args
The latter approach is preferred.
When short range sensors are damaged they still responds to an 'S' command, and still display output following course moves.
Command: c
Course (1-8.99999): 1
Warp Factor (0-12): .5
*** Space Storm, device.S.R..SENSORS damaged ***
---------------
. . . . . . . E
. B . . . . . *
. . . . . * . .
. . * . . . . .
. . . . . . . .
. . . * . . . .
. . . . . . . .
. . . . . . . .
---------------
STARDATE: 2812 CONDITION: YELLOW
QUADRANT: 7 - 2 SECTOR: 8 - 1
ENERGY: 2064 PHOTON TORPEDOS: 10
KLINGONS: 33
Command: c
Course (1-8.99999): 5
Warp Factor (0-12): .75
Repair systems are working on damage to device.S.R..SENSORS, state improved to -3
---------------
. E . . . . . .
. B . . . . . *
. . . . . * . .
. . * . . . . .
. . . . . . . .
. . . * . . . .
. . . . . . . .
. . . . . . . .
---------------
STARDATE: 2813 CONDITION: DOCKED
QUADRANT: 7 - 2 SECTOR: 2 - 1
Most of the existing unit tests use JUnit style asserts It would be better to use Grovvy's power assertions as:
Currently the ship's condition is held in a string member variable which is assigned with / checked against various hard-coded values. This makes localisation awkward and requires additional code to check that only allowed values are used. replacing the string with a class / enum would simplify the code. This is also a prerequisite for issues #33 and #37.
Firing a phaser should:
Note: Some of these items may be deferred until torpedo firing is implemented, or moved into their own enhancement.
Changing log levels has a dramatic effect on the run time of a gradle check
command. e.g. on an old & slow laptop it can vary between 28 seconds, at ERROR level, and over 4 minutes, at TRACE level. Separating the test and main log configuration will resolve this.
Log performance and noisiness should also be reviewed, under a separate issue. It would also good to use common logging configuration between test and main where possible; another issue will be raised for this.
Currently Trek.longRangeScan() is difficult to test. It might be better to move it into Galaxy, or a dedicated class.
Trek.isValid() is overly complex. It should be simpler and clearer.
Note: There is a similar problem in FederationShip.isValid().
JaCoCo shows a complexity of 24. See the JaCoCo report for the current values.
The repeated use of != null
should be eliminated by using the ?.
operator. isValid()
should be replaced by valid
. Screen shot is from the JaCoCo detail report.
FAILURE: Build failed with an exception.
* Where:
Build file 'O:\projects\Trk21\build.gradle' line: 52
* What went wrong:
A problem occurred evaluating root project 'trk21'.
> Could not find method compile() for arguments [{group=org.apache.logging.log4j, name=log4j-api, version=2.11.2}] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
There are currently 58 implemented tests, but test coverage is patchy. Implementing code-coverage reporting would provide a bench-mark.
Energy use should be easier to determine from the log. With the log at level debug and using a filter of (fire)|(energy)|(unit)
, with the Atom language-log package, I can see course changes correctly modifying energy levels, but changes due to damage / enemy-fire are less obvious.
See also issue #42.
While docked the ship should be protected from all enemy attacks, but this is not always the case. The enemy fleet will attack under two conditions:
In scenario 1 the ship is protected, and this prevents the fleet from attacking. A check in Trek.enemyAttacksBeforeShipCanMove()
enables this protection.
In scenario 2 the battle computer initiates a fleet counter-attack without asking the ship if it is protected. This is a bug. A fix is required in Battle.enemyCounterAttacks().
The message appears every time a short-range scan is performed:
Using key: [8, 4]
---------------
. . . . . . . .
. . . . . . . .
. . . . . . . *
. . . . . . . .
. . . . . . . .
* . . . . . . .
. * . . . . . .
. E . . . . . .
---------------
STARDATE: 3600 CONDITION: YELLOW
QUADRANT: 4 - 8 SECTOR: 2 - 8
ENERGY: 3000 PHOTON TORPEDOS: 10
KLINGONS: 23
Looks like the culprit is line 38 in Galaxy.groovy.
It should be relatively easy to eliminate the FederationShipMock class. Getting
rid of TrekMock may be more difficult, due to the coupling between trek and
Repositioner.
Command: s
---------------
. . * . . . . .
. . . . . . . .
. . . . E . . *
. . . . . B . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
---------------
STARDATE: 3116 CONDITION: DOCKED
QUADRANT: 4 - 5 SECTOR: 5 - 3
ENERGY: 3000 PHOTON TORPEDOS: 10
KLINGONS: 17
Command: c
Course (1-8.99999): 7
Warp Factor (0-12): .2
Command: s
---------------
. . * . . . . .
. . . . . . . .
. . . . E . . *
. . . . . B . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
---------------
STARDATE: 3116 CONDITION: DOCKED
QUADRANT: 4 - 5 SECTOR: 5 - 3
ENERGY: 3000 PHOTON TORPEDOS: 10
KLINGONS: 17
Command:
Trk21 is build with Groovy version 2.5.8,, the latest Groovy release is 4.0.6. This is not a "drop-in" replacement, as some Groovy classes have changed or moved. e.g. AntBuilder
. New versions of Jacoco and CodeNarc will be required. Also the Gradlew wrapper will have to be updated.
From: build.gradle:
implementation 'org.codehaus.groovy:groovy-all:2.5.8'
Depends on issue #48.
This is odd as the code looks OK, from a quick glance. (Ignore the hard-coded messages and keys, they're logged as seperate issues.)
Despite the above test a warp factor of .2 is rejected:
This may be related to issue #6 - Minimum warp factor should be 0.125, not 0.25, though that issue is closed.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.