Open essepuntato opened 3 years ago
I don't really understand how to teach the machine to get the best solution. Nevertheless, my function return randomly one of the possibile position near to the opposite colour. The logic is to close the enemy stone.
import random
def place_stone(colour, black, white):
if colour == "black":
place = random.choice(possible_move("black", black, white))
return place
elif colour == "white":
place = random.choice(possible_move("white", black, white))
return place
def possible_move(colour, black, white): # check the free position near the opposite color
if colour == "black":
movement_list = []
for position in white:
list_single_move = single_stone(position, black, white)
movement_list.extend(list_single_move)
return movement_list
elif colour == "white":
movement_list = []
for position in black:
list_single_move = single_stone(position, black, white)
movement_list.extend(list_single_move)
return movement_list
def single_stone(position, black, white): # check the free position near the stone and return a list of free position
list_movement = []
if (position[0] - 1, position[1]) not in black and (position[0] - 1, position[1]) not in white and position[0] - 1 <= 6:
list_movement.append((position[0] - 1, position[1]))
if (position[0] + 1, position[1]) not in black and (position[0] + 1, position[1]) not in white and position[0] + 1 <= 6:
list_movement.append((position[0] + 1, position[1]))
if (position[0], position[1] - 1) not in black and (position[0], position[1] - 1) not in white and position[1] - 1 <= 6:
list_movement.append((position[0], position[1] - 1))
if (position[0], position[1] + 1) not in black and (position[0], position[1] + 1) not in white and position[1] + 1 <= 6:
list_movement.append((position[0], position[1] + 1))
return list_movement
print(place_stone("white", {(1, 5), (1, 4), (2, 6)}, {(2, 5), (2, 4)}))
This function classifies all the free points on the board in these categories:
Then, to select the right move to return, it privileges:
Not a great strategy, but a lot of thoughts about liberties and groups and others and what is better to pursue.
def place_stone(color,black,white):
if len(black & white)==0: # Check that black and white sets don't have common elements
range_x=range(7) # Maximum number of columns
range_y=range(7) # Maximum number of rows
occupied=black.union(white) # Defines a set with all the occupied cells regardless of the color
expanding=list() # Prepares the list of moves that expand the liberties
limiting=list() # Prepares the list of moves that limit opponent's liberties
others=list() # Prepres the list of all other positions
# Gets rid of the black/white dialectics and switches to current/opponent
if color=="white":
current=white
opponent=black
else:
current=black
opponent=white
# Cycles all the positions of the board:
for x in range_x:
for y in range_y:
if ((x,y) not in occupied): # if position is empty
if check_neighbors(x,y,opponent): # if position limits opponent liberties
limiting.append((x,y))
if check_neighbors(x,y,current): # if position expands current color liberties
expanding.append((x,y))
if ((x,y) not in limiting) and ((x,y) not in expanding): # if position has no neighbor stones
others.append((x,y))
bestpos=set(limiting) & set(expanding) # Finds the positons limiting the opponent and expanding the current group
if len(bestpos)>0:
return(list(bestpos)[0]) # Returns the first result that expand your liberty and limits the opponent
if len(limiting)>0:
return(limiting[0]) # Else returns the first result that limits the opponent
if len(expanding)>0:
return expanding[0] # Else returns the first result that expands your liberties
if len(others)>0:
return (others[0]) # Else returns the first free position
return "No position available" # Else no move can be done
else:
return "Each point admits only one stone!"
# This ancillary function only returns if x,y position is adjacent to something in checking set
def check_neighbors(x,y,checking):
return ((x-1,y) in checking) or ((x+1,y) in checking) or ((x,y-1) in checking) or ((x,y+1) in checking)
# TEST CASES
color="white"
black={(2,2),(2,3),(2,4),(2,5)}
white={(2,1),(3,2),(3,3)}
print (place_stone(color,black,white)) # Answers (3,4)
color="black"
black={(4,3),(4,4),(4,5),(5,3),(5,5),(6,3),(6,5)}
white={(5,4)}
print (place_stone(color,black,white)) # Answers (6,4)... My boy!
color="black"
black={(4,3),(4,4),(4,5),(5,3),(5,5),(6,3),(6,5)}
white={(4,3)}
print (place_stone(color,black,white)) # Returns an error
Implement the function below in Python, that takes in input the colour of the player who has to play the turn (parameter colour), the sets of coordinates (i.e. sets of tuples) of all the black stones (parameter black) and white stones (parameter white) already positioned on the board, and returns the x, y coordinate (a tuple) of a free intersection where to place a new colour stone. The coordinates of the various positions of the board are those ones defined in "the board" as in the AlphaGo material available online.
Additional information is available at https://doi.org/10.5281/zenodo.2204836.