1 Commits

Author SHA1 Message Date
Storm Dragon 190cc98aa1 Initial push. 2018-05-09 16:04:59 -04:00
42 changed files with 566 additions and 296 deletions
+1 -4
View File
@@ -1,7 +1,4 @@
storm-games
===========
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>
A collection of games, accessible to the blind, playable by all.
-10
View File
@@ -1,10 +0,0 @@
15 Test
2 Fluff
0 anonymous
0 anonymous
0 anonymous
0 anonymous
0 anonymous
0 anonymous
0 anonymous
0 anonymous
Binary file not shown.
+38
View File
@@ -0,0 +1,38 @@
#!/bin/python
# -*- coding: utf-8 -*-
from storm_games import *
# Initial variable settings
gameName = "Mine Racer"
mode = "menu"
sounds = initialize_gui(gameName)
def game():
pygame.mixer.music.load("sounds/music_car.ogg")
gameOver = False
jump = False
points = 0
position = 0
while not gameOver:
if pygame.mixer.music.get_busy() == 0 and jump == False: pygame.mixer.music.play(-1)
event = pygame.event.wait()
time.sleep(10)
exit_game()
# Game starts at main menu
mode = game_menu("start game", "credits", "exit_game")
while True:
# wait for an event
event = pygame.event.wait()
# if the event is about a keyboard button that have been pressed...
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"
if mode == "menu": exit_game()
# Call the game menu, if needed.
if mode == "menu": mode = game_menu("start game", "credits", "exit_game")
if mode == "start game": game()
time.sleep(.001)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+81
View File
@@ -0,0 +1,81 @@
#!/bin/python
# -*- coding: utf-8 -*-
"""Standard initializations and functions shared by all games."""
import os
from os import listdir
from os.path import isfile, join
from inspect import isfunction
import pygame
import speechd
import time
spd = speechd.Client()
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):
# 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 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:
time.sleep(0.25)
return options[i]
continue
speak(options[i])
event = pygame.event.clear()
time.sleep(0.001)
def credits():
info = (
"Mine Racer: 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)
@@ -9,6 +9,3 @@ TTYtter (optional)
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.
<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>
+64
View File
@@ -0,0 +1,64 @@
#!/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)
+64
View File
@@ -0,0 +1,64 @@
#!/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.
+148
View File
@@ -0,0 +1,148 @@
#!/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)
+23
View File
@@ -0,0 +1,23 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Shoot the bottles as fast as possible.
from storm_games import *
sounds = initialize_gui("Bottle Blaster")
# loop forever (until a break occurs)
while True:
# wait for an event
event = pygame.event.wait()
# if the event is about a keyboard button that have been pressed...
if event.type == pygame.KEYDOWN:
sounds['bottle'].play(-1)
speak("This is a test.")
if event.type == pygame.KEYUP:
sounds['bottle'].stop()
# and if the button is the "q" letter or the "escape" key...
if event.key == pygame.K_ESCAPE:
# ... then exit from the while loop
break
time.sleep(.001)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+29
View File
@@ -0,0 +1,29 @@
#!/bin/python
# -*- coding: utf-8 -*-
"""Standard initializations and functions shared by all games."""
from espeak import espeak
import os
from os import listdir
from os.path import isfile, join
import pygame
import time
def speak(text, interupt = True):
if interupt == True: espeak.cancel()
espeak.set_voice("en-us")
espeak.synth(text)
def initialize_gui(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)
return soundData
Executable
+33
View File
@@ -0,0 +1,33 @@
#!/bin/bash
#simplest way to convert the sex program to bash
#The C version is available from: http://spatula.net/software/sex/
#This version is released under the terms of the WTFPL http://www.wtfpl.net/
#set up random parts of the sentence
faster="$(shuf -n 1 -e "\"Let the games begin!\"" "\"Sweet Jesus!\"" "\"Not that!\"" "\"At last!\"" "\"Land o' Goshen!\"" "\"Is that all?\"" "\"Cheese it, the cops!\"" "\"I never dreamed it could be\"" "\"If I do, you won't respect me!\"" "\"Now!\"" "\"Open sesame!\"" "\"EMR!\"" "\"Again!\"" "\"Faster!\"" "\"Harder!\"" "\"Help!\"" "\"Fuck me harder!\"" "\"Is it in yet?\"" "\"You aren't my father!\"" "\"Doctor, that's not *my* shou\"" "\"No, no, do the goldfish!\"" "\"Holy Batmobile, Batman!\"" "\"He's dead, he's dead!\"" "\"Take me, Robert!\"" "\"I'm a Republican!\"" "\"Put four fingers in!\"" "\"What a lover!\"" "\"Talk dirty, you pig!\"" "\"The ceiling needs painting,\"" "\"Suck harder!\"" "\"The animals will hear!\"" "\"Not in public!\"")"
said="$( shuf -n 1 -e "bellowed" "yelped" "croaked" "growled" "panted" "moaned" "grunted" "laughed" "warbled" "sighed" "ejaculated" "choked" "stammered" "wheezed" "squealed" "whimpered" "salivated" "tongued" "cried" "screamed" "yelled" "said")"
fadj="$(shuf -n 1 -e "saucy" "wanton" "unfortunate" "lust-crazed" "nine-year-old" "bull-dyke" "bisexual" "gorgeous" "sweet" "nymphomaniacal" "large-hipped" "freckled" "forty-five year old" "white-haired" "large-boned" "saintly" "blind" "bearded" "blue-eyed" "large tongued" "friendly" "piano playing" "ear licking" "doe eyed" "sock sniffing" "lesbian" "hairy")"
female="$(shuf -n 1 -e "baggage" "hussy" "woman" "Duchess" "female impersonator" "nymphomaniac" "virgin" "leather freak" "home-coming queen" "defrocked nun" "bisexual budgie" "cheerleader" "office secretary" "sexual deviate" "DARPA contract monitor" "little matchgirl" "ceremonial penguin" "femme fatale" "bosses' daughter" "construction worker" "sausage abuser" "secretary" "Congressman's page" "grandmother" "penguin" "German shepherd" "stewardess" "waitress" "prostitute" "computer science group" "housewife")"
madjec="$(shuf -n 1 -e "thrashing" "slurping" "insatiable" "rabid" "satanic" "corpulent" "nose-grooming" "tripe-fondling" "dribbling" "spread-eagled" "orally fixated" "vile" "awesomely endowed" "handsome" "mush-brained" "tremendously hung" "three-legged" "pile-driving" "cross-dressing" "gerbil buggering" "bung-hole stuffing" "sphincter licking" "hair-pie chewing" "muff-diving" "clam shucking" "egg-sucking" "bicycle seat sniffing")"
male="$(shuf -n 1 -e "rakehell" "hunchback" "lecherous lickspittle" "archduke" "midget" "hired hand" "great Dane" "stallion" "donkey" "electric eel" "paraplegic pothead" "dirty old man" "faggot butler" "friar" "black-power advocate" "follicle fetishist" "handsome priest" "chicken flicker" "homosexual flamingo" "ex-celibate" "drug sucker" "ex-woman" "construction worker" "hair dresser" "dentist" "judge" "social worker")"
diddled="$(shuf -n 1 -e "diddled" "devoured" "fondled" "mouthed" "tongued" "lashed" "tweaked" "violated" "defiled" "irrigated" "penetrated" "ravished" "hammered" "bit" "tongue slashed" "sucked" "fucked" "rubbed" "grudge fucked" "masturbated with" "slurped")"
titadj="$(shuf -n 1 -e "alabaster" "pink-tipped" "creamy" "rosebud" "moist" "throbbing" "juicy" "heaving" "straining" "mammoth" "succulent" "quivering" "rosey" "globular" "varicose" "jiggling" "bloody" "tilted" "dribbling" "oozing" "firm" "pendulous" "muscular" "bovine")"
knockers="$(shuf -n 1 -e "globes" "melons" "mounds" "buds" "paps" "chubbies" "protuberances" "treasures" "buns" "bung" "vestibule" "armpits" "tits" "knockers" "elbows" "eyes" "hooters" "jugs" "lungs" "headlights" "disk drives" "bumpers" "knees" "fried eggs" "buttocks" "charlies" "ear lobes" "bazooms" "mammaries")"
thrust="$(shuf -n 1 -e "plunged" "thrust" "squeezed" "pounded" "drove" "eased" "slid" "hammered" "squished" "crammed" "slammed" "reamed" "rammed" "dipped" "inserted" "plugged" "augured" "pushed" "ripped" "forced" "wrenched")"
dongadj="$(shuf -n 1 -e "bursting" "jutting" "glistening" "Brobdingnagian" "prodigious" "purple" "searing" "swollen" "rigid" "rampaging" "warty" "steaming" "gorged" "trunklike" "foaming" "spouting" "swinish" "prosthetic" "blue veined" "engorged" "horse like" "throbbing" "humongous" "hole splitting" "serpentine" "curved" "steel encased" "glass encrusted" "knobby" "surgically altered" "metal tipped" "open sored" "rapidly dwindling" "swelling" "miniscule" "boney")"
dong="$(shuf -n 1 -e "intruder" "prong" "stump" "member" "meat loaf" "majesty" "bowsprit" "earthmover" "jackhammer" "ramrod" "cod" "jabber" "gusher" "poker" "engine" "brownie" "joy stick" "plunger" "piston" "tool" "manhood" "lollipop" "kidney prodder" "candlestick" "John Thomas" "arm" "testicles" "balls" "finger" "foot" "tongue" "dick" "one-eyed wonder worm" "canyon yodeler" "middle leg" "neck wrapper" "stick shift" "dong" "Linda Lovelace choker")"
twatadj="$(shuf -n 1 -e "pulsing" "hungry" "hymeneal" "palpitating" "gaping" "slavering" "welcoming" "glutted" "gobbling" "cobwebby" "ravenous" "slurping" "glistening" "dripping" "scabiferous" "porous" "soft-spoken" "pink" "dusty" "tight" "odiferous" "moist" "loose" "scarred" "weapon-less" "banana stuffed" "tire tracked" "mouse nibbled" "tightly tensed" "oft traveled" "grateful" "festering")"
twat="$(shuf -n 1 -e "swamp." "honeypot." "jam jar." "butterbox." "furburger." "cherry pie." "cush." "slot." "slit." "cockpit." "damp." "furrow." "sanctum sanctorum." "bearded clam." "continental divide." "paradise valley." "red river valley." "slot machine." "quim." "palace." "ass." "rose bud." "throat." "eye socket." "tenderness." "inner ear." "orifice." "appendix scar." "wound." "navel." "mouth." "nose." "cunt.")"
#set default wordwrap to 80
if [[ "$1" == "-w" && "$2" =~ ^[0-9]+$ && $2 -gt 0 && $2 -le 500 ]] ; then
lineLength=$2
fi
#generate the sentence with wordwrap
if [ -n "$lineLength" ] ; then
echo "$faster $said the $fadj $female as the $madjec $male $diddled her $titadj $knockers and $thrust his $dongadj $dong into her $twatadj $twat" | fold -sw $lineLength
else
echo "$faster $said the $fadj $female as the $madjec $male $diddled her $titadj $knockers and $thrust his $dongadj $dong into her $twatadj $twat"
fi
exit 0
+4 -1
View File
@@ -37,11 +37,14 @@ eval play -q ${sequence} norm -5
sleep .5
unset guess
i=0
ifs="$IFS"
unset IFS
while [ -z "${guess}" ]; do
play -nqV0 synth .2 sq E4 pad .3 norm -5 &
read -sn1 -t .6 guess
read -sn1 -t .6 guess && guess=" "
((i++))
done
IFS="$ifs"
if [ $i -eq $length ]; then
echo "you win!"
else
+2 -103
View File
@@ -1,106 +1,5 @@
Yahtzee by Storm Dragon
Released under the terms of the WTFPL: http://wtfpl.net/
OVERVIEW
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!
Playing
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.
+7 -175
View File
@@ -224,58 +224,12 @@ score_sheet()
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()
{
error="true"
while [ "$error" == "true" ] ; do
#Remove spaces from the reroll string.
continue="${continue//[[:space:]]/}"
continue="$(echo "$continue" | tr -d "[:space:]")"
#Make sure the reroll string contains valid dice options.
if ! [[ "$continue" =~ ^[1-6]+$ ]] ; then
error="true"
@@ -297,8 +251,8 @@ dice_parser()
if [ "$error" == "false" ] ; then
i=0
while [ $i -lt ${#continue} ] ; do
#Remove the selected dice from the dice string (one at a time).
dice="${dice/${continue:$i:1} /}"
#Remove all the selected dice from the dice string.
dice=$(echo "$dice" | sed "s/${continue:$i:1} //")
let i++
done
else
@@ -313,103 +267,6 @@ dice_parser()
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()
{
error="true"
@@ -475,11 +332,9 @@ score_dice()
if [ $# -eq 1 ] ; then
initializer $1
totalPlayers="$1"
cpu="false"
else
initializer 2
totalPlayers=2
cpu="true"
initializer 1
totalPlayers=1
fi
#If the word false is in any player varaible the game is not over.
while [[ $(echo "${player[@]}" | grep "false") ]] ; do
@@ -497,36 +352,13 @@ while [[ $(echo "${player[@]}" | grep "false") ]] ; do
score_sheet $playerIndex
let rollCounter++
if [ $rollCounter -lt 3 ] ; then
#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
read -p "Enter the dice you would like to reroll or enter to keep all the dice." continue
if [ "$continue" != "" ] ; then
dice_parser $playerIndex
fi
fi
done
#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
score_dice $playerIndex
if [ $playerIndex -ge $totalPlayers ] ; then
playerIndex=1
else
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+72
View File
@@ -0,0 +1,72 @@
#!/bin/bash
check_dependancies()
{
if [ $# -eq 0 ] ; then
if [[ $(bash --version | head -n 1 | cut -f 1 -d "." | tr -d "[:alpha:]") < "4" ]] ; then
echo "This game requires bash version 4 or higher. Earlier versions may not be able to successfully run this code."
fi
if ! hash sox &> /dev/null ; then
echo "The program sox is required but does not appear to be installed on your system. Please install sox and try
again."
exit 1
fi
fi
for i in $@ ; do
if ! hash $i &> /dev/null ; then
echo "The program $i is required but does not appear to be installed on your system. Please install $i and try
again."
exit 1
fi
done
}
initialize_players()
{
i=1
while [ $i -le $1 ] ; do
player[$i]=0
let i++
done
}
play_sound()
{
play -qV0 sounds/$@
}
check_dependancies
check_dependancies rolldice
#get terminal width
columns=$(tput cols)
play_sound intro.ogg
#find out how many players there are
if [ $# -gt 1 ] ; then
echo "Usage: $0 or $0 number of players."
exit 1
fi
if [ $# -eq 1 ] ; then
if ! [[ "$1" =~ ^[0-9]+$ ]] ; then
echo "The number of players must be a number, 2 or greater."
exit 1
fi
if [ $1 -lt 2 ] ; then
echo "The number of players must be a number, 2 or greater."
exit 1
fi
totalPlayers=$1
else
totalPlayers=2
cpu=true
fi
initialize_players $totalPlayers
#determine who goes first.
playerIndex=$(rolldice 1d${#player[@]})
while [ $playerIndex -gt 0 ] ; do
score_keeper $playerIndex
let playerIndex++
if [ $playerIndex -gt ${#player[@]} ] ; then
playerIndex=1
fi
done
exit 0