Closed andybalaam closed 9 years ago
Related: #40
Great idea! A few extra thoughts I had on this.
I like the idea of supporting multiple solutions per file, but I'm not keen on the pseudo-structure created by linking the keys via the 1 (particularly in the author key). Perhaps a solution line could optionally contain the author and URL? Alternatively perhaps something like:
solution.1=blah
solution_author.1=blah
solution_url.1=blah
Good idea. I agree that seeing the solution would be a shame. Not sure rot13 would work to hide this. The ;(),0123456789 would not change.
Maybe put them in a separate file. File with the same name, but .res (rabbit escape solution) extension?
Good point about the digits and punctuation. Maybe base64 encoded then? (Although I think Andy is fluent, so this might not be suitable.) Base64 encoded text is longer than unencoded, but this is a simple readily available encoding that obfuscates a large character set, so I think the extra few bytes isn't a big issue.
Further thought about non-solutions. The obvious format is to use the same as a solution - i.e. just specify some number of steps at the end to wait, and assert the level is not won at that point.
Updated to use :
to separate simultaneous actions within the same time step. Disambiguates from the use of ,
to separate co-ordinates.
Added a note that the brackets around (x,y) could be optional.
@tttppp re 1 I share your distaste at linking in this way but don't want to over-engineer. I like the idea of the solution author and url in the same entry, except this will make very long lines, and URLs can contain lots of weird characters making parsing error-prone.
Given all this I'd go for your suggestion, unless we come up with something better:
solution.1=
solution_author.1=
solution_url.1=
Then we leave ourselves open to some kind of automatic-array-building based on numeric suffixes later, but for now we can treat these as opaque keys.
[If we did automatic array building later, it would be nice to upgrade the hints to use the same scheme. I now regret my "back to basics" approach of not including the dot in those.]
@tttppp re 2 a non-solution is a sequence of actions that results in a world state that is not solved. In theory we could try to provide more assertions e.g. "all rabbits are dead", but I think in practice this will normally be enough. For specific other cases we might just want to write unit tests.
@tttppp re 3 very strong point about providing a proof without giving away the solution. On the other hand, in the real level files we ship I'd like it to be as clear as possible, so probably we should support 2 formats.
How about:
solution.1=base64:MjA7ZGlnOygyLDMpOzU7YmFzaDooNCw1KTsoNSw2KTsxMDs=
Perhaps all level properties should support this optionally.
Bear in mind that my allergy to dependencies might mean we have to implement our own Base64 encoder, until we use Java 8: https://docs.oracle.com/javase/8/docs/api/java/util/Base64.Encoder.html
Updated to use @tttppp's .1 format.
btw, in my mind everything everywhere is utf-8, and that includes the text that we encode to base 64.
Also btw, I am not fluent in base64, yet. I imagine after a few weeks of reading solutions we might be.
https://en.wikipedia.org/wiki/Base64#Sample_Implementation_in_Java
should be simple to change to
:hint.1=
I would prefer something like '_' to ':'. ':' is similar to ';' which makes it hard to read.
solution.1=20;dig;(2,3);5;bash_(4,5);(5,6);10;
I think brackets should be mandatory. This is hard to read becuase ';' is like ','
solution.1=20;dig;2,3;5;bash_4,5;5,6;10;
Good point about being hard to read. In the text UI I may make brackets optional, but in the solution format they can be mandatory.
How about |
to separate 2 things that happen at the same instant? _
feels wrong somehow.
solution.1=20;dig;(2,3);5;bash|(4,5);(5,6);10;
solution.1=20;dig;(2,3);5;bash&(4,5);(5,6);10;
Pipe is good. Another idea: ampersand. It reads nicely: equip bash and drop at (4,5).
Yes @GamingInky and I arrived at &
independently over lunch today. I think it's Right.
yes @andybalaam thought because he doesn't like the & symbol he should make it that to show you shouldn't really use it normally.
Updated to use & and to make brackets non-optional.
I have this mainly working, but it's a bit rough still. Sample solution lines are at the bottom of this unit test file: https://github.com/tttppp/rabbit-escape/blob/ecfce38ad70e0727d4d2f9be65201d234ca50f4d/rabbit-escape-engine/test/rabbitescape/engine/TestTextWorldManip.java
It currently only supports one solution per level, and doesn't allow for credits, but might be of use for checking the levels now we have the fixes that @colonelfazackerley has been making.
Silly me didn't mention we were working on it too. Anyway you're way ahead of us. I'll have a look but from the examples it looks perfect.
I've started adding multiple solution support, but I'm accidentally reusing all the Collections that get passed into the world (I initially thought that creating a new world to test a solution against would be separation enough).
The solution syntax is going to be really hard to use without the solution recording feature. Maybe you could have a look how that can be done? (Particularly how should we output a recording to the player?)
If you wanted to work on the same bit though we could come up with a list of issues with the current implementation and work through them on a branch?
Ok, I think the sandbox game is now actually sandboxed. Still need to test selecting and adding tokens that the user doesn't have any of, and generally find out how rabbit-escape exception handling works! Click recording is still a huge outstanding feature.
Also it would be good for someone trying a level to know that at least one of the solutions is a victory solution. For example the following level has one non-solution, but no solution. If the solution is obfuscated then the player may be tricked into playing for a long time.
:num_rabbits=1
:bash=1
:solution.4=bash;(1,1);9;LOST
Q
# # O
#######
Ah, I was expecting non-solutions to look like:
:nonsolution.1=foo;bar
but I see your syntax elegantly allows us to avoid another key type.
For the reason you give, I wonder whether nonsolution
key name is better. We could also just make Rabbit Escape be verbose enough when testing levels that you can see what is a solution or a non-solution.
Merged into a branch called solutionChecker, which I have pushed to github here: https://github.com/andybalaam/rabbit-escape/tree/solutionChecker
I see no reason not to merge this in and work on it in master, but will wait until @tttppp is happy.
I will add comments for changes I make here.
Somehow the line endings got messed up 81e576ec238245f9985a1b07b3127556855494da
Even thought I hate it, I needed to be able to compare Solutions and various kinds of Instruction: 3ccd6b0392e5275d1aa2f08a65e02936e1b9820a and 3eba6313e4e753c9d2effa2497e5a78bf692f28e
Unit tests for SolutionFactory ff582193fef6d6a93b1d78d4faea4f55969f2929
Simpler regular expression a2360fdd83a6b49af5ab1586cec6851ebba68734
Simpler regex for wait instructions, technically allowing waiting zero, but I think that's probably ok 4f83e637049c497946897cd60773333f0c02e3cc
Break out some of the horrible hoops Java requires you to make to check whether something is in an array into a Util method 19e42e00c18ab235ea60922b95f79a5bbad80b45
Use regex groups to find the place token co-ordinates 57b0a02f4644b7c38590b9156dddb2c98c6f887e
Test some error cases c3ea4b8b636844d7c1832d9458ae7f579629201f
Make the command line interface mostly work 5e10b4391e4551ecdc0e1e9d467335c1cf07fd41 c486debf751074c707b22080925930dd8dc17ed2 3a9cf7c38d99eb463a2d6c4468a0f980237d8bdd
Very primitive solution printing 203bbaf708220d1b2077052295a7089ed484f098
So we now have a way of authoring solutions: make runmenu
, then solve the level. The solution is printed out above the "You won!" message.
@andybalaam Happy to merge this to master now. I wanted to ensure that solutions could be added to the existing levels without breaking anything. I've just demonstrated this in a pull request (hopefully!)
Looking great with the ASCII interface and all your commits from last night. Did you get any sleep?! As well as printing steps above "You won!", I think we should print steps above "You lost!" for non-solutions.
I agree that by default the solution checking should be turned off (for built in levels), but I think it might be good to have it on for github/file level loading. If you agree then let's create a new enhancement ticket for it.
Also it would be good to add solution checking to the "round trip" test.
I think the only things left from this ticket are solution author and solution url.
Did you get any sleep?
I slept about 4.30 to 7.30
Happy to merge this to master now
Cool, I will do that as soon as I get a chance. Much better to be working on a single stream whenever possible.
I agree that by default the solution checking should be turned off (for built in levels), but I think it might be good to have it on for github/file level loading. If you agree then let's create a new enhancement ticket for it.
I agree.
Also it would be good to add solution checking to the "round trip" test.
Yes, I am working on that.
I think the only things left from this ticket are solution author and solution url.
This issue is massive - shall we break them into another one?
As well as printing steps above "You won!", I think we should print steps above "You lost!" for non-solutions.
It actually does - I just didn't describe it very well.
Checking all levels have solutions is #140
I managed to break the build with 1e7e87845818b60cd6b8b8aae20447a989025059 somehow - it needed a make clean test
to see it for some reason. Sorry about that. I fixed it and merged into master.
Solution checking for external levels is #141
Closing since the remaining work has other issues (I think - correct me if I'm wrong).
We plan to support specifying solutions and non-solutions inside levels.
The first use of this will be automated tests that check that all levels are soluble even when we change levels or the rules of the world. Other uses might include ensuring that easy "cheat" solutions are not possible, reporting bugs, demo mode, and unit tests.
Requirements:
Proposal: something like:
Translation:
Wait 20 time steps, then in the next time step select the dig ability, then in the next time step place the selected ability at co-ordinates 2,3.
Wait 5 time steps, then next time step do 2 things simultaneously: select the bash ability and place it at 4,5. In the next time step place another at 5,6.
Wait 10 time steps.
Syntax: