Programming Assignment 1 Computer Science 102

Spring 2000. First Draft Due: Feb 13, 11:59pm

Introduction. Your project is to design a program that plays a board game called Connect Four. The purpose of this project is to illustrate the benefits of information hiding and object-oriented programming.

Rules. Connect Four is a generalization of tic-tac-toe. There are two players, called Red and Blue. The Red player goes first, and after that they alternate moves. The board has 7 columns and 6 rows; see the figure below.

>>
6
5 B
4 R B
3 RBB R
2 RBBR R RB
1 BRRR B BB
123456 7

Here, `R' represents those squares where Red has placed her checkers; `B' represents those squares where Blue has placed his checkers. Initially the board is empty, but at each move the current player places one checker on the board. The goal is to get 4 adjacent checkers (of the same color) in a line, either horizontally, vertically, or diagonally. In the example above, Blue can win by placing a checker in column 4.

One key difference between Connect Four and tic-tac-toe is that the board is imagined to be vertical (so that gravity counts). In other words, when a checker is placed in a particular column, it is automatically placed in the lowest empty square of that column.

If the board fills up with neither player winning, then the game is declared a draw.

The Main Program

The current board should be displayed on the terminal at all times. Your board doesn't have to look exactly like the figure above; you may modify it to make it look good on the screen; however, you should use the Graphics described in this assignment. The checkers should be displayed as colored disks, as you will see in the lecture demonstration of the program. Much of the graphics interface will be given to you on the web page. Also the Interface section of the BoardAdt will also be posted there. Download it but don't alter it in any way, If you change it (even adding a comment or changing an indentation), your program will not work.

Using the graphics interface given as a link on the home page will simplify the assignment considerably; Use background(1) for a navy blue background, use palette(3) to get pale blue, (color = 1 in the circle and fillshape procedures) and pink (color = 2, this will represent the Red checker).

Draft #1 (2 points)

Draft #1 requires you to write the BoardADT unit and write a client that enables a humans to play against the computer. The game is played as follows. One player will be the (human) user, and the other player will be the computer. Red always goes first. Before the first game, find out whether the user would like to go first. You should indicate the color representing the user and the one representing the computer in a legend somewhere on the screen. When it is the user's turn to move, ask for the user's move; the user should respond with a column number. If user's response is invalid (either it is not an integer, or it is not between 1 and 7, or that particular column is full), print an error message and ask again. When the user's response is valid, make that move on the board and display it in a written message as well as on the board itself.

When it is the computer's turn, call the function Computer_Move in the unit Player (described below) to find out the computer's move. Display the computer's move in a written message as well as on the board itself.

When one of the players wins, announce that fact. If the game ends in a draw, announce that fact. At the end of each game, find out whether the user wishes to play again. If so, re-initialize the board. The user and the computer should switch colors for the next game. If the players want to stop at the end of a round the game should be terminated.

Your main program should be called connect.pas. It will use the units, BoardADT and Player (described below) and the standard units Crt and Graph3. The uses statement should be written as follows: uses Crt, Graph3, Boardadt, Player. If BoardADT does not follow Graph3 in the uses statement, the variable color will be redefined in Graph3 and you will get a type mismatch error when you use color in the client. Another source of error is declaring the instance of Board_type locally in the client. If you do this, the checkers will not be recorded correctly. Therefor declare the instance globally in for instance, var grid : board_type.

The BoardADT Unit

In the unit BoardADT, you will implement an abstract data type, called board_type, that will allow several useful operations on the board. The interface for this unit is given below; to minimize errors, please copy this from the homepage.

unit BoardADT;

interface
uses graph3;
const
  number_of_columns = 7; 
  number_of_rows :  = 6;

type
  column_type = 1..number_of_columns; {index for columns}
  row_type = 1..number_of_rows; {index for rows}
  square_type = {index for squares}
    record
      column : column_type;
      row : row_type
    end;
  color_type = (red,blue);
  value_type = {what a square contains}
    record
      empty : boolean;   {is square empty?}
      color : color_type {if not empty, what color it is}
    end;
  array_type = array[column_type,row_type] of value_type;
  board_type = 
    object
        procedure Initialize; 
        procedure Make_Move(column : column_type); 
        procedure Get_Value(square : square_type; var Val : value_type); 
        function Get_Current_Color : color_type;
        function Is_Full(column : column_type) : boolean;
        function Is_Win : boolean;
        function Is_Draw : boolean;
      private
        Value : array_type; {the board configuration}
        current_color : color_type; {whose turn it is}
    end; {object board_type}

implementation

{You fill in the implementation of BoardADT.}

end.

The procedure Initialize makes the entire board empty, and makes red the current color (since red begins the game). The procedure Make_Move places a checker of the current color into the next available row in the column numbered column, and then switches the current color. The procedure Get_Value outputs the board value that is in location square. The function Is_Full returns true if the column numbered column is full. The function Is_Win returns true if the player who just moved (namely, the player who is not the current color) has 4 checkers in a line. The function Is_Draw returns true if the board is completely full. When Make_Move is executed the current color is chnaged. Function Get_Current_Color gets you back to the original color. Please note that the first dimension of the array is a column, and the second one, a row. If you don't follow this order, your program will never run correctly. To check things, use range checking the first few times you run the program.

The following describes how to get the moves generated by the computer.

The Player Unit

Below is the interface for the unit Player. Do not write it. Actually, you won't see the source code for the implementation of Player: All you will see is the compiled version in a file named Player.TPU. You will use this unit (and in particular, the function Computer_Move) to get the moves for the computer. I will be sending out the player unit via majordomo.

unit Player;

interface

uses BoardADT;

function Computer_Move(Board : board_type) : column_type;
{Precondition: Board is not completely full.
 Postcondition: Outputs a non-full column to move to.}

implementation

{The implementation of Player has been written.}

end.

The way you get the computer to move is to write in the procedure that registers the computer's move in connect.pas

column:= computer_move(grid);
where grid is of type board_type.
Draft #2 (2 points)
This is the same as draft #1 except for the following:
  1. Now the present move should be differentiated in some way from the previous move. One way to do this is to now draw the checkers as circles and to insert a smaller circle in the circle representing the present move. When the next move is made, the inner circle is removed from the checker representing the previous move.

  2. When a player wins, the winning checker configuration should be differentiable from the other checkers. For instance, you could insert a white circle (color 3) of smaller radius in each of the checkers in the winning configuration.

  3. Each time the player goes, the computer should indicate the player's best move.

Sam Marateck
TUES Jan 25 01:06:15 EST 2000