0

I've just completed a Connect Four game and now I'm wondering how I can keep the board in one place without having it refresh over and over again in the console. I've searched far and wide on the web for any solutions but couldn't find anything.

Below is my full code. Feel free to run it on your IDEs. Any help would be greatly appreciated!

import random
import ast


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'."""
    row = 0
    while row <= len(board) - 1:
        count = 0
        last = ''
        col = 0
        while col <= len(board[0]) - 1:
            row_win = board[row][col]
            if row_win == " ":
                count = 0
                col += 1
                continue
            if row_win == last:
                count += 1
            else:
                count = 1
            if count >= 4:
                return row_win
            last = row_win
            col += 1
        row += 1
    col = 0
    while col <= len(board[0]) - 1:
        count = 0
        last = ''
        row = 0
        while row <= len(board) - 1:
            col_win = board[row][col]
            if col_win == " ":
                count = 0
                row += 1
                continue
            if col_win == last:
                count += 1
            else:
                count = 1
            if count >= 4:
                return col_win
            last = col_win
            row += 1
        col += 1
    row = 0
    while row <= len(board) - 1:
        col = 0
        while col <= len(board[0]) - 1:
            try:
                if (board[row][col] == board[row + 1][col + 1] and board[row + 1][col + 1] == board[row + 2][
                    col + 2] and
                    board[row + 2][col + 2] == board[row + 3][col + 3]) and (
                        board[row][col] != " " or board[row + 1][col + 1] != " " or board[row + 2][col + 2] != " " or
                        board[row + 3][col + 3] != " "):
                    return board[row][col]
            except:
                IndexError
            col += 1
        row += 1
    row = 0
    while row <= len(board) - 1:
        col = 0
        while col <= len(board[0]) - 1:
            try:
                if (board[row][col] == board[row + 1][col - 1] and board[row + 1][col - 1] == board[row + 2][
                    col - 2] and
                    board[row + 2][col - 2] == board[row + 3][col - 3]) and (
                        board[row][col] != " " or board[row + 1][col - 1] != " " or board[row + 2][col - 2] != " " or
                        board[row + 3][col - 3] != " "):
                    return board[row][col]
            except:
                IndexError
            col += 1
        row += 1
    # 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."""
    header = "  "
    i = 1
    while i < len(board[0]):
        header = header + str(i) + "   "
        i += 1
    header = header + str(i)

    print(header)
    separator = "+---+"
    i = 1
    while i < len(board[0]):
        separator = separator + "---+"
        i += 1
    print(separator)

    for row in board:
        print(" ", " | ".join(row))
        separator = "+---+"
        i = 1
        while i < len(board[0]):
            separator = separator + "---+"
            i += 1
        print(separator)

    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 1 and 7, 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_num = "What col would you like to move to (1 - " + str(len(board[0])) + ")? "
            col = int(input(col_num))
            if board[0][col - 1] != ' ':
                print("Sorry, that column is full. Please try again!\n")
            else:
                col = col - 1
                for row in range(len(board) - 1, -1, -1):
                    if board[row][col] == ' ' and not valid_move:
                        board[row][col] = 'X'
                        valid_move = True
        except:
            ValueError
            print("Please enter a valid option! ")

    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, len(board) - 1)
        if board[0][col] != ' ':
            print("Sorry, that column is full. Please try again!\n")
        else:
            for row in range(len(board) - 1, -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:"""

    cf_board = []
    row = int(input("How many rows do you want your game to have? "))
    col = int(input("How many columns do you want your game to have? "))
    move_order = input("Would you like to move first? (y/n) ")
    while move_order.lower() != "y" and move_order.lower() != "n":
        print("Invalid input! Please choose y (yes) or n (no) - case insensitive. ")
        move_order = input("Would you like to move first? (y/n) ")
    if move_order.lower() == "y":
        users_turn = True
    elif move_order.lower() == "n":
        users_turn = False
    free_cells = col * row
    row_str = "\" \""
    board_str = "\" \""
    i = 0
    j = 0

    while i < col - 1:
        row_str = row_str + "," + "\" \""
        i += 1

    board_list = [row_str]
    while j < row - 1:
        board_list.append(row_str)
        j += 1

    cf_board = [list(ast.literal_eval(x)) for x in board_list]
    # for i in range(row-1):
    #     cf_board.append(row_str)

    while not winner(cf_board) and (free_cells > 0):
        display_board(cf_board)
        if users_turn:
            cf_board = make_user_move(cf_board)
            users_turn = not users_turn
        else:
            cf_board = make_computer_move(cf_board)
            users_turn = not users_turn
        free_cells -= 1

    display_board(cf_board)
    if (winner(cf_board) == 'X'):
        print("Y O U   W O N !")
    elif (winner(cf_board) == 'O'):
        print("T H E   C O M P U T E R   W O N !")
    elif free_cells == 0:
        print("S T A L E M A T E !")
    print("\n*** GAME OVER ***\n")


# Start the game!
main()
Vix
  • 192
  • 9
  • I don't understand your question. What do you use to create this board? Always put code as text, not link to external portal. – furas Jan 24 '21 at 19:18
  • @furas Just changed it! – Vix Jan 24 '21 at 19:20
  • 1
    some consoles may have special codes to move cursor, draw colors, etc. and then you can change only some places in console and keep rest of board without redrawing. But not all consoles then have these special codes. You may try find these codes in internet and use it in `print()` or try to use module like [curses](https://docs.python.org/3/howto/curses.html) which uses these codes. – furas Jan 24 '21 at 19:20
  • see also [urwind](http://urwid.org/examples/index.html) – furas Jan 24 '21 at 19:25

1 Answers1

1

I guess the idea you want to implement is similar to make a terminal based progress bar;

For example on unix/linux systems you can update a progress bar or a simple sentence in one place with "\r" character instead of "\n" which used on print() function by default:

from sys import stdout
from time import sleep


def realtime_sentence():
    name = 0
    while name <= 100:
        stdout.write("\r My name is {}".format(name))
        name += 1
        sleep(0.2)


def realtime_progress_bar():
    progress = 0
    while progress <= 100:
        stdout.write("\r Progress: {} {}%".format(progress*"#", progress))
        progress += 1
        sleep(0.2)


realtime_sentence()
realtime_progress_bar()

Also check this question:

  1. Rewrite multiple lines in the console
DRPK
  • 2,023
  • 1
  • 14
  • 27