CS 215 - Fundamentals of Programming II
Spring 2008 - Project 4

40 points


Out: February 20, 2008
Due: March 17, 2008 (2nd Monday after spring break)


Reminder: Programming Projects (as opposed to Homework problems) are to be your own work. See syllabus for definitions of acceptable assistance from others.


The Game of Dots

Dots is a simple game usually played with pencil and paper. The playing field is a two-dimensional array of dots and the only valid move is to connect two adjacent dots horizontally or vertically. (No diagonal moves are allowed.) Players take turns connecting dots, except if a player connects two dots that complete a box (i.e., the top, bottom, left, and right sides of the box have been drawn), then the player fills in the box with her initial and gets a free turn. When all boxes have been filled in, the player who has claimed the most boxes wins. (Ties can be avoided by making sure that the number of possible boxes is odd).


In the following example, the first row shows the first four moves of a 3x3 dots game. (The size of the game is number of boxes.) The players are A and B, and they alternate turns. The second row picks up the same game after several more moves. The first board in the row is before B's turn. B makes a move, yielding the second board, and A completes the box, yielding the third board. A now moves again, completing another box (fourth board), and must move again (fifth board). It is now B's turn, and B will be able to complete 1 box, but must move again, and any additional move will give player A three more boxes. The final score will be A-5, B-4.




To write a computer program for playing Dots, instead of keeping track of a grid of dots, we need to keep track of a grid of boxes. Each grid location has is a box that has 4 sides (called top, bottom, left, and right), initially undrawn, and a label, initially blank. Adjacent boxes share a common side. For example, if two boxes are side by side, the right side of the left box is the same as the left side of the right box. Play is conducted as follows:


Consider the following specification for a BoxGrid class that represents the Dots playing field. Each grid location contains a Box object, that contains information regarding the state of the box. (The Box class will be provided and is explained below.) Grid locations are given as coordinates (row, col) where (0,0) is the upper left-hand corner of the grid.


Specification for BoxGrid Class


Data Attributes

For this project, a BoxGrid is modeled using a dynamically-allocated two-dimensional array of Boxes to allow grids of differing sizes to be created. In addition, to facilitate reporting the score of the game, the BoxGrid class keeps track of the player's names, represented by a single character. Thus the data attributes include at least those shown below. You may add additional appropriate attributes.


Objects

Type

Name

number of rows

int

numRows

number of columns

int

numColumns

first player's name

char

player1

second player's name

char

player2

pointer to grid

Box**

grid


Operations


Objects

Default

Type

Kind

Movement

Name

number of rows

3

int

variable

received

initialRows

number of columns

3

int

variable

received

initialCols

first player's name

'A'

char

variable

received

initialPlayer1

second player's name

'B'

char

variable

received

initialPlayer2



Objects

Type

Kind

Movement

Name

original BoxGrid object

BoxGrid

variable

received

original


Objects

Type

Kind

Movement

Name

original BoxGrid object

BoxGrid

variable

received

original

this BoxGrid object

BoxGrid

variable

returned

*this


Objects

Type

Kind

Movement

Name

number of rows

int

variable

returned

numRows


Objects

Type

Kind

Movement

Name

number of columns

int

variable

returned

numColumns



Objects

Type

Kind

Movement

Name

first player score

int

variable

passed back

p1score

second player score

int

variable

passed back

p2score

is game over?

bool

variable

returned

---



Objects

Type

Kind

Movement

Name

output stream

ostream

variable

received & passed back

out



Objects

Type

Kind

Movement

Name

row index

int

variable

received

row

column index

int

variable

received

col

player's name

char

variable

received

player

completed box?

bool

variable

returned

-----



Assignment

