main
that enables us to play
Conway's Soldiers interactively or check a solution.
First, create a class called Conway
in the cs427_527
namespace. The
header file must be named "conway.h"
and the implementation file
must be named "conway.cpp"
; those must be the only two files
necessary to use the Conway
class and
those files must compile cleanly with the -Wall -pedantic -std=c++11
compiler options.
The Conway
class must have the following members that behave
as follows.
Conway()
that creates the initial state
of a 4-piece puzzle
with a 5-row, 6-column board with 3 pieces in columns 1 through 3
of the middle row and another piece below the rightmost piece.
Conway(istream&)
that creates a
puzzle whose initial state is read from the given stream. The
stream will contain two integers separated by whitespace
and possibly with leading and trailing whitespace on the first line
for the width and height of the board (in that order).
Following the first line will be one line per row containing a string
of 'X'
and '.'
characters where the
'X'
s indicate the initial positions of the pieces.
Each such string will be as long as the board is wide.
Conway(const Conway&)
that creates
an independent copy of the given puzzle state (changes to the
new copy shouldn't affect the original).
Conway(Conway&&)
that
copies the given puzzle state's representation and leaves that
puzzle in a valid (destructable) state. The move constructor
should execute in constant time – the number of steps
required to complete it should not depend on the size of the board
or the number of pieces.
Conway& operator=(const Conway&)
that makes the puzzle on the left of the assignment operator
an independent copy of the puzzle on the right and returns a reference.
to the puzzle on the left.
Conway& operator=(Conway&&)
that copies state of the puzzle on the right of the assignment operator
into the puzzle on the left, leaving the puzzle on the right in
a valid (destructable) state, and returns a reference
to the puzzle on the left. The move assigment should be performed
in $O(\sqrt(n))$ time for a square board with n total spaces.
bool isLegalMove(int fromR, int fromC, int toR, int toC) const
which takes integers representing the row and column of the position
on the board to move from and to move to and determines whether such
a move is legal according to the rules of the puzzle. If either
of the positions is not on the board then the move is illegal.
void makeMove(int fromR, int fromC, int toR, int toC)
which takes a legal move represented by integers giving
the row and column of the position
on the board to move from and to move to and modifies the current
object to reflect the result of that move.
int totalMoves() const
which counts the
number of legal moves performed since the initial state of the
original object (so the count is copied when objects are
copied, moved, or assigned).
bool isSolved() const
which determines if
the current object is in its solved configuration (some piece in the
top row).
In addition, there must be an operator
ostream& operator<<(ostream&, const Conway&)
that outputs the given board to the given stream in the format
read by the version of the constructor that reads from an input stream
(without the first line giving the size of the board).
You may add other members as necessary.
You must use dynamically allocated array for the board -- no STL containers
or smart pointers. If any of the preconditions for functions
and methods are violated then
your code must behave gracefully -- it may not crash or go into an infinite
loop (throwing exceptions is graceful only when the exceptions are caught
in a catch
block that then exits the program gracefully).
Second, create a program with an executable named Conway
that allows users to
play interactively or check a solution as determined by the
command-line arguments.
To play interactvely, the first command-line
argument will be -i
.
The first command-line argument (or second, if -i
is given)
may be -f
, in which case the next argument will be
the name of an input file
whose contents are in the format required by the appropriate
constructor.
If the -f
argument is not present then the
game should start with the four-piece puzzle created by the zero-argument
constructor.
In interactive mode, the program should
read from standard input integers representing the move to make.
There will be four integers per line of input, separated by whitespace and
possibly with leading and trailing whitespace. The four integers
give the row and column of the position to move a piece from and
the position to move it to. If the move is not
legal then the message illegal move
should be printed to
standard output.
The resulting state of the puzzle should be printed to standard output
at the beginning of the program and after each legal move in the form
output by the <<
operator.
The program should continue to read input
until the puzzle is solved or the end of input (the user
gives up). If a move leaves the puzzle in the
solved configuration then then the total number of legal moves made
should be printed as the last line of
standard output after the
solved configuration displayed as the result of the move.
The format should be n moves
where n
is replaced with the number of moves.
In non-interactive mode, the command-line arguments following
the -f
argument and filename (if present)
will be zero or more groups of four integers giving a sequence of
moves to make. The program should print a single
message to standard output, where the message is
Conway: illegal move r1 c1 r2 c2 in position m for
followed on a new line by the puzzle's state before that
attempted move in the format given by the <<
operator, where on m
on the first line is the position
within the sequence of moves of the first illegal move
(the first move is position 1 and each group
of four integers counts as one move), and
r1
, c1
, r2
, c2
is the move that could not be made;
SOLVED
if the last move in the sequence solves the puzzle (or there are no moves in the sequence and
the setup given in the file specified with the
-f
option is the solved configuration); or,
<<
operator otherwise.
In both modes, there must not be anything written to standard output beyond what is specified above. And unless otherwise specified, your program should behave gracefully if any input, whether in interactive mode or on the command-line, is not as specified.
In both modes, a move is given as input by listing the row to move from, the column to move from, the row to move to, and the column to move to in that order. Each row and column index will be a sequence of decimal digits with no leading sign. Rows and columns are indexed starting with 0 for the top row and 0 for the left column.
We reserve the right to deduct points from submissions for violations of the following guidelines.
#include
d regardless of what other files have
been #include
d -- if a declaration is required by
your header files, then #include
the appropriate
header file in your header file (or write a forward declaration in
your header) rather than relying on your #include
rs
to have already #include
d those header files before
they #include
yours.
cin
and cout
with the I/O operators <<
and >>
rather than printf
and scanf
).
const
should be declared as const
.
-Wall
and -pedantic
options.
Conway
program in various ways.
[jrg94@peacock Conway]$ ./Conway -i ...... ...... .XXX.. ...X.. ...... 3 3 1 3 ...... ...X.. .XX... ...... ...... 1 3 0 3 illegal move 2 1 2 3 ...... ...X.. ...X.. ...... ...... [jrg94@peacock Conway]$ ./Conway -i -f conway_2.in ... .X. .X. 2 1 0 1 .X. ... ... 1 moves [jrg94@peacock Conway]$ ./Conway 3 3 1 3 2 1 2 3 2 3 0 3 SOLVED [jrg94@peacock Conway]$ ./Conway 3 3 1 3 1 3 0 3 2 1 2 3 2 3 2 1 Conway: illegal move 1 3 0 3 in position 2 for ...... ...X.. .XX... ...... ...... [jrg94@peacock Conway]$ ./Conway -f conway_21.in 5 4 3 4 5 2 5 4 ......... ......... ......... ....X.... ..XX.XX.. ....XXX.. ..XXXXX.. ..XXXXX.. ....X....
Where conway_2.in
contains
3 3 ... .X. .X.and
conway_21.in
contains
9 9 ......... ......... ......... ......... ..XXXXX.. ..XXXXX.. ..XXXXX.. ..XXXXX.. ....X....