0

2 players works fine but I can't debug the minimax algorithm, it just keeps going.. sorry that the code is messy

import random

board in nested list

board = [[' ',' ',' ',' ',' ',' ',' '],[' ',' ',' ',' ',' ',' ',' '],[' ',' ',' ',' ',' ',' ',' '], [' ',' ',' ',' ',' ',' ',' '],[' ',' ',' ',' ',' ',' ',' '],[' ',' ',' ',' ',' ',' ',' ']]

draws the board

def boarddraw(board): print("\t 1 2 3 4 5 6 7") print("\t+---+---+---+---+---+---+---+") print("\t| "+board[0][0]+" | "+board[0][1]+" | "+board[0][2]+" | "+board[0][3]+" | "+board[0][4]+" | "+board[0][5]+" | "+board[0][6]+" |") print("\t+---+---+---+---+---+---+---+") print("\t| "+board[1][0]+" | "+board[1][1]+" | "+board[1][2]+" | "+board[1][3]+" | "+board[1][4]+" | "+board[1][5]+" | "+board[1][6]+" |") print("\t+---+---+---+---+---+---+---+") print("\t| "+board[2][0]+" | "+board[2][1]+" | "+board[2][2]+" | "+board[2][3]+" | "+board[2][4]+" | "+board[2][5]+" | "+board[2][6]+" |") print("\t+---+---+---+---+---+---+---+") print("\t| "+board[3][0]+" | "+board[3][1]+" | "+board[3][2]+" | "+board[3][3]+" | "+board[3][4]+" | "+board[3][5]+" | "+board[3][6]+" |") print("\t+---+---+---+---+---+---+---+") print("\t| "+board[4][0]+" | "+board[4][1]+" | "+board[4][2]+" | "+board[4][3]+" | "+board[4][4]+" | "+board[4][5]+" | "+board[4][6]+" |") print("\t+---+---+---+---+---+---+---+") print("\t| "+board[5][0]+" | "+board[5][1]+" | "+board[5][2]+" | "+board[5][3]+" | "+board[5][4]+" | "+board[5][5]+" | "+board[5][6]+" |") print("\t+---+---+---+---+---+---+---+")

randomizer to determine who starts

def start(starter = ['p1','p2']): starter = random.choice(starter) return starter

player move

def pmove(valid = [1,2,3,4,5,6,7]): pmove = 0 while pmove not in valid: try: pmove = int(input(player+ ", please select which column you want to drop your piece("+piece+"): (1 - 7): ")) except ValueError: continue return pmove

runs several fuctions to check boardstate for wins for player

def checkwin(board): if winhorizontal(board): return True elif winvertical(board): return True elif windiagonala(board): return True elif windiagonalb(board): return True else: return False

runs checkwin functions and displays winner

def winner(): if checkwin(board): boarddraw(board) print("\n"+player+" won!!!") return True else: return False

checks if board is full, if so, the game is a draw

def free(board): if any(' ' in space for space in board): return True else: print("draw") return False

function to check which is the lowest row of the column that is free

def drop(pmove): i = 0 if board[i][pmove-1] != ' ': return False else: while board[i][pmove-1] == ' ': if i == 5: board[i][pmove-1] = piece return True i += 1 board[i-1][pmove-1] = piece return True

Horizontal check

def winhorizontal(board): for column in range(6): for row in range(4):

        if board[column][row] + board[column][row+1] + board[column][row+2] + board[column][row+3] == 4 * piece:
            return True
        else:
            continue

Vertical check

def winvertical(board):
for column in range(3): for row in range(7): if board[column][row] + board[column+1][row] + board[column+2][row] + board[column+3][row] == 4 * piece: return True else: continue

diagonal check a

def windiagonala(board):
for column in range(3): for row in range(4): if board[column][row] + board[column+1][row+1] + board[column+2][row+2] + board[column+3][row+3] == 4 * piece: return True else: continue

diagonal check b

def windiagonalb(board): for column in range(3,6): for row in range(4): if board[column][row] + board[column-1][row+1] + board[column-2][row+2] + board[column-3][row+3] == 4 * piece: return True else: continue

