ISTA 130 Project 11 (the last project): Connect Four

Collaboration: Complete this project alone and/or with help from UofA section leaders and your instructor.

Due date: Monday 5-Dec by 9:00 pm

Goal: The goal of this project is to practice writing a Python class with a constructor, instance variables, and methods, and to practice working with a 2D array of string (list of lists). To practice this, you will implement the game Connect Four.

Background Information: Connect Four is a two person game that takes place on a 6 row x 7 column game board. To play the game, players take turns dropping red and black checkers onto the board. Since this board is upright, the checkers fall to the lowest checker-free row of the board. The first player to get 4 checkers in a row (either vertically, horizontally, or diagonally) wins the game.

To begin, the following block comment should be at the top of your program:

# Developer: [Your name]

#

# SL: [Your SL's name here]

#

# File: Connect4.py

#

# Due: 9:00 pm, 5-Dec-2011

#

# Purpose: This program simulates a game of Connect 4

Your Connect4 class should have the following instance variables:

·self.board (a 6 x 7 2D list, with every element initialized to the string ‘-’)

·self.player1 (the first player’s name. Initialized to the string passed in the constructor)

·self.player2 (the second player’s name. Initialized to the string passed in the constructor)

Your Connect4 class should have the following methods:

# The Connect4 constructor should initialize the player1 and player2 instance variables # to the passed arguments. Additionally, it should initialize the board instance # variable to a 6 x 7 2D list, with every element in the list set to the character ‘-’

def __init__(self, player1, player2):

# This method should return a string representing the playing board. Each row of the # board in this string should be separated by a new line, and each element should be # separated by a space.

def __str__(self):

# The makeMove method takes two arguments: a player and a column number. This method # should place a checker on the board on the lowest free row of the specified column # number. For example, if there is one checker in column 3 and the player would like to # place another checker in this column, then this checker would be placed at row 4, col # 3. If the player is equal to player1, then an ‘X’ is placed on the board. Otherwise, # an ‘O’ should be placed on the board to represent the checker. After the checker is # placed, the row that it was placed at should be returned.

# PRECONDITION: the col number will always be in range of the board

def makeMove(self, player, col):

# This method should call checkWinHorizontal(), checkWinVertical(), and

# checkWinDiagonal(). If any of those methods return True, then checkWin should return

# True, indicating that the game has been won. Otherwise, False should be returned.

def checkWin(self):

# This method should iterate through the board and check to see if there are four ‘X’ # characters or four ‘O’ characters adjacent to each other in the same row.

def checkWinHorizontal(self):

# This method should iterate through the board and check to see if there are four ‘X’ # characters or four ‘O’ characters adjacent to each other in the same column.

def checkWinVertical(self):

# This method should iterate through the board and check to see if there are four ‘X’ # characters or four ‘O’ characters adjacent to each other in a diagonal on the board. # A diagonal can be formed from the upper left to the lower right, or from the lower # left to the upper right of the board. You will need to check for both of these cases.

def checkWinDiagonal(self):

# This method returns True if no more checkers can be added to the given column.

# If there is room in the given column, False should be returned.

def columnIsFull(self, column):

# This method should iterate through the board and return True if there are no spaces

# open on the board (no elements in the list of lists is ‘-’). If there are spaces

# open on the board, False should be returned.

def boardIsFull(self):

A small test method to show some behavior

The following test is intended to show the client side of the Connect4 class. The constructor and 5 methods are used.

import unittest

from Connect4 import *

class Connect4Test(unittest.TestCase):

def testSeveralMethodsToShowSomeBehavior(self):

player1 = "John"

player2 = "Jane"

game = Connect4(player1, player2)

game.makeMove(player1, 4)

game.makeMove(player2, 4)

game.makeMove(player1, 4)

game.makeMove(player2, 4)

game.makeMove(player1, 4)

self.assertFalse(game.columnIsFull(4))

game.makeMove(player2, 4)

self.assertTrue(game.columnIsFull(4))

# No one won

self.assertFalse(game.checkWin())

# Many columns available still

self.assertFalse(game.boardIsFull())

# __str__ should now return the output shown in comments

print(game)

#- - - - O - -

#- - - - X - -

#- - - - O - -

#- - - - X - -

#- - - - O - -

#- - - - X - -

if __name__ == '__main__':

try: unittest.main()

except SystemExit: pass

At the end of your program, you should include a main function that allows two users to play the game by letting them take turns dropping pieces onto the board. The following is an example output from one game:

Player 1's name: John

Player 2's name: Jane

John's turn.

Enter a column number to drop your piece: 1

------

------

------

------

------

- X - - - - -

Jane's turn.

Enter a column number to drop your piece: 3

------

------

------

------

------

- X - O - - -

John's turn.

Enter a column number to drop your piece: 2

------

------

------

------

------

- X X O - - -

Jane's turn.

Enter a column number to drop your piece: 3

------

------

------

------

- - - O - - -

- X X O - - -

John's turn.

Enter a column number to drop your piece: 6

------

------

------

------

- - - O - - -

- X X O - - X

Jane's turn.

Enter a column number to drop your piece: 3

------

------

------

- - - O - - -

- - - O - - -

- X X O - - X

John's turn.

Enter a column number to drop your piece: 5

------

------

------

- - - O - - -

- - - O - - -

- X X O - X X

Jane's turn.

Enter a column number to drop your piece: 3

------

------

- - - O - - -

- - - O - - -

- - - O - - -

- X X O - X X

Jane wins! :D

After you are finished with your program, you can try playing it with our GUI: (linked 5-Dec)

Grading Criteria : 100pts Subject to change

___ / 80 All of the tests pass in Connect4Test.py (linked 5-Dec)

___ / 20 There is a main method in Connect4.py that plays a console game

•+2 Gets both players names

•+8 Correct players are prompted in correct order, switching for each valid move

•+2 User loses turn if column is out of range (see dialog below)

•+2 User loses turn if column is filled (see dialog below)

•+4 Correct player notified of win as soon as that player wins, game ends

•+2 Both players notified if there is a tie, game ends

John's turn.

Enter a column number to drop your piece: 1

------

------

------

------

------

- X - - - - -

Jane's turn.

Enter a column number to drop your piece: 2

------

------

------

------

------

- X O - - - -

John's turn.

Enter a column number to drop your piece: -1

Invalid choice, you lose your turn.

Jane's turn.

Enter a column number to drop your piece: 2

------

------

------

------

- - O - - - -

- X O - - - -