mirror of
https://github.com/git-learning-game/oh-my-git.git
synced 2024-11-03 19:04:40 +01:00
Write more time-travel levels. Order of chapters in "levels/sequence".
This commit is contained in:
parent
0d097a965d
commit
e638ea2097
10 changed files with 336 additions and 55 deletions
121
cardgame.gd
121
cardgame.gd
|
@ -1,73 +1,92 @@
|
||||||
extends Control
|
extends Control
|
||||||
|
|
||||||
var cards = [
|
var cards = [
|
||||||
|
# {
|
||||||
|
# "command": 'git add .',
|
||||||
|
# "arg_number": 0,
|
||||||
|
# "description": "Add all files in the working directory to the index.",
|
||||||
|
# "energy": 1
|
||||||
|
# },
|
||||||
|
#
|
||||||
|
# {
|
||||||
|
# "command": 'touch "file$RANDOM"',
|
||||||
|
# "arg_number": 0,
|
||||||
|
# "description": "Create a new file.",
|
||||||
|
# "energy": 2
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "command": 'git checkout -b "$RANDOM"',
|
||||||
|
# "arg_number": 0,
|
||||||
|
# "description": "Create a new branch and switch to it.",
|
||||||
|
# "energy": 2
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "command": 'git merge',
|
||||||
|
# "arg_number": 1,
|
||||||
|
# "description": "Merge specified commit into HEAD.",
|
||||||
|
# "energy": 1
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "command": 'git commit --allow-empty -m "$RANDOM"',
|
||||||
|
# "arg_number": 0,
|
||||||
|
# "description": "Add a new commit under HEAD.",
|
||||||
|
# "energy": 1
|
||||||
|
# },
|
||||||
{
|
{
|
||||||
"command": 'git add .',
|
"command": 'git checkout',
|
||||||
"arg_number": 0,
|
"arg_number": 1,
|
||||||
"description": "Add all files in the working directory to the index.",
|
"description": "Travel to a commit!",
|
||||||
|
#"description": "Point HEAD to a branch or commit, and update the index and the working directory.",
|
||||||
"energy": 1
|
"energy": 1
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"command": 'touch "file$RANDOM"',
|
"command": 'git add .; git commit',
|
||||||
"arg_number": 0,
|
"arg_number": 0,
|
||||||
"description": "Create a new file.",
|
"description": "Make a new commit!",
|
||||||
"energy": 2
|
"energy": 1
|
||||||
},
|
|
||||||
{
|
|
||||||
"command": 'git checkout -b "$RANDOM"',
|
|
||||||
"arg_number": 0,
|
|
||||||
"description": "Create a new branch and switch to it.",
|
|
||||||
"energy": 2
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": 'git merge',
|
"command": 'git merge',
|
||||||
"arg_number": 1,
|
"arg_number": 1,
|
||||||
"description": "Merge specified commit into HEAD.",
|
"description": "Merge the specified timeline into yours.",
|
||||||
"energy": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command": 'git commit --allow-empty -m "$RANDOM"',
|
|
||||||
"arg_number": 0,
|
|
||||||
"description": "Add a new commit under HEAD.",
|
|
||||||
"energy": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command": 'git checkout',
|
|
||||||
"arg_number": 1,
|
|
||||||
"description": "Point HEAD to a branch or commit, and update the index and the working directory.",
|
|
||||||
"energy": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command": 'git update-ref -d',
|
|
||||||
"arg_number": 1,
|
|
||||||
"description": "Delete a ref.",
|
|
||||||
"energy": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command": 'git reflog expire --expire=now --all; git prune',
|
|
||||||
"arg_number": 0,
|
|
||||||
"description": "Delete all unreferenced objects.",
|
|
||||||
"energy": 1
|
"energy": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": 'git rebase',
|
"command": 'git rebase',
|
||||||
"arg_number": 1,
|
"arg_number": 1,
|
||||||
"description": "Rebase current branch on top of specified commit.",
|
"description": "Put the events in your current timeline on top of the specified one.",
|
||||||
"energy": 1
|
"energy": 1
|
||||||
},
|
},
|
||||||
{
|
# {
|
||||||
"command": 'git push -f',
|
# "command": 'git update-ref -d',
|
||||||
"arg_number": 0,
|
# "arg_number": 1,
|
||||||
"description": "Push current branch to the remote, overwriting existing commits. Will make everyone angry.",
|
# "description": "Delete a ref.",
|
||||||
"energy": 3
|
# "energy": 1
|
||||||
},
|
# },
|
||||||
{
|
# {
|
||||||
"command": 'git pull',
|
# "command": 'git reflog expire --expire=now --all; git prune',
|
||||||
"arg_number": 0,
|
# "arg_number": 0,
|
||||||
"description": "Pull current branch from the remote.",
|
# "description": "Delete all unreferenced objects.",
|
||||||
"energy": 2
|
# "energy": 1
|
||||||
},
|
# },
|
||||||
|
# {
|
||||||
|
# "command": 'git rebase',
|
||||||
|
# "arg_number": 1,
|
||||||
|
# "description": "Rebase current branch on top of specified commit.",
|
||||||
|
# "energy": 1
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "command": 'git push -f',
|
||||||
|
# "arg_number": 0,
|
||||||
|
# "description": "Push current branch to the remote, overwriting existing commits. Will make everyone angry.",
|
||||||
|
# "energy": 3
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "command": 'git pull',
|
||||||
|
# "arg_number": 0,
|
||||||
|
# "description": "Pull current branch from the remote.",
|
||||||
|
# "energy": 2
|
||||||
|
# },
|
||||||
]
|
]
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
|
18
levels.gd
18
levels.gd
|
@ -18,13 +18,27 @@ func reload():
|
||||||
var file = dir.get_next()
|
var file = dir.get_next()
|
||||||
if file == "":
|
if file == "":
|
||||||
break
|
break
|
||||||
elif not file.begins_with("."):
|
elif not file.begins_with(".") and file != "sequence":
|
||||||
chapter_names.append(file)
|
chapter_names.append(file)
|
||||||
|
|
||||||
dir.list_dir_end()
|
dir.list_dir_end()
|
||||||
chapter_names.sort()
|
chapter_names.sort()
|
||||||
|
|
||||||
for c in chapter_names:
|
var final_chapter_sequence = []
|
||||||
|
|
||||||
|
var chapter_sequence = Array(helpers.read_file("res://levels/sequence", "").split("\n"))
|
||||||
|
|
||||||
|
for chapter in chapter_sequence:
|
||||||
|
if chapter == "":
|
||||||
|
continue
|
||||||
|
if not chapter_names.has(chapter):
|
||||||
|
helpers.crash("Chapter '%s' is specified in the sequence, but could not be found" % chapter)
|
||||||
|
chapter_names.erase(chapter)
|
||||||
|
final_chapter_sequence.push_back(chapter)
|
||||||
|
|
||||||
|
final_chapter_sequence += chapter_names
|
||||||
|
|
||||||
|
for c in final_chapter_sequence:
|
||||||
var chapter = Chapter.new()
|
var chapter = Chapter.new()
|
||||||
chapter.load("res://levels/%s" % c)
|
chapter.load("res://levels/%s" % c)
|
||||||
chapters.push_back(chapter)
|
chapters.push_back(chapter)
|
||||||
|
|
2
levels/sequence
Normal file
2
levels/sequence
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
time-machine
|
||||||
|
low-level
|
41
levels/time-machine/branches
Normal file
41
levels/time-machine/branches
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
[description]
|
||||||
|
|
||||||
|
In this zoo, we found a few parallel timelines. Feel free to travel between the commits to see what's going on! The ends of the timelines have little tags attached.
|
||||||
|
|
||||||
|
But especially the `bad_ending` one needs our attention! Can you travel to the `good_ending` one, and make a new commit that makes everyone happy?
|
||||||
|
|
||||||
|
[setup]
|
||||||
|
|
||||||
|
git checkout -b bad_ending
|
||||||
|
|
||||||
|
mkdir cage
|
||||||
|
mkdir toy_shop
|
||||||
|
echo "Looks very hungry." > cage/lion
|
||||||
|
|
||||||
|
echo "A small child.
|
||||||
|
It really loves cats!
|
||||||
|
It's holding a lollipop." > child
|
||||||
|
git add .
|
||||||
|
git commit -m "The beginning"
|
||||||
|
|
||||||
|
mv child cage
|
||||||
|
git add .
|
||||||
|
git commit -m "The child is curious"
|
||||||
|
git branch good_ending
|
||||||
|
|
||||||
|
git rm cage/child
|
||||||
|
echo "Looks happy. :)" > cage/lion
|
||||||
|
git commit -m "Oh no"
|
||||||
|
|
||||||
|
git checkout HEAD~2
|
||||||
|
git checkout -b boring_ending
|
||||||
|
mv child toy_shop
|
||||||
|
git add .
|
||||||
|
git commit -m "The child is distracted"
|
||||||
|
|
||||||
|
git checkout bad_ending
|
||||||
|
|
||||||
|
[win]
|
||||||
|
|
||||||
|
# Is the child still there, and do we have a commit that's not in bad_ending?
|
||||||
|
{ git ls-tree --name-only -r good_ending | grep child; } && { test "$(git log good_ending ^bad_ending --oneline | wc -l)" -gt 0; }
|
32
levels/time-machine/conflict
Normal file
32
levels/time-machine/conflict
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
[description]
|
||||||
|
|
||||||
|
Sometimes, merging timelines will not be as simple, because they contradict each other.
|
||||||
|
|
||||||
|
For example, in this case, one of our clients wants these timelines merged, but they ate different things for breakfast in both timelines.
|
||||||
|
|
||||||
|
Try to merge them together! You'll notice that there will be a conflict! The time machine will leave it up to you how to proceed: you can edit the problematic item, it will show you the conflicting sections. You can keep either of the two versions - or create a combination of them! Remove the >>>, <<<, and === markers, and make a new commit to finalize the merge!
|
||||||
|
|
||||||
|
Again, let your finalized timeline be the "main" one.
|
||||||
|
|
||||||
|
[setup]
|
||||||
|
|
||||||
|
echo "Just woke up. Is hungry." > tom
|
||||||
|
git add .
|
||||||
|
git commit -m "The beginning"
|
||||||
|
|
||||||
|
git checkout -b pancakes
|
||||||
|
echo "Had blueberry pancakes with maple syrup for breakfast." > tom
|
||||||
|
git add .
|
||||||
|
git commit -m "Pancakes!"
|
||||||
|
|
||||||
|
git checkout -b muesli main
|
||||||
|
echo "Had muesli with oats and strawberries for breakfast." > tom
|
||||||
|
git add .
|
||||||
|
git commit -m "Muesli!"
|
||||||
|
|
||||||
|
git checkout main
|
||||||
|
|
||||||
|
[win]
|
||||||
|
|
||||||
|
# main has a parent, and the parent of both its first and child parents are the same commit:
|
||||||
|
git rev-parse main^ && test "$(git rev-parse main^1~)" = "$(git rev-parse main^2~)"
|
61
levels/time-machine/merge
Normal file
61
levels/time-machine/merge
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
[description]
|
||||||
|
|
||||||
|
Didn't get enouth sleep last night? Here's a trick so that you can sleep a bit longer: just do all your morning activities in parallel universes, and then at the end, merge them together!
|
||||||
|
|
||||||
|
There are already timelines where you get a baguette and coffee. Can you make a third one where you get a donut? Drag the "branch" card to a commit to make a new branch there.
|
||||||
|
|
||||||
|
And then, use the "merge" card to join the specified timeline together with your current one. If you merge everything into "main" in the end, into a reality where you have a baguette, a coffee, and a dount, and are outside of all shops, you can still make it to work on time!
|
||||||
|
|
||||||
|
[setup]
|
||||||
|
|
||||||
|
mkdir bakery coffee_shop donut_shop
|
||||||
|
|
||||||
|
echo "A friendly old lady.
|
||||||
|
Sells delicious baguettes for 5 coins each." > bakery/mary
|
||||||
|
|
||||||
|
echo "A rebellious teenager.
|
||||||
|
Sells good coffee for 2 coins each." > coffee_shop/larry
|
||||||
|
|
||||||
|
echo "A snail. Literally a snail.
|
||||||
|
Sells donuts with an unspecified, slimy filling - for 3 coins each." > donut_shop/gary
|
||||||
|
|
||||||
|
echo "You do not have a baguette.
|
||||||
|
|
||||||
|
You do not have coffee.
|
||||||
|
|
||||||
|
You do not have a donut." > you
|
||||||
|
|
||||||
|
git add .
|
||||||
|
git commit -m "The Beginning"
|
||||||
|
|
||||||
|
git checkout -b baguette
|
||||||
|
echo "You have a baguette.
|
||||||
|
|
||||||
|
You do not have coffee.
|
||||||
|
|
||||||
|
You do not have a donut." > you
|
||||||
|
git mv you bakery
|
||||||
|
git add .
|
||||||
|
git commit -m "You get a baguette"
|
||||||
|
git mv bakery/you .
|
||||||
|
git add .
|
||||||
|
git commit -m "You leave the bakery"
|
||||||
|
|
||||||
|
git checkout -b coffee main
|
||||||
|
echo "You do not have a baguette.
|
||||||
|
|
||||||
|
You have coffee.
|
||||||
|
|
||||||
|
You do not have a donut." > you
|
||||||
|
git mv you coffee_shop
|
||||||
|
git add .
|
||||||
|
git commit -m "You get some coffee"
|
||||||
|
git mv coffee_shop/you .
|
||||||
|
git add .
|
||||||
|
git commit -m "You leave the coffee_shop"
|
||||||
|
|
||||||
|
git checkout main
|
||||||
|
|
||||||
|
[win]
|
||||||
|
|
||||||
|
{ git show main:you | grep "You have a baguette"; } && { git show main:you | grep "You have coffee"; } && { git show main:you | grep "You have a donut"; }
|
72
levels/time-machine/rebase
Normal file
72
levels/time-machine/rebase
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
[description]
|
||||||
|
|
||||||
|
Okay - turns out that saving time in the morning by utilizing parallel universes is against the regulations of the International Time Travel Association. You'll have to do your tasks in sequence after all.
|
||||||
|
|
||||||
|
See the "rebase" card? It takes a specified commit, and puts the events in your current timeline on top of the specified one! This way, make a clean, linear timeline where you visit all three shops.
|
||||||
|
|
||||||
|
[setup]
|
||||||
|
|
||||||
|
mkdir bakery coffee_shop donut_shop
|
||||||
|
|
||||||
|
echo "A friendly old lady.
|
||||||
|
Sells delicious baguettes for 5 coins each." > bakery/mary
|
||||||
|
|
||||||
|
echo "A rebellious teenager.
|
||||||
|
Sells good coffee for 2 coins each." > coffee_shop/larry
|
||||||
|
|
||||||
|
echo "A snail. Literally a snail.
|
||||||
|
Sells donuts with an unspecified, slimy filling - for 3 coins each." > donut_shop/gary
|
||||||
|
|
||||||
|
echo "You do not have a baguette.
|
||||||
|
|
||||||
|
You do not have coffee.
|
||||||
|
|
||||||
|
You do not have a donut." > you
|
||||||
|
|
||||||
|
git add .
|
||||||
|
git commit -m "The Beginning"
|
||||||
|
|
||||||
|
git checkout -b baguette
|
||||||
|
echo "You have a baguette.
|
||||||
|
|
||||||
|
You do not have coffee.
|
||||||
|
|
||||||
|
You do not have a donut." > you
|
||||||
|
git mv you bakery
|
||||||
|
git add .
|
||||||
|
git commit -m "You get a baguette"
|
||||||
|
git mv bakery/you .
|
||||||
|
git add .
|
||||||
|
git commit -m "You leave the bakery"
|
||||||
|
|
||||||
|
git checkout -b coffee main
|
||||||
|
echo "You do not have a baguette.
|
||||||
|
|
||||||
|
You have coffee.
|
||||||
|
|
||||||
|
You do not have a donut." > you
|
||||||
|
git mv you coffee_shop
|
||||||
|
git add .
|
||||||
|
git commit -m "You get some coffee"
|
||||||
|
git mv coffee_shop/you .
|
||||||
|
git add .
|
||||||
|
git commit -m "You leave the coffee shop"
|
||||||
|
|
||||||
|
git checkout -b donut main
|
||||||
|
echo "You do not have a baguette.
|
||||||
|
|
||||||
|
You do not have coffee.
|
||||||
|
|
||||||
|
You have a donut." > you
|
||||||
|
git mv you donut_shop
|
||||||
|
git add .
|
||||||
|
git commit -m "You get a donut"
|
||||||
|
git mv donut_shop/you .
|
||||||
|
git add .
|
||||||
|
git commit -m "You leave the donut shop"
|
||||||
|
|
||||||
|
git checkout baguette
|
||||||
|
|
||||||
|
[win]
|
||||||
|
|
||||||
|
{ git show main:you | grep "You have a baguette"; } && { git show main:you | grep "You have coffee"; } && { git show main:you | grep "You have a donut"; } && { test "$(git log main --oneline | wc -l)" -eq 7; }
|
40
levels/time-machine/welcome
Normal file
40
levels/time-machine/welcome
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
[description]
|
||||||
|
|
||||||
|
Welcome, time agent! Good to see you - we could really use your help with fixing some temporal paradoxes!
|
||||||
|
|
||||||
|
First, let's make you familiar with the time machine you'll be using: each yellow box you see is a frozen point in time, we call them "commits"! You can travel to one by dragging the "checkout" card to it, and you can go back to the present by dragging it on the blue "main" node!
|
||||||
|
|
||||||
|
The grey panel to the left shows your current environment - click on an object to inspect or modify it!
|
||||||
|
|
||||||
|
Can you find out what happened here? Then, come back to the present, fix the problem, and make a new commit!
|
||||||
|
|
||||||
|
[setup]
|
||||||
|
|
||||||
|
mkdir room1 room2
|
||||||
|
echo "A young girl with brown, curly hair." > room1/little_sister
|
||||||
|
echo "This piggy bank belongs to the big sister.
|
||||||
|
It contains 10 coins." > room2/piggy_bank
|
||||||
|
git add .
|
||||||
|
git commit -m "The beginning"
|
||||||
|
|
||||||
|
mv room1/little_sister room2
|
||||||
|
git add .
|
||||||
|
git commit -m "Little sister walks over"
|
||||||
|
|
||||||
|
echo "Has 10 coins." >> room2/little_sister
|
||||||
|
echo "This piggy bank belongs to the big sister.
|
||||||
|
It is empty." > room2/piggy_bank
|
||||||
|
git add .
|
||||||
|
git commit -m "Little sister does something"
|
||||||
|
|
||||||
|
mv room2/little_sister room1
|
||||||
|
git add .
|
||||||
|
git commit -m "Little sister walks back"
|
||||||
|
|
||||||
|
[win]
|
||||||
|
|
||||||
|
{ git show refs/heads/main:room2/piggy_bank | grep "10 coins"; } && { git show refs/heads/main:room1/little_sister | grep -v "10 coins"; }
|
||||||
|
|
||||||
|
[congrats]
|
||||||
|
|
||||||
|
Wonderful! Now that you're familiar with the time machine, let's look at some more complicated situations...
|
2
main.gd
2
main.gd
|
@ -27,7 +27,7 @@ func _ready():
|
||||||
helpers.crash("Could not change to sandbox scene")
|
helpers.crash("Could not change to sandbox scene")
|
||||||
return
|
return
|
||||||
|
|
||||||
current_chapter = 1
|
current_chapter = 0
|
||||||
current_level = 0
|
current_level = 0
|
||||||
|
|
||||||
# Initialize level select.
|
# Initialize level select.
|
||||||
|
|
2
shell.gd
2
shell.gd
|
@ -15,7 +15,7 @@ func cd(dir):
|
||||||
# Run a shell command given as a string. Run this if you're interested in the
|
# Run a shell command given as a string. Run this if you're interested in the
|
||||||
# output of the command.
|
# output of the command.
|
||||||
func run(command, crash_on_fail=true):
|
func run(command, crash_on_fail=true):
|
||||||
var debug = false
|
var debug = true
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
print("$ %s" % command)
|
print("$ %s" % command)
|
||||||
|
|
Loading…
Reference in a new issue