runs checkwin functions and displays winner

def winner1(): if checkwin1(board): print("won") return True else: return False

runs checkwin functions and displays winner

def winner2(): if checkwin2(board): print("lost") return True else: return False

def checkwin1(board): if winhorizontal1(board): return True elif winvertical1(board): return True elif windiagonala1(board): return True elif windiagonalb1(board): return True else: return False

def checkwin2(board): if winhorizontal2(board): return True elif winvertical2(board): return True elif windiagonala2(board): return True elif windiagonalb2(board): return True else: return False

Horizontal check AI1

def winhorizontal1(board): for column in range(6): for row in range(4):

        if board[column][row] + board[column][row+1] + board[column][row+2] + board[column][row+3] == 4 * dr:
            return True
        else:
            continue

Vertical check AI1

def winvertical1(board):
for column in range(3): for row in range(7): if board[column][row] + board[column+1][row] + board[column+2][row] + board[column+3][row] == 4 * dr: return True else: continue

diagonal check a AI1

def windiagonala1(board):
for column in range(3): for row in range(4): if board[column][row] + board[column+1][row+1] + board[column+2][row+2] + board[column+3][row+3] == 4 * dr: return True else: continue

diagonal check b AI1

def windiagonalb1(board): for column in range(3,6): for row in range(4): if board[column][row] + board[column-1][row+1] + board[column-2][row+2] + board[column-3][row+3] == 4 * dr: return True else: continue

Horizontal check AI2

def winhorizontal2(board): for column in range(6): for row in range(4):

        if board[column][row] + board[column][row+1] + board[column][row+2] + board[column][row+3] == 4 * pl:
            return True
        else:
            continue

Vertical check AI2

def winvertical2(board):
for column in range(3): for row in range(7): if board[column][row] + board[column+1][row] + board[column+2][row] + board[column+3][row] == 4 * pl: return True else: continue

diagonal check a AI2

def windiagonala2(board):
for column in range(3): for row in range(4): if board[column][row] + board[column+1][row+1] + board[column+2][row+2] + board[column+3][row+3] == 4 * pl: return True else: continue

diagonal check b AI2

def windiagonalb2(board): for column in range(3,6): for row in range(4): if board[column][row] + board[column-1][row+1] + board[column-2][row+2] + board[column-3][row+3] == 4 * pl: return True else: continue

def compmove(): bestscore = -10000
bestmove = 0
for move in range(7):
if board[0][move] == ' ':
j = 0 while board[j][move] == ' ': if j == 5: board[j][move] = dr score = deepretard(board, 0, False) board[j][move] = ' '
if score > bestscore:
bestscore = score bestmove = move return bestscore j += 1 board[j-1][move] = dr score = deepretard(board, 0, False) board[j-1][move] = ' ' if score > bestscore:
bestscore = score print(bestscore)
bestmove = move + 1

return bestmove

def deepretard(board, treedepth, max): if winner1():
return 1
elif winner2():
return -1
elif not free(board):
return 0
if max:
bestscore = -10000
for move in range(7):
if board[0][move] == ' ':
i = 0 while board[i][move] == ' ': if i == 5: board[i][move] = dr score = deepretard(board, treedepth + 1, False) board[i][move] = ' '
if score > bestscore:
bestscore = score return bestscore i += 1 board[i-1][move] = dr score = deepretard(board, treedepth + 1, False) board[i-1][move] = ' '
if score > bestscore:
bestscore = score
return bestscore else: bestscore = 10000
for move in range(7):
if board[0][move] == ' ':
i = 0 while board[i][move] == ' ': if i == 5: board[i][move] = pl score = deepretard(board, treedepth + 1, True) board[i][move] = ' '
if score < bestscore:
bestscore = score return bestscore i += 1 board[i-1][move] = pl score = deepretard(board, treedepth + 1, True) board[i-1][move] = ' '
if score < bestscore:
bestscore = score return bestscore

Game start

