diff --git a/Connect Four/README.md b/Connect Four/README.md new file mode 100644 index 0000000..622a49d --- /dev/null +++ b/Connect Four/README.md @@ -0,0 +1,37 @@ +# Connect Four +I have created the board game, "Connect Four", using the programming language Python. The entire project was created all on one file. This was a project I chose to develop during my spare time as this was not a common project constructed by other developers. The program follows all rules of the game, where players can win by either having 4 in a row horizontally, vertically, or diagonally. The dimensions for this particular game is a 6x7 board. In other words, the board is designed as 6 rows and 7 columns. Therefore, I initialized a nested list called board that contains the 7 columns as elements, and the 6 rows within each element. + +``` +board = [["-"] * 6, ["-"] * 6, ["-"] * 6, ["-"] * 6, ["-"] * 6, ["-"] * 6, ["-"] * 6] +``` + + +Determining the logic for a player to have 4 in a row diagonally proved to be the most challenging in my opinion. The best solution was to view this as positive and negative slopes since these diagonals were +either from the bottom left to top right, or the top left to bottom right. Afterwards, I created two separate boards to determine all possible coordinates that can be starting points to create 4 in a row as shown +in the table below: + +Note: The coordinate is [col, row] + +### Positive Slope Possible Starting Points +| | | | | | | | +|------------|------------|------------|------------|------------|------------|------------| +| 1.1 | 2.1 | 3.1 | 4.1 | 5.1 | 6.1 | 7.1 | +| 1.2 | 2.2 | 3.2 | 4.2 | 5.2 | 6.2 | 7.2 | +| 1.3 | 2.3 | 3.3 | 4.3 | 5.3 | 6.3 | 7.3 | +| 1.4 | 2.4 | 3.4 | 4.4 | 5.4 | 6.4 | 7.4 | +| 1.5 | 2.5 | 3.5 | 4.5 | 5.5 | 6.5 | 7.5 | +| 1.6 | 2.6 | 3.6 | 4.6 | 5.6 | 6.6 | 7.6 | + + +### Negative Slope Possible Starting Points +| | | | | | | | +|------------|------------|------------|------------|------------|------------|------------| +| 1.1 | 2.1 | 3.1 | 4.1 | 5.1 | 6.1 | 7.1 | +| 1.2 | 2.2 | 3.2 | 4.2 | 5.2 | 6.2 | 7.2 | +| 1.3 | 2.3 | 3.3 | 4.3 | 5.3 | 6.3 | 7.3 | +| 1.4 | 2.4 | 3.4 | 4.4 | 5.4 | 6.4 | 7.4 | +| 1.5 | 2.5 | 3.5 | 4.5 | 5.5 | 6.5 | 7.5 | +| 1.6 | 2.6 | 3.6 | 4.6 | 5.6 | 6.6 | 7.6 | + +What I noticed is the positive slope starting points are from rows 4-6 and columns 1-4, while the negatiive slope starting points are from rows 1-3 and columns 1-4. Therefore, each type of slope has its own +function and nested for loop that iterates through only the possible starting points. \ No newline at end of file diff --git a/Connect Four/connectfour.py b/Connect Four/connectfour.py new file mode 100644 index 0000000..c5fd146 --- /dev/null +++ b/Connect Four/connectfour.py @@ -0,0 +1,242 @@ +import random + +board = [["-"] * 6, ["-"] * 6, ["-"] * 6, ["-"] * 6, ["-"] * 6, ["-"] * 6, ["-"] * 6] + + +def gamePlayTwoPlayers(p1, p2): + win = "" + while win == "": + column = int(input("{}'s turn. Enter which column you would like to drop your piece into: ".format(p1))) + connectFourBoard(column, "X") + + if check_vertical_win(p1, p2, column): + print() + print(check_vertical_win(p1, p2, column)) + break + if check_horizontal_win(p1, p2): + print() + print(check_horizontal_win(p1, p2)) + break + if check_positive_diagonal_win(p1, p2): + print() + print(check_positive_diagonal_win(p1, p2)) + break + if check_negative_diagonal_win(p1, p2): + print() + print(check_negative_diagonal_win(p1, p2)) + break + + column = int(input("{}'s turn. Enter which column you would like to drop your piece into: ".format(p2))) + connectFourBoard(column, "O") + + if check_vertical_win(p1, p2, column): + print() + print(check_vertical_win(p1, p2, column)) + break + if check_horizontal_win(p1, p2): + print() + print(check_horizontal_win("x", "O")) + break + if check_positive_diagonal_win(p1, p2): + print() + print(check_positive_diagonal_win(p1, p2)) + break + if check_negative_diagonal_win(p1, p2): + print() + print(check_negative_diagonal_win(p1, p2)) + break + + +def gamePlayOnePlayer(p1, p2): + win = "" + while win == "": + column = int(input("{}'s turn. Enter which column you would like to drop your piece into: ".format(p1))) + connectFourBoard(column, "X") + + if check_vertical_win(p1, p2, column): + print() + print(check_vertical_win(p1, p2, column)) + break + if check_horizontal_win(p1, p2): + print() + print(check_horizontal_win(p1, p2)) + break + if check_positive_diagonal_win(p1, p2): + print() + print(check_positive_diagonal_win(p1, p2)) + break + if check_negative_diagonal_win(p1, p2): + print() + print(check_negative_diagonal_win(p1, p2)) + break + + print() + + column = random.randint(1, 7) + connectFourBoard(column, "O") + + if check_vertical_win(p1, p2, column): + print() + print(check_vertical_win(p1, p2, column)) + break + if check_horizontal_win(p1, p2): + print() + print(check_horizontal_win(p1, p2)) + break + if check_positive_diagonal_win(p1, p2): + print() + print(check_positive_diagonal_win(p1, p2)) + break + if check_negative_diagonal_win(p1, p2): + print() + print(check_negative_diagonal_win(p1, p2)) + break + + +def connectFourBoard(col, playerIcon): + col -= 1 + coordinate = [] + + for row in range(len(board[col])-1, -1, -1): + if board[col][row] == "-": + board[col][row] = playerIcon + coordinate.append([row, col]) + break + for row in range(len(board)): + for col in range(len(board[row])): + print("|", board[row][col], "|", board[row+1][col], "|", board[row+2][col], "|", board[row+3][col], "|", + board[row+4][col], "|", board[row+5][col], "|", board[row+6][col], "|") + break + + +def check_vertical_win(p1, p2, col): + playerCount1 = 0 + playerCount2 = 0 + col -= 1 + + for row in range(len(board[col])-1, -1, -1): + if board[col][row] == "X": + playerCount1 += 1 + playerCount2 = 0 + elif board[col][row] == "O": + playerCount2 += 1 + playerCount1 = 0 + + if playerCount1 == 4: + return "{} Wins".format(p1) + elif playerCount2 == 4: + return "{} Wins".format(p2) + + +def check_horizontal_win(p1, p2): + for row in range(len(board[0])-1, -1, -1): + playerCount1 = 0 + playerCount2 = 0 + for col in range(len(board)): + if board[col][row] == "X": + playerCount1 += 1 + playerCount2 = 0 + elif board[col][row] == "O": + playerCount2 += 1 + playerCount1 = 0 + elif board[col][row] == "-": + playerCount1 = 0 + playerCount2 = 0 + + if playerCount1 == 4: + return "{} Wins".format(p1) + elif playerCount2 == 4: + return "{} Wins".format(p2) + + +def check_positive_diagonal_win(p1, p2): + playerCount1 = 0 + playerCount2 = 0 + + for row in range(len(board[0])-1, -1, -1): + for col in range(len(board)-3): + if board[col][row] == "X": + playerCount1 += 1 + while playerCount1 < 4: + col += 1 + row -= 1 + if board[col][row] == "X": + playerCount1 += 1 + else: + playerCount1 = 0 + break + elif board[col][row] == "O": + playerCount1 += 1 + while playerCount1 < 4: + col += 1 + row -= 1 + if board[col][row] == "O": + playerCount1 += 1 + else: + playerCount1 = 0 + break + + if playerCount1 == 4: + return "{} Wins".format(p1) + elif playerCount2 == 4: + return "{} Wins".format(p2) + else: + playerCount1 = 0 + playerCount2 = 0 + + +def check_negative_diagonal_win(p1, p2): + playerCount1 = 0 + playerCount2 = 0 + + for row in range(len(board[0])-3): + for col in range(len(board)-3): + if board[col][row] == "X": + playerCount1 += 1 + while playerCount1 < 4: + col += 1 + row -= 1 + if board[col][row] == "X": + playerCount1 += 1 + else: + playerCount1 = 0 + break + elif board[col][row] == "O": + playerCount1 += 1 + while playerCount1 < 4: + col += 1 + row += 1 + if board[col][row] == "O": + playerCount1 += 1 + else: + playerCount1 = 0 + break + + if playerCount1 == 4: + return "{} Wins".format(p1) + elif playerCount2 == 4: + return "{} Wins".format(p2) + else: + playerCount1 = 0 + playerCount2 = 0 + + +def main(): + print("Welcome to Connect Four! Connect 4 of your pieces in either horizontal, vertical, or diagonal to win.") + + numPlayers = int(input("Choose how many players: ")) + + while numPlayers not in [1,2]: + numPlayers = int(input("Sorry for the value you entered was invalid. Are you playing with 1 or 2 players: ")) + + if numPlayers == 1: + player1 = input("Player 1, please enter your name: ") + player2 = "CPU" + gamePlayTwoPlayers(player1, player2) + elif numPlayers == 2: + player1 = input("Player 1, please enter your name: ") + player2 = input("Player 2, please enter your name: ") + gamePlayTwoPlayers(player1, player2) + + +main() \ No newline at end of file diff --git a/README.md b/README.md index 007b2e8..d0fa783 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,9 @@ More information on contributing and the general code of conduct for discussion | Blackjack | [Blackjack](https://github.com/DhanushNehru/Python-Scripts/tree/master/Blackjack) | A game of Blackjack - let's get a 21. | | Chessboard | [Chessboard](https://github.com/DhanushNehru/Python-Scripts/tree/master/Chess%20Board) | Creates a chessboard using matplotlib. | | Compound Interest Calculator | [Compound Interest Calculator](https://github.com/DhanushNehru/Python-Scripts/tree/master/Calculate%20Compound%20Interest) | A Python script to calculate compound interest. | -| Countdown Timer | [Countdown Timer](https://github.com/DhanushNehru/Python-Scripts/tree/master/Countdown%20Timer) | Displays a message when the Input time elapses. | | Convert Temperature | [Convert Temperature](https://github.com/DhanushNehru/Python-Scripts/tree/master/Convert%20Temperature) | A python script to convert temperature between Fahreheit, Celsius and Kelvin | +| Connect Four | [Connect Four](https://github.com/DhanushNehru/Python-Scripts/tree/master/Connect%20Four) | A Python script for the board game Connect Four, which can be played by 1-2 players | +| Countdown Timer | [Countdown Timer](https://github.com/DhanushNehru/Python-Scripts/tree/master/Countdown%20Timer) | Displays a message when the Input time elapses. | | Crop Images | [Crop Images](https://github.com/DhanushNehru/Python-Scripts/tree/master/Crop%20Images) | A Python script to crop a given image. | | CSV to Excel | [CSV to Excel](https://github.com/DhanushNehru/Python-Scripts/tree/master/CSV%20to%20Excel) | A Python script to convert a CSV to an Excel file. | | Currency Script | [Currency Script](https://github.com/DhanushNehru/Python-Scripts/tree/master/Currency%20Script) | A Python script to convert the currency of one country to that of another. | @@ -110,7 +111,7 @@ More information on contributing and the general code of conduct for discussion | PDF to Audio | [PDF to Audio](https://github.com/DhanushNehru/Python-Scripts/tree/master/PDF%20to%20Audio) | Converts PDF to audio. | | PDF to Text | [PDF to text](https://github.com/DhanushNehru/Python-Scripts/tree/master/PDF%20to%20text) | Converts PDF to text. | | PDF merger and splitter | [PDF Merger and Splitter](https://github.com/AbhijitMotekar99/Python-Scripts/blob/master/PDF%20Merger%20and%20Splitter/PDF%20Merger%20and%20Splitter.py) | Create a tool that can merge multiple PDF files into one or split a single PDF into separate pages. | -| Pizza Order | [Pizza Order](https://github.com/DhanushNehru/Python-Scripts/tree/master/Pizza%20Order) | An algorithm designed to handle pizza orders from customers with accurate receipts and calculations. | +| Pizza Order | [Pizza Order](https://github.com/DhanushNehru/Python-Scripts/tree/master/Pizza%20Order) | An algorithm designed to handle pizza orders from customers with accurate receipts and calculations. | | Planet Simulation | [Planet Simulation](https://github.com/DhanushNehru/Python-Scripts/tree/master/Planet%20Simulation) | A simulation of several planets rotating around the sun. | | Playlist Exchange | [Playlist Exchange](https://github.com/DhanushNehru/Python-Scripts/tree/master/Playlist%20Exchange) | A Python script to exchange songs and playlists between Spotify and Python. | | Pigeonhole Sort | [Algorithm](https://github.com/DhanushNehru/Python-Scripts/tree/master/PigeonHole) | The pigeonhole sort algorithm to sort your arrays efficiently! |