No7Ex Q
No7Ex Q

Reputation: 25

Python: Trying to program a variant of connect four: Winning condition doesn't stop

I have been trying to program a variant of connect four for my programming class. The board is 6x8 in size. In the variant I'm trying to program, the winning condition is to essentially build an L.

This means any construction of the form
X
X
X X
is a winning condition.
I have been trying to make a function that checks every single column for the same symbol consecutively to build a pair. And a function to do the same for every row. With these two functions I would then check if 2 pairs are consecutive, because no matter how you combine a vertical and horizontal pair, it will always build an 'L'.

To make a clear board I'm using

def ClearBoardSingle():
    global Board
    Board = [['0' for i in range(8)] for i in range(6)]
    BoardPrint()
    PlayerMoveSingle()

And for my interface I'm using

def BoardPrint():
    global Board
    global GameMoves
    global PlayerTurn
    global Player1Symbol
    global Player2Symbol
    print('\n\nMoves done: ' + str(GameMoves))
    print('To Restart: R | To Quit: Q')
    print('Valid choices: 1, 2, 3, 4, 5, 6, 7, 8')
    if PlayerTurn == 0:
        print('It\'s ' +str(Player1Symbol) + '\'s Turn')
    if PlayerTurn == 1:
        print('It\'s ' +str(Player2Symbol) + '\'s Turn')
    print(Board[0])
    print(Board[1])
    print(Board[2])
    print(Board[3])
    print(Board[4])
    print(Board[5])

I already figured out how to change Variables inside the Board, and I'm pretty much done. The only thing I don't know how to implement is the winning condition. I tried this function for the Rows:

def VerticalList(Column):
    global Board
    global Choice
    global Row0
    Column = int(Column)
    Choice = int(Choice)
    print(Column,' C')
    while Column > 0:
        for Board[Column][Choice] in range(Column):
            Row0.append(Board[Column][Choice])
            if Column ==6 or Column == -1:
                break
            else:
                VerticalList(Column-1)
        if Column ==0:
            break
        else:
            continue
    if Column == 0:
        Column += 1
        while Column < 5:
            Column +=1
            if Row0[Column] == Row0[Column-1]:
                print('Pair')
            else:
                print('No Pair')
                pass
    else:
        pass

But it enters an endless Loop.
I have no ideas anymore on how to implement the winning condition. I'd appreciate any kind of help or ideas. If you want me to post the whole code or other kinds of snippets, ask for them.

Thank you in anticipation!

Upvotes: 2

Views: 766

Answers (1)

mitoRibo
mitoRibo

Reputation: 4548

Cool problem, below looks like a lot of code, but it's not really. I haven't checked this extensively, so I'm not confident that it doesn't find false positives, but it seems to find L's that it should be finding. The main thing I did was use itertools.combinations to take all 4-sized groups of the positions of X's and then check if they looked like patterns I was expecting for L's. In check_four_group I look at the differences within the row and columns.

from itertools import combinations
def disp_board(board): 
    for row in board: 
        print(row)

def check_winning(board): 
    winning = False 

    #Find all row,col positions of the X's
    x_poses = [(i,j) for i in range(6) for j in range(8) if board[i][j] == 'X'] 

    #Loop through every combination of four X's since it takes four to make the 'L'
    for group in combinations(x_poses,4):
        if(check_four_group(group)): 
            winning = True 
            break 
    return winning

def check_four_group(group): 
    rows,cols = zip(*[(r,c) for r,c in group]) 
    row_diffs = [rows[i+1]-rows[i] for i in range(len(rows)-1)] 
    col_diffs = [cols[i+1]-cols[i] for i in range(len(cols)-1)] 

    #Uncomment this to print the row and col diffs
    #print(row_diffs) 
    #print(col_diffs)

    # Finds:
    #  X
    #  X
    #  X X
    if row_diffs == [1,1,0] and col_diffs == [0,0,1]:
        return True

    # Finds:
    #    X
    #    X
    #  X X
    elif row_diffs == [1,1,0] and col_diffs == [0,-1,1]:
        return True

    # Finds:
    #  X X
    #    X
    #    X
    elif row_diffs == [0,1,1] and col_diffs == [1,0,0]:
        return True

    # Finds:
    #  X X
    #  X
    #  X
    elif row_diffs == [0,1,1] and col_diffs == [1,-1,0]:
        return True

    # Otherwise it's not there at all (not thinking about horizontal L's but could add that)
    else:
        return False

#Test case 1
def test_case_1():
    board = [['0' for i in range(8)] for i in range(6)] 
    board[2][1] = 'X' 
    board[2][2] = 'X' 
    board[3][1] = 'X' 
    board[4][1] = 'X' 
    return board

#Test case 2
def test_case_2():
    board = [['0' for i in range(8)] for i in range(6)] 
    board[2][1] = 'X' 
    board[2][0] = 'X' 
    board[3][1] = 'X' 
    board[4][1] = 'X' 
    return board

#Test case 3
def test_case_3():
    board = [['0' for i in range(8)] for i in range(6)] 
    board[1][0] = 'X' 
    board[2][0] = 'X' 
    board[3][0] = 'X' 
    board[3][1] = 'X' 
    return board

#Test case 4
def test_case_4():
    board = [['0' for i in range(8)] for i in range(6)] 
    board[1][2] = 'X' 
    board[2][2] = 'X' 
    board[3][2] = 'X' 
    board[3][1] = 'X'
    return board

##################
#Start of program#
##################
board = test_case_1()
#board = test_case_2()
#board = test_case_3()
#board = test_case_4()

disp_board(board)
if check_winning(board): 
    print('Victory')
else: 
    print('Keep playing')

Upvotes: 1

Related Questions