Programming Assignment 1 Computer Science 102

Spring 1998. First Draft Due: Feb 14, 9:00pm

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 Turtle Graphics. 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, your program will not work in draft 2 when you play against the machine..

If you use 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 two humans to play each other. The following describes how the game in this situation is played. Let red represent the first player and blue, the second. Let red go first. Ask for red's move; red should respond with a column number. If red's response is invalid (either it is not an integer, or it is not between 1 and 7, or that particular column is full), ask again. When the red's response is valid, make that move on the board.

Let the other player (blue) go next. Display each player's move in a written message (say, below the board), as well as the move on the board itself.

When one of the players wins, announce that fact on the display. If the game ends in a draw, announce that fact. At the end of each game, find out whether the users wish to play again. If so, re-initialize the board and for simplicity follow the same order as before, red first, blue second. If the players want to stop, the game should be terminated.

Your main program should be called play_two.pas. It will use the unit, called BoardADT described below and the standard units Crt and Graph3.

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

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. Function Get_Current_Color changes the current color. Please note that the first dimension of the array is a column, and the second one, a row. If you dont follow this order, your program will never run correctly. To check things, use range checking the first few times you run the program.

Draft 2 (2 points)

Using much of the code of play_two, write a program that allows a human to play the computer.

The following describes how the game against the computer is played. 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 be red or blue. 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 just as in draft #1. 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. To be fair, the user and the computer will switch colors for the next game.

Your main program should be called connect.pas. It will use two units, called BoardADT and Player, described below.

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 connect4.pas

column:= computer_move(grid);
where grid is of type board_adt.

Sam Marateck
Tue Jan 28 01:06:15 EST 1998/I>