print(""" _________ __ _____
_ ___ \ ____ ____ ____ ____ _____/ |_ / | | / \ / / _ \ / \ / _/ __ _/ ___\ \ / | |_ \ _( <_> ) | \ | \ ___/\ ___| | / ^ / ______ /____/|___| /___| /___ >___ >| ____ | / / / / / || \t\t\t\t\t By Jeroen Penders """) print("Welcome to Connect 4 version 1.1\n") print("AI is coming soon, for now this is only a 2 player game, enjoy!\n") print("Enter 1 to play against DeepRetard AI") print("Enter 2 to play a 2 player game") playercount = int(input("Enter 1 or 2: ")) if playercount == 2: name1 = input("Player 1 please enter your name: ") name2 = input("Player 2 please enter your name: ") print("\nHello, "+name1+" and "+name2+"!\n" ) input("Please press enter to see who begins\n") starter = start() if starter == 'p1': player1 = name1 player2 = name2 print(name1+" begins!\n") input("Press enter to begin...") else: player2 = name1 player1 = name2 print(name2+" begins!\n") input("Press enter to begin...") while free(board): player = player1 piece = 'X' boarddraw(board) p1move = pmove() while not drop(p1move): boarddraw(board) print("Column is full...") p1move = pmove() if winner(): exit() player = player2 piece = 'O' boarddraw(board) p2move = pmove() while not drop(p2move): boarddraw(board) print("Column is full...") p2move = pmove() if winner(): exit()

# only displayed if board is full
boarddraw(board)
print(&quot;Board is full, it's a draw...&quot;)

else: name1 = input("Please enter your name: ") name2 = "DeepRetard" print("\nHello, "+name1+"! So you think you can defeat DeepRetard?") input("Press enter to see who begins") starter = start() if starter == 'p1': player1 = name1 player2 = name2 print(name1+" begins!\n") input("Press enter to begin...") piece = 'X' pl = 'X' dr = 'O' player = player1 boarddraw(board) p1move = pmove() while not drop(p1move): boarddraw(board) print("Column is full...") p1move = pmove() if not free(board): print("The game is a draw...") exit() if winner(): exit() player = player2 compm = compmove() p2move = pmove(compm) if winner(): exit()

else:
    player2 = name1
    player1 = name2
    print(name2+&quot; begins!\n&quot;)
    input(&quot;Press enter to begin...&quot;)
    dr = 'X'
    pl = 'O'
    player = player1
    boarddraw(board)
    compm = compmove()
    p2move = pmove(compm)
    while not drop(p1move):
        boarddraw(board)
        print(&quot;Column is full...&quot;)
        p1move = pmove()
    if not free(board):
        print(&quot;The game is a draw...&quot;)
        exit()
    if winner():
        exit()
    player = player2
    boarddraw(board)
    p1move = pmove()
    while not drop(p1move):
        boarddraw(board)
        print(&quot;Column is full...&quot;)
        p1move = pmove()
    if not free(board):
        print(&quot;The game is a draw...&quot;)
        exit()
    if winner():
        exit()
</code></pre>
Jerpen80
  • 1
  • 1
  • 1
    It looks to me like your algorithm is set to explore the game tree exhaustively, without ever falling back on a heuristic. So, checking all 7 possible moves, then all 7 possible replies to each of those, then all 7 possible replies to each of those... until there are no more legal moves to check. Since Connect 4 has something like 4.5 trillion game states, and your code has no memoization to avoid re-checking the equivalent states from multiple directions, you might not be in an "infinite" loop, just busy checking more possibilities than can be explored in a reasonable time frame. – DMGregory Jul 24 '21 at 12:07
  • Thank you for your quick reply! I will look into that! I'm just a beginner but making the minimax algorithm more efficient is definitely something I want to expore! – Jerpen80 Jul 24 '21 at 12:15
  • 1
    Try stopping at a tree depth of 4 or so, and see if that is enough that your algorithm terminates in a reasonable time. If so, then it's probably not an infinite loop, just biting off more computation than you can chew, and you can update your question to ask for help writing a fallback heuristic to handle cases beyond your exploration horizon. – DMGregory Jul 24 '21 at 12:40

0 Answers0