How to Determine Winner in Connect Four Game [closed] - python

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I've a relatively new beginner to python who just wants to learn as much as he can and to just fiddle around with the language. I've began to make my own Connect Four game, and everything's all right except the identification of a winner when 4 pieces are in a row (whether it be row-wise, column-wise, or diagonal-wise) In my winner(board) function, I've first tested out a win for a row. Please see my winner(board) function below:
import random
def winner(board):
"""This function accepts the Connect Four board as a parameter.
If there is no winner, the function will return the empty string "".
If the user has won, it will return 'X', and if the computer has
won it will return 'O'."""
for row in range(4):
if (board[row][0] == board[row][1] == board[row][2]) == board[row][3] and \
(board[row][0] != " "):
return board[row][0]
for col in range(4):
if (board[0][col] == board[1][col] == board[2][col]) == board[3][col] and \
(board[row][0] != " "):
return board[0][col]
# No winner: return the empty string
return ""
def display_board(board):
"""This function accepts the Connect Four board as a parameter.
It will print the Connect Four board grid (using ASCII characters)
and show the positions of any X's and O's. It also displays
the column numbers on top of the board to help
the user figure out the coordinates of their next move.
This function does not return anything."""
print(" 0 1 2 3 4 5 6")
print(" " + board[0][0] + " | " + board[0][1] + " | " + board[0][2] + " | " + board[0][3] + " | " + board[0][
4] + " | " + board[0][5] + " | " + board[0][6])
print(" ---+---+---+---+---+---+---")
print(" " + board[1][0] + " | " + board[1][1] + " | " + board[1][2] + " | " + board[1][3] + " | " + board[1][
4] + " | " + board[1][5] + " | " + board[1][6])
print(" ---+---+---+---+---+---+---")
print(" " + board[2][0] + " | " + board[2][1] + " | " + board[2][2] + " | " + board[2][3] + " | " + board[2][
4] + " | " + board[2][5] + " | " + board[2][6])
print(" ---+---+---+---+---+---+---")
print(" " + board[3][0] + " | " + board[3][1] + " | " + board[3][2] + " | " + board[3][3] + " | " + board[3][
4] + " | " + board[3][5] + " | " + board[3][6])
print(" ---+---+---+---+---+---+---")
print(" " + board[4][0] + " | " + board[4][1] + " | " + board[4][2] + " | " + board[4][3] + " | " + board[4][
4] + " | " + board[4][5] + " | " + board[4][6])
print(" ---+---+---+---+---+---+---")
print(" " + board[5][0] + " | " + board[5][1] + " | " + board[5][2] + " | " + board[5][3] + " | " + board[5][
4] + " | " + board[5][5] + " | " + board[5][6])
print(" ---+---+---+---+---+---+---")
print(" " + board[6][0] + " | " + board[6][1] + " | " + board[6][2] + " | " + board[6][3] + " | " + board[6][
4] + " | " + board[6][5] + " | " + board[6][6])
print()
def make_user_move(board):
"""This function accepts the Connect Four board as a parameter.
It will ask the user for a row and column. If the row and
column are each within the range of 0 and 6, and that square
is not already occupied, then it will place an 'X' in that square."""
valid_move = False
while not valid_move:
try:
col = int(input("What col would you like to move to (0-6):"))
if board[0][col] != ' ':
print("Sorry, that column is full. Please try again!\n")
else:
for row in range(6, -1, -1):
if board[row][col] == ' ' and not valid_move:
board[row][col] = 'X'
valid_move = True
except:
ValueError
return board
def make_computer_move(board):
"""This function accepts the Connect Four board as a parameter.
It will randomly pick row and column values between 0 and 6.
If that square is not already occupied it will place an 'O'
in that square. Otherwise, another random row and column
will be generated."""
computer_valid_move = False
while not computer_valid_move:
col = random.randint(0, 6)
if board[0][col] != ' ':
print("Sorry, that column is full. Please try again!\n")
else:
for row in range(6, -1, -1):
if board[row][col] == ' ' and not computer_valid_move:
board[row][col] = 'O'
computer_valid_move = True
return board
def main():
"""The Main Game Loop:"""
free_cells = 42
users_turn = True
ttt_board = [[" ", " ", " ", " ", " ", " ", " "], [" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "], [" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "], [" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "]]
while not winner(ttt_board) and (free_cells > 0):
display_board(ttt_board)
if users_turn:
ttt_board = make_user_move(ttt_board)
users_turn = not users_turn
else:
ttt_board = make_computer_move(ttt_board)
users_turn = not users_turn
free_cells -= 1
display_board(ttt_board)
if (winner(ttt_board) == 'X'):
print("Y O U W O N !")
elif (winner(ttt_board) == 'O'):
print("I W O N !")
else:
print("S T A L E M A T E !")
print("\n*** GAME OVER ***\n")
# Start the game!
main()
However, whenever I run the program and get 4 in a row, it doesn't say that I won or anything. It just continues the program. Hopefully someone can help me out :)
There's another thing. How would I check for row and column winners without having to list out all the possible rows and columns that a win can exist? Is there an efficient way for this?
Thank you so much!

