Aegg
Aegg

Reputation: 63

Tic Tac Toe Python 2.7

I'm working on a tic tac toe program, and for some reason when I'm trying to print a 3x3 board it won't work. I have to print a 4x4 board instead. The way the program is supposed to work is that we're supposed to enter a row then a column it then prints either a X or O at those coordinates, but like I said... it won't work for a 3x3 board. Whenever I enter row 3 or column 3 it says that the coordinates are out of range... Any help would be greatly appreciated. Thank you.

def playTicTacToe():
    rows,cols = 4,4
    winLength = 3
    board = makeNewBoard(rows, cols)
    moves = 0
    player = 1
    while (moves < rows*cols):
        row,col = getMove(board, player)
        board = setPiece(board, row, col, player)
        if (didWin(board, player, winLength)):
            printBoard(board)
            print getPieceLabel(player), " WINS!!!"
            return
        player = otherPlayer(player)
        moves += 1
    print "TIE GAME!!!!"


def makeNewBoard(rows, cols): return [([0]*cols) for row in xrange(rows)]
def getRows(board): return len(board)
def getCols(board): return len(board[0])
def getPiece(board, row, col): return board[row][col]
def setPiece(board, row, col, value):
    board[row][col] = value
    return board

def isEmpty(board, row, col):
    return (getPiece(board, row, col) == 0)

def isOnBoard(board, row, col):
    rows = getRows(board)
    cols = getCols(board)
    return ((row >= 0) and (row < rows) and
            (col >= 0) and (col < cols))    

def getPieceLabel(piece):
    if (piece == 1): return "X"
    elif (piece == 2): return "O"
    else: return "-"

def printBoard(board):
    print "\n**************************"
    rows = getRows(board)
    cols = getCols(board)
    for row in xrange(rows):
        for col in xrange(cols):
            piece = getPiece(board, row, col)
            label = getPieceLabel(piece)
            print label,
        print


def didWin(board, player, winLength):
    rows = getRows(board)
    cols = getCols(board)
    for startRow in xrange(rows):
        for startCol in xrange(cols):
            if (didWin1(board, player, winLength, startRow, startCol)):
                return True
    return False            

def didWin1(board, player, winLength, startRow, startCol):
    for drow in xrange(-1,+2):
        for dcol in xrange(-1,+2):
            if ((drow != 0) or (dcol != 0)):
                if (didWin2(board, player, winLength,
                            startRow, startCol, drow, dcol)):
                    return True
    return False

def didWin2(board, player, winLength,
            startRow, startCol, drow, dcol):
    rows = getRows(board)
    cols = getCols(board)
    for step in xrange(winLength):
        row = startRow + step*drow
        col = startCol + step*dcol
        if (not isOnBoard(board, row, col)):
            return False
        elif (getPiece(board, row, col) != player):
            return False
    return True


def otherPlayer(player):
    return 1 if (player == 2) else 2


def oops(msg):
    print "  ", msg, "Try again."


def readInt(prompt):
    while (True):
        try:
            return int(raw_input(prompt))
        except:
            oops("Input must be an integer.")

def getMove(board, player):
    while (True):
        printBoard(board)
        print "Enter move for player", getPieceLabel(player)
        row = readInt("  Row --> ")
        col = readInt("  Col --> ")
        if (not isOnBoard(board, row, col)):
            oops("Out of range (not on the board)!")
        elif (not isEmpty(board, row, col)):
            oops("Already occupied!")
        else:
            return (row, col)

playTicTacToe()   

Upvotes: 0

Views: 750

Answers (3)

Jake Nixon
Jake Nixon

Reputation: 93

I've tried it out with just changing the second line to:

rows,cols = 3,3

I did this in a python 2.7 interpreter and it's fine! Did you forget that Python uses the indexes 0, 1 and 2 instead of 1, 2 and 3?

Use 0 in place of 1 Use 1 in place of 2 Use 2 in place of 3

You could try and make it so that the game uses 1, 2 and 3 to make it more user-friendly, good luck! :)

Upvotes: 1

xor
xor

Reputation: 2698

You should be using a value less than what you enter as index because in python and most of the othe languages indexing starts from 0

set

row,cols=3,3

and in getMove() function use this instead

row = readInt("  Row --> ")-1
col = readInt("  Col --> ")-1

Upvotes: 2

C.B.
C.B.

Reputation: 8326

When you enter 3 for row or column, you are calling

isOnBoard(board, 3, 3)

which calls

rows = getRows(board)

which sets rows to 3

which causes

(row < rows)

to evaluate to false

You want to decrement row and col to comply with Python's zero-based indexing

Upvotes: 2

Related Questions