Link to home
Start Free TrialLog in
Avatar of Tom Varghese
Tom Varghese

asked on

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

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
Avatar of noci
noci

You are missing the vertical moves... 7f is also missing.
4h could never have been a legal move, so how could that be selected?
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

This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.