Your winner function has a hard time finding a winner because it just looks at the top left 4 by 4 square. You need to find a way to look at the whole rows and columns for 4 equal in a row.
This code part could check the rows.
for row in range(7):
i = 0
last = ''
for col in range(7):
this = board[row][col]
if this == " ":
i = 0
continue
if this == last:
i+= 1
else:
i = 1
if i >= 4:
return this
last = this
You could gain performance by only checking the column and row of the latest inserted brick.

Related

How to make a word list have all lowercase letters

I created a hangman game but when I enter the correct letter if it is not the correct uppercase/lowercase then it counts it wrong. I don't know how to convert my word list in only lowercase letters. My word list is on another file that I imported. Below is the code.
`
import random
import time
from words import word_list
# Initial Steps to invite in the game:
print("\nWelcome to Hangman!\n")
name = input("Enter Your name: ")
print("Hello " + name + "! Good Luck!")
time.sleep(2)
print("The Game is About to Start!\n Let's Play Hangman!")
time.sleep(3)
# The parameters we require to execute the game:
def main():
global count
global display
global word
global already_guessed
global length
global play_game
words_to_guess = (word_list)
word = random.choice(words_to_guess)
length = len(word)
count = 0
display = '_' * length
already_guessed = []
play_game = ""
# A loop to re-execute the game when the first round ends:
def play_loop():
global play_game
play_game = input("Do You want to play again? y = yes, n = no \n")
while play_game not in ["y", "n","Y","N"]:
play_game = input("Do You want to play again? y = yes, n = no \n")
if play_game == "y":
main()
elif play_game == "n":
print("Thanks For Playing! We expect you back again!")
exit()
# Initializing all the conditions required for the game:
def hangman():
global count
global display
global word
global already_guessed
global play_game
limit = 9
guess = input("This is the Hangman Word: " + display + " Enter your guess: \n")
guess = guess.strip()
if len(guess.strip()) == 0 or len(guess.strip()) >= 2 or guess <= "9":
print("Invalid Input, Try a letter\n")
hangman()
elif guess in word:
already_guessed.extend([guess])
index = word.find(guess)
word = word[:index] + "_" + word[index + 1:]
display = display[:index] + guess + display[index + 1:]
print(display + "\n")
elif guess in already_guessed:
print("Try another letter.\n")
else:
count += 1
if count == 1:
time.sleep(1)
print(" _____ \n"
" | \n"
" | \n"
" | \n"
" | \n"
" | \n"
" | \n"
"__|__\n")
print("Wrong guess. " + str(limit - count) + " guesses remaining\n")
elif count == 2:
time.sleep(1)
print(" _____ \n"
" | | \n"
" | |\n"
" | \n"
" | \n"
" | \n"
" | \n"
"__|__\n")
print("Wrong guess. " + str(limit - count) + " guesses remaining\n")
elif count == 3:
time.sleep(1)
print(" _____ \n"
" | | \n"
" | |\n"
" | | \n"
" | \n"
" | \n"
" | \n"
"__|__\n")
print("Wrong guess. " + str(limit - count) + " guesses remaining\n")
elif count == 4:
time.sleep(1)
print(" _____ \n"
" | | \n"
" | |\n"
" | | \n"
" | O \n"
" | \n"
" | \n"
"__|__\n")
print("Wrong guess. " + str(limit - count) + " last guess remaining\n")
elif count == 5:
time.sleep(1)
print(" _____ \n"
" | | \n"
" | |\n"
" | | \n"
" | O \n"
" | | \n"
" | \n"
"__|__\n")
print("Wrong guess. " + str(limit - count) + " last guess remaining\n")
elif count == 6:
time.sleep(1)
print(" _____ \n"
" | | \n"
" | |\n"
" | | \n"
" | O \n"
" | /| \n"
" | \n"
"__|__\n")
print("Wrong guess. " + str(limit - count) + " last guess remaining\n")
elif count == 7:
time.sleep(1)
print(" _____ \n"
" | | \n"
" | |\n"
" | | \n"
" | O \n"
" | /|\ \n"
" | \n"
"__|__\n")
print("Wrong guess. " + str(limit - count) + " last guess remaining\n")
elif count == 8:
time.sleep(1)
print(" _____ \n"
" | | \n"
" | |\n"
" | | \n"
" | O \n"
" | /|\ \n"
" | / \n"
"__|__\n")
print("Wrong guess. " + str(limit - count) + " last guess remaining\n")
elif count == 9:
time.sleep(1)
print(" _____ \n"
" | | \n"
" | |\n"
" | | \n"
" | O \n"
" | /|\ \n"
" | / \ \n"
"__|__\n")
print("Wrong guess. You are hanged!!!\n")
print("The word was:",already_guessed,word)
play_loop()
if word == '_' * length:
print("Congrats! You have guessed the word correctly!")
play_loop()
elif count != limit:
hangman()
main()
hangman()
`
I wanted the letter to be counted right regardless if it is inputted as uppercase or lowercase. What resulted was it being counted as an incorrect guess even though the letter was correct.
Constructive Feedback Wanted!

