Skip to content

Commit 536e860

Browse files
committed
add games folder and simple game demonstrating nu code concepts
1 parent 123cc5f commit 536e860

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed

games/humlespring_adventure.nu

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
#!/usr/bin/env nu
2+
3+
# --- Game Data ---
4+
5+
# Define the locations in the village
6+
let map = {
7+
village_square: {
8+
desc: "You are in the charming village square of Humlespring. Cobblestones pave the ground. Paths lead north, east, and west. Olivia is here, looking worried."
9+
exits: { north: "tavern", east: "market", west: "alexander_house" }
10+
items: ["leaflet"]
11+
npcs: {
12+
olivia: "Olivia paces back and forth. 'Oh, Alexander... have you seen Mittens? My cat is missing! I last saw her near the old oak tree by the market.'"
13+
}
14+
},
15+
tavern: {
16+
desc: "The 'Leaky Mug' tavern. It smells faintly of ale and sawdust. The only exit is south."
17+
exits: { south: "village_square" }
18+
items: ["mug"]
19+
npcs: {}
20+
},
21+
market: {
22+
desc: "The village market area. Stalls are mostly empty now, but an old oak tree stands tall nearby. A faint 'meow' can be heard from the tree. The path leads back west."
23+
exits: { west: "village_square" }
24+
items: [] # Mittens isn't an 'item' to take, but is found here
25+
npcs: {}
26+
special: "You look up the old oak tree and see Mittens stuck on a branch! You carefully coax her down." # Add a trigger for this
27+
},
28+
alexander_house: {
29+
desc: "You are outside a small, tidy cottage. This must be Alexander's house. The only exit is east. Alexander is tending his small garden."
30+
exits: { east: "village_square" }
31+
items: ["watering_can"]
32+
npcs: {
33+
alexander: "'Ah, hello!' Alexander says, wiping his brow. 'Lovely day, isn't it? Though Olivia seems quite upset about her cat, Mittens. Maybe check near the big oak by the market?'"
34+
}
35+
}
36+
}
37+
38+
# --- Game State ---
39+
40+
# Player's current status (mutable)
41+
mut player_state = {
42+
location: "village_square" # Starting location ID
43+
inventory: []
44+
found_cat: false
45+
}
46+
47+
# --- Helper Functions ---
48+
49+
# Describe the current location
50+
def describe_location [state: record, map: record] {
51+
let current_loc_id = $state.location
52+
let loc_data = ($map | get $current_loc_id)
53+
54+
# Description
55+
print $loc_data.desc
56+
57+
# Items
58+
if not ($loc_data.items | is-empty) {
59+
print $"You see here: ($loc_data.items | str join ', ')"
60+
}
61+
62+
# NPCs
63+
let npcs = ($loc_data.npcs | columns)
64+
if not ($npcs | is-empty) {
65+
print $"People here: ($npcs | str join ', ')"
66+
}
67+
68+
# Exits
69+
let exits = ($loc_data.exits | columns | str join ', ')
70+
print $"Exits are: ($exits)"
71+
72+
# Check for winning condition trigger
73+
if $current_loc_id == "market" and not $state.found_cat {
74+
print "\nHint: Maybe you should 'search tree'?"
75+
}
76+
}
77+
78+
# Handle player actions are now inlined in the main loop below
79+
80+
# --- Main Game Loop ---
81+
82+
print "Welcome to Humlespring!"
83+
print "-------------------------"
84+
describe_location $player_state $map
85+
86+
loop {
87+
# Get player input
88+
let user_input = (input "> " | str trim)
89+
90+
# Skip empty input
91+
if $user_input == "" { continue }
92+
93+
# Parse input (simple verb-noun)
94+
let parts = ($user_input | split row " ")
95+
let verb = ($parts | get 0 | str downcase)
96+
# Use `get` and `default` for robust noun handling (handles commands with no noun)
97+
let noun = if ($parts | length) > 1 { $parts | get 1 | default "" | str downcase } else {""}
98+
99+
# grab the current location once
100+
let loc_data = ($map | get $player_state.location)
101+
102+
# Handle the action directly in the loop
103+
match $verb {
104+
"quit" | "exit" => {
105+
print "Goodbye!"
106+
exit
107+
}
108+
"look" | "l" => {
109+
describe_location $player_state $map
110+
}
111+
"go" | "move" => {
112+
if ( $noun not-in ( $loc_data.exits | columns )) {
113+
print "You can't go that way."
114+
} else {
115+
let new_loc = ($loc_data.exits | get $noun)
116+
$player_state.location = $new_loc
117+
print $"You go ($noun)."
118+
print "" # line break
119+
describe_location $player_state $map
120+
}
121+
}
122+
"inventory" | "i" => {
123+
if ($player_state.inventory | is-empty) {
124+
print "Your inventory is empty."
125+
} else {
126+
print $"You are carrying: ($player_state.inventory | str join ', ')"
127+
}
128+
}
129+
"take" | "get" => {
130+
if ($loc_data.items | find -r $noun).0? != null {
131+
# Just add to inventory
132+
$player_state.inventory = ($player_state.inventory | append $noun)
133+
print $"You take the ($noun)."
134+
} else {
135+
print $"There is no '($noun)' here to take."
136+
}
137+
}
138+
"talk" => {
139+
if ($loc_data.npcs | get $noun) == null {
140+
print $"There is no one called '($noun)' here to talk to."
141+
} else {
142+
print ($loc_data.npcs | get $noun)
143+
}
144+
}
145+
"search" => {
146+
if $noun == "tree" and $player_state.location == "market" {
147+
if $player_state.found_cat {
148+
print "You already found Mittens!"
149+
} else {
150+
print ($loc_data | get special)
151+
$player_state.found_cat = true
152+
print "\nMittens purrs happily in your arms. You should return her to Olivia!"
153+
}
154+
} else {
155+
print "You search around, but find nothing special."
156+
}
157+
}
158+
"give" => {
159+
if $noun == "cat" and $player_state.location == "village_square" and $player_state.found_cat {
160+
if ('olivia' in ($loc_data.npcs | columns)) {
161+
print "\nYou give Mittens back to Olivia. She is overjoyed!"
162+
print "'Oh, thank you, thank you!' she cries, hugging her cat. 'You saved her!'"
163+
print "\n*** Congratulations! You completed the adventure! ***"
164+
exit
165+
} else {
166+
print "Olivia isn't here right now."
167+
}
168+
} else if $player_state.found_cat and $noun == "cat" {
169+
print "You need to be in the village square to give the cat back to Olivia."
170+
} else {
171+
print "You don't have that to give, or you can't give it here/now."
172+
}
173+
}
174+
_ => {
175+
print "I don't understand that command. Try: go, look, take, inventory, talk, search, give, quit."
176+
}
177+
}
178+
print "" # Add a newline for better readability
179+
}

0 commit comments

Comments
 (0)