Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4fa7976ee | ||
|
|
fe20a8dbd0 | ||
|
|
9edf3f6a6b | ||
|
|
45cb4b6bbb | ||
|
|
5c32ce0ad3 | ||
|
|
4a25240149 | ||
|
|
a4cf0bc5ba | ||
|
|
33d9738dde |
@@ -1,4 +1,7 @@
|
|||||||
storm-games
|
storm-games
|
||||||
===========
|
===========
|
||||||
|
|
||||||
A collection of games, accessible to the blind, playable by all.
|
A collection of command line games, accessible to the blind, playable by all.
|
||||||
|
|
||||||
|
<script src="https://liberapay.com/stormdragon2976/widgets/button.js"></script>
|
||||||
|
<noscript><a href="https://liberapay.com/stormdragon2976/donate"><img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg"></a></noscript>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
10 Anonymous
|
15 Test
|
||||||
0 Anonymous
|
2 Fluff
|
||||||
0 anonymous
|
0 anonymous
|
||||||
0 anonymous
|
0 anonymous
|
||||||
0 anonymous
|
0 anonymous
|
||||||
|
|||||||
189
bottleblaster/bottleblaster.lua
Normal file
189
bottleblaster/bottleblaster.lua
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
-- Store operating system commands in a variable.
|
||||||
|
function os.capture(cmd, raw)
|
||||||
|
local f = assert(io.popen(cmd, 'r'))
|
||||||
|
local s = assert(f:read('*a'))
|
||||||
|
f:close()
|
||||||
|
if raw then
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
s = string.gsub(s, '^%s+', '')
|
||||||
|
s = string.gsub(s, '%s+$', '')
|
||||||
|
s = string.gsub(s, '[\n\r]+', ' ')
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Speak with appropriate tool.
|
||||||
|
local function speak(text)
|
||||||
|
if os.capture("uname") == "Linux" then
|
||||||
|
os.execute('spd-say "' .. text .. '"')
|
||||||
|
else
|
||||||
|
os.execute('say "' .. text .. '"')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Window related variables.
|
||||||
|
local gameName = "Bottle Blaster"
|
||||||
|
|
||||||
|
local SDL = require "SDL"
|
||||||
|
local mixer = require "SDL.mixer"
|
||||||
|
local ret, err = SDL.init { SDL.flags.Video }
|
||||||
|
if not ret then
|
||||||
|
error(err)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function trySDL(func, ...)
|
||||||
|
local t = { func(...) }
|
||||||
|
|
||||||
|
if not t[1] then
|
||||||
|
error(t[#t])
|
||||||
|
end
|
||||||
|
|
||||||
|
return table.unpack(t)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function exit_game(SDL, mixer)
|
||||||
|
SDL.quit()
|
||||||
|
mixer.quit()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local win, err = SDL.createWindow {
|
||||||
|
title = gameName,
|
||||||
|
width = 320,
|
||||||
|
height = 320
|
||||||
|
}
|
||||||
|
|
||||||
|
if not win then
|
||||||
|
error(err)
|
||||||
|
end
|
||||||
|
|
||||||
|
trySDL(mixer.openAudio, 44100, SDL.audioFormat.S16, 2, 1024)
|
||||||
|
-- Load all game sounds here:
|
||||||
|
-- Format: local variableName = trySDL(mixer.loadWAV, "path/to/file")
|
||||||
|
-- Supported file types flac, ogg, wav
|
||||||
|
local bottle =
|
||||||
|
{
|
||||||
|
trySDL(mixer.loadWAV, "sounds/glass1.ogg"),
|
||||||
|
trySDL(mixer.loadWAV, "sounds/glass2.ogg"),
|
||||||
|
trySDL(mixer.loadWAV, "sounds/glass3.ogg")
|
||||||
|
}
|
||||||
|
local gun =
|
||||||
|
{
|
||||||
|
trySDL(mixer.loadWAV, "sounds/gun1.ogg"),
|
||||||
|
trySDL(mixer.loadWAV, "sounds/gun2.ogg"),
|
||||||
|
trySDL(mixer.loadWAV, "sounds/gun3.ogg"),
|
||||||
|
trySDL(mixer.loadWAV, "sounds/gun4.ogg"),
|
||||||
|
trySDL(mixer.loadWAV, "sounds/gun5.ogg")
|
||||||
|
}
|
||||||
|
local empty = trySDL(mixer.loadWAV, "sounds/empty.ogg")
|
||||||
|
local load = {}
|
||||||
|
load[3] = trySDL(mixer.loadWAV, "sounds/load3.ogg")
|
||||||
|
load[4] = trySDL(mixer.loadWAV, "sounds/load3.ogg")
|
||||||
|
load[5] = trySDL(mixer.loadWAV, "sounds/load5.ogg")
|
||||||
|
|
||||||
|
local function play_sound(sound, channel, loop)
|
||||||
|
channel = channel or -1
|
||||||
|
loop = loop or 0
|
||||||
|
sound:playChannel(channel, loop)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function play_at_location(sound, xPosition, yPosition)
|
||||||
|
channel = channel or -1
|
||||||
|
loop = loop or 0
|
||||||
|
xPosition = xPosition or 0
|
||||||
|
yPosition = yPosition or 0
|
||||||
|
mixer.SetPanning(-1, 255, 127)
|
||||||
|
sound:playChannel(-1, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function game_intro()
|
||||||
|
local sound = trySDL(mixer.loadWAV, "sounds/game-intro.ogg")
|
||||||
|
sound:playChannel(-1, 0)
|
||||||
|
while mixer.playing(-1) > 0 do
|
||||||
|
SDL.delay(100)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Game variables
|
||||||
|
local direction = ""
|
||||||
|
local holdKey = {}
|
||||||
|
local keyName = ""
|
||||||
|
local loaded = true
|
||||||
|
local playerPosition = math.random(0, 30)
|
||||||
|
local running = true
|
||||||
|
local weapon = 1
|
||||||
|
|
||||||
|
-- game functions.
|
||||||
|
local function player_move(position, direction)
|
||||||
|
if direction == "Left" and position > 0 then
|
||||||
|
position = position - 1
|
||||||
|
end
|
||||||
|
if direction == "Right" and position < 30 then
|
||||||
|
position = position + 1
|
||||||
|
end
|
||||||
|
return position
|
||||||
|
end
|
||||||
|
|
||||||
|
game_intro()
|
||||||
|
-- Main game loop.
|
||||||
|
while running do
|
||||||
|
-- Need a timer to make holding arrows move at a slower speed. for player_move()
|
||||||
|
playerPosition = player_move(playerPosition, direction)
|
||||||
|
-- Iterate over all events, this function does not block.
|
||||||
|
for e in SDL.pollEvent() do
|
||||||
|
if e.type == SDL.event.KeyUp then --chrys just recognice the keyup and free the loop
|
||||||
|
keyName = SDL.getKeyName(e.keysym.sym)
|
||||||
|
holdKey[keyName] = false
|
||||||
|
direction = ""
|
||||||
|
-- speak(playerPosition)
|
||||||
|
end
|
||||||
|
if e.type == SDL.event.Quit then
|
||||||
|
running = false
|
||||||
|
elseif e.type == SDL.event.KeyDown and not holdKey[keyName] then -- chrysif not already down ( see below)
|
||||||
|
keyName = SDL.getKeyName(e.keysym.sym)
|
||||||
|
holdKey[keyName] = true --chrys mark the remember the keydown
|
||||||
|
if keyName == "Q" then
|
||||||
|
running = exit_game(SDL, mixer)
|
||||||
|
elseif keyName == "Left Shift" or keyName == "Right Shift" then
|
||||||
|
if weapon >= 3 and loaded == false then
|
||||||
|
-- Need to not allow firing until loading is complete.
|
||||||
|
play_sound(load[weapon])
|
||||||
|
end
|
||||||
|
loaded = true
|
||||||
|
elseif keyName == "Space" then
|
||||||
|
if loaded == true then
|
||||||
|
play_sound(gun[weapon])
|
||||||
|
play_sound(bottle[math.random(1, #bottle)])
|
||||||
|
else
|
||||||
|
play_sound(empty)
|
||||||
|
end
|
||||||
|
if weapon >= 3 then
|
||||||
|
loaded = false
|
||||||
|
end
|
||||||
|
elseif keyName == "Left" or keyName == "Right" then
|
||||||
|
direction = keyName
|
||||||
|
elseif tonumber(keyName) == nil then -- make sure keyName can be converted to a number for remaing if statements to avoid a crash.
|
||||||
|
keyName = "0"
|
||||||
|
elseif tonumber(keyName) >= 1 and tonumber(keyName) <= 5 then
|
||||||
|
weapon = tonumber(keyName)
|
||||||
|
if weapon >= 3 then
|
||||||
|
loaded = false
|
||||||
|
else
|
||||||
|
loaded = true
|
||||||
|
end
|
||||||
|
if weapon == 1 then
|
||||||
|
speak("pistal")
|
||||||
|
elseif weapon == 2 then
|
||||||
|
speak("beretta")
|
||||||
|
elseif weapon == 3 then
|
||||||
|
speak("boomstick shotgun")
|
||||||
|
elseif weapon == 4 then
|
||||||
|
speak("pump action shotgun")
|
||||||
|
elseif weapon == 5 then
|
||||||
|
speak("bo and arrow")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
BIN
bottleblaster/sounds/bottle.ogg
Normal file
BIN
bottleblaster/sounds/bottle.ogg
Normal file
Binary file not shown.
BIN
bottleblaster/sounds/empty.ogg
Normal file
BIN
bottleblaster/sounds/empty.ogg
Normal file
Binary file not shown.
BIN
bottleblaster/sounds/game-intro.ogg
Normal file
BIN
bottleblaster/sounds/game-intro.ogg
Normal file
Binary file not shown.
BIN
bottleblaster/sounds/glass1.ogg
Normal file
BIN
bottleblaster/sounds/glass1.ogg
Normal file
Binary file not shown.
BIN
bottleblaster/sounds/glass2.ogg
Normal file
BIN
bottleblaster/sounds/glass2.ogg
Normal file
Binary file not shown.
BIN
bottleblaster/sounds/glass3.ogg
Normal file
BIN
bottleblaster/sounds/glass3.ogg
Normal file
Binary file not shown.
BIN
bottleblaster/sounds/gun1.ogg
Normal file
BIN
bottleblaster/sounds/gun1.ogg
Normal file
Binary file not shown.
BIN
bottleblaster/sounds/gun2.ogg
Normal file
BIN
bottleblaster/sounds/gun2.ogg
Normal file
Binary file not shown.
BIN
bottleblaster/sounds/gun3.ogg
Normal file
BIN
bottleblaster/sounds/gun3.ogg
Normal file
Binary file not shown.
BIN
bottleblaster/sounds/gun4.ogg
Normal file
BIN
bottleblaster/sounds/gun4.ogg
Normal file
Binary file not shown.
BIN
bottleblaster/sounds/gun5.ogg
Normal file
BIN
bottleblaster/sounds/gun5.ogg
Normal file
Binary file not shown.
BIN
bottleblaster/sounds/load3.ogg
Normal file
BIN
bottleblaster/sounds/load3.ogg
Normal file
Binary file not shown.
BIN
bottleblaster/sounds/load4.ogg
Normal file
BIN
bottleblaster/sounds/load4.ogg
Normal file
Binary file not shown.
BIN
bottleblaster/sounds/load5.ogg
Normal file
BIN
bottleblaster/sounds/load5.ogg
Normal file
Binary file not shown.
@@ -1,95 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Get the coluns and lines of the "screen"
|
|
||||||
cols=$(tput cols)
|
|
||||||
lines=$(tput lines)
|
|
||||||
# Settings to improve accessibility of dialog.
|
|
||||||
export DIALOGOPTS='--insecure --no-lines --visit-items'
|
|
||||||
|
|
||||||
inputbox() {
|
|
||||||
# Returns: text entered by the user
|
|
||||||
# Args 1, Instructions for box.
|
|
||||||
# args: 2 initial text (optional)
|
|
||||||
dialog --backtitle "$(gettext "Enter text and press enter.")" \
|
|
||||||
--clear \
|
|
||||||
--inputbox "$1" 0 0 "$2" --stdout
|
|
||||||
}
|
|
||||||
|
|
||||||
msgbox() {
|
|
||||||
# Returns: None
|
|
||||||
# Shows the provided message on the screen with an ok button.
|
|
||||||
dialog --clear --msgbox "$*" 10 72
|
|
||||||
}
|
|
||||||
|
|
||||||
infobox() {
|
|
||||||
# Returns: None
|
|
||||||
# Shows the provided message on the screen with no buttons.
|
|
||||||
local timeout=3
|
|
||||||
dialog --infobox "$*" 0 0
|
|
||||||
read -n1 -t $timeout continue
|
|
||||||
# Clear any keypresses from the buffer
|
|
||||||
clear_buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
yesno() {
|
|
||||||
# Returns: Yes or No
|
|
||||||
# Args: Question to user.
|
|
||||||
# Called in if $(yesno) == "Yes"
|
|
||||||
# Or variable=$(yesno)
|
|
||||||
if dialog --clear --backtitle "$(gettext "Press 'Enter' for \"yes\" or 'Escape' for \"no\".")" --yesno "$*" 0 0 ; then
|
|
||||||
echo "Yes"
|
|
||||||
else
|
|
||||||
echo "No"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
get_keypress() {
|
|
||||||
# Returnes the pressed key.
|
|
||||||
# There arre two ways to use this function.
|
|
||||||
# first way, get_keypress variableName
|
|
||||||
# Second way variableName="$(get_keypress)"
|
|
||||||
# This variable name is long to absolutely minimize possibility of collision.
|
|
||||||
local getKeypressFunctionReturnVariable=$1
|
|
||||||
local returnedKeypress
|
|
||||||
# Unset IFS to capture any key that is pressed.
|
|
||||||
local ifs="$IFS"
|
|
||||||
unset IFS
|
|
||||||
read -sn1 returnedKeypress
|
|
||||||
# Restore IFS
|
|
||||||
IFS="$ifs"
|
|
||||||
if [[ $getKeypressFunctionReturnVariable ]]; then
|
|
||||||
eval $getKeypressFunctionReturnVariable="'$returnedKeypress'"
|
|
||||||
else
|
|
||||||
echo "$returnedKeypress"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
menulist() {
|
|
||||||
# Args: menu options
|
|
||||||
# returns: selected option
|
|
||||||
# set gameMenu to control the message.
|
|
||||||
declare -a menuList
|
|
||||||
for i in $@ ; do
|
|
||||||
menuList+=("$i" "$i")
|
|
||||||
done
|
|
||||||
dialog --backtitle "${menuMessage:-Game menu...}" \
|
|
||||||
--clear \
|
|
||||||
--no-tags \
|
|
||||||
--menu "Please make your selection" 0 0 0 "${menuList[@]}" --stdout
|
|
||||||
}
|
|
||||||
|
|
||||||
numpicker() {
|
|
||||||
# Args: max number, Min numberr optional.
|
|
||||||
# returns: selected number
|
|
||||||
# set gameMenu to control the message.
|
|
||||||
declare -a menuList
|
|
||||||
local max=$1
|
|
||||||
local min=${2:-10}
|
|
||||||
for i in $(seq $min $max) ; do
|
|
||||||
menuList+=("$i" "$i")
|
|
||||||
done
|
|
||||||
dialog --backtitle "${menuMessage:-Numeric menu...}" \
|
|
||||||
--clear \
|
|
||||||
--no-tags \
|
|
||||||
--menu "Please select a number between $min and $max." 0 0 0 "${menuList[@]}" --stdout
|
|
||||||
}
|
|
||||||
108
getkey.sh
Executable file
108
getkey.sh
Executable file
@@ -0,0 +1,108 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Reset terminal to current state when we exit.
|
||||||
|
trap "stty $(stty -g)" EXIT
|
||||||
|
|
||||||
|
# Disable echo and special characters, set input timeout to 0.2 seconds.
|
||||||
|
stty -echo -icanon time 2 || exit $?
|
||||||
|
|
||||||
|
# String containing all keypresses.
|
||||||
|
KEYS=""
|
||||||
|
|
||||||
|
# Set field separator to BELL (should not occur in keypresses)
|
||||||
|
IFS=$'\a'
|
||||||
|
|
||||||
|
# Input loop.
|
||||||
|
while [ 1 ]; do
|
||||||
|
|
||||||
|
# Read more input from keyboard when necessary.
|
||||||
|
while read -t 0 ; do
|
||||||
|
read -s -r -d "" -N 1 -t 0.2 CHAR && KEYS="$KEYS$CHAR" || break
|
||||||
|
done
|
||||||
|
# If no keys to process, wait 0.05 seconds and retry.
|
||||||
|
if [ -z "$KEYS" ]; then
|
||||||
|
sleep 0.02
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check the first (next) keypress in the buffer.
|
||||||
|
case "$KEYS" in
|
||||||
|
$'\x1B\x5B\x41'*) # Up arrow
|
||||||
|
KEYS="${KEYS##???}"
|
||||||
|
KEY="Arrow_U"
|
||||||
|
;;
|
||||||
|
$'\x1B\x5B\x42'*) # Down Arrow
|
||||||
|
KEYS="${KEYS##???}"
|
||||||
|
KEY="Arrow_D"
|
||||||
|
;;
|
||||||
|
$'\x1B\x5B\x44'*) # Left Arrow
|
||||||
|
KEYS="${KEYS##???}"
|
||||||
|
KEY="Arrow_L"
|
||||||
|
;;
|
||||||
|
$'\x1B\x5B\x43'*) # Right Arrow
|
||||||
|
KEYS="${KEYS##???}"
|
||||||
|
KEY="Arrow_R"
|
||||||
|
;;
|
||||||
|
$'\x1B\x4F\x48'*) # Home
|
||||||
|
KEYS="${KEYS##???}"
|
||||||
|
KEY="Home"
|
||||||
|
;;
|
||||||
|
$'\x1B\x5B\x31\x7E'*) # Home (Numpad)
|
||||||
|
KEYS="${KEYS##????}"
|
||||||
|
KEY="Home"
|
||||||
|
;;
|
||||||
|
$'\x1B\x4F\x46'*) # End
|
||||||
|
KEYS="${KEYS##???}"
|
||||||
|
KEY="End"
|
||||||
|
;;
|
||||||
|
$'\x1B\x5B\x34\x7E'*) # End (Numpad)
|
||||||
|
KEYS="${KEYS##????}"
|
||||||
|
KEY="End"
|
||||||
|
;;
|
||||||
|
$'\x1B\x5B\x45'*) # 5 (Numpad)
|
||||||
|
KEYS="${KEYS#???}"
|
||||||
|
KEY="Numpad_5"
|
||||||
|
;;
|
||||||
|
$'\x1B\x5B\x35\x7e'*) # PageUp
|
||||||
|
KEYS="${KEYS##????}"
|
||||||
|
KEY="Page_U"
|
||||||
|
;;
|
||||||
|
$'\x1B\x5B\x36\x7e'*) # PageDown
|
||||||
|
KEYS="${KEYS##????}"
|
||||||
|
KEY="Page_D"
|
||||||
|
;;
|
||||||
|
$'\x1B\x5B\x32\x7e'*) # Insert
|
||||||
|
KEYS="${KEYS##????}"
|
||||||
|
KEY="Insert"
|
||||||
|
;;
|
||||||
|
$'\x1B\x5B\x33\x7e'*) # Delete
|
||||||
|
KEYS="${KEYS##????}"
|
||||||
|
KEY="Delete"
|
||||||
|
;;
|
||||||
|
$'\n'*|$'\r'*) # Enter/Return
|
||||||
|
KEYS="${KEYS##?}"
|
||||||
|
KEY="Enter"
|
||||||
|
;;
|
||||||
|
$'\t'*) # Tab
|
||||||
|
KEYS="${KEYS##?}"
|
||||||
|
KEY="Tab"
|
||||||
|
;;
|
||||||
|
$'\x1B') # Esc (without anything following!)
|
||||||
|
KEYS="${KEYS##?}"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
$'\x1B'*) # Unknown escape sequences
|
||||||
|
echo -n "Unknown escape sequence (${#KEYS} chars): \$'"
|
||||||
|
echo -n "$KEYS" | od --width=256 -t x1 | sed -e '2,99 d; s|^[0-9A-Fa-f]* ||; s| |\\x|g; s|$|'"'|"
|
||||||
|
KEYS=""
|
||||||
|
;;
|
||||||
|
[$'\x01'-$'\x1F'$'\x7F']*) # Consume control characters
|
||||||
|
KEYS="${KEYS##?}"
|
||||||
|
;;
|
||||||
|
*) # Printable characters.
|
||||||
|
KEY="${KEYS:0:1}"
|
||||||
|
KEYS="${KEYS#?}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo "$KEY"
|
||||||
|
done
|
||||||
32
godville-tracker/datachecker.sh
Executable file
32
godville-tracker/datachecker.sh
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#If there is more than one command line arg something is wrong
|
||||||
|
if [ $# -gt 1 ] ; then
|
||||||
|
echo "usage:
|
||||||
|
$0 godname"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#set godName variable if it was passed from the command line
|
||||||
|
if [ $# -eq 1 ] ; then
|
||||||
|
godName="$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#read from file if it exists, and name wasn't passed in on command line
|
||||||
|
if [ -f .godville-trackerrc -a $# -eq 0 ] ; then
|
||||||
|
source .godville-trackerrc
|
||||||
|
fi
|
||||||
|
|
||||||
|
#if name is not set in file, prompt for it here
|
||||||
|
if [ -z "$godName" ] ; then
|
||||||
|
read -p "Please enter the god's name? " godName
|
||||||
|
fi
|
||||||
|
|
||||||
|
godvilleInfo="$(curl -Ss "http://godvillegame.com/gods/api/${godName}.json")"
|
||||||
|
clear
|
||||||
|
#remove most of the json stuff
|
||||||
|
godvilleInfo="$(echo "$godvilleInfo" | sed -e 's/":"/ /g' -e 's/","/\n/g')"
|
||||||
|
godvilleInfo="$(echo "$godvilleInfo" | sed -e 's/":/ /g' -e 's/,"/\n/g')"
|
||||||
|
godvilleInfo="$(echo "$godvilleInfo" | sed -e 's/{"//g' -e 's/"}//g')"
|
||||||
|
echo "$godvilleInfo"
|
||||||
|
exit 0
|
||||||
103
godville-tracker/godville-tracker
Executable file
103
godville-tracker/godville-tracker
Executable file
@@ -0,0 +1,103 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#If there is more than one command line arg something is wrong
|
||||||
|
if [ $# -gt 1 ] ; then
|
||||||
|
echo "usage:
|
||||||
|
$0 godname"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#set godName variable if it was passed from the command line
|
||||||
|
if [ $# -eq 1 ] ; then
|
||||||
|
godName="$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#read from file if it exists, and name wasn't passed in on command line
|
||||||
|
if [ -f .godville-trackerrc -a $# -eq 0 ] ; then
|
||||||
|
source .godville-trackerrc
|
||||||
|
fi
|
||||||
|
|
||||||
|
#if name is not set in file, prompt for it here
|
||||||
|
if [ -z "$godName" ] ; then
|
||||||
|
read -p "Please enter the god's name? " godName
|
||||||
|
fi
|
||||||
|
|
||||||
|
#Counter variable initialization
|
||||||
|
i=60
|
||||||
|
#main update loop
|
||||||
|
while [ "${continue^}" != "Q" ] ; do
|
||||||
|
#Update info every minute
|
||||||
|
if [ $i -ge 60 ] ; then
|
||||||
|
godvilleInfo="$(curl -Ss "http://godvillegame.com/gods/api/${godName}.json")"
|
||||||
|
#godvilleInfo="$(cat tmp.txt)"
|
||||||
|
clear
|
||||||
|
#remove most of the json stuff, and other formatting goodness
|
||||||
|
godvilleInfo="$(echo "$godvilleInfo" | sed -e 's/":"/ /g' -e 's/","/\n/g')"
|
||||||
|
godvilleInfo="$(echo "$godvilleInfo" | sed -e 's/":/ /g' -e 's/,"/\n/g')"
|
||||||
|
godvilleInfo="$(echo "$godvilleInfo" | sed -e 's/{"//g' -e 's/"}//g' -e 's/}}//g' -e 's/\\u201[c|d]/"/g')"
|
||||||
|
#load info into variables
|
||||||
|
alignment="$(echo "$godvilleInfo" | grep "^alignment" | cut -d ' ' -f2-)"
|
||||||
|
bricks_cnt="$(echo "$godvilleInfo" | grep "^bricks_cnt" | cut -d ' ' -f2-)"
|
||||||
|
bricks_cnt=$(echo "scale=1;$bricks_cnt * 0.1" | bc)
|
||||||
|
clan="$(echo "$godvilleInfo" | grep "^clan " | cut -d ' ' -f2-)"
|
||||||
|
clan_position="$(echo "$godvilleInfo" | grep "^clan_position" | cut -d ' ' -f2-)"
|
||||||
|
gender="$(echo "$godvilleInfo" | grep "^gender" | cut -d ' ' -f2-)"
|
||||||
|
gold_approx="$(echo "$godvilleInfo" | grep "^gold_approx" | cut -d ' ' -f2-)"
|
||||||
|
inventory="$(echo "$godvilleInfo" | grep "^inventory " | cut -d ' ' -f2-)"
|
||||||
|
inventory_max_num="$(echo "$godvilleInfo" | grep "^inventory_max_num" | cut -d ' ' -f2-)"
|
||||||
|
level="$(echo "$godvilleInfo" | grep "^level" | cut -d ' ' -f2-)"
|
||||||
|
name="$(echo "$godvilleInfo" | grep "^name" | cut -d ' ' -f2-)"
|
||||||
|
max_health="$(echo "$godvilleInfo" | grep "^max_health" | cut -d ' ' -f2-)"
|
||||||
|
motto="$(echo "$godvilleInfo" | grep "^motto" | cut -d ' ' -f2-)"
|
||||||
|
pet_class="$(echo "$godvilleInfo" | grep "^pet_class" | cut -d ' ' -f2-)"
|
||||||
|
pet_level="$(echo "$godvilleInfo" | grep "^pet_level" | cut -d ' ' -f2-)"
|
||||||
|
pet_name="$(echo "$godvilleInfo" | grep "^pet pet_name" | cut -d ' ' -f3-)"
|
||||||
|
quest="$(echo "$godvilleInfo" | grep "^quest" | cut -d ' ' -f2-)"
|
||||||
|
temple_completed_at="$(echo "$godvilleInfo" | grep "^temple_completed_at" | cut -d ' ' -f2-)"
|
||||||
|
if [ "$temple_completed_at" != "null" ] ; then
|
||||||
|
temple_completed_at="$(date --date="$temple_completed_at" +'%I:%M%p %A, %B %d, %Y')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#display Information
|
||||||
|
echo "God
|
||||||
|
Name: $godName
|
||||||
|
|
||||||
|
Hero
|
||||||
|
Name: $name ($gender)
|
||||||
|
Motto: $motto
|
||||||
|
Personality: $alignment"
|
||||||
|
#Not everyone is in a clan:
|
||||||
|
if [ -n "$clan" ] ; then
|
||||||
|
echo "Guild: $clan ($clan_position)"
|
||||||
|
fi
|
||||||
|
echo "Level: $level
|
||||||
|
Inventory: ### / $inventory_max_num
|
||||||
|
Health: ### / $max_health
|
||||||
|
Quest: $quest
|
||||||
|
Gold: $gold_approx
|
||||||
|
Bricks for Temple: $bricks_cnt%"
|
||||||
|
#Not everyone has completed their temple
|
||||||
|
if [ "$temple_completed_at" != "null" ] ; then
|
||||||
|
echo "Temple Completed: $temple_completed_at"
|
||||||
|
fi
|
||||||
|
#Not everyone has a pet
|
||||||
|
if [ -n "$pet_name" ] ; then
|
||||||
|
echo
|
||||||
|
echo "Pet
|
||||||
|
Name: $pet_name
|
||||||
|
Class $pet_class"
|
||||||
|
#Not all pets show a level
|
||||||
|
if [[ "$pet_level" =~ ^[0-9]+$ ]] ; then
|
||||||
|
echo "Level: $pet_level"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
#reset counter variable
|
||||||
|
i=0
|
||||||
|
fi
|
||||||
|
#Wait for user input and sleep for 1 second
|
||||||
|
read -t1 -n1 continue
|
||||||
|
#Incriment counter
|
||||||
|
let i++
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
exit 0
|
||||||
30
menu.sh
30
menu.sh
@@ -1,30 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
export DIALOGOPTS='--no-lines --visit-items'
|
|
||||||
cols=$(tput cols)
|
|
||||||
lines=$(tput lines)
|
|
||||||
path="$(realpath "$0")"
|
|
||||||
path="${path%/*}"
|
|
||||||
declare -A gameList
|
|
||||||
for i in $path/*/ ; do
|
|
||||||
i="${i::-1}"
|
|
||||||
gameList[${i##*/}]="${i}"
|
|
||||||
done
|
|
||||||
gameList[exit]="Exit"
|
|
||||||
while : ; do
|
|
||||||
game="$(dialog --backtitle "Storm Games" \
|
|
||||||
--menu "Select A Game" $((lines - 5)) $cols $((lines / 2)) $(
|
|
||||||
for i in ${!gameList[@]} ; do
|
|
||||||
echo "$i"
|
|
||||||
echo '|'
|
|
||||||
done) --stdout)"
|
|
||||||
if [[ "$game" != "exit" && -n "$game" ]]; then
|
|
||||||
cd "${gameList[$game]}"
|
|
||||||
./$game""
|
|
||||||
echo
|
|
||||||
read -n1 -p "Press any key to continue" continue
|
|
||||||
else
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
exit 0
|
|
||||||
@@ -9,3 +9,6 @@ TTYtter (optional)
|
|||||||
|
|
||||||
Playing
|
Playing
|
||||||
You are given a scrambled list of numbers from 1 to 9. Press the number you want to flip from, and that number, plus all the numbers after it will reverse. the object of the game is to get the numbers in the right order, 123456789, in as few tries as possible.
|
You are given a scrambled list of numbers from 1 to 9. Press the number you want to flip from, and that number, plus all the numbers after it will reverse. the object of the game is to get the numbers in the right order, 123456789, in as few tries as possible.
|
||||||
|
|
||||||
|
<script src="https://liberapay.com/stormdragon2976/widgets/button.js"></script>
|
||||||
|
<noscript><a href="https://liberapay.com/stormdragon2976/donate"><img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg"></a></noscript>
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
#!/bin/python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from storm_games import *
|
|
||||||
|
|
||||||
# Initial variable settings
|
|
||||||
mode = "menu"
|
|
||||||
sounds = initialize_gui("Numnastics")
|
|
||||||
|
|
||||||
def game(mode):
|
|
||||||
i = 0
|
|
||||||
startTime = time.time()
|
|
||||||
tries = 0
|
|
||||||
numberList = list("123456789")
|
|
||||||
random.shuffle(numberList)
|
|
||||||
while ''.join(numberList) != "123456789":
|
|
||||||
event = pygame.event.wait()
|
|
||||||
if event.type == pygame.KEYDOWN:
|
|
||||||
# Escape is the back/exit key, close the game if not playing, or return to menu if playing.
|
|
||||||
if event.key == pygame.K_ESCAPE:
|
|
||||||
if mode != "menu":
|
|
||||||
mode = "menu"
|
|
||||||
return mode
|
|
||||||
elif mode == "menu": exit_game()
|
|
||||||
elif event.key in [pygame.K_1, pygame.K_2, pygame.K_3, pygame.K_4, pygame.K_5, pygame.K_6,pygame.K_7, pygame.K_8, pygame.K_9]:
|
|
||||||
i = numberList.index((pygame.key.name(event.key)))
|
|
||||||
speak(numberList[i])
|
|
||||||
elif event.key in [pygame.K_LEFT, pygame.K_UP]:
|
|
||||||
if i > 0: i = i - 1
|
|
||||||
speak(numberList[i])
|
|
||||||
elif event.key in [pygame.K_RIGHT, pygame.K_DOWN]:
|
|
||||||
if i < len(numberList) - 1: i = i + 1
|
|
||||||
speak(numberList[i])
|
|
||||||
elif event.key == pygame.K_SPACE:
|
|
||||||
speak(str(' '.join(numberList[i:len(numberList)])))
|
|
||||||
continue
|
|
||||||
elif event.key == pygame.K_RETURN:
|
|
||||||
if i != -1:
|
|
||||||
reversedNumberList = numberList[i:len(numberList)]
|
|
||||||
reversedNumberList.reverse()
|
|
||||||
del numberList[i:len(numberList)]
|
|
||||||
numberList.extend(reversedNumberList)
|
|
||||||
tries = tries + 1
|
|
||||||
sounds['flip'].play()
|
|
||||||
speak(str(' '.join(numberList[i:len(numberList)])))
|
|
||||||
else:
|
|
||||||
i = -1
|
|
||||||
sounds['error'].play()
|
|
||||||
endTime = round(time.time() - startTime, 2)
|
|
||||||
message = [
|
|
||||||
"Congratulations! You beat Numnastics in " + str(tries) + " tries.",\
|
|
||||||
"Your time was " + str(endTime) + " seconds."]
|
|
||||||
display_message(message)
|
|
||||||
sounds['win'].play()
|
|
||||||
time.sleep(sounds['win'].get_length())
|
|
||||||
return "menu"
|
|
||||||
|
|
||||||
# Game starts at main menu
|
|
||||||
mode = game_menu("start game", "instructions", "credits", "exit_game")
|
|
||||||
while True:
|
|
||||||
if mode == "menu": mode = game_menu("start game", "instructions", "credits", "exit_game")
|
|
||||||
if mode == "start game": mode = game(mode)
|
|
||||||
time.sleep(.001)
|
|
||||||
|
|
||||||
Binary file not shown.
@@ -1,148 +0,0 @@
|
|||||||
#!/bin/python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""Standard initializations and functions shared by all games."""
|
|
||||||
|
|
||||||
import configparser
|
|
||||||
import os
|
|
||||||
from os import listdir
|
|
||||||
from os.path import isfile, join
|
|
||||||
from inspect import isfunction
|
|
||||||
from xdg import BaseDirectory
|
|
||||||
import pygame
|
|
||||||
import random
|
|
||||||
import requests
|
|
||||||
import speechd
|
|
||||||
import time
|
|
||||||
|
|
||||||
localConfig = configparser.ConfigParser()
|
|
||||||
globalConfig = configparser.ConfigParser()
|
|
||||||
spd = speechd.Client()
|
|
||||||
|
|
||||||
def write_config(writeGlobal = False):
|
|
||||||
if writeGlobal == False:
|
|
||||||
with open(gamePath, 'w') as configfile:
|
|
||||||
localConfig.write(configfile)
|
|
||||||
else:
|
|
||||||
with open(globalPath, 'w') as configfile:
|
|
||||||
globalConfig.write(configfile)
|
|
||||||
|
|
||||||
def speak(text, interupt = True):
|
|
||||||
if interupt == True: spd.cancel()
|
|
||||||
spd.say(text)
|
|
||||||
|
|
||||||
def exit_game():
|
|
||||||
spd.close()
|
|
||||||
pygame.quit()
|
|
||||||
exit()
|
|
||||||
|
|
||||||
def initialize_gui(gameTitle):
|
|
||||||
# Check for, and possibly create, storm-games path
|
|
||||||
global globalPath
|
|
||||||
global gamePath
|
|
||||||
globalPath = BaseDirectory.xdg_config_home + "/storm-games"
|
|
||||||
gamePath = globalPath + "/" + str.lower(str.replace(gameTitle, " ", "-") + "config")
|
|
||||||
globalPath = globalPath + "/config"
|
|
||||||
if not os.path.exists(gamePath): os.makedirs(gamePath)
|
|
||||||
# Seed the random generator to the clock
|
|
||||||
random.seed()
|
|
||||||
# Set game's name
|
|
||||||
global gameName
|
|
||||||
gameName = gameTitle
|
|
||||||
# start pygame
|
|
||||||
pygame.init()
|
|
||||||
# start the display (required by the event loop)
|
|
||||||
pygame.display.set_mode((320, 200))
|
|
||||||
pygame.display.set_caption(gameTitle)
|
|
||||||
# Load sounds from the sound directory and creates a list like that {'bottle': 'bottle.ogg'}
|
|
||||||
soundFiles = [f for f in listdir("sounds/") if isfile(join("sounds/", f)) and (f.split('.')[1].lower() in ["ogg","wav"])]
|
|
||||||
#lets make a dict with pygame.mixer.Sound() objects {'bottle':<soundobject>}
|
|
||||||
soundData = {}
|
|
||||||
for f in soundFiles:
|
|
||||||
soundData[f.split('.')[0]] = pygame.mixer.Sound("sounds/" + f)
|
|
||||||
soundData['game-intro'].play()
|
|
||||||
time.sleep(soundData['game-intro'].get_length())
|
|
||||||
return soundData
|
|
||||||
|
|
||||||
def display_message(info):
|
|
||||||
info.append("Press escape or enter to continue.")
|
|
||||||
info.reverse()
|
|
||||||
info.append("Use the up and down arrow keys to navigate this message.")
|
|
||||||
info.reverse()
|
|
||||||
i = 0
|
|
||||||
speak(str(info[0:len(info)]))
|
|
||||||
while True:
|
|
||||||
event = pygame.event.wait()
|
|
||||||
if event.type == pygame.KEYDOWN:
|
|
||||||
if event.key == pygame.K_ESCAPE or event.key == pygame.K_RETURN: return
|
|
||||||
if event.key == pygame.K_DOWN and i < len(info) - 1: i = i + 1
|
|
||||||
if event.key == pygame.K_UP and i > 0: i = i - 1
|
|
||||||
speak(info[i])
|
|
||||||
event = pygame.event.clear()
|
|
||||||
time.sleep(0.001)
|
|
||||||
|
|
||||||
def instructions():
|
|
||||||
info = (
|
|
||||||
"Welcome to " + gameName + ": brought to you by Storm Dragon. Use the up and down arrows to navigate these instructions.",\
|
|
||||||
"The object of the game is to arrange the random string of numbers so they read one through nine in as few tries as possible.",\
|
|
||||||
"You can use the up or left arrow to move back in the string, and the down or right arrow to move forward, or close to the end of the string of numbers.",\
|
|
||||||
"you can also jump directly to the number you want by pressing it on your keyboard. If you want to go to the number 8 in the string, just press 8.",\
|
|
||||||
"When you are on the number you want, press the enter key and that number, plus all the numbers to the end of the string, will be reversed.",\
|
|
||||||
"For example, if you have the string of numbers 1 2 3 4 5 6 9 8 7, pressing enter while on the number 9 will reverse 9 8 7, making the string 1 2 3 4 5 6 7 8 9 and you will win the game.",\
|
|
||||||
"If you need to her the string of numbers from your current position, press the spacebar.",\
|
|
||||||
"Have fun, and good luck!",\
|
|
||||||
"Press escape or enter to return to the game menu.")
|
|
||||||
i = 0
|
|
||||||
speak(info[i])
|
|
||||||
while True:
|
|
||||||
event = pygame.event.wait()
|
|
||||||
if event.type == pygame.KEYDOWN:
|
|
||||||
if event.key == pygame.K_ESCAPE or event.key == pygame.K_RETURN: return
|
|
||||||
if event.key == pygame.K_DOWN and i < len(info) - 1: i = i + 1
|
|
||||||
if event.key == pygame.K_UP and i > 0: i = i - 1
|
|
||||||
speak(info[i])
|
|
||||||
event = pygame.event.clear()
|
|
||||||
time.sleep(0.001)
|
|
||||||
|
|
||||||
def credits():
|
|
||||||
info = (
|
|
||||||
gameName + ": brought to you by Storm Dragon",\
|
|
||||||
"Billy Wolfe, designer and coder.",\
|
|
||||||
"http://stormdragon.tk",\
|
|
||||||
"Press escape or enter to return to the game menu.")
|
|
||||||
i = 0
|
|
||||||
speak(info[i])
|
|
||||||
while True:
|
|
||||||
event = pygame.event.wait()
|
|
||||||
if event.type == pygame.KEYDOWN:
|
|
||||||
if event.key == pygame.K_ESCAPE or event.key == pygame.K_RETURN: return
|
|
||||||
if event.key == pygame.K_DOWN and i < len(info) - 1: i = i + 1
|
|
||||||
if event.key == pygame.K_UP and i > 0: i = i - 1
|
|
||||||
speak(info[i])
|
|
||||||
event = pygame.event.clear()
|
|
||||||
time.sleep(0.001)
|
|
||||||
|
|
||||||
def game_menu(*options):
|
|
||||||
loop = True
|
|
||||||
pygame.mixer.music.load("sounds/music_menu.ogg")
|
|
||||||
pygame.mixer.music.set_volume(0.75)
|
|
||||||
pygame.mixer.music.play(-1)
|
|
||||||
i = 0
|
|
||||||
speak(options[i])
|
|
||||||
while loop == True:
|
|
||||||
event = pygame.event.wait()
|
|
||||||
if event.type == pygame.KEYDOWN:
|
|
||||||
if event.key == pygame.K_ESCAPE: exit_game()
|
|
||||||
if event.key == pygame.K_DOWN and i < len(options) - 1: i = i + 1
|
|
||||||
if event.key == pygame.K_UP and i > 0: i = i - 1
|
|
||||||
if event.key == pygame.K_RETURN:
|
|
||||||
try:
|
|
||||||
eval(options[i] + "()")
|
|
||||||
continue
|
|
||||||
except:
|
|
||||||
pygame.mixer.music.fadeout(500)
|
|
||||||
time.sleep(0.25)
|
|
||||||
return options[i]
|
|
||||||
continue
|
|
||||||
speak(options[i])
|
|
||||||
event = pygame.event.clear()
|
|
||||||
time.sleep(0.001)
|
|
||||||
38
simon/simon
38
simon/simon
@@ -8,33 +8,6 @@
|
|||||||
# There are 2 sets of keybindings. uijk or erdf.
|
# There are 2 sets of keybindings. uijk or erdf.
|
||||||
# The lowest note is e or u, with r or i being the next highest.
|
# The lowest note is e or u, with r or i being the next highest.
|
||||||
# Finally d or j follow by f and k for the ascending pitches.
|
# Finally d or j follow by f and k for the ascending pitches.
|
||||||
# Note the arrow keys may also be used.
|
|
||||||
# Down is lowest with left, then right, then up in order of pitch.
|
|
||||||
|
|
||||||
get_key() {
|
|
||||||
# Arrow keys translate to upper case letters.
|
|
||||||
# Up arrow is A
|
|
||||||
# Down arrow is B
|
|
||||||
# Left arrow is D
|
|
||||||
local __key
|
|
||||||
local __lastKey
|
|
||||||
while [[ -z "$__key" && -z "$__lastKey" ]]; do
|
|
||||||
read -t 001 -rsn1 __key
|
|
||||||
while [[ "$__key" =~ [[:cntrl:][:punct:]] ]]; do
|
|
||||||
# Key may be an arrow or something else, so remove punct and cntrl characters and try again.
|
|
||||||
if [[ -n "$__key" ]]; then
|
|
||||||
__lastKey="$__key"
|
|
||||||
else
|
|
||||||
__key="$__lastKey"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
read -t 001 -rsn1 __key
|
|
||||||
done
|
|
||||||
done
|
|
||||||
# Return __key if it contains a letter.
|
|
||||||
# If it doesn't, then a punctuation key was pressed, so return __lastKey instead.
|
|
||||||
[[ -n "$__key" ]] && echo "$__key" || echo "$__lastKey"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Simon notes
|
# Simon notes
|
||||||
notes=("sq E4" "sq C#4" "sq A3" "sq E3")
|
notes=("sq E4" "sq C#4" "sq A3" "sq E3")
|
||||||
@@ -51,12 +24,11 @@ done
|
|||||||
# Clear the player variable
|
# Clear the player variable
|
||||||
unset player
|
unset player
|
||||||
i=0
|
i=0
|
||||||
while : ; do
|
while read -sn1 key ; do
|
||||||
key="$(get_key)"
|
key="$(echo "$key" | tr 'fk' '0')"
|
||||||
key="$(echo "$key" | tr 'Afk' '0')"
|
key="$(echo "$key" | tr 'dj' '1')"
|
||||||
key="$(echo "$key" | tr 'Cdj' '1')"
|
key="$(echo "$key" | tr 'ir' '2')"
|
||||||
key="$(echo "$key" | tr 'Dir' '2')"
|
key="$(echo "$key" | tr 'eu' '3')"
|
||||||
key="$(echo "$key" | tr 'Beu' '3')"
|
|
||||||
player=(${player[@]} $key)
|
player=(${player[@]} $key)
|
||||||
# make sure the pressed key exists in the array.
|
# make sure the pressed key exists in the array.
|
||||||
if [[ "$key" =~ [0-3] ]]; then
|
if [[ "$key" =~ [0-3] ]]; then
|
||||||
|
|||||||
19
soundboard/soundboard
Executable file
19
soundboard/soundboard
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ $# -ne 1 ] ; then
|
||||||
|
echo "Usage: soundboard name, where name is the name of a soundboard you want to load."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! [ -d sounds/$1 ] ; then
|
||||||
|
echo "soundboard $1 not found."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while [ 1 -gt 0 ] ; do
|
||||||
|
read -sn1 key
|
||||||
|
if [ -f sounds/$1/$key.ogg ] ; then
|
||||||
|
play -qV0 sounds/$1/$key.ogg&
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
exit 0
|
||||||
BIN
soundboard/sounds/drums/c.ogg
Normal file
BIN
soundboard/sounds/drums/c.ogg
Normal file
Binary file not shown.
BIN
soundboard/sounds/drums/d.ogg
Normal file
BIN
soundboard/sounds/drums/d.ogg
Normal file
Binary file not shown.
BIN
soundboard/sounds/drums/e.ogg
Normal file
BIN
soundboard/sounds/drums/e.ogg
Normal file
Binary file not shown.
BIN
soundboard/sounds/drums/f.ogg
Normal file
BIN
soundboard/sounds/drums/f.ogg
Normal file
Binary file not shown.
BIN
soundboard/sounds/drums/i.ogg
Normal file
BIN
soundboard/sounds/drums/i.ogg
Normal file
Binary file not shown.
BIN
soundboard/sounds/drums/j.ogg
Normal file
BIN
soundboard/sounds/drums/j.ogg
Normal file
Binary file not shown.
BIN
soundboard/sounds/drums/k.ogg
Normal file
BIN
soundboard/sounds/drums/k.ogg
Normal file
Binary file not shown.
BIN
soundboard/sounds/drums/l.ogg
Normal file
BIN
soundboard/sounds/drums/l.ogg
Normal file
Binary file not shown.
BIN
soundboard/sounds/drums/o.ogg
Normal file
BIN
soundboard/sounds/drums/o.ogg
Normal file
Binary file not shown.
BIN
soundboard/sounds/drums/q.ogg
Normal file
BIN
soundboard/sounds/drums/q.ogg
Normal file
Binary file not shown.
BIN
soundboard/sounds/drums/r.ogg
Normal file
BIN
soundboard/sounds/drums/r.ogg
Normal file
Binary file not shown.
BIN
soundboard/sounds/drums/t.ogg
Normal file
BIN
soundboard/sounds/drums/t.ogg
Normal file
Binary file not shown.
BIN
soundboard/sounds/drums/u.ogg
Normal file
BIN
soundboard/sounds/drums/u.ogg
Normal file
Binary file not shown.
BIN
soundboard/sounds/drums/v.ogg
Normal file
BIN
soundboard/sounds/drums/v.ogg
Normal file
Binary file not shown.
BIN
soundboard/sounds/drums/w.ogg
Normal file
BIN
soundboard/sounds/drums/w.ogg
Normal file
Binary file not shown.
BIN
soundboard/sounds/drums/y.ogg
Normal file
BIN
soundboard/sounds/drums/y.ogg
Normal file
Binary file not shown.
@@ -35,15 +35,15 @@ sequence="${sequence}\"|sox -np synth 0.0$(($RANDOM % 5 + 4)) sq ${notes[$(($RAN
|
|||||||
done
|
done
|
||||||
eval play -q ${sequence} norm -5
|
eval play -q ${sequence} norm -5
|
||||||
sleep .5
|
sleep .5
|
||||||
guess="win"
|
unset guess
|
||||||
i=0
|
i=0
|
||||||
while [[ "${guess}" == "win" ]]; do
|
while [ -z "${guess}" ]; do
|
||||||
play -nqV0 synth .2 sq E4 pad .3 norm -5 &
|
play -nqV0 synth .2 sq E4 pad .3 norm -5 &
|
||||||
read -sn1 -t .6 guess || guess="win"
|
read -sn1 -t .6 guess
|
||||||
((i++))
|
((i++))
|
||||||
done
|
done
|
||||||
if [ $i -eq $length ]; then
|
if [ $i -eq $length ]; then
|
||||||
echo "you win! The answer was $length!"
|
echo "you win!"
|
||||||
else
|
else
|
||||||
echo "you lose"
|
echo "you lose"
|
||||||
echo "You guessed $i. the actual number was $length."
|
echo "You guessed $i. the actual number was $length."
|
||||||
|
|||||||
@@ -255,9 +255,6 @@ noteLength="0.75"
|
|||||||
;;
|
;;
|
||||||
"=")
|
"=")
|
||||||
noteLength="1.00"
|
noteLength="1.00"
|
||||||
;;
|
|
||||||
$'\e')
|
|
||||||
exit 0
|
|
||||||
esac
|
esac
|
||||||
if [ "$instrument" == "12" ] ; then
|
if [ "$instrument" == "12" ] ; then
|
||||||
play -qn -V0 synth pl ${note}$(($octave + 1)) pl ${note}${octave} delay 0 0.02 remix - $effect fade 0 $noteLength vol $volume &> /dev/null &
|
play -qn -V0 synth pl ${note}$(($octave + 1)) pl ${note}${octave} delay 0 0.02 remix - $effect fade 0 $noteLength vol $volume &> /dev/null &
|
||||||
|
|||||||
105
yahtzee/README
105
yahtzee/README
@@ -1,5 +1,106 @@
|
|||||||
Yahtzee by Storm Dragon
|
Yahtzee by Storm Dragon
|
||||||
Released under the terms of the WTFPL: http://wtfpl.net/
|
Released under the terms of the WTFPL: http://wtfpl.net/
|
||||||
|
|
||||||
Playing
|
OVERVIEW
|
||||||
Each player gets up to 3 rolls of the dice. To select the dice to reroll, enter the number shown. For example, if you roll 1, 2, 4, 5 and 6, you can choose to reroll 1 and 6 by typing 16 or 61 or 1 6 or 6 1. To select no dice, just press enter. To select a slot on the score sheet, press the letter of the slot you want, s for small straight, l for large straight, 3 for 3s etc. To select 3 of a kind press #. To select four of a kind press $. Yahtzee is currently PVP only. You can play with one player, in solataire mode.
|
|
||||||
|
Yahtzee is a classic dice game where you roll five dice and try to make specific combinations to score points. The goal is to fill all 13 scoring categories on your score sheet with the highest possible scores.
|
||||||
|
|
||||||
|
GETTING STARTED
|
||||||
|
|
||||||
|
Running the game:
|
||||||
|
./yahtzee - Play against CPU opponent (2 player mode)
|
||||||
|
./yahtzee 1 - Play solo (solitaire mode)
|
||||||
|
./yahtzee 3 - Play with 3 human players
|
||||||
|
./yahtzee N - Play with N human players
|
||||||
|
|
||||||
|
GAME RULES
|
||||||
|
|
||||||
|
On each turn, you get up to 3 rolls of five dice:
|
||||||
|
1. First roll - All 5 dice are rolled
|
||||||
|
2. After seeing the results, choose which dice to keep and which to reroll
|
||||||
|
3. Second roll - Selected dice are rerolled
|
||||||
|
4. Choose again which dice to keep/reroll
|
||||||
|
5. Third roll - Final reroll
|
||||||
|
6. Choose a scoring category to mark on your score sheet
|
||||||
|
|
||||||
|
The game ends when all players have filled all 13 categories on their score sheet. The player with the highest total score wins!
|
||||||
|
|
||||||
|
HOW TO REROLL DICE
|
||||||
|
|
||||||
|
After each roll, you'll see your current dice (for example: "1, 2, 4, 5, 6").
|
||||||
|
To reroll dice, type the specific dice you want to REROLL:
|
||||||
|
- Type "16" to reroll one 1 and one 6
|
||||||
|
- Type "223" to reroll two 2s and one 3
|
||||||
|
- Type "4444" to reroll four 4s
|
||||||
|
- Type "2" to reroll just one 2 (if you have "2, 2, 3, 4, 5")
|
||||||
|
- Press Enter with no input to keep all dice (skip remaining rolls)
|
||||||
|
|
||||||
|
The game removes dice one at a time as you type them, so you can reroll specific quantities
|
||||||
|
|
||||||
|
SCORING CATEGORIES
|
||||||
|
|
||||||
|
Upper Section (1s through 6s):
|
||||||
|
1, 2, 3, 4, 5, 6 - Sum of all dice showing that number
|
||||||
|
Example: Roll 2, 2, 3, 2, 5 and choose "2s" = 6 points (2+2+2)
|
||||||
|
Bonus: If upper section totals 63+ points, earn 35 point bonus
|
||||||
|
|
||||||
|
Lower Section (special combinations):
|
||||||
|
3 of a kind (#) - At least 3 dice the same = sum of ALL dice
|
||||||
|
4 of a kind ($) - At least 4 dice the same = sum of ALL dice
|
||||||
|
Full House (F) - 3 of one number + 2 of another = 25 points
|
||||||
|
Small Straight (S) - Sequence of 4 dice (1234, 2345, or 3456) = 30 points
|
||||||
|
Large Straight (L) - Sequence of 5 dice (12345 or 23456) = 40 points
|
||||||
|
Yahtzee (Y) - All 5 dice the same = 50 points
|
||||||
|
(additional Yahtzees = 100 points each!)
|
||||||
|
Chance (C) - Any combination = sum of all dice
|
||||||
|
|
||||||
|
SELECTING A SCORING SLOT
|
||||||
|
|
||||||
|
After your final roll, choose where to score by pressing:
|
||||||
|
1-6 - Number categories (1s, 2s, 3s, 4s, 5s, 6s)
|
||||||
|
# - Three of a kind
|
||||||
|
$ - Four of a kind
|
||||||
|
F - Full house
|
||||||
|
S - Small straight
|
||||||
|
L - Large straight
|
||||||
|
Y - Yahtzee
|
||||||
|
C - Chance
|
||||||
|
|
||||||
|
Important: Each category can only be used once per game. If you don't match a category's requirements, you'll score 0 points for that category.
|
||||||
|
|
||||||
|
STRATEGY TIPS
|
||||||
|
|
||||||
|
- Try to get the upper section bonus (63+ points) by maximizing high numbers (4s, 5s, 6s)
|
||||||
|
- Keep pairs and three-of-a-kind when going for Full House or Yahtzee
|
||||||
|
- Watch for straight possibilities (consecutive numbers)
|
||||||
|
- Save Chance for when nothing else scores
|
||||||
|
- The CPU opponent uses smart strategy - it keeps multiples and potential straights, and prioritizes high-value scoring categories
|
||||||
|
|
||||||
|
CPU OPPONENT
|
||||||
|
|
||||||
|
When playing against the CPU (default mode), the computer will:
|
||||||
|
- Automatically decide which dice to reroll based on the current hand
|
||||||
|
- Choose the best available scoring category
|
||||||
|
- Display its decisions so you can see what it's doing
|
||||||
|
|
||||||
|
EXAMPLE TURN
|
||||||
|
|
||||||
|
Roll 1: "2, 2, 3, 5, 6"
|
||||||
|
- Keep the pair of 2s, reroll the others
|
||||||
|
- Type: "356" and press Enter (rerolls the 3, 5, and 6)
|
||||||
|
|
||||||
|
Roll 2: "2, 2, 2, 4, 6"
|
||||||
|
- Nice! Three 2s. Keep them, reroll the 4 and 6
|
||||||
|
- Type: "46" and press Enter (rerolls the 4 and 6)
|
||||||
|
|
||||||
|
Roll 3: "2, 2, 2, 2, 5"
|
||||||
|
- Four of a kind! Sum = 2+2+2+2+5 = 13
|
||||||
|
- Press "$" to score 13 points in the 4-of-a-kind category
|
||||||
|
|
||||||
|
REQUIREMENTS
|
||||||
|
|
||||||
|
- bash 4.0 or higher
|
||||||
|
- sox (for sound effects)
|
||||||
|
- rolldice utility
|
||||||
|
|
||||||
|
Have fun and may the dice be in your favor!
|
||||||
|
|||||||
182
yahtzee/yahtzee
182
yahtzee/yahtzee
@@ -224,12 +224,58 @@ score_sheet()
|
|||||||
echo "|"
|
echo "|"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cpu_decide_reroll()
|
||||||
|
{
|
||||||
|
#CPU logic for deciding which dice to reroll
|
||||||
|
#Strategy: Keep pairs, three-of-a-kind, or higher; reroll singletons
|
||||||
|
local rerollDice=""
|
||||||
|
|
||||||
|
#Count occurrences of each die value
|
||||||
|
local count1=$(echo "$dice" | tr -cd "1" | wc -c)
|
||||||
|
local count2=$(echo "$dice" | tr -cd "2" | wc -c)
|
||||||
|
local count3=$(echo "$dice" | tr -cd "3" | wc -c)
|
||||||
|
local count4=$(echo "$dice" | tr -cd "4" | wc -c)
|
||||||
|
local count5=$(echo "$dice" | tr -cd "5" | wc -c)
|
||||||
|
local count6=$(echo "$dice" | tr -cd "6" | wc -c)
|
||||||
|
|
||||||
|
#Check for potential straights first - if we have 4 in a row, keep them all
|
||||||
|
if [[ "$dice" =~ "1" && "$dice" =~ "2" && "$dice" =~ "3" && "$dice" =~ "4" ]] ; then
|
||||||
|
#Keep 1,2,3,4 - reroll anything that's not those
|
||||||
|
rerollDice=$(echo "$dice" | tr -d " 1234")
|
||||||
|
continue="$rerollDice"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [[ "$dice" =~ "2" && "$dice" =~ "3" && "$dice" =~ "4" && "$dice" =~ "5" ]] ; then
|
||||||
|
#Keep 2,3,4,5 - reroll anything that's not those
|
||||||
|
rerollDice=$(echo "$dice" | tr -d " 2345")
|
||||||
|
continue="$rerollDice"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [[ "$dice" =~ "3" && "$dice" =~ "4" && "$dice" =~ "5" && "$dice" =~ "6" ]] ; then
|
||||||
|
#Keep 3,4,5,6 - reroll anything that's not those
|
||||||
|
rerollDice=$(echo "$dice" | tr -d " 3456")
|
||||||
|
continue="$rerollDice"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
#Otherwise, reroll dice that only appear once (singletons)
|
||||||
|
#Only add a die to reroll list if it exists AND appears only once
|
||||||
|
[ $count1 -eq 1 ] && rerollDice="${rerollDice}1"
|
||||||
|
[ $count2 -eq 1 ] && rerollDice="${rerollDice}2"
|
||||||
|
[ $count3 -eq 1 ] && rerollDice="${rerollDice}3"
|
||||||
|
[ $count4 -eq 1 ] && rerollDice="${rerollDice}4"
|
||||||
|
[ $count5 -eq 1 ] && rerollDice="${rerollDice}5"
|
||||||
|
[ $count6 -eq 1 ] && rerollDice="${rerollDice}6"
|
||||||
|
|
||||||
|
continue="$rerollDice"
|
||||||
|
}
|
||||||
|
|
||||||
dice_parser()
|
dice_parser()
|
||||||
{
|
{
|
||||||
error="true"
|
error="true"
|
||||||
while [ "$error" == "true" ] ; do
|
while [ "$error" == "true" ] ; do
|
||||||
#Remove spaces from the reroll string.
|
#Remove spaces from the reroll string.
|
||||||
continue="$(echo "$continue" | tr -d "[:space:]")"
|
continue="${continue//[[:space:]]/}"
|
||||||
#Make sure the reroll string contains valid dice options.
|
#Make sure the reroll string contains valid dice options.
|
||||||
if ! [[ "$continue" =~ ^[1-6]+$ ]] ; then
|
if ! [[ "$continue" =~ ^[1-6]+$ ]] ; then
|
||||||
error="true"
|
error="true"
|
||||||
@@ -251,8 +297,8 @@ dice_parser()
|
|||||||
if [ "$error" == "false" ] ; then
|
if [ "$error" == "false" ] ; then
|
||||||
i=0
|
i=0
|
||||||
while [ $i -lt ${#continue} ] ; do
|
while [ $i -lt ${#continue} ] ; do
|
||||||
#Remove all the selected dice from the dice string.
|
#Remove the selected dice from the dice string (one at a time).
|
||||||
dice=$(echo "$dice" | sed "s/${continue:$i:1} //")
|
dice="${dice/${continue:$i:1} /}"
|
||||||
let i++
|
let i++
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
@@ -267,6 +313,103 @@ dice_parser()
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_slot_name()
|
||||||
|
{
|
||||||
|
#Convert slot number to readable name
|
||||||
|
case $1 in
|
||||||
|
1) echo "1s" ;;
|
||||||
|
2) echo "2s" ;;
|
||||||
|
3) echo "3s" ;;
|
||||||
|
4) echo "4s" ;;
|
||||||
|
5) echo "5s" ;;
|
||||||
|
6) echo "6s" ;;
|
||||||
|
7) echo "3 of a kind" ;;
|
||||||
|
8) echo "4 of a kind" ;;
|
||||||
|
9) echo "Chance" ;;
|
||||||
|
10) echo "Full house" ;;
|
||||||
|
11) echo "Large straight" ;;
|
||||||
|
12) echo "Small straight" ;;
|
||||||
|
13) echo "Yahtzee" ;;
|
||||||
|
*) echo "Unknown" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu_choose_score()
|
||||||
|
{
|
||||||
|
#CPU logic for choosing best available scoring slot
|
||||||
|
#Priority: Yahtzee > Large Straight > Full House > 4-of-kind > 3-of-kind > Small Straight > high value slots > low value slots > Chance
|
||||||
|
local bestSlot=0
|
||||||
|
|
||||||
|
#Check available slots in priority order
|
||||||
|
i=13
|
||||||
|
while [ $i -ge 1 ] ; do
|
||||||
|
#Only consider slots that are available (still "false")
|
||||||
|
if [[ $(echo "${player[$1]}" | cut -d ":" -f $i) == "false" ]] ; then
|
||||||
|
#Check if this slot has a score available
|
||||||
|
if [ ${score[$i]} -gt 0 ] ; then
|
||||||
|
#Prioritize high-value special combinations
|
||||||
|
case $i in
|
||||||
|
13) #Yahtzee - highest priority
|
||||||
|
bestSlot=$i
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
11) #Large straight
|
||||||
|
if [ $bestSlot -eq 0 ] ; then
|
||||||
|
bestSlot=$i
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
10) #Full house
|
||||||
|
if [ $bestSlot -eq 0 -o $bestSlot -eq 12 -o $bestSlot -lt 7 ] ; then
|
||||||
|
bestSlot=$i
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
8) #4 of a kind
|
||||||
|
if [ $bestSlot -eq 0 -o $bestSlot -eq 12 -o $bestSlot -lt 7 ] ; then
|
||||||
|
bestSlot=$i
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
7) #3 of a kind
|
||||||
|
if [ $bestSlot -eq 0 -o $bestSlot -lt 7 ] ; then
|
||||||
|
bestSlot=$i
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
12) #Small straight
|
||||||
|
if [ $bestSlot -eq 0 -o $bestSlot -lt 7 ] ; then
|
||||||
|
bestSlot=$i
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*) #Number slots (1-6) - prefer higher numbers
|
||||||
|
if [ $bestSlot -eq 0 -o \( $bestSlot -lt 7 -a $i -gt $bestSlot \) ] ; then
|
||||||
|
bestSlot=$i
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
let i--
|
||||||
|
done
|
||||||
|
|
||||||
|
#If no scoring slot found, use chance or lowest available slot
|
||||||
|
if [ $bestSlot -eq 0 ] ; then
|
||||||
|
if [[ $(echo "${player[$1]}" | cut -d ":" -f 9) == "false" ]] ; then
|
||||||
|
bestSlot=9
|
||||||
|
else
|
||||||
|
#Find any available slot
|
||||||
|
i=1
|
||||||
|
while [ $i -le 13 ] ; do
|
||||||
|
if [[ $(echo "${player[$1]}" | cut -d ":" -f $i) == "false" ]] ; then
|
||||||
|
bestSlot=$i
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
let i++
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fieldIndex=$bestSlot
|
||||||
|
sleep 1
|
||||||
|
}
|
||||||
|
|
||||||
score_dice()
|
score_dice()
|
||||||
{
|
{
|
||||||
error="true"
|
error="true"
|
||||||
@@ -332,9 +475,11 @@ score_dice()
|
|||||||
if [ $# -eq 1 ] ; then
|
if [ $# -eq 1 ] ; then
|
||||||
initializer $1
|
initializer $1
|
||||||
totalPlayers="$1"
|
totalPlayers="$1"
|
||||||
|
cpu="false"
|
||||||
else
|
else
|
||||||
initializer 1
|
initializer 2
|
||||||
totalPlayers=1
|
totalPlayers=2
|
||||||
|
cpu="true"
|
||||||
fi
|
fi
|
||||||
#If the word false is in any player varaible the game is not over.
|
#If the word false is in any player varaible the game is not over.
|
||||||
while [[ $(echo "${player[@]}" | grep "false") ]] ; do
|
while [[ $(echo "${player[@]}" | grep "false") ]] ; do
|
||||||
@@ -352,13 +497,36 @@ while [[ $(echo "${player[@]}" | grep "false") ]] ; do
|
|||||||
score_sheet $playerIndex
|
score_sheet $playerIndex
|
||||||
let rollCounter++
|
let rollCounter++
|
||||||
if [ $rollCounter -lt 3 ] ; then
|
if [ $rollCounter -lt 3 ] ; then
|
||||||
read -p "Enter the dice you would like to reroll or enter to keep all the dice." continue
|
#CPU logic for rerolls
|
||||||
|
if [ "$cpu" == "true" -a $playerIndex -eq 2 ] ; then
|
||||||
|
cpu_decide_reroll
|
||||||
|
echo "CPU decides to reroll: $continue"
|
||||||
|
sleep 1
|
||||||
|
else
|
||||||
|
read -p "Enter the dice you would like to reroll (e.g. '223' rerolls two 2s and one 3): " continue
|
||||||
|
fi
|
||||||
if [ "$continue" != "" ] ; then
|
if [ "$continue" != "" ] ; then
|
||||||
dice_parser $playerIndex
|
dice_parser $playerIndex
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
score_dice $playerIndex
|
#Clear continue variable before scoring
|
||||||
|
unset continue
|
||||||
|
#CPU logic for scoring
|
||||||
|
if [ "$cpu" == "true" -a $playerIndex -eq 2 ] ; then
|
||||||
|
cpu_choose_score $playerIndex
|
||||||
|
slotName=$(get_slot_name $fieldIndex)
|
||||||
|
echo "CPU chooses $slotName for ${score[$fieldIndex]} points."
|
||||||
|
#Set the score in the player variable.
|
||||||
|
player[$playerIndex]="$(echo "${player[$playerIndex]}" | sed 's/:/\n/g' | sed -e $fieldIndex"s/false/${score[$fieldIndex]}/" | tr "\n" ":" | sed 's/:$//')"
|
||||||
|
playerScore="$(echo "${player[$playerIndex]}" | tr -d "[:alpha:]" | tr -s ":" | tr ":" "+" | sed -e 's/^\+//' -e 's/\+$//')"
|
||||||
|
echo "Player $playerIndex's score is $(($playerScore))."
|
||||||
|
echo
|
||||||
|
read -n 1 -p "Press enter to continue..." continue
|
||||||
|
echo
|
||||||
|
else
|
||||||
|
score_dice $playerIndex
|
||||||
|
fi
|
||||||
if [ $playerIndex -ge $totalPlayers ] ; then
|
if [ $playerIndex -ge $totalPlayers ] ; then
|
||||||
playerIndex=1
|
playerIndex=1
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user