Python if statements and loops are a bit redundant in my connect 4 game

I'm doing a python class assignment but my teacher tells me that a block of my code is a bit redundant. Basically it is a connect 4 game I am building.
So this is my code, it doesn't have any errors but the block of code from the if statements is a bit redundant.
def draw_board(field):
for row in field:
for column in row:
print("|" + column, end="")
print("|")
Board = [[" ", " ", " ", " ", " ", " ", " "], #0
[" ", " ", " ", " ", " ", " ", " "], #1
[" ", " ", " ", " ", " ", " ", " "], #2
[" ", " ", " ", " ", " ", " ", " "], #3
[" ", " ", " ", " ", " ", " ", " "], #4
[" ", " ", " ", " ", " ", " ", " "]] #5
Player1 = input("Enter Player: ")
Player2 = input("Enter Player: ")
turn = Player1
while True:
print("Players Turn:", turn)
if turn == Player1:
SelectColumn = int(input("Select Column from 0-6: \n"))
if Board[-1][SelectColumn] == " ":
Board[-1][SelectColumn] = Player1
turn = Player2
elif Board[-2][SelectColumn] == " ":
Board[-2][SelectColumn] = Player1
turn = Player2
elif Board[-3][SelectColumn] == " ":
Board[-3][SelectColumn] = Player1
turn = Player2
elif Board[-4][SelectColumn] == " ":
Board[-4][SelectColumn] = Player1
turn = Player2
elif Board[-5][SelectColumn] == " ":
Board[-5][SelectColumn] = Player1
turn = Player2
elif Board[-6][SelectColumn] == " ":
Board[-6][SelectColumn] = Player1
turn = Player2
else:
SelectColumn = int(input("Select Column from 0-6: \n"))
if Board[-1][SelectColumn] == " ":
Board[-1][SelectColumn] = Player2
turn = Player1
elif Board[-2][SelectColumn] == " ":
Board[-2][SelectColumn] = Player2
turn = Player1
elif Board[-3][SelectColumn] == " ":
Board[-3][SelectColumn] = Player2
turn = Player1
elif Board[-4][SelectColumn] == " ":
Board[-4][SelectColumn] = Player2
turn = Player1
elif Board[-5][SelectColumn] == " ":
Board[-5][SelectColumn] = Player2
turn = Player1
elif Board[-6][SelectColumn] == " ":
Board[-6][SelectColumn] = Player2
turn = Player1
draw_board(Board)
I was wondering, is there any way of shortening this code but still being able to accomplish the same purpose or is it okay as it is?
You can do 2 things:
Use a for loop
Use values 1 and -1 for the turns
Also I think you meant to put draw_board(Board) inside the loop.
Anyways doing the two things above can make your code much cleaner.
I also added a check so that users can't select filled columns.
def draw_board(field):
for row in field:
for column in row:
print("|" + column, end="")
print("|")
Board = [[" ", " ", " ", " ", " ", " ", " "], #0
[" ", " ", " ", " ", " ", " ", " "], #1
[" ", " ", " ", " ", " ", " ", " "], #2
[" ", " ", " ", " ", " ", " ", " "], #3
[" ", " ", " ", " ", " ", " ", " "], #4
[" ", " ", " ", " ", " ", " ", " "]] #5
turn = 1
Player1 = input("Enter Player: ")
Player2 = input("Enter Player: ")
while True:
player = Player1 if turn > 0 else Player2
print("Player's Turn:", player)
SelectColumn = int(input("Select Column from 0-5: \n"))
# Prevent users from selecting already filled columns
while Board[0][SelectColumn] != " ":
SelectColumn = int(input("Select Column from 0-6: \n"))
# fill column
for i in range(6):
if Board[-(i + 1)][SelectColumn] == " ":
Board[-(i + 1)][SelectColumn] = player
break
turn *= -1 # 'swap' players
draw_board(Board)
# logic for checking winner would go here