The Box class and the Exception classes are provided for this assignment. They may be copied on the Linux server using:


   cp /home/hwang/cs215/project4/*.* .


There are three files, except2.h (same as except.h with addition of the DuplicateError exception), box.h and box.cpp. You may not modify these files. However, if you feel you need more operations from the Box class, talk to the instructor. The Box class defines operations that allow the Box object to be manipulated and accessed in accordance with the Dots game rules. The files contain comments explaining what each function does. Hopefully, this is sufficient.


Write the implementation of the BoxGrid class specified above. The BoxGrid class definition should be put in header file boxgrid.h with suitable compilation guards. The implementations of the BoxGrid member functions should be put in source file boxgrid.cpp. The BoxGrid class must be implemented using a dynamically-allocated two-dimensional array. Projects that do not use a dynamically-allocated two-dimensional array will be returned for resubmission with late penalty. The member function names and the order of the parameters must be as specified above. Your code will be linked with a grading driver program that expects this. Note that the main program may not be using all of the specified functions. However, all of the functions must be correct to receive full credit. Note: you may added additional private member function to the BoxGrid class as needed.


Write a main program in file dots.cpp that implements the Dots game described above using the BoxGrid class. This game will be text-based and interactive. It should have the following features:


A sample run of a program meeting these specifications is shown below.


You must submit a makefile named Makefile.project4 that creates executable name dots for your project. Submissions without working makefiles will be assessed up to a 3-point penalty as indicated in the syllabus. It should conform to the examples given in the handout Very Basic make and demonstrated in class.


REMINDER: Your project must compile for it to be graded. Submissions that do not compile will be returned for resubmission and assessed a late penalty. Submissions that do not substantially work also will be returned for resubmission and assessed a late penalty.


Follow the guidelines in the C++ Programming Style Guideline handout. As stated in the syllabus, part of the grade on a programming project depends on how well you adhere to the guidelines. The grader will look at your code listing and grade it according to the guidelines.


What to submit

Electronically submit a tarfile containing your Makefile.project4, boxgrid.h, boxgrid.cpp, and dots.cpp as explained in the handout Submission Instructions for CS 215. Turn in a hardcopy of your Makefile.project4, boxgrid.h, boxgrid.cpp, and dots.cpp. Please do not submit box.h, box.cpp, or except2.h (either in the tarfile or in hardcopy). The submission system will judge only the BoxGrid class implementation. It will not run the Dots game itself.


Sample run


$ ./dots 3 3 A B
   0 1 2
  . . . .
0        
  . . . .
1        
  . . . .
2        
  . . . .

RandomPlayer A's turn:
RandomPlayer A choses [0,2] Left

   0 1 2
  . . . .
0     |  
  . . . .
1        
  . . . .
2        
  . . . .

HumanPlayer B's turn:
Enter row #, column #, and side (t, b, l, r) separated by spaces: 0 0 t
HumanPlayer B chooses [0,0] Top

   0 1 2
  ._. . .
0     |  
  . . . .
1        
  . . . .
2        
  . . . .

RandomPlayer A's turn:
RandomPlayer A choses [0,2] Bottom


   0 1 2
  ._. . .
0     |  
  . . ._.
1        
  . . . .
2        
  . . . .

HumanPlayer B's turn:
Enter row #, column #, and side (t, b, l, r) separated by spaces: 0 0 l
HumanPlayer B chooses [0,0] Left

   0 1 2
  ._. . .
0 |   |  
  . . ._.
1        
  . . . .
2        
  . . . .

8<---snip: later in the game -->8

   0 1 2
  ._. . .
0 |   |  
  ._. ._.
1 |      
  . . . .
2 |   |  
  . . ._.

HumanPlayer B's turn:
Enter row #, column #, and side (t, b, l, r) separated by spaces: 0 0 r
HumanPlayer B chooses [0,0] Right

   0 1 2
  ._. . .
0 |B| |  
  ._. ._.
1 |      
  . . . .
2 |   |  
  . . ._.

HumanPlayer B's turn:
Enter row #, column #, and side (t, b, l, r) separated by spaces: 2 0 r
HumanPlayer B chooses [2,0] Right

   0 1 2
  ._. . .
0 |B| |  
  ._. ._.
1 |      
  . . . .
2 | | |  
  . . ._.

8<---snip: later in the game -->8

   0 1 2
  ._._._.
0 |B| |  
  ._. ._.
1 |      
  . . ._.
2 | | |B|
  . ._._.

RandomPlayer A's turn:
RandomPlayer A choses [1,1] Bottom

   0 1 2
  ._._._.
0 |B| |  
  ._. ._.
1 |      
  . ._._.
2 | |A|B|
  . ._._.

RandomPlayer A's turn:
RandomPlayer A choses [1,1] Right

   0 1 2
  ._._._.
0 |B| |  
  ._. ._.
1 |   |  
  . ._._.
2 | |A|B|
  . ._._.

8<---snip: later in the game -->8

   0 1 2
  ._._._.
0 |B|B|B|
  ._._._.
1 | |B|B|
  . ._._.
2 | |A|B|
  . ._._.

HumanPlayer B's turn:
Enter row #, column #, and side (t, b, l, r) separated by spaces: 0 1 b
That side is already drawn in - try again
Enter row #, column #, and side (t, b, l, r) separated by spaces: 1 0 b
HumanPlayer B chooses [1,0] Bottom

   0 1 2
  ._._._.
0 |B|B|B|
  ._._._.
1 |B|B|B|
  ._._._.
2 | |A|B|
  . ._._.


HumanPlayer B's turn:
Enter row #, column #, and side (t, b, l, r) separated by spaces: 2 0 b
HumanPlayer B chooses [2,0] Bottom

   0 1 2
  ._._._.
0 |B|B|B|
  ._._._.
1 |B|B|B|
  ._._._.
2 |B|A|B|
  ._._._.

The final score is: A - 1; B - 8
Player B wins


Extra credit (5 points)

There is one addition that may be completed for extra credit. If you do the extra credit, you are expected to submit two versions of the project, one regular project, and one with the extra credit.


Write a third player function StrategicPlayer that chooses the row index, column index, and side autonomously based on a strategy devised by you. E.g., it might look for boxes with 3 sides drawn in so that it might draw in the fourth side and get another turn. It otherwise must meet the specifications for a player function. The main program submitted for the extra credit must replace the call to RandomPlayer with a call to StrategicPlayer (i.e., HumanPlayer is still used as the second player function). However, you might want to try playing a random player against a strategic player. Hopefully, a strategic player should always beat a random player. The amount of extra credit awarded will depend partially on the sophistication of the strategy implemented.


Submit a tarfile as explained above except that the makefile must be named Makefile.project4EC and the main program file should be named dotsEC.cpp. There will be a separate entry in the submission system for the extra credit. The submission system only will make sure that an extra credit project compiles. It will not run the program.

Revised: 02/23/08 9 of 9