Snake Watch
This small exercise in ascii graphics reads a series of values from a
single line of input and produces a shape that might be called a snake.
(Or possibly something not snake-like at all, depending on the input.)
The shape
is made by printing a series of lines, each containing a
specified character repeated a specified number of times placed
at a specified offset from the left side. After each
line is printed, the offset, length, and possibly the character change.
The input specifies all the sizes and changes. As noted, it is a single
line containing the following values, in order, separated by spaces.
- An integer giving the initial offset from the left. (How many spaces
to print at the front of the first line.)
- The integer width of the group of the specified character on the
first line.
- A series of one or more groups of four values as follows:
- A positive
integer count of the number of lines to generate for this group.
- An integer change in the offset to be made after each line is
printed. This is a signed value, so may be positive, zero or
negative.
- An integer change in the group width to be made after each line is
printed. This is also a signed value.
- A single non-blank character to print repeatedly to form
the group.
Since that explanation was so straightforward and crystal
clear, I'm sure this following example is completely unnecessary:
[bennet@localhost shaper]$ ./shaper
10 20 12 1 1 \ 9 -1 -2 /
\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
////////////////////////////////
//////////////////////////////
////////////////////////////
//////////////////////////
////////////////////////
//////////////////////
////////////////////
//////////////////
////////////////
The first line is input and the rest is output. The initial line consists
of 20 characters printed 10 away from the left, as specified by the first
two input values. The first group of four then prints 12 lines, each
containing the \ character. The first of these lines has 20 \ characters
starting 10 spaces from the left, as directed by the initial counts.
Each successive line from the first group is indented one position further
right, and the group of characters is one longer, as directed by the increment
values in that group. The second group then generates 9 lines of /, starting
at the incremented position and size from group one. Each line is
then indented one space less, and is two characters shorter than the one
before, as given in the input.
A further wrinkle is that you must only print within a 79-character
window on the console line. The rules above can easily produce a
negative left indent. In that case, you should start your run at the
left edge (don't print leading spaces), and shorten the length of
the group to account for the characters which have
fallen off the left.
Likewise, if printing extends past 79 characters, crop (don't print) the
extra ones on the right. Suppress printing characters when out of
range, but retain the true value of the left indent and size as though
the terminal were infinitely wide. A later line might bring the
printing back into range. Likewise, the width may become negative.
In that case, print nothing, but maintain the (theoretical) width in
case it becomes positive again at a later row.
[bennet@localhost shaper]$ ./shaper
30 30 9 -4 -2 = 10 5 4 | 20 -2 -3 # 6 1 4 @
==============================
============================
==========================
========================
======================
====================
==================
================
============
||||||
|||||||||||||||
||||||||||||||||||||
||||||||||||||||||||||||
||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||||||||
###################################
#####################################
#######################################
#########################################
########################################
#####################################
##################################
###############################
############################
#########################
######################
###################
################
#############
##########
#######
####
#
@@@@
@@@@@@@@
@@@@@@@@@@@@
The above shows the shape falling off the left, then moving over
and falling off the right. Near the bottom, the width becomes negative
for a while, until the last group widens it back to positive. This
creates some blank lines. You can also get blank lines if the shape
moves completely off one side or the other, but you should continue keeping
track in case it moves back into view.
The input for this beast is a bit tricky, so I've given you a
starting code
that shows a good way to read it. It uses a trick similar to one you
may have seen with Java Scanner: It first reads the line as a string,
then uses the string to create a new stream for reading the contents
as numbers. They are actually two different classes in C++, but support
the same I/O operations: the familiar >> and <<.
When your program works, is well-commented and properly indented,
submit over the web
here.