How do I add a new line before appending(+=) my variable with another variable in python?

I am using Rasa X as my front end. I can't see how that would have anything to do with it, but I figured I will mention it just in case. Anyway, I have a variable that is collecting cell values from my excel sheet. I am using a loop statement add the values to my variable "requested_information". After the loop finishes, I add the string "\n" and my variable "missing_info" to it. When requested_information is printed, the new line is not in there. Here is the text result:
And here is my code:
for column in load_data.column_names:
project_name_cell = str(sheet["B{}".format(row)].value)
main_cell = str(sheet["" + column + "{}".format(row)].value)
if project_id_provided == False:
requested_information += "The " + load_data.column_names[column] + " for project " + project_name_cell + " is " + main_cell + ".\n"
else:
if main_cell == "n/a" or main_cell == None:
missing_info_list.append(load_data.column_names[column])
continue
if column == "E" or column == "G" or column == "I" or column == "J":
requested_information += "The " + load_data.column_names[column] + " is " + phone_formatter(main_cell) + ".\n"
elif column == "M" or column == "N" or column == "O" or column == "P":
requested_information += "The " + load_data.column_names[column] + " is " + "${:,.2f}".format(float(main_cell)) + ".\n"
elif column == "Q":
requested_information += "The " + load_data.column_names[column] + " is " + "{:.2%}".format(float(str(main_cell))) + ".\n"
elif column == "D" or column == "F" or column == "H":
if main_cell != None or main_cell == "":
if rasa_actions_settings.include_email_functions == False:
requested_information += ("The " + load_data.column_names[column] + " is " + main_cell + ".\n")
#else:
##NOTE - Uncomment procedures to enable personal emails being attached to the employees' contact info
#email = email_functions.GetEmailAddress(main_cell)
#firstName = main_cell.split(" ")
#requested_information += ("The " + load_data.column_names[column] + " is " + main_cell + " and " + firstName[0] + "'s email address is " + email + ".\n")
elif column == "R":
date = main_cell.split(" ")[0]
requested_information += "The " + load_data.column_names[column] + " is " + "{}/{}/{}".format(date[5:7], date[8:], date[0:4]) + ".\n"
else:
requested_information += "The " + load_data.column_names[column] + " is " + main_cell + ".\n"
project_id_provided = True
if len(missing_info_list) > 0:
missing_info += " There doesn't seem to be any information for the following catagories: \n"
first_item_used = False
for missing_catagory in missing_info_list:
if first_item_used == False:
first_item_used = True
missing_info += missing_catagory
else:
missing_info += ", " + missing_catagory
if len(missing_info_list) == 1:
missing_info = " There doesn't seem to be any information for the " + missing_info_list[0]
requested_information += "\n" + missing_info + "." #NOTE - HERE, THE STRINGS ARE COMBINED
dispatcher.utter_message(requested_information)

Is is possible to derive a Connect Four out of my Tic Tac Toe game?

