Skip to content

Instantly share code, notes, and snippets.

@LVMBDV
Created May 27, 2018 19:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LVMBDV/3084c6e3a98ef1500971a91c5e3bec2e to your computer and use it in GitHub Desktop.
Save LVMBDV/3084c6e3a98ef1500971a91c5e3bec2e to your computer and use it in GitHub Desktop.
A "The Oregon Trail" clone in space, in bash.
#!/bin/bash
FUEL_COST=5
FOOD_COST=2
START_FUEL=50
START_FOOD=70
START_PARTS=2
START_CREW_SIZE=4
WINDOW_HEIGHT=0
WINDOW_WIDTH=0
MENU_HEIGHT=0
RANDOM_EVENTS=(ILLNESS BREAKDOWN FLUX RAIDERS BLACKHOLE)
LANDMARKS=(
"Pluto, long since occupied with long-range sensors and scanners, stands ready to, and indeed continues to probe the far reaches of the galaxy."
"At the edge of the Sol system lies a treacherous asteroid belt. Many have been crushed by stray asteroids and misguided judgement."
"The nearest star system to Sol, in ages past it stood as a reminder of the boundaries of sub-light travel, now a low-population sanctuary for adventurers and traders."
"This region of space is particularly devoid of matter. Such low-density pockets are known to exist, but the vastness of it is astounding."
"Rigel Prime, the center of the Rigel system, burns hot, basking its planetary bodies in warmth and radiation."
"Tau Ceti Beta has recently become a waypoint for colonists headed towards Orion. There are many ships and makeshift stations in the vicinity."
"You have come into range of the first man-made structure in this region of space. It has been constructed not by travellers from Sol, but by colonists from Orion. It stands as a monument to the colonists' success."
"You have made it to Orion! Congratulations! Your crew is one of the few to start a new foothold for mankind!"
)
function initialize {
# Populate the crew using the user names of currently logged in users and some preset names.
NAMES=($(who | awk '{print $1}' | sort | uniq) carmen charles sam nick isabelle jean emilio ian pat theodore)
CREW=($(whoami))
while [ ${#CREW[@]} -lt $START_CREW_SIZE ]; do
name=${NAMES[$[$RANDOM % ${#NAMES[@]}]]}
unique=true
for index in $(seq 0 $[${#CREW[@]} - 1]); do
if [ ${CREW[$index]} = $name ]; then
unique=false
break
fi
done
if [ $unique = true ]; then
CREW+=($name)
fi
done
CREW=($(echo "${CREW[*]}" | sed 's/[^ ]\+/\L\u&/g'))
STATE=START
TURN=0
FUEL=$START_FUEL
FOOD=$START_FOOD
SPARE_PARTS=$START_PARTS
}
function consume_fuel {
((FUEL-=FUEL_COST))
}
function consume_food {
((FOOD-=FOOD_COST*${#CREW[@]}))
}
function spend_day {
consume_fuel
consume_food
}
function check_inventory {
if [ $TURN -ge $((${#LANDMARKS[@]} - 1)) ]; then
STATE=WIN
elif [ ${#CREW[@]} -le 0 ]; then
dialog --msgbox 'Your entire crew died, and your ship joins the fleet of ghost-ships littering the galaxy.' $WINDOW_HEIGHT $WINDOW_WIDTH
STATE=LOSE
elif [ $FUEL -le 0 ]; then
dialog --msgbox 'You ran out of fuel, and drift, slowly, into a star.' $WINDOW_HEIGHT $WINDOW_WIDTH
STATE=LOSE
elif [ $FOOD -le 0 ]; then
dialog --msgbox 'You ran out of food and starved.' $WINDOW_HEIGHT $WINDOW_WIDTH
STATE=LOSE
fi
}
function game_in_progress {
[ $STATE != WIN ] && [ $STATE != LOSE ]
}
function random_event {
if [ $TURN -eq 2 ] && [ $[$RANDOM % 100] -lt 30 ]; then
STATE=COLLISION
elif [ $[$RANDOM % 100] -lt 75 ]; then
STATE=${RANDOM_EVENTS[$[$RANDOM % ${#RANDOM_EVENTS[@]}]]}
else
STATE=NOTHING
fi
}
function process_event {
case $STATE in
ILLNESS)
dialog --msgbox "A deadly illness has been contracted!\n${CREW[0]} was killed by the disease." $WINDOW_HEIGHT $WINDOW_WIDTH
CREW=("${CREW[@]:1}")
;;
BREAKDOWN)
if [ $SPARE_PARTS -gt 0 ]; then
CHOICE=$(dialog --no-cancel --no-ok --menu "Oh no! The engine has broken down!\nYou can repair it with an engine part, or you can make repairs for 3 days." $WINDOW_HEIGHT $WINDOW_WIDTH $MENU_HEIGHT 'Use part' '' 'Wait 3 days' '' 2>&1 >/dev/tty)
if [ "$CHOICE" = 'Use part' ]; then
((SPARE_PARTS--))
else
consume_food && consume_food
fi
else
dialog --msgbox "Oh no! The engine has broken down!\nYou have to make repairs for 3 days." $WINDOW_HEIGHT $WINDOW_WIDTH
consume_food && consume_food
fi
;;
FLUX)
CHOICE=$(dialog --no-cancel --no-ok --menu "This region of space is highly turbulent. \nIf we go slowly we may avoid more damage, but if we keep our speed we won't waste supplies." $WINDOW_HEIGHT $WINDOW_WIDTH $MENU_HEIGHT 'Slow down' '' 'Continue' '' 2>&1 >/dev/tty)
if [ "$CHOICE" = 'Slow down' ]; then
consume_food && consume_food
else
if [ $[$RANDOM % 100] -lt 75 ]; then
STATE=BREAKDOWN
process_event
fi
fi
;;
RAIDERS)
if [ $[$RANDOM % 100] -lt 50 ]; then
STOLEN_FOOD=$((($RANDOM % 10) + 1))
STOLEN_FOOD=$(($STOLEN_FOOD <= $FOOD ? $STOLEN_FOOD : $FOOD))
((FOOD-=STOLEN_FOOD))
STOLEN_FUEL=$((($RANDOM % 10) + 1))
STOLEN_FUEL=$(($STOLEN_FUEL <= $FUEL ? $STOLEN_FUEL : $FUEL))
((FUEL-=STOLEN_FUEL))
dialog --msgbox "Raiders have come aboard your ship!\nThey have stolen $STOLEN_FOOD food and $STOLEN_FUEL fuel." $WINDOW_HEIGHT $WINDOW_WIDTH
elif [ $[$RANDOM % 100] -lt 10 ]; then
dialog --msgbox "Raiders have come aboard your ship!\n${CREW[0]} tried to fight back, but was killed." $WINDOW_HEIGHT $WINDOW_WIDTH
CREW=("${CREW[@]:1}")
else
dialog --msgbox "Raiders have come aboard your ship!\nFortunately, you fended them off without any trouble." $WINDOW_HEIGHT $WINDOW_WIDTH
fi
;;
BLACKHOLE)
CHOICE=$(dialog --no-cancel --no-ok --menu "Sensors indicate that a black hole's gravitational field is affecting the region of space we were headed through. We could stay of course, but risk of being overcome by its gravity, or we could change course to go around, which will take longer." $WINDOW_HEIGHT $WINDOW_WIDTH $MENU_HEIGHT 'Go around' '' 'Continue' '' 2>&1 >/dev/tty)
if [ "$CHOICE" = 'Go around' ]; then
spend_day && spend_day
else
if [ $[$RANDOM % 100] -lt 50 ]; then
dialog --msgbox "You were swept away into the black hole." $WINDOW_HEIGHT $WINDOW_WIDTH
STATE=LOSE
fi
fi
;;
COLLISION)
LOST_FOOD=$((($RANDOM % 10) + 1))
LOST_FOOD=$(($LOST_FOOD <= $FOOD ? $LOST_FOOD : $FOOD))
((FOOD-=LOST_FOOD))
LOST_FUEL=$((($RANDOM % 10) + 1))
LOST_FUEL=$(($LOST_FUEL <= $FUEL ? $LOST_FUEL : $FUEL))
((FUEL-=LOST_FUEL))
if [ $SPARE_PARTS -gt 0 ]; then
CHOICE=$(dialog --no-cancel --no-ok --menu "Something hit us! Looks like there's some hull damage.\n $LOST_FOOD food and $LOST_FUEL fuel was vented out into space.\nYou can repair the damage with hull plates, or you can spend the next 3 days welding scrap together." $WINDOW_HEIGHT $WINDOW_WIDTH $MENU_HEIGHT 'Use part' '' 'Wait' '' 2>&1 >/dev/tty)
if [ "$CHOICE" = 'Use part' ]; then
((SPARE_PARTS--))
else
consume_food && consume_food
fi
else
dialog --msgbox "Oh no! The engine has broken down!\nYou have to make repairs for 3 days." $WINDOW_HEIGHT $WINDOW_WIDTH
consume_food && consume_food
fi
;;
esac
}
function tick {
CHOICE=$(dialog --no-cancel --no-ok --menu "${LANDMARKS[$[$TURN]]}\n\nCrew: ${CREW[*]}\nSpare Parts: ${SPARE_PARTS}\nFood: ${FOOD}\nFuel: ${FUEL}" $WINDOW_HEIGHT $WINDOW_WIDTH $MENU_HEIGHT 'Continue' '' 'Kill a crewmember' '' 2>&1 >/dev/tty)
if [ "$CHOICE" = 'Kill a crewmember' ]; then
CREW=("${CREW[@]:1}")
fi
check_inventory
if game_in_progress; then
random_event
else
return
fi
process_event
spend_day
check_inventory
((TURN++))
}
initialize
while game_in_progress; do
tick
done
clear
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment