Python -Othello - Bugs with Legal Move and Flipping all pieces

Tom Varghese
Tom Varghese used Ask the Experts™
on
I am designing the game Othello or Reversegram as it is known in some places. I'm almost done coding the game save for tallying up the final score and tweaking the AI to make more intelligent moves (currently only doing random moves). However, I am encountering certain bugs that appear. While the CPU and I keep flipping the pieces, there will come some point where I either cannot make a move even though it is certainly legal to do so. As well as the fact that when I play certain moves usually around the edges, it sometimes won't flip the opposing pieces even though I just made a legal move. If I can get some help understanding where I should be making my edits--I think the error might be in the "findLegal" function. Thank you for your help!

Note: I recreated the board with W on 6b, and B on 7b and 8a and could make the legal move of W on 8b so vertical moves are generally accepted and work up until a certain point which I'm confused about. In addition, I originally set up the board in the picture with random pieces throughout to accelerate the game and also to test out the various issues I had (so please ignore the random W on 4h).
othello.py
Screen-Shot-2018-12-18-at-10.52.37-P.png
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
nociSoftware Engineer
Distinguished Expert 2018

Commented:
You are missing the vertical moves... 7f is also missing.
4h could never have been a legal move, so how could that be selected?
nociSoftware Engineer
Distinguished Expert 2018

Commented:
Slightly different approach... and it generates valid moves....
(Code converted from an ancient Assembler version i wrote).
This aproach is fairly linear, if you want to know more about optimal strategy in generating moves...
This is the naive one (starting upper left, to bottom right), better would be to do important fields first and less important ones later.
Claude Shannon has written a book on game theory which also tackles this one.


#!/usr/bin/python3

'''
Othello is a 2-player strategy game revolving around capturing as many pieces as possible
at the conclusion of the game. Each player chooses either black or white as their color.
To capture a piece, black (white) must flip the opponent's rival color piece to turn it White
(Black). To flip a piece, the player must place his piece around the opponent's piece
so it is in the middle of their own pieces. For example, if the board shows "BW" then black
can play a piece next to W so it becomes "BWB" and so the W is flipped to become "BBB".

For more information on game rules, please refer to http://www.ultraboardgames.com/othello/game-rules.php
'''
import random
import sys
import copy
from time import sleep


'''
Board layout is 8x8 for efficient search....
10x10, border value = 3, empty = 0, 1 = black, 2 = white 
As only linear arrays are needed it will be mapped to a 100 element data array.
'''
FREE=0
WHITE=1
BLACK=2
BORDER=3
nextpos = [-10, -9 , 1, 11, 10, 9, -1, -11]    # next board pos in linear... clockwise, first = up... = -10, 
board = []
for i in range(100):
    board.append(0)
def clear_board(board):
    for col in range(10):
        for row in range(10):
            if row==0 or row==9 or col==0 or col == 9:
                board[row*10+col] = BORDER
            else:
                board[row*10+col] = FREE;

def set_board(board,row,col,val):
    board[10*row+col] = val

def flip_board(board,row,col):
    board[10*row+col] = 3 - board[10*row+col]

def setup_board(board):
    clear_board(board)
    set_board(board,4,4,WHITE)
    set_board(board,4,5,WHITE)
    set_board(board,5,4,BLACK)
    set_board(board,5,5,BLACK)

mark = ['.','W','B','#']
colmark=[' ','a','b','c','d','e','f','g','h',' ']
def print_board(board):
    str=""
    for row in range(10):
        str = str + "%d "%row
        for col in range(10):
            str = str + mark[board[10*row+col]]+" "
        str = str + "\n"
    str = str + "  "
    for col in range(10):
        str = str + colmark[col] + " "
    str = str + "\n\n"
    print(str)

def gen_moves(board, player):   # Naive...
    moves=[]
    opponent=3-player
    for field in range(11,89):
        if board[field] == FREE:
            for direction in range(8):
                start = field+nextpos[direction]
                if board[start] == opponent:
                    while board[start] == opponent:
                        start = start+nextpos[direction]
                    if board[start] == player:
                        moves.append(field)                 # found a valid move
                        break                                           # no need to look further, next field
    return moves;

def print_moves(moves):
    print ("moves: ")
    for m in moves:
        print("%d %c" % ( m/10, colmark[m % 10]))
    print("\n")


setup_board(board)
print_board(board)
print("WHITE:\n")
moves = gen_moves(board,WHITE)
print_moves(moves)
print("\nBLACK:\n")
moves = gen_moves(board,BLACK)
print_moves(moves)

exit

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial