Hi, this is python(3.4) programming problem and I have to implement a variant of
ID: 3826364 • Letter: H
Question
Hi, this is python(3.4) programming problem and I have to implement a variant of the game "Connect Four" on game boards of arbitrary dimensions. Below is my code for the problem but I have an error when I run it. error: if horizontal_winner(game_board) >= 1 or vertical_winner(game_board) >= 1 or diagonal_winner(game_board) TypeError: unorderable types: NoneType() >= int() How can I solve the problem? class Board: def __init__(self, num_rows, num_cols): self._num_rows = num_rows self._num_cols = num_cols self._slots = [] for i in range(0, num_rows): self._slots.append([]) for j in range(0, num_cols): self._slots[-1].append('.') # DO NOT MODIFY THE Board CLASS IN ANY WAY! # Displays the board. Note that slot [0][0] is in the bottom-left corner of the board. # [num_rows-1][num_cols-1] is the position of the slot in the upper-right corner def display_board(board): for i in range(board._num_rows-1, -1, -1): row = ''.join(board._slots[i]) print(row) # PART I # Returns True if the board is completely filled with pieces. def board_full(board): for i in range(board._num_cols): if board._slots[board._num_rows - 1][i] == '.': return False return True # PART II # Drops a piece in the board into the desired column number. # If player is 1, drop an 'X'. If player is 2, drop an 'O'. (letter Oh). # Returns the number of the row that the piece landed in (where the bottommost row is row #1). # If the game piece can be dropped, return the row number where the piece landed, otherwise return -1. # Note that col_num is given as a value in the range 1 through board._num_cols, NOT 0 through board._num_cols-1. def drop_piece(board, col_num, player): piece = '.' if player == 1: piece = 'X' elif player == 2: piece = 'O' else: return -1 if col_num < 0 or col_num > board._num_cols: return -1 if board._slots[board._num_rows - 1][col_num] != '.': return -1 for i in range(board._num_rows): if board._slots[i][col_num] == '.': board._slots[i][col_num] = piece return i + 1 # PART III # Determines if a player has won the game by putting four pieces next to each other in a single row. # Returns 1 if player 1 has won the game by placing four X's contiguously in a single row. # Returns 2 if player 2 has won the game by placing four O's contiguously in a single row. # Returns 0 if no one has won yet by placing pieces in this manner. # This function must not modify the contents of the game board. def horizontal_winner(board): for i in range(board._num_rows): curr = '' count = 0 for j in range(board._num_cols): if board._slots[i][j] == '.': count = 0 elif board._slots[i][j] == curr: count += 1 else: curr = board._slots[i][j] count = 1 if count == 4: if curr == 'X': return 1 elif curr == 'O': return 2 else: return 0 # PART IV # Determines if a player has won the game by putting four pieces on top of each other in a single column. # Returns 1 if player 1 has won the game by placing four X's contiguously in a single column. # Returns 2 if player 2 has won the game by placing four O's contiguously in a single column. # Returns 0 if no one has won yet by placing pieces in this manner. # This function must not modify the contents of the game board. def vertical_winner(board): for j in range(board._num_cols): curr = '' count = 0 for i in range(board._num_rows): if board._slots[i][j] == '.': count = 0 elif board._slots[i][j] == curr: count += 1 else: curr = board._slots[i][j] count = 1 if count == 4: if curr == 'X': return 1 elif curr == 'O': return 2 else: return 0 # PART V # Determines if a player has won the game by placing four pieces in a diagonal. # Returns 1 if player 1 has won the game by placing four X's diagonally. # Returns 2 if player 2 has won the game by placing four O's diagonally. # Returns 0 if no one has won yet by placing pieces in this manner. # This function must not modify the contents of the game board. def diagonal_winner(board): for i in range(board._num_rows - 4): for j in range(board._num_cols - 4): piece = board._slots[i][j] if piece == '.': continue flag = True for k in range(1, 4): if board._slots[i + k][j + k] != piece: flag = False break if flag: if piece == 'X': return 1 else: return 2 piece = board._slots[board._num_rows - 1 - i][j] if piece == '.': continue flag = True for k in range(1, 4): if board._slots[board._num_rows - 1 - i - k][j - k] != piece: flag = False if flag: if piece == 'X': return 1 else: return 2 # PART VI # Drops a bomb into a given column. # If the column number is outside the range 1 through num_cols, return -1 and do not change the state of the board. # Otherwise, remove all the pieces from the column, replacing them with '.', and then return col_num. # Note that col_num is given as a value in the range 1 through board._num_cols, NOT 0 through board._num_cols-1. def drop_bomb(board, col_num): col_num = col_num - 1 if col_num < 0 or col_num > board._num_cols - 1: return -1 for i in range(board._num_rows): board._slots[i][col_num] = '.' return col_num + 1 # DO NOT MODIFY THE CODE BELOW IN ANY WAY! if __name__ == "__main__": print('Welcome to Connect Four: CSE 101 Edition! ') num_rows = int(input('Enter number of rows in board. Must be >= 4: ')) num_cols = int(input('Enter number of columns in board. Must be >= 4: ')) game_board = Board(num_rows, num_cols) print('Player 1: You are X') print('Player 2: You are O') print('Let's start the game!') winner = None player = 1 # can be 1 or 2 bombs = [1,1] # how many bombs each player has remaining to use while not board_full(game_board) and winner is None: print(' Player {}'s turn!'.format(player)) display_board(game_board) col = int(input('Which column do you want to drop a piece into? (1-{}) '.format(game_board._num_cols))) use_bomb = 'n' if bombs[player-1] > 0: use_bomb = input('Do you want to use your bomb piece? (y/n) ') if use_bomb.lower() == 'y': col = drop_bomb(game_board, col) if col == -1: print('You can't drop a bomb into that column. You lose your bomb and your turn!') bombs[player-1] -= 1 else: row = drop_piece(game_board, col, player) if row == -1: print('You can't drop a piece into that column. You lose your turn!') if horizontal_winner(game_board) >= 1 or vertical_winner(game_board) >= 1 or diagonal_winner(game_board): print(' Player {} won the game!'.format(player)) break player = 3-player # take turns display_board(game_board) if board_full(game_board): print(' Game Over! It was a tie!') else: print(' Game Over!')
Explanation / Answer
online code link at last. Issue was thre was no default return value specified so in case your return statement didn't reach there was NOne being return. I have fixed that. But am not sure on whether your overall logic is correct.
class Board:
def __init__(self, num_rows, num_cols):
self._num_rows = num_rows
self._num_cols = num_cols
self._slots = []
for i in range(0, num_rows):
self._slots.append([])
for j in range(0, num_cols):
self._slots[-1].append('.')
# DO NOT MODIFY THE Board CLASS IN ANY WAY!
# Displays the board. Note that slot [0][0] is in the bottom-left corner of the board.
# [num_rows-1][num_cols-1] is the position of the slot in the upper-right corner
def display_board(board):
for i in range(board._num_rows-1, -1, -1):
row = ''.join(board._slots[i])
print(row)
# PART I
# Returns True if the board is completely filled with pieces.
def board_full(board):
for i in range(board._num_cols):
if board._slots[board._num_rows - 1][i] == '.':
return False
return True
# PART II
# Drops a piece in the board into the desired column number.
# If player is 1, drop an 'X'. If player is 2, drop an 'O'. (letter Oh).
# Returns the number of the row that the piece landed in (where the bottommost row is row #1).
# If the game piece can be dropped, return the row number where the piece landed, otherwise return -1.
# Note that col_num is given as a value in the range 1 through board._num_cols, NOT 0 through board._num_cols-1.
def drop_piece(board, col_num, player):
piece = '.'
if player == 1:
piece = 'X'
elif player == 2:
piece = 'O'
else:
return -1
if col_num < 0 or col_num > board._num_cols:
return -1
if board._slots[board._num_rows - 1][col_num] != '.':
return -1
for i in range(board._num_rows):
if board._slots[i][col_num] == '.':
board._slots[i][col_num] = piece
return i + 1
# PART III
# Determines if a player has won the game by putting four pieces next to each other in a single row.
# Returns 1 if player 1 has won the game by placing four X's contiguously in a single row.
# Returns 2 if player 2 has won the game by placing four O's contiguously in a single row.
# Returns 0 if no one has won yet by placing pieces in this manner.
# This function must not modify the contents of the game board.
def horizontal_winner(board):
for i in range(board._num_rows):
curr = ''
count = 0
for j in range(board._num_cols):
if board._slots[i][j] == '.':
count = 0
elif board._slots[i][j] == curr:
count += 1
else:
curr = board._slots[i][j]
count = 1
if count == 4:
if curr == 'X':
return 1
elif curr == 'O':
return 2
else:
return 0
return 0
# PART IV
# Determines if a player has won the game by putting four pieces on top of each other in a single column.
# Returns 1 if player 1 has won the game by placing four X's contiguously in a single column.
# Returns 2 if player 2 has won the game by placing four O's contiguously in a single column.
# Returns 0 if no one has won yet by placing pieces in this manner.
# This function must not modify the contents of the game board.
def vertical_winner(board):
for j in range(board._num_cols):
curr = ''
count = 0
for i in range(board._num_rows):
if board._slots[i][j] == '.':
count = 0
elif board._slots[i][j] == curr:
count += 1
else:
curr = board._slots[i][j]
count = 1
if count == 4:
if curr == 'X':
return 1
elif curr == 'O':
return 2
else:
return 0
return 0
# PART V
# Determines if a player has won the game by placing four pieces in a diagonal.
# Returns 1 if player 1 has won the game by placing four X's diagonally.
# Returns 2 if player 2 has won the game by placing four O's diagonally.
# Returns 0 if no one has won yet by placing pieces in this manner.
# This function must not modify the contents of the game board.
def diagonal_winner(board):
for i in range(board._num_rows - 4):
for j in range(board._num_cols - 4):
piece = board._slots[i][j]
if piece == '.':
continue
flag = True
for k in range(1, 4):
if board._slots[i + k][j + k] != piece:
flag = False
break
if flag:
if piece == 'X':
return 1
else:
return 2
piece = board._slots[board._num_rows - 1 - i][j]
if piece == '.':
continue
flag = True
for k in range(1, 4):
if board._slots[board._num_rows - 1 - i - k][j - k] != piece:
flag = False
if flag:
if piece == 'X':
return 1
else:
return 2
return 0
# PART VI
# Drops a bomb into a given column.
# If the column number is outside the range 1 through num_cols, return -1 and do not change the state of the board.
# Otherwise, remove all the pieces from the column, replacing them with '.', and then return col_num.
# Note that col_num is given as a value in the range 1 through board._num_cols, NOT 0 through board._num_cols-1.
def drop_bomb(board, col_num):
col_num = col_num - 1
if col_num < 0 or col_num > board._num_cols - 1:
return -1
for i in range(board._num_rows):
board._slots[i][col_num] = '.'
return col_num + 1
# DO NOT MODIFY THE CODE BELOW IN ANY WAY!
if __name__ == "__main__":
print('Welcome to Connect Four: CSE 101 Edition! ')
num_rows = int(input('Enter number of rows in board. Must be >= 4: '))
num_cols = int(input('Enter number of columns in board. Must be >= 4: '))
game_board = Board(num_rows, num_cols)
print('Player 1: You are X')
print('Player 2: You are O')
print('Let's start the game!')
winner = None
player = 1 # can be 1 or 2
bombs = [1,1] # how many bombs each player has remaining to use
while not board_full(game_board) and winner is None:
print(' Player {}'s turn!'.format(player))
display_board(game_board)
col = int(input('Which column do you want to drop a piece into? (1-{}) '.format(game_board._num_cols)))
use_bomb = 'n'
if bombs[player-1] > 0:
use_bomb = input('Do you want to use your bomb piece? (y/n) ')
if use_bomb.lower() == 'y':
col = drop_bomb(game_board, col)
if col == -1:
print('You can't drop a bomb into that column. You lose your bomb and your turn!')
bombs[player-1] -= 1
else:
row = drop_piece(game_board, col, player)
if row == -1:
print('You can't drop a piece into that column. You lose your turn!')
if horizontal_winner(game_board) >= 1 or vertical_winner(game_board) >= 1 or diagonal_winner(game_board):
print(' Player {} won the game!'.format(player))
break
player = 3-player # take turns
display_board(game_board)
if board_full(game_board):
print(' Game Over! It was a tie!')
else:
print(' Game Over!')
# pastebin link of code: https://pastebin.com/5s78p4K8
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.