There was a very popular pencil and paper game school-aged
children played to hone their spelling skills, but it seems to have fallen
into disfavor. A number of alternatives have cropped up, which are basically
the same rules but different graphics. Seaman is one of them.
This is a two-player game: one person chooses a word and draws out dashes for each letter of that word (so the other player knows how long it is, but not the word itself. This second person tries to guess the word, one letter at a time. The first player fills in the correct letters, and adds a body part to a stick figure for each incorrect guess. When the stick figure is fully drawn, the first player wins; otherwise if the word is fully spelled, the second player wins.
The program you will write today is the scorekeeper for two human players. The first player enters a word, then the second player begins to type in single letters under the computer's supervison. At first the computer will merely keep a numerical score, but after that is working, the program can also draw the stick figure.
By this time, you should have already worked your way through PBJ, Calculator, Guessing Game, and RPS. You should already be familiar with the process of defining your computer program in English, then converting every part of that description into one of the Five Concepts, after which it should run in the English Computer. If you missed or skipped over these informational sessions and you find the next step difficult, you might go back and review one or more of these preparational sessions:
1. You Already Know HowThree times you watched me go from a vague idea to runnable code, and once you did it yourself, four different programs in all.
2. Conditionals & Input
3. Iteration & Variables
4. Calculator
5. Guessing Game
6. Rock Paper Scissors
Now you get to do another one on your own. Click this button to open our "Integrated Development Environment" in a new window, which you can position to one side or above or below the instructions in this page:
Button to open IDE
If you don't know how to begin, Watch this video to
see if it helps:
Seaman Video Introduction (5 minutes) Transcript below
If you are doing fine, but don't know how to extract
a single character from a whole word, Watch this video (and/or read the
transcript):
Get Character from English Word (3 minutes) Transcript belowIf you have the setup working, but are unsure how to do the Seaman scoring, Watch this video to see how to extract and compare individual letters (or read the transcript):
Seaman Scoring (3 minutes) Transcript below
After you have a simple numerical scoring working
for Seaman, Watch this video for an introduction to ASCII
graphics (or read the transcript):
ASCII Graphics (3 minutes) Transcript belowYou can make your implementation of ASCII graphics into a separate part of your program by making it into a Subroutine, which you can do several different versions of of the graphics (or none at all) as differently names subroutines, which a minor tweak to the calling line -- or even a conditional -- will select the one you want. This next video introduces the idea of Subroutines in this context, and joins it with the other Five Concepts as an essential element of programming:
Subroutines (5 minutes) Transcript
If you have an English description of your game, but
you do not know how to turn it into lines of "Five Concepts" items,
Raise
your hand in Zoom to get a Mentor to look at your description and suggest
a way forward.
If each line of the English description of your game already begins with one of the keywords in the Reference section from the English IDE, but your program misbehaves when you try to run it, Watch this video to see if it helps:
Debugging Video (0 minutes) (Transcript) [This video and transcript are not ready yet]If you didn't see anything in the video to help your situation, Raise your hand in Zoom to get a Mentor to look at your program and suggest a way forward.
When your game runs, Raise your hand in Zoom to continue.
If you are like me and prefer to read at your own pace instead of whatever pace set in some video, You can read the transcripts here.
1a. Word Input (1st player) &I suggest you read through all four segment descriptions below before you start to code, because later design decisions affect earlier parts of the code. Software design is often like that. In other sciences it is called "Irreducible Complexity" = the idea that the whole system is non-functional if any single critical component is left out or non-functional. For unit testing (testing individual components in isolation, which is a good idea) you can stub in the missing components, but of course the whole system does not work without them.
1b. Presentation (to 2nd player)2a. Letter Input (2nd player)
2b. Scoring (counting, by computer)
It is possible to input the first player's word in a single Input command, and then count the letters in it, but you already know how to input the letters one at a time and then concatenate them into a single word while counting the number of letters:
Let theWord = ""
Let guessWd = ""
Let nLets = 0
Repeat
Input letter 1
If letter < "A" then Exit
Let theWord = theWord # letter
Add 1 to nLets
Next
Repeat 33 {to clear screen}
Print " "
Next
Repeat nLetsor else include that one line inside the Input loop (above). Then you print that line before and after each time the second player guesses a letter. Of course you only print it once inside the guess loop, but if you print it after the user has guessed, then you need to print it also before the loop starts. If you print it inside the loop, but before the second player guesses, then you must print the final result after the loop is done, or else place your loop exit (either too many wrong guesses, or else the word is correctly guessed, see Scoring below) in the middle, after printing the word but before you accept another input (see Letter Input below).
Let guessWd = guessWd # "_"
Next
Print guessWd
The iteration ends when either the whole word has been guessed, or else the stick figure has been fully drawn (or the count reaches 6 or whatever number of body parts there are).
Replacing the corresponding dash in guessWd is probably easiest to understand if you simply reconstruct it in a new variable (here: nuly), then copy it back:
Let nuly = ""Knowing when the whole word has been guessed is probably simplest if you keep a separate count of the correctly guessed letters (perhaps counting down from the original word size nLets, or else counting up until the number of correct letter substitutions matches the total). Note that this count must survive the inner letter-check iteration, that is, you need a separate counter variable for the total, different from the seen counter inside the letter-check loop.
Let offs = 0
Let seen = 0
Repeat nLets
Character looky = theWord,offs {get next letter from original word}
Character prio = guessWd,offs {get corresponding letter as guessed}
Add 1 to offs
if looky=letter then Add 1 to seen {replace letter in guessWd}
Otherwise Let looky = prio {preserve previous guess or dash}
Let nuly = nuly # looky
Next
Let guessWd = nuly {this is now updated guess}
If seen>0 then {score match}
If seen=0 then {score no-match}
If you still have trouble, Raise your hand in Zoom to get a Mentor to look at your program and suggest a way forward.
If you look at the Quick Reference panel of the English IDE page, in the lower right corner is the Character command linked to its definition in the Kitchen/English Reference page. You probably should become comfortable with reading command definitions like this one, because it is the definitive way for programmers to understand the tools they work with. For our purposes today, we want to write something like this:
Character letter = theWord,offswhere theWord is the word you want a letter from, and offs is the zero-based offset (= the number of letters to the left to skip over) in that word.
To replace a letter in a particular position in the word you can use the Substring command to extract the left and right context, then put the three together:
Substring left = theWord,0,offsLess complicated for Seaman, where you always walk through the whole word anyway, is to build a replacement copy as you go:
Substring right = theWord,offs+1,nLets {or any large number}
Let theWord = left # letter # right
Let nuly = ""
Let offs = 0
Repeat nLets
Character letter = theWord,offs
Add 1 to offs
{maybe change it, then put it back..}
Let nuly = nuly # letter
Next
Let theWord = nuly
The drawing depends on a monospaced font, which is common in computer output, partly for historical reasons, but probably also because ASCII graphics and space-tabbed tables are so common and depend only on the equal spacing of the characters. ASCII (pronounced "ASS-key") was the original American Standard Code for Information Interchange, which became included as the first 128 characters in the ISO standard that replaced it. Here is our stick figure fully drawn:
_
( )
_|_
/ | \
/ | \
|
/ \
/ \
_/ \_
There is an obvious partition of this figure into six body parts
-- head, spine, two arms, and two legs -- which six wrong letter guesses
will fully draw. You could, if you wanted more latitude, separate off the
shoulders and two feet, and perhaps a hat. The point is that this character
can be entirely drawn with special characters from your keyboard, spaced
out by the spacebar.
We can similarly draw a sailboat for him to stand on (hence the name "Seaman" which is also a pun on "see, [a] man"):
/| _
/ | ( )
/ | _|_
/ | / | \
/ | / | \
/ | |
/ | / \
/ | / \
/________| _/ \_
______________________
\ /
The characters you use for this are the spacebar, the forward slant
(next to the shift key on most QWERTY keyboards) the
backward slant and vertical bar (on the same key, next to the backspace)
the left and right parentheses (shift-9 and shift-0) and the underscore
(shift-hyphen, usually between the zero and the equals/plus keys). For
drawing halftone (gray-scale) images you can use the period or back-accent
to fill a light gray, and "#" (shift-3) or "@" (shift-2) or capital-M for
near-black, with other keys to supply mid-tone ranges between.
Basically you write the horizontal lines of the image into character string constants in your program, which you print out as needed:
Print " /| _"
Print " / | ( )"
Print " / | _|_"
Print " / | / | \"
Print " / | / | \"
Print " / | |"
Print " / | / \"
Print " / | / \"
Print " /________| _/ \_"
Print " ______________________"
Print " \ /"
The body parts are not drawn until after the requisite number of
guess errors; you can use conditionals to print those lines either with
the body parts or without -- in some cases (like the arms) there are four
versions of the line: one with no body, one with only the spine, and the
other two with one or two arms -- or else you can construct variable strings
conditionally, then always print the same strings (as modified by the addition
of body parts).
We do not have arrays in the Kitchen English programming language, but when you get to Java you can put all possible lines into a large constant array, then print them off by line number. You can still do something like that in the English computer if you use a subroutine -- see the video on Subroutines, or read the transcript -- with a sequence of conditional assignments, like this
"IxTxt"and then call it be presetting the parameter variable (here: ix) then printing the subroutine result, or else compositing several results into one line:
let txt = ""
if ix=1 let txt = " /|"
if ix=2 let txt = " / |"
...
if ix=4+5+8 let txt = " ( )"
...
Done
let ix = row
let line = txt
let txt = ""
if nerrs>0 if row<10 repeat 1
let ix = row*4+nerrs+8
IxTxt
let line = line # txt
next
Print line
Again when we get to Java, you can put the reference indexes to
these lines into a second array variable [or additional indexed lines in
your subroutine], so that you don't waste a lot of table space on duplicated
strings. It's messy in English (it's messy in Java too), but it looks so
cool to show off to your programmer friends -- non-programmers simply won't
understand why it's cool, sort of like people who see nothing funny about
the T-shirt that reads:
There are 10 kinds of people in the world,The first indexed fetch is a line of equally spaced index numbers, so you can use a Substring command to pick off 2-digit index numbers to go fetch the actual strings. If it feels like it's too hard, don't worry, you'll get another shot at it after we get to Java.
Those who understand binary,
and those who don't.
I have not given you much sample code here because I think you can write
it all yourself. If you get stuck, ask a mentor for help, that's what they
are here for.
[2021 August 31a]