Создание списка допустимых ходов для компьютера в реверси (python)
Я относительно новичок в программировании, поэтому прошу прощения за отсутствие элегантного кода здесь. Программа стала немного запутанной, но я нахожусь в точке, где я хочу закончить ее и увидеть результат. Во всяком случае, в этой функции я пытаюсь создать список допустимых ходов для компьютера.
- доска - это список из 64 списков двух предметов, каждый из которых представляет место на доске реверси
- player - это фигура игрока, которая является либо "X", либо "O" (определено ранее в программе)
- компьютер является частью компьютера, которая является противоположностью
Первый шаг - собрать все места на доске, которые в настоящее время не заполнены (valid_list). Затем я пытаюсь пройтись по каждому из этих пятен, чтобы увидеть, является ли любое соседнее пятно частью игрока. Если это так, я хочу собрать все места так, чтобы в той же строке (или столбце) находился другой компьютерный фрагмент. Код, кажется, имеет смысл для меня, но дает неожиданные результаты. Мне просто интересно, если кто-нибудь может догадаться, что вызывает странные результаты (список valid_list1).
def comp_move(board, player, computer):
valid_list = []
for xcoord in range(8):
for ycoord in range(8):
if board[xcoord][ycoord] == ' ':
valid_list.append([xcoord, ycoord])
copy = getCopy(board)
num_list = [-1,0,1,-1,1,-1,0,1]
num_list2 = [-1,-1,-1,0,0,1,1,1]
for num in range(8):
for i in range(len(valid_list)):
xcoord_orig = valid_list[i][0]
ycoord_orig = valid_list[i][1]
xcoord1 = valid_list[i][0] + num_list[num]
ycoord1 = valid_list[i][1] + num_list2[num]
#test to see whether any of the surrounding spots are occupied by the player's piece
if 0 <= xcoord1 <= 7 and 0 <= ycoord1 <= 7:
piece = board[xcoord1][ycoord1]
if piece == player:
move_list = []
move_list1 = []
move_list2 = []
move_list3 = []
move_list4 = []
move_list5 = []
move_list6 = []
move_list7 = []
valid_list1 = []
#I changed the beginning of the range to 2 because we already know that the adjacent piece is the player's piece
#test spots above
for i in range(2,8):
#iterate through spots above the computer's spot.
#create a list of all the spots above the computer's spot
xcoordT = xcoord_orig
ycoordT = ycoord_orig - i
if 0 <= ycoordT <= 7:
if board[xcoordT][ycoordT] == computer:
move_list.append([xcoordT, ycoordT])
if move_list:
valid_list1.append([xcoord_orig, ycoord_orig])
#Test spots below
for i in range(2,8):
xcoordB = xcoord_orig
ycoordB = ycoord_orig + i
if 0 <= ycoordB <= 7:
if board[xcoordB][ycoordB] == computer:
move_list1.append([xcoordB, ycoordB])
if move_list1:
valid_list1.append([xcoord_orig, ycoord_orig])
#Test spots to the right
for i in range(2,8):
xcoordR = xcoord_orig + i
ycoordR = ycoord_orig
if 0 <= xcoordR <= 7:
if board[xcoordR][ycoordR] == computer:
move_list2.append([xcoordR, ycoordR])
if move_list2:
valid_list1.append([xcoord_orig, ycoord_orig])
#Test spots to the left
for i in range(2,8):
xcoordL = xcoord_orig - i
ycoordL = ycoord_orig
if 0 <= xcoordL <= 7:
if board[xcoordL][ycoordL] == computer:
move_list3.append([xcoordL, ycoordL])
if move_list3:
valid_list1.append([xcoord_orig, ycoord_orig])
#Test upper-right diagonal spots
for i in range(2,8):
xcoordTD = xcoord_orig + i
ycoordTD = ycoord_orig - i
if 0 <= xcoordTD <= 7 and 0 <= ycoordTD <= 7:
if board[xcoordTD][ycoordTD] == computer:
move_list4.append([xcoordTD, ycoordTD])
if move_list4:
valid_list1.append([xcoord_orig, ycoord_orig])
#Test lower-right diagonal spots
for i in range(2,8):
xcoordBD = xcoord_orig + i
ycoordBD = ycoord_orig + i
if 0 <= xcoordBD <= 7 and 0 <= ycoordBD <= 7:
if board[xcoordBD][ycoordBD] == computer:
move_list5.append([xcoordBD, ycoordBD])
if move_list5:
valid_list1.append([xcoord_orig, ycoord_orig])
#Test upper-left diagonal spots
for i in range(2,8):
xcoordTD1 = xcoord_orig - i
ycoordTD1 = ycoord_orig - i
if 0 <= xcoordTD1 <= 7 and 0 <= ycoordTD1 <= 7:
if board[xcoordTD1][ycoordTD1] == computer:
move_list6.append([xcoordTD1, ycoordTD1])
if move_list6:
valid_list1.append([xcoord_orig, ycoord_orig])
#Test lower-left diagal spots
for i in range(2,8):
xcoordBD1 = xcoord_orig - i
ycoordBD1 = ycoord_orig + i
if 0 <= xcoordBD1 <= 7 and 0 <= ycoordBD1 <= 7:
if board[xcoordBD1][ycoordBD1] == computer:
move_list7.append([xcoordBD1, ycoordBD1])
if move_list7:
valid_list1.append([xcoord_orig, ycoord_orig])
3 ответа
Мне нравится представлять доску Отелло в виде 10х10 с рядом пустых квадратов по краю. Тогда вместо того, чтобы использовать координаты x и y, вы представляете положение в виде единого значения P=Y*10+x, где x и y переходят от 0 до 9. Тогда ваши num_list и numlist2 становятся единым списком со значениями направления dir=[-11,-10,-9,-1,1,9,10,11], представляющие 8 направлений. Вы сканируете доску из положения p, глядя на доску [p+dir[d]* расстояние]. Теперь у Python нет массивов, и просмотр N-го элемента списка может оказаться не самым эффективным способом, но все, что вы делаете в 2D, становится проще в 1D. Кстати, так как вы всегда сканируете смежные или диагональные квадраты и смотрите, насколько следующий квадрат занят частью противника или вашим собственным, цикл естественным образом заканчивается на границе пустых квадратов, и у вас никогда не будет чтобы проверить, бежите ли вы от края доски. Это не решит вашу конкретную проблему реализации, но эту реализацию будет намного легче отлаживать:-)
Я не мог понять это из вашего вопроса, но из вашего кода похоже, что ваш valid_list1 будет заполнен списками, содержащими все те же значения (исходные координаты компьютера). Я не думаю, что это то, что вы хотите.
Если вы замените свой if move_listi:
заявления (где я - номер move_list) с valid_list1 += move_listi
Например:
# if move_list: -- REMOVE THESE LINES
# valid_list1.append([xcoord_orig, ycoord_orig])
valid_list1 += move_list
...
# if move_list1: -- REMOVE THESE LINES
# valid_list1.append([xcoord_orig, ycoord_orig])
valid_list1 += move_list1
...
# Repeat for move_list2 - move_list7
Опять же, я не совсем уверен, что это было то, что вы спрашивали. Если это не так, дайте мне знать. valid_list1 будет содержать список всех мест, где компьютер находится в зоне прямой видимости от исходного компьютера.
import numpy
def ai_player(board, scores, turn, valid_moves):
"""
Input:
board: numpy array of the disks for each player, e.g.
[[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 2, 0, 0, 0],
[0, 0, 0, 2, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]]
- 0 empty locations
- 1 player 1's disks
- 2 player 2's disks
scores: list of score values - [0, 0]
turn: integer turn counter (starts from 1)
valid_moves: numpy array of valid disk locations, represented in row
column combinations:
e.g [[3, 5], # row 3 - col 5
[5, 3], # row 5 - col 3
[4, 2], # etc.
[3, 4]]
Return:
disk loction index --> a numpy array or a list
--> a valid row - col combination to place a disk
--> location must be empty
--> location must have flanks
e.g. if valid_moves = [[3, 5], # row 3 - col 5
[5, 3], # row 5 - col 3
[4, 2], # etc.
[3, 4]]
and you want to place a disk at location row 4, col 2 then you
need to return [4, 2]
"""
как вы программируете это, зная, что у вас есть четыре входа, или если вы хотите, как вы программируете в другом, чтобы получить лучшие valid_moves .