Programming Assignment 1 Computer Science 102

Spring 1997

First Draft Due: Feb 14, 9:00pm

Introduction to Draft 1 (1 point)

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.

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. This Interface section cannot be changed. If you change it, your program will not work in draft 1, and when you play against the machine in Draft 2. 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. 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. 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).

When it is the user's turn to move, ask for the user's move; the user should respond with a column number. If the 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), ask again. When the user's response is valid, make that move on the board.

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 (say, below the board), 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 Play2, described below.

Draft #1

Draft #1 requires you to write the BoardADT unit and test it with Play2 as indicated below.

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

I have written a unit called play2 available on the home page that allows two players to play each other. Use this to test the ability of your unit BoardADT to detect a win or draw. To use play2, run main.pas, it is available in the home page. It's a simple client that starts with uses play2. The body part of the program should have only one statement: main. For draft 1, just get the BoardADT working. Test with play2 which will be sent to you via majordomo. The player.tpu is not needed for this part of the program.

Draft 2 (2 points)

Write a program called play2 so that two humans can play each other. Finally, using much of the code of play2 write a program that allows a human to play the machine.

The Player Unit

Below is the interface for the unit Player, which will be available on the homepage. 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.

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 1997