mirror of https://github.com/tLDP/LDP
updated
This commit is contained in:
parent
8456bfd681
commit
8b4da601ad
|
@ -7,17 +7,89 @@
|
||||||
|
|
||||||
|
|
||||||
==================================================================
|
==================================================================
|
||||||
Current version = 5.2
|
Current version = 5.3
|
||||||
http://personal.riverusers.com/~thegrendel/abs-guide-5.2.tar.bz2
|
http://personal.riverusers.com/~thegrendel/abs-guide-5.3.tar.bz2
|
||||||
http://personal.riverusers.com/~thegrendel/abs-guide.pdf
|
http://personal.riverusers.com/~thegrendel/abs-guide.pdf
|
||||||
|
|
||||||
------------------------------------------------------------------
|
--------------------------------------------------------------------
|
||||||
News: Version 5.2 release. . . .
|
News: "Petals Around the Rose" (petals.sh) example script added.
|
||||||
New example scripts.
|
"Crossword Puzzle Solver" (cw-solver.sh) example script added.
|
||||||
New section on version 3.2 update to Bash.
|
"Perquackey" type game (qky.sh) example script added.
|
||||||
More on !#/bin/env bash.
|
====================================================================
|
||||||
More coherent definition of "recursion."
|
|
||||||
==================================================================
|
Version 5.3, Goldenberry release
|
||||||
|
05/11/08
|
||||||
|
|
||||||
|
1) In "Special Variable Types" section of "Introduction to Variables and
|
||||||
|
Fixed exit-status error in second "shift-past.sh" example.
|
||||||
|
(Thank you, E. Choroba!)
|
||||||
|
At "#" entry, added "quoted" to "escaped" for "#" in non-comment lines.
|
||||||
|
Added a number of missing "Ctl-?" entries. Now, the entire alphabet
|
||||||
|
is complete <g>.
|
||||||
|
At "Ctl-N" entry, added footnote about history buffer.
|
||||||
|
|
||||||
|
2) In "Tests" chapter:
|
||||||
|
In "Test Constructs" section:
|
||||||
|
At [[ double brackets ]] construct, added discussion and example on
|
||||||
|
arithmetic evaluation of octal and hex constants within [[ ... ]].
|
||||||
|
(Thank you, Moritz Gronbach!)
|
||||||
|
Consolidated entire [[ ... ]] topic into a single <sidebar>.
|
||||||
|
|
||||||
|
3) In "Text Processing" section of "External Commands" Chapter:
|
||||||
|
Added "cw-solver.sh" (crossword puzzle solver) example script.
|
||||||
|
|
||||||
|
4) In "System and Administrative Commands" chapter:
|
||||||
|
At "lockfile" entry:
|
||||||
|
Updated in-line example per suggestion of E. Choroba.
|
||||||
|
Added info to footnote defining "semaphore."
|
||||||
|
|
||||||
|
5) In "Internal Commands and Builtins" chapter:
|
||||||
|
At "read" entry, appended Antonio Macchi's suggestions to
|
||||||
|
"arrow-detect.sh" example.
|
||||||
|
|
||||||
|
6) In "Quoting Variables" section of "Quoting" chapter:
|
||||||
|
Added simple in-line example.
|
||||||
|
|
||||||
|
7) In "Debugging" chapter:
|
||||||
|
Changed note defining 'signal' into a sidebar and removed superfluous
|
||||||
|
comma.
|
||||||
|
|
||||||
|
8) In "Gotchas" chapter:
|
||||||
|
Added item about unintended consequences of preserving whitespace
|
||||||
|
within a variable. (Thank you, Claus Tirel, for inspiring me to do
|
||||||
|
this.)
|
||||||
|
|
||||||
|
9) In "Assorted Tips" section of "Miscellany" chapter:
|
||||||
|
At return value trickery discussion,
|
||||||
|
added Caution about only one "echo" statement in a function.
|
||||||
|
|
||||||
|
10) In "Operator Precedence" section "Miscellany" chapter:
|
||||||
|
Fixed an error in the table (!= is not a "combination assignment"
|
||||||
|
operator.
|
||||||
|
|
||||||
|
11) In "Contributed Scripts" appendix:
|
||||||
|
Added "Petals Around the Rose" example script.
|
||||||
|
(Thank you, Serghey Rodin!)
|
||||||
|
Modified "basics-reviewed.bash" script, per contribution
|
||||||
|
of Cliff Bamford. (Many thanks!)
|
||||||
|
In "basics-reviewed.bash" script, fixed two typos.
|
||||||
|
Added very long and complex "qky.sh" (Perquackey-type game) script.
|
||||||
|
|
||||||
|
12) In "Exit Codes With Special Meanings" appendix:
|
||||||
|
Added footnote about previously unused exit codes
|
||||||
|
in the 64-78 range now allocated.
|
||||||
|
(Thank you, Greg Metcalfe, for pointing this out.)
|
||||||
|
|
||||||
|
13) In "Bibliography" section:
|
||||||
|
Added reference/link to Penguin Pete's site.
|
||||||
|
|
||||||
|
14) In "Exercise" appendix:
|
||||||
|
Added humorous preface.
|
||||||
|
|
||||||
|
15) Cleanups/fixups to main text, appendices, and script examples where
|
||||||
|
appropriate.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Version 5.2, Silverberry release
|
Version 5.2, Silverberry release
|
||||||
03/16/08
|
03/16/08
|
||||||
|
|
|
@ -698,6 +698,8 @@
|
||||||
<firstterm>unalias</firstterm></para></listitem>
|
<firstterm>unalias</firstterm></para></listitem>
|
||||||
</itemizedlist></para>
|
</itemizedlist></para>
|
||||||
|
|
||||||
|
<para><link linkend="agram2">Anagramming</link></para>
|
||||||
|
|
||||||
<para><link linkend="lcons1"><firstterm>And</firstterm> list</link>
|
<para><link linkend="lcons1"><firstterm>And</firstterm> list</link>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
|
@ -809,6 +811,8 @@
|
||||||
elements</link></para></listitem>
|
elements</link></para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
|
<para><link linkend="readarrow">Arrow keys</link>, detecting</para>
|
||||||
|
|
||||||
<para><link linkend="asciitable">ASCII table</link></para>
|
<para><link linkend="asciitable">ASCII table</link></para>
|
||||||
|
|
||||||
<!-- ********************** -->
|
<!-- ********************** -->
|
||||||
|
@ -880,6 +884,8 @@
|
||||||
<para><link linkend="biblio">Bibliography</link></para>
|
<para><link linkend="biblio">Bibliography</link></para>
|
||||||
<para><link linkend="bisonref">Bison</link> utility</para>
|
<para><link linkend="bisonref">Bison</link> utility</para>
|
||||||
<para><link linkend="bitwsops1">Bitwise operators</link></para>
|
<para><link linkend="bitwsops1">Bitwise operators</link></para>
|
||||||
|
<para><link linkend="blockdevref">Block devices</link>, testing
|
||||||
|
for</para>
|
||||||
|
|
||||||
<para><link linkend="codeblockref">Blocks of code</link>
|
<para><link linkend="codeblockref">Blocks of code</link>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
|
@ -969,6 +975,8 @@
|
||||||
</itemizedlist></para>
|
</itemizedlist></para>
|
||||||
|
|
||||||
|
|
||||||
|
<para><link linkend="chardevref">Character devices</link>, testing
|
||||||
|
for</para>
|
||||||
<para><link linkend="childref">Child processes</link></para>
|
<para><link linkend="childref">Child processes</link></para>
|
||||||
<para><link linkend="nullref">Colon</link>, <command>: </command>,
|
<para><link linkend="nullref">Colon</link>, <command>: </command>,
|
||||||
equivalent to the <link linkend="trueref">true</link> Bash
|
equivalent to the <link linkend="trueref">true</link> Bash
|
||||||
|
@ -1063,6 +1071,8 @@
|
||||||
<para><link linkend="cstyle"><firstterm>C</firstterm>-style syntax
|
<para><link linkend="cstyle"><firstterm>C</firstterm>-style syntax
|
||||||
</link>, for handling variables</para>
|
</link>, for handling variables</para>
|
||||||
|
|
||||||
|
<para><link linkend="cwsolver">Crossword puzzle solver</link></para>
|
||||||
|
|
||||||
<para>Curly brackets {}
|
<para>Curly brackets {}
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para><link linkend="curlybracketsref">in
|
<listitem><para><link linkend="curlybracketsref">in
|
||||||
|
@ -1169,9 +1179,15 @@
|
||||||
(<command>table</command>)</para>
|
(<command>table</command>)</para>
|
||||||
<para><link linkend="dotfilesref"><firstterm>dot files</firstterm></link>,
|
<para><link linkend="dotfilesref"><firstterm>dot files</firstterm></link>,
|
||||||
<quote>hidden</quote> setup and configuration files</para>
|
<quote>hidden</quote> setup and configuration files</para>
|
||||||
|
|
||||||
<para><link linkend="dblbrackets">Double brackets</link>
|
<para><link linkend="dblbrackets">Double brackets</link>
|
||||||
<command>[[ ... ]]</command> <link linkend="ifthen">test</link>
|
<command>[[ ... ]]</command> <link linkend="ifthen">test</link>
|
||||||
construct</para>
|
construct</para>
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para>and <link linkend="dblbraev">evaluation of
|
||||||
|
<firstterm>octal/hex</firstterm> constants</link></para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
<para><link linkend="dblquo">Double quotes</link>
|
<para><link linkend="dblquo">Double quotes</link>
|
||||||
<command>" ... "</command> <firstterm>weak</firstterm> quoting</para>
|
<command>" ... "</command> <firstterm>weak</firstterm> quoting</para>
|
||||||
<para><link linkend="doublespace">Double-spacing a text
|
<para><link linkend="doublespace">Double-spacing a text
|
||||||
|
@ -1223,6 +1239,10 @@
|
||||||
using</link></para></listitem>
|
using</link></para></listitem>
|
||||||
</itemizedlist></para>
|
</itemizedlist></para>
|
||||||
|
|
||||||
|
<para><link linkend="dblbraev">Evaluation of
|
||||||
|
<firstterm>octal/hex</firstterm> constants within
|
||||||
|
[[ ... ]]</link></para>
|
||||||
|
|
||||||
<para><link linkend="usingexecref">exec</link> command,
|
<para><link linkend="usingexecref">exec</link> command,
|
||||||
using in <link linkend="ioredirref">redirection</link></para>
|
using in <link linkend="ioredirref">redirection</link></para>
|
||||||
|
|
||||||
|
@ -1548,6 +1568,8 @@
|
||||||
loop</para>
|
loop</para>
|
||||||
<para><link linkend="inittabref">Initialization table</link>,
|
<para><link linkend="inittabref">Initialization table</link>,
|
||||||
<filename>/etc/inittab</filename></para>
|
<filename>/etc/inittab</filename></para>
|
||||||
|
<para><link linkend="codeblockref">Inline group</link>,
|
||||||
|
i.e., code block</para>
|
||||||
<para><link linkend="iitest">Interactive script</link>, test for</para>
|
<para><link linkend="iitest">Interactive script</link>, test for</para>
|
||||||
<para><link linkend="ioredirref">I/O redirection</link></para>
|
<para><link linkend="ioredirref">I/O redirection</link></para>
|
||||||
|
|
||||||
|
@ -1897,6 +1919,12 @@
|
||||||
with</link></para></listitem>
|
with</link></para></listitem>
|
||||||
</itemizedlist></para>
|
</itemizedlist></para>
|
||||||
|
|
||||||
|
<para><link linkend="qky"><emphasis>Perquackey</emphasis>-type
|
||||||
|
anagramming game</link> (<emphasis>Quackey</emphasis> script)</para>
|
||||||
|
|
||||||
|
<para><link linkend="petals"><emphasis>Petals Around the
|
||||||
|
Rose</emphasis></link></para>
|
||||||
|
|
||||||
<para><link linkend="processiddef">PID</link>,
|
<para><link linkend="processiddef">PID</link>,
|
||||||
<firstterm>Process ID</firstterm>, an identification
|
<firstterm>Process ID</firstterm>, an identification
|
||||||
number assigned to a running process.</para>
|
number assigned to a running process.</para>
|
||||||
|
@ -1965,6 +1993,9 @@
|
||||||
within <firstterm>test</firstterm> brackets</para></listitem>
|
within <firstterm>test</firstterm> brackets</para></listitem>
|
||||||
<listitem><para><link linkend="gnuref"><firstterm>GNU</firstterm>
|
<listitem><para><link linkend="gnuref"><firstterm>GNU</firstterm>
|
||||||
command set</link>, in cross-platform scripts</para></listitem>
|
command set</link>, in cross-platform scripts</para></listitem>
|
||||||
|
<listitem><para><link linkend="rvtcaution2">Multiple echo
|
||||||
|
statements</link> in a <link linkend="rvt">function whose
|
||||||
|
output is captured</link></para></listitem>
|
||||||
<listitem><para><link linkend="nullvar"><firstterm>null</firstterm>
|
<listitem><para><link linkend="nullvar"><firstterm>null</firstterm>
|
||||||
variable assignment</link></para></listitem>
|
variable assignment</link></para></listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -1988,6 +2019,9 @@
|
||||||
<para><link linkend="ptailgrep"><firstterm>tail</firstterm>
|
<para><link linkend="ptailgrep"><firstterm>tail</firstterm>
|
||||||
<option>-f</option> to <firstterm>grep</firstterm></link></para>
|
<option>-f</option> to <firstterm>grep</firstterm></link></para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem><para>Preserving <firstterm>whitespace</firstterm>
|
||||||
|
within a variable, <link linkend="varsplitting">unintended
|
||||||
|
consequences</link></para></listitem>
|
||||||
<listitem><para><link linkend="suidscr"><firstterm>suid</firstterm>
|
<listitem><para><link linkend="suidscr"><firstterm>suid</firstterm>
|
||||||
commands inside a script</link></para></listitem>
|
commands inside a script</link></para></listitem>
|
||||||
<listitem><para><link linkend="undocf">Undocumented
|
<listitem><para><link linkend="undocf">Undocumented
|
||||||
|
@ -2125,6 +2159,9 @@
|
||||||
|
|
||||||
<para>* * *</para>
|
<para>* * *</para>
|
||||||
|
|
||||||
|
<para><link linkend="qky">Quackey</link>, a
|
||||||
|
<emphasis>Perquackey</emphasis>-type anagramming game (script)</para>
|
||||||
|
|
||||||
<para>Question mark, <command>? </command>
|
<para>Question mark, <command>? </command>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para><link linkend="quexregex">Character
|
<listitem><para><link linkend="quexregex">Character
|
||||||
|
@ -2552,6 +2589,16 @@
|
||||||
<firstterm>script example</firstterm></para>
|
<firstterm>script example</firstterm></para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><firstterm>strchr()</firstterm>, <link
|
||||||
|
linkend="substringindex2">equivalent of</link></para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><firstterm>strlen()</firstterm>, <link
|
||||||
|
linkend="strlen">equivalent of</link></para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Substring extraction</para>
|
<para>Substring extraction</para>
|
||||||
<para><link linkend="substrextr01">${string:position}</link></para>
|
<para><link linkend="substrextr01">${string:position}</link></para>
|
||||||
|
@ -2789,6 +2836,10 @@
|
||||||
<firstterm>return value</firstterm> from
|
<firstterm>return value</firstterm> from
|
||||||
a function</link></para></listitem>
|
a function</link></para></listitem>
|
||||||
|
|
||||||
|
<listitem><para><link linkend="captureretval">Capturing
|
||||||
|
the return value</link> of a function, using
|
||||||
|
<firstterm>echo</firstterm></para></listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Comment blocks</para>
|
<para>Comment blocks</para>
|
||||||
<para>Using <link linkend="cblock1"><firstterm>anonymous
|
<para>Using <link linkend="cblock1"><firstterm>anonymous
|
||||||
|
@ -2980,7 +3031,7 @@
|
||||||
<para><link
|
<para><link
|
||||||
linkend="failquote">within <firstterm>test</firstterm>
|
linkend="failquote">within <firstterm>test</firstterm>
|
||||||
brackets</link></para>
|
brackets</link></para>
|
||||||
<para><link linkend="quotingws">to preserve
|
<para><link linkend="wsquo">to preserve
|
||||||
<firstterm>whitespace</firstterm></link></para>
|
<firstterm>whitespace</firstterm></link></para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><para><link
|
<listitem><para><link
|
||||||
|
@ -2999,10 +3050,13 @@
|
||||||
error message</para></listitem>
|
error message</para></listitem>
|
||||||
<listitem><para><link linkend="uninitvar1">Uninitialized</link>
|
<listitem><para><link linkend="uninitvar1">Uninitialized</link>
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
<listitem><para><link linkend="varsplitting">Unquoted
|
||||||
|
variable</link>,
|
||||||
|
<firstterm>splitting</firstterm></para></listitem>
|
||||||
|
<listitem><para><link
|
||||||
|
linkend="unsetref">Unsetting</link></para></listitem>
|
||||||
<listitem><para><link
|
<listitem><para><link
|
||||||
linkend="unsetref">Unsetting</link></para></listitem>
|
linkend="bvuntyped">Untyped</link></para></listitem>
|
||||||
<listitem><para><link
|
|
||||||
linkend="bvuntyped">Untyped</link></para></listitem>
|
|
||||||
|
|
||||||
</itemizedlist></para>
|
</itemizedlist></para>
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ hash-example.sh (comment in line 3: < --> <, > --> >)
|
||||||
quote-fetch.sh (comment in line 26: & --> &)
|
quote-fetch.sh (comment in line 26: & --> &)
|
||||||
ftpget.sh (comment in line 28)
|
ftpget.sh (comment in line 28)
|
||||||
whx.sh (comment in line 259)
|
whx.sh (comment in line 259)
|
||||||
pad.sh, (comment in line 6, lines 26, 27, 28, 29, 30, 33, 34).
|
pad.sh, (comments in line 6, lines 26, 27, 28, 29, 30, 33, 34).
|
||||||
nightly-backup.sh (comment in line 4)
|
nightly-backup.sh (comment in line 4)
|
||||||
tohtml.sh: lines 22-33
|
tohtml.sh: lines 22-33
|
||||||
lines 35-36
|
lines 35-36
|
||||||
|
@ -91,3 +91,14 @@ insertion-sort.sh:
|
||||||
tree2.sh:
|
tree2.sh:
|
||||||
line 38 (comment)
|
line 38 (comment)
|
||||||
line 88
|
line 88
|
||||||
|
|
||||||
|
petals.sh
|
||||||
|
line 54
|
||||||
|
|
||||||
|
qky.sh
|
||||||
|
line 7
|
||||||
|
line 63
|
||||||
|
line 87
|
||||||
|
line 113
|
||||||
|
(The unaltered, executable script can be downloaded from
|
||||||
|
http://personal.riverusers.com/~thegrendel/qky.sh)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -96,6 +96,29 @@ exit $OTHER
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
exit $?
|
||||||
|
|
||||||
|
# ========================================= #
|
||||||
|
|
||||||
|
# Antonio Macchi has a simpler alternative.
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
read -sn1 a
|
||||||
|
test "$a" == `echo -en "\e"` || continue
|
||||||
|
read -sn1 a
|
||||||
|
test "$a" == "[" || continue
|
||||||
|
read -sn1 a
|
||||||
|
case "$a" in
|
||||||
|
A) echo "up";;
|
||||||
|
B) echo "down";;
|
||||||
|
C) echo "right";;
|
||||||
|
D) echo "left";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
# ========================================= #
|
# ========================================= #
|
||||||
|
|
||||||
# Exercise:
|
# Exercise:
|
||||||
|
|
|
@ -9,15 +9,16 @@
|
||||||
#
|
#
|
||||||
# Edited for layout by M.C.
|
# Edited for layout by M.C.
|
||||||
# (author of the "Advanced Bash Scripting Guide")
|
# (author of the "Advanced Bash Scripting Guide")
|
||||||
|
# Fixes and updates (04/08) by Cliff Bamford.
|
||||||
|
|
||||||
|
|
||||||
# This script tested under Bash versions 2.04, 2.05a and 2.05b.
|
# This script tested under Bash versions 2.04, 2.05a and 2.05b.
|
||||||
# It may not work with earlier versions.
|
# It may not work with earlier versions.
|
||||||
# This demonstration script generates one --intentional--
|
# This demonstration script generates one --intentional--
|
||||||
#+ "command not found" error message. See line 394.
|
#+ "command not found" error message. See line 436.
|
||||||
|
|
||||||
# The current Bash maintainer, Chet Ramey, has fixed the items noted
|
# The current Bash maintainer, Chet Ramey, has fixed the items noted
|
||||||
#+ for an upcoming version of Bash.
|
#+ for later versions of Bash.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ unset VarNull
|
||||||
# A variable name may be defined but empty (null contents).
|
# A variable name may be defined but empty (null contents).
|
||||||
VarEmpty='' # Two, adjacent, single quotes.
|
VarEmpty='' # Two, adjacent, single quotes.
|
||||||
|
|
||||||
# A variable name my be defined and non-empty
|
# A variable name may be defined and non-empty.
|
||||||
VarSomething='Literal'
|
VarSomething='Literal'
|
||||||
|
|
||||||
# A variable may contain:
|
# A variable may contain:
|
||||||
|
@ -174,7 +175,7 @@ echo ${@} # Same as above
|
||||||
# Elements of a Bash-Array need not all be of the same type.
|
# Elements of a Bash-Array need not all be of the same type.
|
||||||
###
|
###
|
||||||
# Elements of a Bash-Array may be undefined (null reference).
|
# Elements of a Bash-Array may be undefined (null reference).
|
||||||
# That is, a Bash-Array my be "subscript sparse."
|
# That is, a Bash-Array may be "subscript sparse."
|
||||||
###
|
###
|
||||||
# Elements of a Bash-Array may be defined and empty (null contents).
|
# Elements of a Bash-Array may be defined and empty (null contents).
|
||||||
###
|
###
|
||||||
|
@ -196,102 +197,143 @@ echo ${@} # Same as above
|
||||||
# -- msz
|
# -- msz
|
||||||
|
|
||||||
|
|
||||||
|
echo "========================================================="
|
||||||
|
|
||||||
|
# Lines 202 - 334 supplied by Cliff Bamford. (Thanks!)
|
||||||
|
# Demo --- Interaction with Arrays, quoting, IFS, echo, * and @ ---
|
||||||
|
#+ all affect how things work
|
||||||
|
|
||||||
|
ArrayVar[0]='zero' # 0 normal
|
||||||
|
ArrayVar[1]=one # 1 unquoted literal
|
||||||
|
ArrayVar[2]='two' # 2 normal
|
||||||
|
ArrayVar[3]='three' # 3 normal
|
||||||
|
ArrayVar[4]='I am four' # 4 normal with spaces
|
||||||
|
ArrayVar[5]='five' # 5 normal
|
||||||
|
unset ArrayVar[6] # 6 undefined
|
||||||
|
ArrayValue[7]='seven' # 7 normal
|
||||||
|
ArrayValue[8]='' # 8 defined but empty
|
||||||
|
ArrayValue[9]='nine' # 9 normal
|
||||||
|
|
||||||
|
|
||||||
# Demo time -- initialize the previously declared ArrayVar as a
|
echo '--- Here is the array we are using for this test'
|
||||||
#+ sparse array.
|
|
||||||
# (The 'unset ... ' is just documentation here.)
|
|
||||||
|
|
||||||
unset ArrayVar[0] # Just for the record
|
|
||||||
ArrayVar[1]=one # Unquoted literal
|
|
||||||
ArrayVar[2]='' # Defined, and empty
|
|
||||||
unset ArrayVar[3] # Just for the record
|
|
||||||
ArrayVar[4]='four' # Quoted literal
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Translate the %q format as: Quoted-Respecting-IFS-Rules.
|
|
||||||
echo
|
echo
|
||||||
echo '- - Outside of double-quotes - -'
|
echo "ArrayVar[0]='zero' # 0 normal"
|
||||||
###
|
echo "ArrayVar[1]=one # 1 unquoted literal"
|
||||||
printf %q ${ArrayVar[*]} # Glob-Pattern All-Elements-Of
|
echo "ArrayVar[2]='two' # 2 normal"
|
||||||
|
echo "ArrayVar[3]='three' # 3 normal"
|
||||||
|
echo "ArrayVar[4]='I am four' # 4 normal with spaces"
|
||||||
|
echo "ArrayVar[5]='five' # 5 normal"
|
||||||
|
echo "unset ArrayVar[6] # 6 undefined"
|
||||||
|
echo "ArrayValue[7]='seven' # 7 normal"
|
||||||
|
echo "ArrayValue[8]='' # 8 defined but empty"
|
||||||
|
echo "ArrayValue[9]='nine' # 9 normal"
|
||||||
echo
|
echo
|
||||||
echo 'echo command:'${ArrayVar[*]}
|
|
||||||
###
|
|
||||||
printf %q ${ArrayVar[@]} # All-Elements-Of
|
|
||||||
echo
|
|
||||||
echo 'echo command:'${ArrayVar[@]}
|
|
||||||
|
|
||||||
# The use of double-quotes may be translated as: Enable-Substitution.
|
|
||||||
|
|
||||||
# There are five cases recognized for the IFS setting.
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo '- - Within double-quotes - Default IFS of space-tab-newline - -'
|
|
||||||
IFS=$'\x20'$'\x09'$'\x0A' # These three bytes,
|
|
||||||
#+ in exactly this order.
|
|
||||||
|
|
||||||
|
|
||||||
printf %q "${ArrayVar[*]}" # Glob-Pattern All-Elements-Of
|
|
||||||
echo
|
|
||||||
echo 'echo command:'"${ArrayVar[*]}"
|
|
||||||
###
|
|
||||||
printf %q "${ArrayVar[@]}" # All-Elements-Of
|
|
||||||
echo
|
|
||||||
echo 'echo command:'"${ArrayVar[@]}"
|
|
||||||
|
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo '- - Within double-quotes - First character of IFS is ^ - -'
|
echo '---Case0: No double-quotes, Default IFS of space,tab,newline ---'
|
||||||
# Any printing, non-whitespace character should do the same.
|
IFS=$'\x20'$'\x09'$'\x0A' # In exactly this order.
|
||||||
IFS='^'$IFS # ^ + space tab newline
|
echo 'Here is: printf %q {${ArrayVar[*]}'
|
||||||
###
|
printf %q ${ArrayVar[*]}
|
||||||
printf %q "${ArrayVar[*]}" # Glob-Pattern All-Elements-Of
|
|
||||||
echo
|
echo
|
||||||
echo 'echo command:'"${ArrayVar[*]}"
|
echo 'Here is: printf %q {${ArrayVar[@]}'
|
||||||
###
|
printf %q ${ArrayVar[@]}
|
||||||
printf %q "${ArrayVar[@]}" # All-Elements-Of
|
|
||||||
echo
|
echo
|
||||||
echo 'echo command:'"${ArrayVar[@]}"
|
echo 'Here is: echo ${ArrayVar[*]}'
|
||||||
|
echo ${ArrayVar[@]}
|
||||||
|
echo 'Here is: echo {${ArrayVar[@]}'
|
||||||
|
echo ${ArrayVar[@]}
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo '- - Within double-quotes - Without whitespace in IFS - -'
|
echo '---Case1: Within double-quotes - Default IFS of space-tab-
|
||||||
IFS='^:%!'
|
newline ---'
|
||||||
###
|
IFS=$'\x20'$'\x09'$'\x0A' # These three bytes,
|
||||||
printf %q "${ArrayVar[*]}" # Glob-Pattern All-Elements-Of
|
echo 'Here is: printf %q "{${ArrayVar[*]}"'
|
||||||
|
printf %q "${ArrayVar[*]}"
|
||||||
echo
|
echo
|
||||||
echo 'echo command:'"${ArrayVar[*]}"
|
echo 'Here is: printf %q "{${ArrayVar[@]}"'
|
||||||
###
|
printf %q "${ArrayVar[@]}"
|
||||||
printf %q "${ArrayVar[@]}" # All-Elements-Of
|
|
||||||
echo
|
echo
|
||||||
echo 'echo command:'"${ArrayVar[@]}"
|
echo 'Here is: echo "${ArrayVar[*]}"'
|
||||||
|
echo "${ArrayVar[@]}"
|
||||||
|
echo 'Here is: echo "{${ArrayVar[@]}"'
|
||||||
|
echo "${ArrayVar[@]}"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo '- - Within double-quotes - IFS set and empty - -'
|
echo '---Case2: Within double-quotes - IFS is q'
|
||||||
|
IFS='q'
|
||||||
|
echo 'Here is: printf %q "{${ArrayVar[*]}"'
|
||||||
|
printf %q "${ArrayVar[*]}"
|
||||||
|
echo
|
||||||
|
echo 'Here is: printf %q "{${ArrayVar[@]}"'
|
||||||
|
printf %q "${ArrayVar[@]}"
|
||||||
|
echo
|
||||||
|
echo 'Here is: echo "${ArrayVar[*]}"'
|
||||||
|
echo "${ArrayVar[@]}"
|
||||||
|
echo 'Here is: echo "{${ArrayVar[@]}"'
|
||||||
|
echo "${ArrayVar[@]}"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo '---Case3: Within double-quotes - IFS is ^'
|
||||||
|
IFS='^'
|
||||||
|
echo 'Here is: printf %q "{${ArrayVar[*]}"'
|
||||||
|
printf %q "${ArrayVar[*]}"
|
||||||
|
echo
|
||||||
|
echo 'Here is: printf %q "{${ArrayVar[@]}"'
|
||||||
|
printf %q "${ArrayVar[@]}"
|
||||||
|
echo
|
||||||
|
echo 'Here is: echo "${ArrayVar[*]}"'
|
||||||
|
echo "${ArrayVar[@]}"
|
||||||
|
echo 'Here is: echo "{${ArrayVar[@]}"'
|
||||||
|
echo "${ArrayVar[@]}"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo '---Case4: Within double-quotes - IFS is ^ followed by
|
||||||
|
space,tab,newline'
|
||||||
|
IFS=$'^'$'\x20'$'\x09'$'\x0A' # ^ + space tab newline
|
||||||
|
echo 'Here is: printf %q "{${ArrayVar[*]}"'
|
||||||
|
printf %q "${ArrayVar[*]}"
|
||||||
|
echo
|
||||||
|
echo 'Here is: printf %q "{${ArrayVar[@]}"'
|
||||||
|
printf %q "${ArrayVar[@]}"
|
||||||
|
echo
|
||||||
|
echo 'Here is: echo "${ArrayVar[*]}"'
|
||||||
|
echo "${ArrayVar[@]}"
|
||||||
|
echo 'Here is: echo "{${ArrayVar[@]}"'
|
||||||
|
echo "${ArrayVar[@]}"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo '---Case6: Within double-quotes - IFS set and empty '
|
||||||
IFS=''
|
IFS=''
|
||||||
###
|
echo 'Here is: printf %q "{${ArrayVar[*]}"'
|
||||||
printf %q "${ArrayVar[*]}" # Glob-Pattern All-Elements-Of
|
printf %q "${ArrayVar[*]}"
|
||||||
echo
|
echo
|
||||||
echo 'echo command:'"${ArrayVar[*]}"
|
echo 'Here is: printf %q "{${ArrayVar[@]}"'
|
||||||
###
|
printf %q "${ArrayVar[@]}"
|
||||||
printf %q "${ArrayVar[@]}" # All-Elements-Of
|
|
||||||
echo
|
echo
|
||||||
echo 'echo command:'"${ArrayVar[@]}"
|
echo 'Here is: echo "${ArrayVar[*]}"'
|
||||||
|
echo "${ArrayVar[@]}"
|
||||||
|
echo 'Here is: echo "{${ArrayVar[@]}"'
|
||||||
|
echo "${ArrayVar[@]}"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo '- - Within double-quotes - IFS undefined - -'
|
echo '---Case7: Within double-quotes - IFS is unset'
|
||||||
unset IFS
|
unset IFS
|
||||||
###
|
echo 'Here is: printf %q "{${ArrayVar[*]}"'
|
||||||
printf %q "${ArrayVar[*]}" # Glob-Pattern All-Elements-Of
|
printf %q "${ArrayVar[*]}"
|
||||||
echo
|
echo
|
||||||
echo 'echo command:'"${ArrayVar[*]}"
|
echo 'Here is: printf %q "{${ArrayVar[@]}"'
|
||||||
###
|
printf %q "${ArrayVar[@]}"
|
||||||
printf %q "${ArrayVar[@]}" # All-Elements-Of
|
|
||||||
echo
|
echo
|
||||||
echo 'echo command:'"${ArrayVar[@]}"
|
echo 'Here is: echo "${ArrayVar[*]}"'
|
||||||
|
echo "${ArrayVar[@]}"
|
||||||
|
echo 'Here is: echo "{${ArrayVar[@]}"'
|
||||||
|
echo "${ArrayVar[@]}"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo '---End of Cases---'
|
||||||
|
echo "========================================================="; echo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Put IFS back to the default.
|
# Put IFS back to the default.
|
||||||
|
@ -392,7 +434,7 @@ echo $_simple not defined # No variable by that name.
|
||||||
|
|
||||||
###
|
###
|
||||||
$(_simple) # Gives an error message:
|
$(_simple) # Gives an error message:
|
||||||
# line 394: SimpleFunc: command not found
|
# line 436: SimpleFunc: command not found
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
@ -784,8 +826,7 @@ echo ${ArrayVar[@]:1:2} # four - The only element with content.
|
||||||
# In versions 2.04, 2.05a and 2.05b,
|
# In versions 2.04, 2.05a and 2.05b,
|
||||||
#+ Bash does not handle sparse arrays as expected using this notation.
|
#+ Bash does not handle sparse arrays as expected using this notation.
|
||||||
#
|
#
|
||||||
# The current Bash maintainer, Chet Ramey, has corrected this
|
# The current Bash maintainer, Chet Ramey, has corrected this.
|
||||||
#+ for an upcoming version of Bash.
|
|
||||||
|
|
||||||
|
|
||||||
echo '- Non-sparse array -'
|
echo '- Non-sparse array -'
|
||||||
|
@ -821,8 +862,8 @@ echo ${stringZ#123} # Unchanged (not a prefix).
|
||||||
echo ${stringZ#$(_abc)} # ABC123ABCabc
|
echo ${stringZ#$(_abc)} # ABC123ABCabc
|
||||||
echo ${arrayZ[@]#abc} # Applied to each element.
|
echo ${arrayZ[@]#abc} # Applied to each element.
|
||||||
|
|
||||||
# Fixed by Chet Ramey for an upcoming version of Bash.
|
|
||||||
# echo ${sparseZ[@]#abc} # Version-2.05b core dumps.
|
# echo ${sparseZ[@]#abc} # Version-2.05b core dumps.
|
||||||
|
# Has since been fixed by Chet Ramey.
|
||||||
|
|
||||||
# The -it would be nice- First-Subscript-Of
|
# The -it would be nice- First-Subscript-Of
|
||||||
# echo ${#sparseZ[@]#*} # This is NOT valid Bash.
|
# echo ${#sparseZ[@]#*} # This is NOT valid Bash.
|
||||||
|
@ -833,8 +874,8 @@ echo ${stringZ##1*3} # Unchanged (not a prefix)
|
||||||
echo ${stringZ##a*C} # abc
|
echo ${stringZ##a*C} # abc
|
||||||
echo ${arrayZ[@]##a*c} # ABCABC 123123 ABCABC
|
echo ${arrayZ[@]##a*c} # ABCABC 123123 ABCABC
|
||||||
|
|
||||||
# Fixed by Chet Ramey for an upcoming version of Bash
|
|
||||||
# echo ${sparseZ[@]##a*c} # Version-2.05b core dumps.
|
# echo ${sparseZ[@]##a*c} # Version-2.05b core dumps.
|
||||||
|
# Has since been fixed by Chet Ramey.
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo '- - Suffix sub-element removal - -'
|
echo '- - Suffix sub-element removal - -'
|
||||||
|
@ -846,8 +887,8 @@ echo ${stringZ%1*3} # Unchanged (not a suffix).
|
||||||
echo ${stringZ%$(_abc)} # abcABC123ABC
|
echo ${stringZ%$(_abc)} # abcABC123ABC
|
||||||
echo ${arrayZ[@]%abc} # Applied to each element.
|
echo ${arrayZ[@]%abc} # Applied to each element.
|
||||||
|
|
||||||
# Fixed by Chet Ramey for an upcoming version of Bash.
|
|
||||||
# echo ${sparseZ[@]%abc} # Version-2.05b core dumps.
|
# echo ${sparseZ[@]%abc} # Version-2.05b core dumps.
|
||||||
|
# Has since been fixed by Chet Ramey.
|
||||||
|
|
||||||
# The -it would be nice- Last-Subscript-Of
|
# The -it would be nice- Last-Subscript-Of
|
||||||
# echo ${#sparseZ[@]%*} # This is NOT valid Bash.
|
# echo ${#sparseZ[@]%*} # This is NOT valid Bash.
|
||||||
|
@ -858,8 +899,8 @@ echo ${stringZ%%1*3} # Unchanged (not a suffix)
|
||||||
echo ${stringZ%%b*c} # a
|
echo ${stringZ%%b*c} # a
|
||||||
echo ${arrayZ[@]%%b*c} # a ABCABC 123123 ABCABC a
|
echo ${arrayZ[@]%%b*c} # a ABCABC 123123 ABCABC a
|
||||||
|
|
||||||
# Fixed by Chet Ramey for an upcoming version of Bash.
|
|
||||||
# echo ${sparseZ[@]%%b*c} # Version-2.05b core dumps.
|
# echo ${sparseZ[@]%%b*c} # Version-2.05b core dumps.
|
||||||
|
# Has since been fixed by Chet Ramey.
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo '- - Sub-element replacement - -'
|
echo '- - Sub-element replacement - -'
|
||||||
|
|
|
@ -23,19 +23,21 @@
|
||||||
#+ disregards such parameters as
|
#+ disregards such parameters as
|
||||||
#+ board tilt-angle, rolling friction of the marbles,
|
#+ board tilt-angle, rolling friction of the marbles,
|
||||||
#+ angles of impact, and elasticity of the pegs.
|
#+ angles of impact, and elasticity of the pegs.
|
||||||
# How does this affect the accuracy of the simulation?
|
# To what extent does this affect the accuracy of the simulation?
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
PASSES=500 # Number of particle interactions / marbles.
|
PASSES=500 # Number of particle interactions / marbles.
|
||||||
ROWS=10 # Number of "collisions" (or horiz. peg rows).
|
ROWS=10 # Number of "collisions" (or horiz. peg rows).
|
||||||
RANGE=3 # 0 - 2 output range from $RANDOM.
|
RANGE=3 # 0 - 2 output range from $RANDOM.
|
||||||
POS=0 # Left/right position.
|
POS=0 # Left/right position.
|
||||||
|
RANDOM=$$ # Seeds the random number generator from PID
|
||||||
|
#+ of script.
|
||||||
|
|
||||||
declare -a Slots # Array holding cumulative results of passes.
|
declare -a Slots # Array holding cumulative results of passes.
|
||||||
NUMSLOTS=21 # Number of slots at bottom of board.
|
NUMSLOTS=21 # Number of slots at bottom of board.
|
||||||
|
|
||||||
|
|
||||||
Initialize_Slots () { # Zero out all elements of array.
|
Initialize_Slots () { # Zero out all elements of the array.
|
||||||
for i in $( seq $NUMSLOTS )
|
for i in $( seq $NUMSLOTS )
|
||||||
do
|
do
|
||||||
Slots[$i]=0
|
Slots[$i]=0
|
||||||
|
@ -49,7 +51,7 @@ Show_Slots () {
|
||||||
echo -n " "
|
echo -n " "
|
||||||
for i in $( seq $NUMSLOTS ) # Pretty-print array elements.
|
for i in $( seq $NUMSLOTS ) # Pretty-print array elements.
|
||||||
do
|
do
|
||||||
printf "%3d" ${Slots[$i]} # Three spaces per result.
|
printf "%3d" ${Slots[$i]} # Allot three spaces per result.
|
||||||
done
|
done
|
||||||
|
|
||||||
echo # Row of slots:
|
echo # Row of slots:
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
# Theoretically, the more shots taken, the better the fit.
|
# Theoretically, the more shots taken, the better the fit.
|
||||||
# However, a shell script, as opposed to a compiled language
|
# However, a shell script, as opposed to a compiled language
|
||||||
#+ with floating-point math built in, requires a few compromises.
|
#+ with floating-point math built in, requires a few compromises.
|
||||||
# This tends to lower the accuracy of the simulation, of course.
|
# This tends to lower the accuracy of the simulation.
|
||||||
|
|
||||||
|
|
||||||
DIMENSION=10000 # Length of each side of the plot.
|
DIMENSION=10000 # Length of each side of the plot.
|
||||||
|
@ -42,6 +42,8 @@ MAXSHOTS=1000 # Fire this many shots.
|
||||||
# 10000 or more would be better, but would take too long.
|
# 10000 or more would be better, but would take too long.
|
||||||
PMULTIPLIER=4.0 # Scaling factor to approximate PI.
|
PMULTIPLIER=4.0 # Scaling factor to approximate PI.
|
||||||
|
|
||||||
|
M_PI=3.141592654 # Actual value of PI, for comparison purposes.
|
||||||
|
|
||||||
get_random ()
|
get_random ()
|
||||||
{
|
{
|
||||||
SEED=$(head -n 1 /dev/urandom | od -N 1 | awk '{ print $2 }')
|
SEED=$(head -n 1 /dev/urandom | od -N 1 | awk '{ print $2 }')
|
||||||
|
@ -61,7 +63,7 @@ EOF
|
||||||
)
|
)
|
||||||
# Setting "scale" to zero rounds down result to integer value,
|
# Setting "scale" to zero rounds down result to integer value,
|
||||||
#+ a necessary compromise in this script.
|
#+ a necessary compromise in this script.
|
||||||
# This diminshes the accuracy of the simulation, unfortunately.
|
# This diminshes the accuracy of the simulation.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,6 +74,7 @@ shots=0
|
||||||
splashes=0
|
splashes=0
|
||||||
thuds=0
|
thuds=0
|
||||||
Pi=0
|
Pi=0
|
||||||
|
error=0
|
||||||
|
|
||||||
while [ "$shots" -lt "$MAXSHOTS" ] # Main loop.
|
while [ "$shots" -lt "$MAXSHOTS" ] # Main loop.
|
||||||
do
|
do
|
||||||
|
@ -107,9 +110,11 @@ do
|
||||||
done
|
done
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "After $shots shots, PI looks like approximately $Pi."
|
echo "After $shots shots, PI looks like approximately $Pi"
|
||||||
# Tends to run a bit high . . .
|
# Tends to run a bit high . . .
|
||||||
# Probably due to round-off error and imperfect randomness of $RANDOM.
|
# Probably due to round-off error and imperfect randomness of $RANDOM.
|
||||||
|
error=$(echo "scale=9; $Pi - $M_PI" | bc)
|
||||||
|
echo "Deviation from mathematical value of PI = $error"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# }
|
# }
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# cw-solver.sh
|
||||||
|
|
||||||
|
# Crossword puzzle and anagramming word game solver.
|
||||||
|
# You know *some* of the letters in the word you're looking for,
|
||||||
|
#+ so you need a list of all valid words
|
||||||
|
#+ with the known letters in given positions.
|
||||||
|
# For example: w...i....n
|
||||||
|
# 1???5????10
|
||||||
|
# w in position 1, 3 unknowns, i in the 5th, 4 unknowns, n at the end.
|
||||||
|
# (See comments at end of script.)
|
||||||
|
|
||||||
|
|
||||||
|
E_NOPATT=71
|
||||||
|
DICT=/usr/share/dict/word.lst
|
||||||
|
# ^^^^^^^^ Looks for word list here.
|
||||||
|
# ASCII word list, one word per line.
|
||||||
|
# If you happen to need an appropriate list,
|
||||||
|
#+ download the author's "yawl" word list package.
|
||||||
|
# http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
|
||||||
|
# or
|
||||||
|
# http://personal.riverusers.com/~thegrendel/yawl-0.3.2.tar.gz
|
||||||
|
|
||||||
|
|
||||||
|
if [ -z "$1" ] # If no word pattern specified
|
||||||
|
then #+ as a command-line argument . . .
|
||||||
|
echo #+ . . . then . . .
|
||||||
|
echo "Usage:" #+ Usage message.
|
||||||
|
echo
|
||||||
|
echo ""$0" \"pattern,\""
|
||||||
|
echo "where \"pattern\" is in the form"
|
||||||
|
echo "xxx..x.x..."
|
||||||
|
echo
|
||||||
|
echo "The x's represent known letters,"
|
||||||
|
echo "and the periods are unknown letters (blanks)."
|
||||||
|
echo "Letters and periods can be in any position."
|
||||||
|
echo "For example, try: cw-solver.sh w...i....n"
|
||||||
|
echo
|
||||||
|
exit $E_NOPATT
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
# ===============================================
|
||||||
|
# This is where all the work gets done.
|
||||||
|
grep ^"$1"$ "$DICT" # Yes, only one line!
|
||||||
|
# | |
|
||||||
|
# ^ is start-of-word regex anchor.
|
||||||
|
# $ is end-of-word regex anchor.
|
||||||
|
|
||||||
|
# From _Stupid Grep Tricks_, vol. 1,
|
||||||
|
#+ a book the ABS Guide author may yet get around
|
||||||
|
#+ to writing one of these days . . .
|
||||||
|
# ===============================================
|
||||||
|
echo
|
||||||
|
|
||||||
|
|
||||||
|
exit $? # Script terminates here.
|
||||||
|
# If there are too many words generated,
|
||||||
|
#+ redirect the output to a file.
|
||||||
|
|
||||||
|
cw-solver w...i....n
|
||||||
|
|
||||||
|
twichildren
|
||||||
|
wellington
|
||||||
|
workingman
|
||||||
|
workingmen
|
|
@ -1,5 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Creating a swapfile.
|
# Creating a swap file.
|
||||||
|
|
||||||
|
# A swap file provides a temporary storage cache
|
||||||
|
#+ which helps speed up certain filesystem operations.
|
||||||
|
|
||||||
ROOT_UID=0 # Root has $UID 0.
|
ROOT_UID=0 # Root has $UID 0.
|
||||||
E_WRONG_USER=65 # Not root?
|
E_WRONG_USER=65 # Not root?
|
||||||
|
|
|
@ -10,23 +10,24 @@
|
||||||
# On a rectangular grid, let each "cell" be either "living" or "dead". #
|
# On a rectangular grid, let each "cell" be either "living" or "dead". #
|
||||||
# Designate a living cell with a dot, and a dead one with a blank space.#
|
# Designate a living cell with a dot, and a dead one with a blank space.#
|
||||||
# Begin with an arbitrarily drawn dot-and-blank grid, #
|
# Begin with an arbitrarily drawn dot-and-blank grid, #
|
||||||
#+ and let this be the starting generation, "generation 0". #
|
#+ and let this be the starting generation, "generation 0." #
|
||||||
# Determine each successive generation by the following rules: #
|
# Determine each successive generation by the following rules: #
|
||||||
# 1) Each cell has 8 neighbors, the adjoining cells #
|
# 1) Each cell has 8 neighbors, the adjoining cells #
|
||||||
#+ left, right, top, bottom, and the 4 diagonals. #
|
#+ left, right, top, bottom, and the 4 diagonals. #
|
||||||
|
# #
|
||||||
# 123 #
|
# 123 #
|
||||||
# 4*5 #
|
# 4*5 The * is the cell in question. #
|
||||||
# 678 #
|
# 678 #
|
||||||
# #
|
# #
|
||||||
# 2) A living cell with either 2 or 3 living neighbors remains alive. #
|
# 2) A living cell with either 2 or 3 living neighbors remains alive. #
|
||||||
# 3) A dead cell with 3 living neighbors becomes alive (a "birth"). #
|
|
||||||
SURVIVE=2 #
|
SURVIVE=2 #
|
||||||
|
# 3) A dead cell with 3 living neighbors becomes alive (a "birth"). #
|
||||||
BIRTH=3 #
|
BIRTH=3 #
|
||||||
# 4) All other cases result in a dead cell for the next generation. #
|
# 4) All other cases result in a dead cell for the next generation. #
|
||||||
# ##################################################################### #
|
# ##################################################################### #
|
||||||
|
|
||||||
|
|
||||||
startfile=gen0 # Read the starting generation from the file "gen0".
|
startfile=gen0 # Read the starting generation from the file "gen0" ...
|
||||||
# Default, if no other file specified when invoking script.
|
# Default, if no other file specified when invoking script.
|
||||||
#
|
#
|
||||||
if [ -n "$1" ] # Specify another "generation 0" file.
|
if [ -n "$1" ] # Specify another "generation 0" file.
|
||||||
|
@ -36,7 +37,7 @@ fi
|
||||||
|
|
||||||
############################################
|
############################################
|
||||||
# Abort script if "startfile" not specified
|
# Abort script if "startfile" not specified
|
||||||
#+ AND
|
#+ and
|
||||||
#+ "gen0" not present.
|
#+ "gen0" not present.
|
||||||
|
|
||||||
E_NOSTARTFILE=68
|
E_NOSTARTFILE=68
|
||||||
|
@ -58,7 +59,7 @@ DEAD1=_
|
||||||
#+ but a large grid will will cause very slow execution).
|
#+ but a large grid will will cause very slow execution).
|
||||||
ROWS=10
|
ROWS=10
|
||||||
COLS=10
|
COLS=10
|
||||||
# Change above two variables to match grid size, if necessary.
|
# Change above two variables to match grid size, as desired.
|
||||||
# ---------------------------------------------------------- #
|
# ---------------------------------------------------------- #
|
||||||
|
|
||||||
GENERATIONS=10 # How many generations to cycle through.
|
GENERATIONS=10 # How many generations to cycle through.
|
||||||
|
@ -81,7 +82,7 @@ generation=0 # Initialize generation count.
|
||||||
let "cells = $ROWS * $COLS"
|
let "cells = $ROWS * $COLS"
|
||||||
# How many cells.
|
# How many cells.
|
||||||
|
|
||||||
declare -a initial # Arrays containing "cells".
|
declare -a initial # Arrays containing "cells."
|
||||||
declare -a current
|
declare -a current
|
||||||
|
|
||||||
display ()
|
display ()
|
||||||
|
@ -229,8 +230,8 @@ GetCount () # Count live cells in passed cell's neighborhood.
|
||||||
IsValid $t_top $row
|
IsValid $t_top $row
|
||||||
if [ $? -eq "$TRUE" ]
|
if [ $? -eq "$TRUE" ]
|
||||||
then
|
then
|
||||||
if [ ${array[$t_top]} = "$ALIVE1" ]
|
if [ ${array[$t_top]} = "$ALIVE1" ] # Redundancy here.
|
||||||
then
|
then # Can be optimized?
|
||||||
let "count += 1"
|
let "count += 1"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -274,7 +275,7 @@ do
|
||||||
array[$i]=. #+ represent the cell as a period.
|
array[$i]=. #+ represent the cell as a period.
|
||||||
else
|
else
|
||||||
array[$i]="_" # Otherwise underscore
|
array[$i]="_" # Otherwise underscore
|
||||||
fi #+ (which will later be converted to space).
|
fi #+ (will later be converted to space).
|
||||||
let "i += 1"
|
let "i += 1"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@ -368,3 +369,7 @@ exit 0 # END
|
||||||
#+ for the script to run.
|
#+ for the script to run.
|
||||||
# This would make unnecessary any changes to variables
|
# This would make unnecessary any changes to variables
|
||||||
#+ in the script for an altered grid size.
|
#+ in the script for an altered grid size.
|
||||||
|
#
|
||||||
|
# Exercise: Optimize this script.
|
||||||
|
# It has some repetitive and redundant code,
|
||||||
|
#+ for example, lines 335-336.
|
||||||
|
|
|
@ -80,7 +80,7 @@
|
||||||
<row>
|
<row>
|
||||||
<entry><option>-e -f -t -x, etc.</option></entry>
|
<entry><option>-e -f -t -x, etc.</option></entry>
|
||||||
<entry><firstterm>unary</firstterm> comparison</entry>
|
<entry><firstterm>unary</firstterm> comparison</entry>
|
||||||
<entry><firstterm>files</firstterm></entry>
|
<entry>file-test</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><option>< -lt > -gt <= -le >= -ge</option></entry>
|
<entry><option>< -lt > -gt <= -le >= -ge</option></entry>
|
||||||
|
@ -90,10 +90,11 @@
|
||||||
<row>
|
<row>
|
||||||
<entry><option>-nt -ot -ef</option></entry>
|
<entry><option>-nt -ot -ef</option></entry>
|
||||||
<entry><firstterm>compound</firstterm> comparison</entry>
|
<entry><firstterm>compound</firstterm> comparison</entry>
|
||||||
<entry><firstterm>files</firstterm></entry>
|
<entry>file-test</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><option>== -eq != -ne</option></entry>
|
<entry><option>== -eq <link linkend="notequal">!=</link>
|
||||||
|
-ne</option></entry>
|
||||||
<entry>equality / inequality</entry>
|
<entry>equality / inequality</entry>
|
||||||
<entry>test operators, string and integer</entry>
|
<entry>test operators, string and integer</entry>
|
||||||
</row>
|
</row>
|
||||||
|
@ -152,7 +153,7 @@
|
||||||
<firstterm>test</firstterm>)</entry>
|
<firstterm>test</firstterm>)</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><option>*= /= %= += -= <<= >>= &= !=</option></entry>
|
<entry><option>*= /= %= += -= <<= >>= &=</option></entry>
|
||||||
<entry><link linkend="arithopscomb">combination
|
<entry><link linkend="arithopscomb">combination
|
||||||
assignment</link></entry>
|
assignment</link></entry>
|
||||||
<entry>times-equal, divide-equal, mod-equal, etc.</entry>
|
<entry>times-equal, divide-equal, mod-equal, etc.</entry>
|
||||||
|
|
|
@ -0,0 +1,194 @@
|
||||||
|
#!/bin/bash -i
|
||||||
|
# petals.sh
|
||||||
|
|
||||||
|
#########################################################################
|
||||||
|
# Petals Around the Rose #
|
||||||
|
# #
|
||||||
|
# Version 0.1 Created by Serghey Rodin #
|
||||||
|
# Version 0.2 Modded by ABS Guide Author #
|
||||||
|
# #
|
||||||
|
# License: GPL3 #
|
||||||
|
# Used in ABS Guide with permission. #
|
||||||
|
# ##################################################################### #
|
||||||
|
|
||||||
|
hits=0 # Correct guesses.
|
||||||
|
WIN=6 # Mastered the game.
|
||||||
|
ALMOST=5 # One short of mastery.
|
||||||
|
EXIT=exit # Give up early?
|
||||||
|
|
||||||
|
RANDOM=$$ # Seeds the random number generator from PID of script.
|
||||||
|
|
||||||
|
|
||||||
|
# Bones (ASCII graphics for dice)
|
||||||
|
bone1[1]="| |"
|
||||||
|
bone1[2]="| o |"
|
||||||
|
bone1[3]="| o |"
|
||||||
|
bone1[4]="| o o |"
|
||||||
|
bone1[5]="| o o |"
|
||||||
|
bone1[6]="| o o |"
|
||||||
|
bone2[1]="| o |"
|
||||||
|
bone2[2]="| |"
|
||||||
|
bone2[3]="| o |"
|
||||||
|
bone2[4]="| |"
|
||||||
|
bone2[5]="| o |"
|
||||||
|
bone2[6]="| o o |"
|
||||||
|
bone3[1]="| |"
|
||||||
|
bone3[2]="| o |"
|
||||||
|
bone3[3]="| o |"
|
||||||
|
bone3[4]="| o o |"
|
||||||
|
bone3[5]="| o o |"
|
||||||
|
bone3[6]="| o o |"
|
||||||
|
bone="+---------+"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Functions
|
||||||
|
|
||||||
|
instructions () {
|
||||||
|
|
||||||
|
clear
|
||||||
|
echo -n "Do you need instructions? (y/n) "; read ans
|
||||||
|
if [ "$ans" = "y" -o "$ans" = "Y" ]; then
|
||||||
|
clear
|
||||||
|
echo -e '\E[34;47m' # Blue type.
|
||||||
|
|
||||||
|
# "cat document"
|
||||||
|
cat <<INSTRUCTIONSZZZ
|
||||||
|
The name of the game is Petals Around the Rose,
|
||||||
|
and that name is significant.
|
||||||
|
Five dice will roll and you must guess the "answer" for each roll.
|
||||||
|
It will be zero or an even number.
|
||||||
|
After your guess, you will be told the answer for the roll, but . . .
|
||||||
|
that's ALL the information you will get.
|
||||||
|
|
||||||
|
Six consecutive correct guesses admits you to the
|
||||||
|
Fellowship of the Rose.
|
||||||
|
INSTRUCTIONSZZZ
|
||||||
|
|
||||||
|
echo -e "\033[0m" # Turn off blue.
|
||||||
|
else clear
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fortune ()
|
||||||
|
{
|
||||||
|
RANGE=7
|
||||||
|
FLOOR=0
|
||||||
|
number=0
|
||||||
|
while [ "$number" -le $FLOOR ]
|
||||||
|
do
|
||||||
|
number=$RANDOM
|
||||||
|
let "number %= $RANGE" # 1 - 6.
|
||||||
|
done
|
||||||
|
|
||||||
|
return $number
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
throw () { # Calculate each individual die.
|
||||||
|
fortune; B1=$?
|
||||||
|
fortune; B2=$?
|
||||||
|
fortune; B3=$?
|
||||||
|
fortune; B4=$?
|
||||||
|
fortune; B5=$?
|
||||||
|
|
||||||
|
calc () { # Function embedded within a function!
|
||||||
|
case "$1" in
|
||||||
|
3 ) rose=2;;
|
||||||
|
5 ) rose=4;;
|
||||||
|
* ) rose=0;;
|
||||||
|
esac # Simplified algorithm.
|
||||||
|
# Doesn't really get to the heart of the matter.
|
||||||
|
return $rose
|
||||||
|
}
|
||||||
|
|
||||||
|
answer=0
|
||||||
|
calc "$B1"; answer=$(expr $answer + $(echo $?))
|
||||||
|
calc "$B2"; answer=$(expr $answer + $(echo $?))
|
||||||
|
calc "$B3"; answer=$(expr $answer + $(echo $?))
|
||||||
|
calc "$B4"; answer=$(expr $answer + $(echo $?))
|
||||||
|
calc "$B5"; answer=$(expr $answer + $(echo $?))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
game ()
|
||||||
|
{ # Generate graphic display of dice throw.
|
||||||
|
throw
|
||||||
|
echo -e "\033[1m" # Bold.
|
||||||
|
echo -e "\n"
|
||||||
|
echo -e "$bone\t$bone\t$bone\t$bone\t$bone"
|
||||||
|
echo -e \
|
||||||
|
"${bone1[$B1]}\t${bone1[$B2]}\t${bone1[$B3]}\t${bone1[$B4]}\t${bone1[$B5]}"
|
||||||
|
echo -e \
|
||||||
|
"${bone2[$B1]}\t${bone2[$B2]}\t${bone2[$B3]}\t${bone2[$B4]}\t${bone2[$B5]}"
|
||||||
|
echo -e \
|
||||||
|
"${bone3[$B1]}\t${bone3[$B2]}\t${bone3[$B3]}\t${bone3[$B4]}\t${bone3[$B5]}"
|
||||||
|
echo -e "$bone\t$bone\t$bone\t$bone\t$bone"
|
||||||
|
echo -e "\n\n\t\t"
|
||||||
|
echo -e "\033[0m" # Turn off bold.
|
||||||
|
echo -n "There are how many petals around the rose? "
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================== #
|
||||||
|
|
||||||
|
instructions
|
||||||
|
|
||||||
|
while [ "$petal" != "$EXIT" ] # Main loop.
|
||||||
|
do
|
||||||
|
game
|
||||||
|
read petal
|
||||||
|
echo "$petal" | grep [0-9] >/dev/null # Filter response for digit.
|
||||||
|
# Otherwise just roll dice again.
|
||||||
|
if [ "$?" -eq 0 ] # If-loop #1.
|
||||||
|
then
|
||||||
|
if [ "$petal" == "$answer" ]; then # If-loop #2.
|
||||||
|
echo -e "\nCorrect. There are $petal petals around the rose.\n"
|
||||||
|
(( hits++ ))
|
||||||
|
|
||||||
|
if [ "$hits" -eq "$WIN" ]; then # If-loop #3.
|
||||||
|
echo -e '\E[31;47m' # Red type.
|
||||||
|
echo -e "\033[1m" # Bold.
|
||||||
|
echo "You have unraveled the mystery of the Rose Petals!"
|
||||||
|
echo "Welcome to the Fellowship of the Rose!!!"
|
||||||
|
echo "(You are herewith sworn to secrecy.)"; echo
|
||||||
|
echo -e "\033[0m" # Turn off red & bold.
|
||||||
|
break # Exit!
|
||||||
|
else echo "You have $hits correct so far."; echo
|
||||||
|
|
||||||
|
if [ "$hits" -eq "$ALMOST" ]; then
|
||||||
|
echo "Just one more gets you to the heart of the mystery!"; echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi # Close if-loop #3.
|
||||||
|
|
||||||
|
else
|
||||||
|
echo -e "\nWrong. There are $answer petals around the rose.\n"
|
||||||
|
hits=0 # Reset number of correct guesses.
|
||||||
|
fi # Close if-loop #2.
|
||||||
|
|
||||||
|
echo -n "Hit ENTER for the next roll, or type \"exit\" to end. "
|
||||||
|
read
|
||||||
|
if [ "$REPLY" = "$EXIT" ]; then exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi # Close if-loop #1.
|
||||||
|
|
||||||
|
clear
|
||||||
|
done # End of main (while) loop.
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
exit $?
|
||||||
|
|
||||||
|
# Resources:
|
||||||
|
# ---------
|
||||||
|
# 1) http://en.wikipedia.org/wiki/Petals_Around_the_Rose
|
||||||
|
# (Wikipedia entry.)
|
||||||
|
# 2) http://www.borrett.id.au/computing/petals-bg.htm
|
||||||
|
# (How Bill Gates coped with the Petals Around the Rose challenge.)
|
|
@ -0,0 +1,462 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# qky.sh
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# QUACKEY: a somewhat simplified version of Perquackey [TM]. #
|
||||||
|
# #
|
||||||
|
# Author: Mendel Cooper <thegrendel@theriver.com> #
|
||||||
|
# version 0.1.02 03 May, 2008 #
|
||||||
|
# License: GPL3 #
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
WLIST=/usr/share/dict/word.lst
|
||||||
|
# ^^^^^^^^ Word list file found here.
|
||||||
|
# ASCII word list, one word per line, UNIX format.
|
||||||
|
# A suggested list is the script author's "yawl" word list package.
|
||||||
|
# http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
|
||||||
|
# or
|
||||||
|
# http://personal.riverusers.com/~thegrendel/yawl-0.3.2.tar.gz
|
||||||
|
|
||||||
|
NONCONS=0 # Word not constructable from letter set.
|
||||||
|
CONS=1 # Constructable.
|
||||||
|
SUCCESS=0
|
||||||
|
NG=1
|
||||||
|
FAILURE=''
|
||||||
|
NULL=0 # Zero out value of letter (if found).
|
||||||
|
MINWLEN=3 # Minimum word length.
|
||||||
|
MAXCAT=5 # Maximum number of words in a given category.
|
||||||
|
PENALTY=200 # General-purpose penalty for unacceptable words.
|
||||||
|
total=
|
||||||
|
E_DUP=70 # Duplicate word error.
|
||||||
|
|
||||||
|
TIMEOUT=10 # Time for word input.
|
||||||
|
|
||||||
|
NVLET=10 # 10 letters for non-vulnerable.
|
||||||
|
VULET=13 # 13 letters for vulnerable (not yet implemented).
|
||||||
|
|
||||||
|
declare -a Words
|
||||||
|
declare -a Status
|
||||||
|
declare -a Score=( 0 0 0 0 0 0 0 0 0 0 0 )
|
||||||
|
|
||||||
|
|
||||||
|
letters=( a n s r t m l k p r b c i d s i d z e w u e t f
|
||||||
|
e y e r e f e g t g h h i t r s c i t i d i j a t a o l a
|
||||||
|
m n a n o v n w o s e l n o s p a q e e r a b r s a o d s
|
||||||
|
t g t i t l u e u v n e o x y m r k )
|
||||||
|
# Letter distribution table shamelessly borrowed from "Wordy" game,
|
||||||
|
#+ ca. 1992, written by a certain fine fellow named Mendel Cooper.
|
||||||
|
|
||||||
|
declare -a LS
|
||||||
|
|
||||||
|
numelements=${#letters[@]}
|
||||||
|
randseed="$1"
|
||||||
|
|
||||||
|
instructions ()
|
||||||
|
{
|
||||||
|
clear
|
||||||
|
echo "Welcome to QUACKEY, the anagramming word construction game."; echo
|
||||||
|
echo -n "Do you need instructions? (y/n) "; read ans
|
||||||
|
|
||||||
|
if [ "$ans" = "y" -o "$ans" = "Y" ]; then
|
||||||
|
clear
|
||||||
|
echo -e '\E[31;47m' # Red foreground. '\E[34;47m' for blue.
|
||||||
|
cat <<INSTRUCTION1
|
||||||
|
|
||||||
|
QUACKEY is a variant of Perquackey [TM].
|
||||||
|
The rules are the same, but the scoring is simplified
|
||||||
|
and plurals of previously played words are allowed.
|
||||||
|
"Vulnerable" play is not yet implemented,
|
||||||
|
but it is otherwise feature-complete.
|
||||||
|
|
||||||
|
As the game begins, the player gets 10 letters.
|
||||||
|
The object is to construct valid dictionary words
|
||||||
|
of at least 3-letter-length from the letterset.
|
||||||
|
Each word-length category
|
||||||
|
-- 3-letter, 4-letter, 5-letter, ... --
|
||||||
|
fills up with the fifth word entered,
|
||||||
|
and no further words in that category are accepted.
|
||||||
|
|
||||||
|
The penalty for too-short (two-letter), duplicate, unconstructable,
|
||||||
|
and invalid (not in dictionary) words is -200. The same penalty applies
|
||||||
|
to attempts to enter a word in a filled-up category.
|
||||||
|
|
||||||
|
INSTRUCTION1
|
||||||
|
|
||||||
|
echo -n "Hit ENTER for next page of instructions. "; read az1
|
||||||
|
|
||||||
|
cat <<INSTRUCTION2
|
||||||
|
|
||||||
|
The scoring mostly corresponds to classic Perquackey:
|
||||||
|
The first 3-letter word scores 60, plus 10 for each additional one.
|
||||||
|
The first 4-letter word scores 120, plus 20 for each additional one.
|
||||||
|
The first 5-letter word scores 200, plus 50 for each additional one.
|
||||||
|
The first 6-letter word scores 300, plus 100 for each additional one.
|
||||||
|
The first 7-letter word scores 500, plus 150 for each additional one.
|
||||||
|
The first 8-letter word scores 750, plus 250 for each additional one.
|
||||||
|
The first 9-letter word scores 1000, plus 500 for each additional one.
|
||||||
|
The first 10-letter word scores 2000, plus 2000 for each additional one.
|
||||||
|
|
||||||
|
Category completion bonuses are:
|
||||||
|
3-letter words 100
|
||||||
|
4-letter words 200
|
||||||
|
5-letter words 400
|
||||||
|
6-letter words 800
|
||||||
|
7-letter words 2000
|
||||||
|
8-letter words 10000
|
||||||
|
This is a simplification of the absurdly complicated Perquackey bonus
|
||||||
|
scoring system.
|
||||||
|
|
||||||
|
INSTRUCTION2
|
||||||
|
|
||||||
|
echo -n "Hit ENTER for final page of instructions. "; read az1
|
||||||
|
|
||||||
|
cat <<INSTRUCTION3
|
||||||
|
|
||||||
|
|
||||||
|
Hitting just ENTER for a word entry ends the game.
|
||||||
|
|
||||||
|
Individual word entry is timed to a maximum of 10 seconds.
|
||||||
|
*** Timing out on an entry ends the game. ***
|
||||||
|
Other than that, the game is untimed.
|
||||||
|
|
||||||
|
--------------------------------------------------
|
||||||
|
Game statistics are automatically saved to a file.
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
For competitive ("duplicate") play, a previous letterset
|
||||||
|
may be duplicated by repeating the script's random seed,
|
||||||
|
command-line parameter \$1.
|
||||||
|
For example, "qky 7633" specifies the letterset
|
||||||
|
c a d i f r h u s k ...
|
||||||
|
INSTRUCTION3
|
||||||
|
|
||||||
|
echo; echo -n "Hit ENTER to begin game. "; read az1
|
||||||
|
|
||||||
|
echo -e "\033[0m" # Turn off red.
|
||||||
|
else clear
|
||||||
|
fi
|
||||||
|
|
||||||
|
clear
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
seed_random ()
|
||||||
|
{ # Seed random number generator.
|
||||||
|
if [ -n "$randseed" ] # Can specify random seed.
|
||||||
|
then #+ for play in competitive mode.
|
||||||
|
# RANDOM="$randseed"
|
||||||
|
echo "RANDOM seed set to "$randseed""
|
||||||
|
else
|
||||||
|
randseed="$$" # Or get random seed from process ID.
|
||||||
|
echo "RANDOM seed not specified, set to Process ID of script ($$)."
|
||||||
|
fi
|
||||||
|
|
||||||
|
RANDOM="$randseed"
|
||||||
|
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
get_letset ()
|
||||||
|
{
|
||||||
|
element=0
|
||||||
|
echo -n "Letterset:"
|
||||||
|
|
||||||
|
for lset in $(seq $NVLET)
|
||||||
|
do # Pick random letters to fill out letterset.
|
||||||
|
LS[element]="${letters[$((RANDOM%numelements))]}"
|
||||||
|
((element++))
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "${LS[@]}"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
add_word ()
|
||||||
|
{
|
||||||
|
wrd="$1"
|
||||||
|
local idx=0
|
||||||
|
|
||||||
|
Status[0]=""
|
||||||
|
Status[3]=""
|
||||||
|
Status[4]=""
|
||||||
|
|
||||||
|
while [ "${Words[idx]}" != '' ]
|
||||||
|
do
|
||||||
|
if [ "${Words[idx]}" = "$wrd" ]
|
||||||
|
then
|
||||||
|
Status[3]="Duplicate-word-PENALTY"
|
||||||
|
let "Score[0]= 0 - $PENALTY"
|
||||||
|
let "Score[1]-=$PENALTY"
|
||||||
|
return $E_DUP
|
||||||
|
fi
|
||||||
|
|
||||||
|
((idx++))
|
||||||
|
done
|
||||||
|
|
||||||
|
Words[idx]="$wrd"
|
||||||
|
get_score
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
get_score()
|
||||||
|
{
|
||||||
|
local wlen=0
|
||||||
|
local score=0
|
||||||
|
local bonus=0
|
||||||
|
local first_word=0
|
||||||
|
local add_word=0
|
||||||
|
local numwords=0
|
||||||
|
|
||||||
|
wlen=${#wrd}
|
||||||
|
numwords=${Score[wlen]}
|
||||||
|
Score[2]=0
|
||||||
|
Status[4]="" # Initialize "bonus" to 0.
|
||||||
|
|
||||||
|
case "$wlen" in
|
||||||
|
3) first_word=60
|
||||||
|
add_word=10;;
|
||||||
|
4) first_word=120
|
||||||
|
add_word=20;;
|
||||||
|
5) first_word=200
|
||||||
|
add_word=50;;
|
||||||
|
6) first_word=300
|
||||||
|
add_word=100;;
|
||||||
|
7) first_word=500
|
||||||
|
add_word=150;;
|
||||||
|
8) first_word=750
|
||||||
|
add_word=250;;
|
||||||
|
9) first_word=1000
|
||||||
|
add_word=500;;
|
||||||
|
10) first_word=2000
|
||||||
|
add_word=2000;; # This category modified from original rules!
|
||||||
|
esac
|
||||||
|
|
||||||
|
((Score[wlen]++))
|
||||||
|
if [ ${Score[wlen]} -eq $MAXCAT ]
|
||||||
|
then # Category completion bonus scoring simplified!
|
||||||
|
case $wlen in
|
||||||
|
3 ) bonus=100;;
|
||||||
|
4 ) bonus=200;;
|
||||||
|
5 ) bonus=400;;
|
||||||
|
6 ) bonus=800;;
|
||||||
|
7 ) bonus=2000;;
|
||||||
|
8 ) bonus=10000;;
|
||||||
|
esac # Needn't worry about 9's and 10's.
|
||||||
|
Status[4]="Category-$wlen-completion***BONUS***"
|
||||||
|
Score[2]=$bonus
|
||||||
|
else
|
||||||
|
Status[4]="" # Erase it.
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
let "score = $first_word + $add_word * $numwords"
|
||||||
|
if [ "$numwords" -eq 0 ]
|
||||||
|
then
|
||||||
|
Score[0]=$score
|
||||||
|
else
|
||||||
|
Score[0]=$add_word
|
||||||
|
fi # All this to distinguish last-word score
|
||||||
|
#+ from total running score.
|
||||||
|
let "Score[1] += ${Score[0]}"
|
||||||
|
let "Score[1] += ${Score[2]}"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
get_word ()
|
||||||
|
{
|
||||||
|
local wrd=''
|
||||||
|
read -t $TIMEOUT wrd # Timed read.
|
||||||
|
echo $wrd
|
||||||
|
}
|
||||||
|
|
||||||
|
is_constructable ()
|
||||||
|
{ # This was the most complex and difficult-to-write function.
|
||||||
|
local -a local_LS=( "${LS[@]}" ) # Local copy of letter set.
|
||||||
|
local is_found=0
|
||||||
|
local idx=0
|
||||||
|
local pos
|
||||||
|
local strlen
|
||||||
|
local local_word=( "$1" )
|
||||||
|
strlen=${#local_word}
|
||||||
|
|
||||||
|
while [ "$idx" -lt "$strlen" ]
|
||||||
|
do
|
||||||
|
is_found=$(expr index "${local_LS[*]}" "${local_word:idx:1}")
|
||||||
|
if [ "$is_found" -eq "$NONCONS" ] # Not constructable!
|
||||||
|
then
|
||||||
|
echo "$FAILURE"; return
|
||||||
|
else
|
||||||
|
((pos = ($is_found - 1) / 2)) # Compensate for spaces betw. letters!
|
||||||
|
local_LS[pos]=$NULL # Zero out used letters.
|
||||||
|
((idx++)) # Bump index.
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "$SUCCESS"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
is_valid ()
|
||||||
|
{ # Surprisingly easy to check if word in dictionary ...
|
||||||
|
fgrep -qw "$1" "$WLIST" # ... thanks to 'grep' ...
|
||||||
|
echo $?
|
||||||
|
}
|
||||||
|
|
||||||
|
check_word ()
|
||||||
|
{
|
||||||
|
if [ -z "$1" ]
|
||||||
|
then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
Status[1]=""
|
||||||
|
Status[2]=""
|
||||||
|
Status[3]=""
|
||||||
|
Status[4]=""
|
||||||
|
|
||||||
|
iscons=$(is_constructable "$1")
|
||||||
|
if [ "$iscons" ]
|
||||||
|
then
|
||||||
|
Status[1]="constructable"
|
||||||
|
v=$(is_valid "$1")
|
||||||
|
if [ "$v" -eq "$SUCCESS" ]
|
||||||
|
then
|
||||||
|
Status[2]="valid"
|
||||||
|
strlen=${#1}
|
||||||
|
|
||||||
|
if [ ${Score[strlen]} -eq "$MAXCAT" ] # Category full!
|
||||||
|
then
|
||||||
|
Status[3]="Category-$strlen-overflow-PENALTY"
|
||||||
|
return $NG
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$strlen" in
|
||||||
|
1 | 2 )
|
||||||
|
Status[3]="Two-letter-word-PENALTY"
|
||||||
|
return $NG;;
|
||||||
|
* )
|
||||||
|
Status[3]=""
|
||||||
|
return $SUCCESS;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
Status[3]="Not-valid-PENALTY"
|
||||||
|
return $NG
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
Status[3]="Not-constructable-PENALTY"
|
||||||
|
return $NG
|
||||||
|
fi
|
||||||
|
|
||||||
|
### FIXME: Streamline the above code.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
display_words ()
|
||||||
|
{
|
||||||
|
local idx=0
|
||||||
|
local wlen0
|
||||||
|
|
||||||
|
clear
|
||||||
|
echo "Letterset: ${LS[@]}"
|
||||||
|
echo "Threes: Fours: Fives: Sixes: Sevens: Eights:"
|
||||||
|
echo "------------------------------------------------------------"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
while [ "${Words[idx]}" != '' ]
|
||||||
|
do
|
||||||
|
wlen0=${#Words[idx]}
|
||||||
|
case "$wlen0" in
|
||||||
|
3) ;;
|
||||||
|
4) echo -n " " ;;
|
||||||
|
5) echo -n " " ;;
|
||||||
|
6) echo -n " " ;;
|
||||||
|
7) echo -n " " ;;
|
||||||
|
8) echo -n " " ;;
|
||||||
|
esac
|
||||||
|
echo "${Words[idx]}"
|
||||||
|
((idx++))
|
||||||
|
done
|
||||||
|
|
||||||
|
### FIXME: The word display is pretty crude.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
play ()
|
||||||
|
{
|
||||||
|
word="Start game" # Dummy word, to start ...
|
||||||
|
|
||||||
|
while [ "$word" ] # If player just hits return (blank word),
|
||||||
|
do #+ then game ends.
|
||||||
|
echo "$word: "${Status[@]}""
|
||||||
|
echo -n "Last score: [${Score[0]}] TOTAL score: [${Score[1]}]: Next word: "
|
||||||
|
total=${Score[1]}
|
||||||
|
word=$(get_word)
|
||||||
|
check_word "$word"
|
||||||
|
|
||||||
|
if [ "$?" -eq "$SUCCESS" ]
|
||||||
|
then
|
||||||
|
add_word "$word"
|
||||||
|
else
|
||||||
|
let "Score[0]= 0 - $PENALTY"
|
||||||
|
let "Score[1]-=$PENALTY"
|
||||||
|
fi
|
||||||
|
|
||||||
|
display_words
|
||||||
|
done # Exit game.
|
||||||
|
|
||||||
|
### FIXME: The play () function calls too many other functions.
|
||||||
|
### This is perilously close to "spaghetti code" ...
|
||||||
|
}
|
||||||
|
|
||||||
|
end_of_game ()
|
||||||
|
{ # Save and display stats.
|
||||||
|
|
||||||
|
#######################Autosave##########################
|
||||||
|
savefile=qky.save.$$
|
||||||
|
# ^^ PID of script
|
||||||
|
echo `date` >> $savefile
|
||||||
|
echo "Letterset # $randseed (random seed) ">> $savefile
|
||||||
|
echo -n "Letterset: " >> $savefile
|
||||||
|
echo "${LS[@]}" >> $savefile
|
||||||
|
echo "---------" >> $savefile
|
||||||
|
echo "Words constructed:" >> $savefile
|
||||||
|
echo "${Words[@]}" >> $savefile
|
||||||
|
echo >> $savefile
|
||||||
|
echo "Score: $total" >> $savefile
|
||||||
|
|
||||||
|
echo "Statistics for this round saved in \""$savefile"\""
|
||||||
|
#########################################################
|
||||||
|
|
||||||
|
echo "Score for this round: $total"
|
||||||
|
echo "Words: ${Words[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------#
|
||||||
|
instructions
|
||||||
|
seed_random
|
||||||
|
get_letset
|
||||||
|
play
|
||||||
|
end_of_game
|
||||||
|
# ---------#
|
||||||
|
|
||||||
|
exit $?
|
||||||
|
|
||||||
|
# TODO:
|
||||||
|
#
|
||||||
|
# 1) Clean up code!
|
||||||
|
# 2) Prettify the display_words () function (maybe with widgets?).
|
||||||
|
# 3) Improve the time-out ... maybe change to untimed entry,
|
||||||
|
#+ but with a time limit for the overall round.
|
||||||
|
# 4) An on-screen countdown timer would be nice.
|
||||||
|
# 5) Implement "vulnerable" mode of play.
|
||||||
|
# 6) Improve save-to-file capability (and maybe make it optional).
|
||||||
|
# 7) Fix bugs!!!
|
|
@ -26,3 +26,6 @@ adr=${1:-`whoami`} # Default to current user, if not specified.
|
||||||
echo "At `date`, script \"`basename $0`\" mailed to "$adr"."
|
echo "At `date`, script \"`basename $0`\" mailed to "$adr"."
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|
||||||
|
# Note that the "mailx" command (in "send" mode) may be substituted
|
||||||
|
#+ for "mail" ... but with somewhat different options.
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
|
|
||||||
# TMOUT=3 Also works, as of newer versions of Bash.
|
# TMOUT=3 Also works, as of newer versions of Bash.
|
||||||
|
|
||||||
|
TIMER_INTERRUPT=14
|
||||||
TIMELIMIT=3 # Three seconds in this instance. May be set to different value.
|
TIMELIMIT=3 # Three seconds in this instance.
|
||||||
|
# May be set to different value.
|
||||||
|
|
||||||
PrintAnswer()
|
PrintAnswer()
|
||||||
{
|
{
|
||||||
|
@ -13,28 +14,30 @@ PrintAnswer()
|
||||||
echo $answer
|
echo $answer
|
||||||
else # Don't want to mix up the two instances.
|
else # Don't want to mix up the two instances.
|
||||||
echo "Your favorite veggie is $answer"
|
echo "Your favorite veggie is $answer"
|
||||||
kill $! # Kills no longer needed TimerOn function running in background.
|
kill $! # Kills no-longer-needed TimerOn function
|
||||||
# $! is PID of last job running in background.
|
#+ running in background.
|
||||||
|
# $! is PID of last job running in background.
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TimerOn()
|
TimerOn()
|
||||||
{
|
{
|
||||||
sleep $TIMELIMIT && kill -s 14 $$ &
|
sleep $TIMELIMIT && kill -s 14 $$ &
|
||||||
# Waits 3 seconds, then sends sigalarm to script.
|
# Waits 3 seconds, then sends sigalarm to script.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Int14Vector()
|
Int14Vector()
|
||||||
{
|
{
|
||||||
answer="TIMEOUT"
|
answer="TIMEOUT"
|
||||||
PrintAnswer
|
PrintAnswer
|
||||||
exit 14
|
exit $TIMER_INTERRUPT
|
||||||
}
|
}
|
||||||
|
|
||||||
trap Int14Vector 14 # Timer interrupt (14) subverted for our purposes.
|
trap Int14Vector $TIMER_INTERRUPT
|
||||||
|
# Timer interrupt (14) subverted for our purposes.
|
||||||
|
|
||||||
echo "What is your favorite vegetable "
|
echo "What is your favorite vegetable "
|
||||||
TimerOn
|
TimerOn
|
||||||
|
@ -42,12 +45,14 @@ read answer
|
||||||
PrintAnswer
|
PrintAnswer
|
||||||
|
|
||||||
|
|
||||||
# Admittedly, this is a kludgy implementation of timed input,
|
# Admittedly, this is a kludgy implementation of timed input.
|
||||||
#+ however the "-t" option to "read" simplifies this task.
|
# However, the "-t" option to "read" simplifies this task.
|
||||||
# See "t-out.sh", below.
|
# See the "t-out.sh" script.
|
||||||
|
# However, what about timing not just single user input,
|
||||||
|
#+ but an entire script?
|
||||||
|
|
||||||
# If you need something really elegant...
|
# If you need something really elegant ...
|
||||||
#+ consider writing the application in C or C++,
|
#+ consider writing the application in C or C++,
|
||||||
#+ using appropriate library functions, such as 'alarm' and 'setitimer'.
|
#+ using appropriate library functions, such as 'alarm' and 'setitimer.'
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|
Loading…
Reference in New Issue