I'm somewhat of a beginner and I'm wondering if I'd be able to derive a Connect Four game out of my existing Tic Tac Toe game. I somewhat understand the mechanics, but am stumped at how to expand the board to 7 (rows) x 6 (columns). I know that there won't be any use for rows, because a column would be fine because a piece drops to the bottom of a Connect Four game. Below is my Tic Tac Toe code.
"""
Author: Victor Xu
Date: Jan 12, 2021
Description: An implementation of the game Tic-Tac-Toe in Python,
using a nested list, and everything else we've learned this quadmester!
"""
import random
def winner(board):
"""This function accepts the Tic-Tac-Toe board as a parameter.
If there is no winner, the function will return the empty string "".
If the user has won, it will return 'X', and if the computer has
won it will return 'O'."""
# Check rows for winner
for row in range(3):
if (board[row][0] == board[row][1] == board[row][2]) and \
(board[row][0] != " "):
return board[row][0]
# COMPLETE THE REST OF THE FUNCTION CODE BELOW
for col in range(3):
if (board[0][col] == board[1][col] == board[2][col]) and \
(board[0][col] != " "):
return board[0][col]
# Check diagonal (top-left to bottom-right) for winner
if (board[0][0] == board[1][1] == board[2][2]) and \
(board[0][0] != " "):
return board[0][0]
# Check diagonal (bottom-left to top-right) for winner
if (board[0][2] == board[1][1] == board[2][0]) and \
(board[0][2] != " "):
return board[0][2]
# No winner: return the empty string
return ""
def display_board(board):
"""This function accepts the Tic-Tac-Toe board as a parameter.
It will print the Tic-Tac-Toe board grid (using ASCII characters)
and show the positions of any X's and O's. It also displays
the column and row numbers on top and beside the board to help
the user figure out the coordinates of their next move.
This function does not return anything."""
print(" 0 1 2")
print("0: " + board[0][0] + " | " + board[0][1] + " | " + board[0][2])
print(" ---+---+---")
print("1: " + board[1][0] + " | " + board[1][1] + " | " + board[1][2])
print(" ---+---+---")
print("2: " + board[2][0] + " | " + board[2][1] + " | " + board[2][2])
print()
def make_user_move(board):
"""This function accepts the Tic-Tac-Toe board as a parameter.
It will ask the user for a row and column. If the row and
column are each within the range of 0 and 2, and that square
is not already occupied, then it will place an 'X' in that square."""
valid_move = False
while not valid_move:
row = int(input("What row would you like to move to (0-2):"))
col = int(input("What col would you like to move to (0-2):"))
if (0 <= row <= 2) and (0 <= col <= 2) and (board[row][col] == " "):
board[row][col] = 'X'
valid_move = True
else:
print("Sorry, invalid square. Please try again!\n")
def make_computer_move(board):
"""This function accepts the Tic-Tac-Toe board as a parameter.
It will randomly pick row and column values between 0 and 2.
If that square is not already occupied it will place an 'O'
in that square. Otherwise, another random row and column
will be generated."""
computer_valid_move = False
while not computer_valid_move:
row = random.randint(0, 2)
col = random.randint(0, 2)
if (0 <= row <= 2) and (0 <= col <= 2) and (board[row][col] == " "):
board[row][col] = 'O'
computer_valid_move = True
def main():
"""Our Main Game Loop:"""
free_cells = 9
users_turn = True
ttt_board = [[" ", " ", " "], [" ", " ", " "], [" ", " ", " "]]
while not winner(ttt_board) and (free_cells > 0):
display_board(ttt_board)
if users_turn:
make_user_move(ttt_board)
users_turn = not users_turn
else:
make_computer_move(ttt_board)
users_turn = not users_turn
free_cells -= 1
display_board(ttt_board)
if (winner(ttt_board) == 'X'):
print("Y O U W O N !")
elif (winner(ttt_board) == 'O'):
print("I W O N !")
else:
print("S T A L E M A T E !")
print("\n*** GAME OVER ***\n")
# Start the game!
main()
Also, I'm unsure how to check for a winning combination (connecting 4 in a row) since the board has become much larger. In a 3 x 3 tic tac toe board, I could list out the diagonal coordinates and that would be it, but it's much more difficult with a board larger than 4 x 4. Any guidance would be appreciated!
EDIT
I've created a 7 x 6 board for my Connect Four game, but now I don't know how to verify if a column's space is empty because Connect Four pieces drop to the bottom. Below is my code:
"""
Author: Victor Xu
Date: Jan 12, 2021
Description: An implementation of the game Tic-Tac-Toe in Python,
using a nested list, and everything else we've learned this quadmester!
"""
import random
def winner(board):
"""This function accepts the Tic-Tac-Toe board as a parameter.
If there is no winner, the function will return the empty string "".
If the user has won, it will return 'X', and if the computer has
won it will return 'O'."""
# No winner: return the empty string
return ""
def display_board(board):
"""This function accepts the Tic-Tac-Toe board as a parameter.
It will print the Tic-Tac-Toe board grid (using ASCII characters)
and show the positions of any X's and O's. It also displays
the column and row numbers on top and beside the board to help
the user figure out the coordinates of their next move.
This function does not return anything."""
print(" 0 1 2 3 4 5 6")
print(" " + board[0][0] + " | " + board[0][1] + " | " + board[0][2] + " | " + board[0][3] + " | " + board[0][
4] + " | " + board[0][5] + " | " + board[0][6])
print(" ---+---+---+---+---+---+---")
print(" " + board[1][0] + " | " + board[1][1] + " | " + board[1][2] + " | " + board[1][3] + " | " + board[1][
4] + " | " + board[1][5] + " | " + board[1][6])
print(" ---+---+---+---+---+---+---")
print(" " + board[2][0] + " | " + board[2][1] + " | " + board[2][2] + " | " + board[2][3] + " | " + board[2][
4] + " | " + board[2][5] + " | " + board[2][6])
print(" ---+---+---+---+---+---+---")
print(" " + board[3][0] + " | " + board[3][1] + " | " + board[3][2] + " | " + board[3][3] + " | " + board[3][
4] + " | " + board[3][5] + " | " + board[3][6])
print(" ---+---+---+---+---+---+---")
print(" " + board[4][0] + " | " + board[4][1] + " | " + board[4][2] + " | " + board[4][3] + " | " + board[4][
4] + " | " + board[4][5] + " | " + board[4][6])
print(" ---+---+---+---+---+---+---")
print(" " + board[5][0] + " | " + board[5][1] + " | " + board[5][2] + " | " + board[5][3] + " | " + board[5][
4] + " | " + board[5][5] + " | " + board[5][6])
print(" ---+---+---+---+---+---+---")
print(" " + board[6][0] + " | " + board[6][1] + " | " + board[6][2] + " | " + board[6][3] + " | " + board[6][
4] + " | " + board[6][5] + " | " + board[6][6])
print()
def make_user_move(board):
"""This function accepts the Tic-Tac-Toe board as a parameter.
It will ask the user for a row and column. If the row and
column are each within the range of 0 and 2, and that square
is not already occupied, then it will place an 'X' in that square."""
valid_move = False
while not valid_move:
col = int(input("What col would you like to move to (0-6):"))
if (0 <= col <= 6) and (board[col] == " "):
board[col] = 'X'
valid_move = True
else:
print("Sorry, invalid square. Please try again!\n")
def make_computer_move(board):
"""This function accepts the Tic-Tac-Toe board as a parameter.
It will randomly pick row and column values between 0 and 2.
If that square is not already occupied it will place an 'O'
in that square. Otherwise, another random row and column
will be generated."""
computer_valid_move = False
while not computer_valid_move:
col = random.randint(0, 6)
if (0 <= col <= 6) and (board[col] == " "):
board[col] = 'O'
computer_valid_move = True
def main():
"""Our Main Game Loop:"""
free_cells = 42
users_turn = True
ttt_board = [[" ", " ", " ", " ", " ", " ", " "], [" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "], [" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "], [" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "]]
while not winner(ttt_board) and (free_cells > 0):
display_board(ttt_board)
if users_turn:
make_user_move(ttt_board)
users_turn = not users_turn
else:
make_computer_move(ttt_board)
users_turn = not users_turn
free_cells -= 1
display_board(ttt_board)
if (winner(ttt_board) == 'X'):
print("Y O U W O N !")
elif (winner(ttt_board) == 'O'):
print("I W O N !")
else:
print("S T A L E M A T E !")
print("\n*** GAME OVER ***\n")
# Start the game!
main()
Whenever I enter a column number, it says that it's not a valid square...
You're currently checking if the column is 'X'
board[col] = 'X'
But the column can't be a string - because it's a list.
You need to check what the highest element with the value of 'X'. Replace
if board[col][6] == 'X':
print("Sorry, that column is full. Please try again!\n")
else:
for row in range(6, 0, -1):
if board[col][row] == 'X':
board[col][row + 1] = 'X'
valid_move = True
if not valid_move:
board[col][0] = 'X'
valid_move = True
You'll learn far better ways to work with lists as you continue to learn programming but this should get you started for now!

Edit: Python - Going from 1 Player to Two Player Game Using Functions

I posted something similar earlier, but I did a horrible job of asking the right question.
I'm trying to code a two player connect four game, but can only manage a 1 player game, with the user playing against the computer. Can anyone help me with trying to write a 2 player approach to the game? I'm still quite a beginner and am still learning the ropes, so apologies if this is still not a good question and/or is too vague.
Here's my current code:
import random
def winner(board):
# Check rows
for row in range(6):
for col in range(3):
if (board[row][col] == board[row][col + 1] == board[row][col + 2] == board[row][col + 3]) and (board[row][col] != " "):
return board[row][col]
# Check columns
for col in range(6):
for row in range(3):
if (board[row][col] == board[row + 1][col] == board[row + 2][col] == board[row + 3][col]) and (board[row][col] != " "):
return board[row][col]
# Check diagonal A
for row in range(3):
for col in range(4):
if (board[row][col] == board[row + 1][col + 1] == board[row + 2][col + 2] == board[row + 3][col + 3]) and (board[row][col] != " "):
return board[row][col]
# Check diagonal B
for row in range(5, 2, -1):
for col in range(3):
if (board[row][col] == board[row - 1][col + 1] == board[row - 2][col + 2] == board[row - 3][col + 3]) and (board[row][col] != " "):
return board[row][col]
# Tie (just returns an empty string)
return ""
def printBoard(board):
# there are probably better ways to print a board, but I didn"t want to bother with another function, especially since the number of columns and rows are fixed in this game.
print (" 1 2 3 4 5 6 7")
print ("1: " + board[0][0] + " | " + board[0][1] + " | " + board[0][2] + " | " + board[0][3] + " | " + board[0][4] + " | " + board[0][5] + " | " + board[0][6] + " | " + board[0][7])
print (" ---+---+---+---+---+---+---")
print ("2: " + board[1][0] + " | " + board[1][1] + " | " + board[1][2] + " | " + board[1][3] + " | " + board[1][4] + " | " + board[1][5] + " | " + board [1][6] + " | " + board [1][7])
print (" ---+---+---+---+---+---+---+")
print ("3: " + board[2][0] + " | " + board[2][1] + " | " + board[2][2] + " | " + board[2][3] + " | " + board [2][4] + " | " + board [2][5] + " | " + board [2][6] + " | " + board [2][7])
print (" ---+---+---+---+---+---+---+")
print ("4: " + board[3][0] + " | " + board[3][1] + " | " + board[3][2] + " | " + board[3][3] + " | " + board [3][4] + " | " + board [3][5] + " | " + board [3][6] + " | " + board [3][7])
print (" ---+---+---+---+---+---+---+")
print ("5: " + board[4][0] + " | " + board[4][1] + " | " + board[4][2] + " | " + board[4][3] + " | " + board [4][4] + " | " + board [4][5] + " | " + board [4][6] + " | " + board [4][7])
print (" ---+---+---+---+---+---+---+")
print ("6: " + board[5][0] + " | " + board[5][1] + " | " + board[5][2] + " | " + board[5][3] + " | " + board [5][4] + " | " + board [5][5] + " | " + board [5][6] + " | " + board [5][7])
print
def playerMove(board):
validMove = False
while not validMove:
col = input("What column would you like to play? :")
for row in range (6,0,-1):
if (1 <= int(row) <= 6) and (1 <= int(col) <= 7) and (board[int(row)-1][int(col)-1] == " "):
board[int(row)-1][int(col)-1] = "X"
validMove = True
break
else:
print ("Invalid input. Please try again!\n")
def computerTurn(board):
validMove = False
while not validMove:
row = random.randint(0,5)
col = random.randint(0,6)
for row in range (5,0,-1):
if board[row][col] == " ":
board[row][col] = "O"
validMove = True
break
def game():
openCells = 42
playerTurn = True
count = 1
newBoard = [ [ " ", " ", " ", " ", " ", " "," ", " "], [ " ", " ", " ", " ", " "," ", " ", " "], [ " ", " ", " ", " ", " ", " ", " ", " "], [ " ", " ", " ", " ", " ", " ", " ", " "], [ " ", " ", " ", " ", " ", " ", " ", " "], [ " ", " ", " ", " ", " ", " ", " ", " "] ]
while not winner(newBoard) and (openCells > 0):
printBoard(newBoard)
if playerTurn:
playerMove(newBoard)
playerTurn = not playerTurn
else:
computerTurn(newBoard)
playerTurn = not playerTurn
openCells -= 1
printBoard(newBoard)
if (winner(newBoard) == "X"):
print ("You Won!")
print ("\nGAME OVER")
elif (winner(newBoard) == "O"):
print ("The Computer Won!")
print ("\nGAME OVER")
else:
print ("Tie!")
print ("\nGAME OVER \n")
EDIT:I modified my code so that I got rid of the computerTurn function and incorporated 2 user inputs in my playerMove function, however my game keeps looping back to player name inputs instead of alternating between turns.
Here's the new code (note that only the last couple functions were changed):
def playerMove(board):
turn = 0
players = []
numPlayers = 2
checkers = ['X','O']
for i in range(numPlayers):
players.append(input("Please enter player"+str(i+1)+" name: "))
validMove = False
while not validMove:
col = input(players[turn]+" what column would you like to play? :")
for row in range (6,0,-1):
if (1 <= int(row) <= 6) and (1 <= int(col) <= 7) and (board[int(row)-1][int(col)-1] == " "):
board[int(row)-1][int(col)-1] = "X"
validMove = True
break
else:
print ("Invalid input. Please try again!\n")
def game():
openCells = 42
playerTurn = True
turn = 0
players = []
numPlayers = 2
count = 1
newBoard = [ [ " ", " ", " ", " ", " ", " "," ", " "], [ " ", " ", " ", " ", " "," ", " ", " "], [ " ", " ", " ", " ", " ", " ", " ", " "], [ " ", " ", " ", " ", " ", " ", " ", " "], [ " ", " ", " ", " ", " ", " ", " ", " "], [ " ", " ", " ", " ", " ", " ", " ", " "] ]
while not winner(newBoard) and (openCells > 0):
printBoard(newBoard)
playerMove(newBoard)
playerTurn = not playerTurn
openCells -= 1
printBoard(newBoard)
if (winner(newBoard) == "X"):
print ("You Won!")
print ("GAME OVER")
elif (winner(newBoard) == "O"):
print ("The Computer Won!")
print ("GAME OVER")
else:
print ("Tie!")
print ("GAME OVER")
game()
I found a simpler way: I made a new function, playerMoveO, and renamed your old one playerMoveX. I made playerMoveO look like this:
def playerMoveO(board):
validMove = False
while not validMove:
col = input("You are the O player. What column would you like to play? :")
for row in range (6,0,-1):
if (1 <= int(row) <= 6) and (1 <= int(col) <= 7) and (board[int(row)-1][int(col)-1] == " "):
board[int(row)-1][int(col)-1] = "O"
validMove = True
break
else:
print ("Invalid input. Please try again!\n")
I also changed playerMoveX to look like this:
def playerMoveX(board):
validMove = False
while not validMove:
col = input("You are the X player. What column would you like to play? :")
for row in range (6,0,-1):
if (1 <= int(row) <= 6) and (1 <= int(col) <= 7) and (board[int(row)-1][int(col)-1] == " "):
board[int(row)-1][int(col)-1] = "X"
validMove = True
break
else:
print ("Invalid input. Please try again!\n")
Then, I changed the main loop, but I replaced the computerTurn function with playerMoveO. It works fine :D
EDIT
Obviously, there is a cleaner way. In this one, the playerMove function is passed the current symbol. So:
def playerMove(board, symbol):
validMove = False
while not validMove:
col = input("You are the {} player. What column would you like to play? :".format(symbol))
for row in range (6,0,-1):
if (1 <= int(row) <= 6) and (1 <= int(col) <= 7) and (board[int(row)-1][int(col)-1] == " "):
board[int(row)-1][int(col)-1] = symbol
validMove = True
break
else:
print ("Invalid input. Please try again!\n")
And in the main loop, there is a variable, currentSymbol, which is changed after each turn:
def game():
openCells = 42
playerTurn = True
count = 1
newBoard = [ [ " ", " ", " ", " ", " ", " "," ", " "], [ " ", " ", " ", " ", " "," ", " ", " "], [ " ", " ", " ", " ", " ", " ", " ", " "], [ " ", " ", " ", " ", " ", " ", " ", " "], [ " ", " ", " ", " ", " ", " ", " ", " "], [ " ", " ", " ", " ", " ", " ", " ", " "] ]
currentSymbol = "X"
while not winner(newBoard) and (openCells > 0):
printBoard(newBoard)
playerMove(newBoard, currentSymbol)
if currentSymbol == "X": currentSymbol = "O"
elif currentSymbol == "O": currentSymbol = "X"
openCells -= 1
printBoard(newBoard)
if (winner(newBoard) == "X"):
print ("X Won!")
print ("\nGAME OVER")
elif (winner(newBoard) == "O"):
print ("O Won!")
print ("\nGAME OVER")
else:
print ("Tie!")
print ("\nGAME OVER \n")

Categories