Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 11, 2017 11:13:45

Geo166
Зарегистрирован: 2017-01-11
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

Крестики-нолики.

Что-то не так с ф-ей possible_moves. Как сделать ее рабочей?вернее,чтобы работала она корректно,потому что на данный момент программа заполняет все позиции ноликами после хода пользователя.

 import os
import sys  
import time
WIN=10
LOSE=-10
def score(grid):
    if is_go(grid, 'O'):   #who wins if end
        return WIN, 'O'
    elif is_go(grid, 'X'):
        return LOSE, 'X'
    else:
        return 0, 0
def minimax(grid, depth, maximize):
    sc, choice = score(grid)
    if depth == 0 or sc == WIN or sc == LOSE:
        return sc, grid
    if maximize:
        best = LOSE
        moves = possible_moves(grid, 'O')
        for i in moves:
            v, move = minimax(i, depth-1, False)
            if v > best-1:
                br = i
                best = v
        return best, br
    else:
        best = WIN
        moves = possible_moves(grid, 'X')
        for i in moves:
            v, move = minimax(i, depth-1, True)
            if v <= best:
                br = i
                best = v
        return best, br                                 #best end and best brunch
def is_go(grid, value):
    if  grid[0][0] == value and \
        grid[0][1] == value and \
        grid[0][2] == value:
        return True
    if grid[1][0] == value and \
       grid[1][1] == value and \
       grid[1][2] == value:
        return True
    if grid[2][0] == value and \
       grid[2][1] == value and \
       grid[2][2] == value:
        return True
    if grid[0][0] == value and \
       grid[1][0] == value and \
       grid[2][0] == value:
        return True
    if grid[0][1] == value and \
       grid[1][1] == value and \
       grid[2][1] == value:
        return True
    if grid[0][2] == value and \
       grid[1][2] == value and \
       grid[2][2] == value:
        return True
    if grid[0][0] == value and \
       grid[1][1] == value and \
       grid[2][2] == valuee:
        return True
    if grid[0][2] == value and \
       grid[1][1] == value and \
       grid[2][0] == value:
        return True
    return False
def possible_moves(grid, value):
    list_of_moves = []
    for row in range(3):
        for col in range(3):
            if grid[row][col] == '-':
                grid[row][col] = value
                list_of_moves.append(grid)
    return list_of_moves
def next_m(grid):
    sc, game = minimax(grid, 2, True)
    if (game == None):
        final(sc, [])	  
    sc, value = score(grid)
    return sc, 'xx'
def final(sc, grid):
    if grid == []:
        print ('drawn')    
    elif sc == LOSE:
        print ('You win')   
    elif sc == WIN:
        print ('You lose')
       
   
def print_board(grid):
    for rows in grid:
        for cols in rows:
            print (cols)
        print ("\n")
def choice(grid):
    for x in range(3):
        for y in range(3):
            x=int(input())
            y=int(input())
            return x,y
            
def inst():
    print ("Players choice is X and my choice is O")
    time.sleep(1)
def init(grid):
    for r in range(3):
        for c in range(3):
            grid[r][c] = '-'
def main():
    grid = [['-','-','-'],['-','-','-'],['-','-','-']]
    inst()
    while True:
        print_board(grid)
        print ("(row, column)\n")
        row,col = choice(grid)
        if grid[row][col] != '-':
            print ("Choice filled")
            continue
        grid[row][col] = 'X'
        sc, value = score(grid)
        final(sc, grid)
        
        sc, value = next_m(grid)
        final(sc, grid)
if __name__ == "__main__":
    main()

Отредактировано Geo166 (Янв. 11, 2017 11:14:11)

Офлайн

#2 Янв. 11, 2017 13:56:43

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Крестики-нолики.

потому что он делает ровно то что вы ему говорите. давайте разберем ваш код

 def possible_moves(grid, value):
    list_of_moves = []
    for row in range(3):  
        for col in range(3):  # тут понятно вложеный цикл строки и колоки
            if grid[row][col] == '-':  # если ячейка грида не заполнена
                grid[row][col] = value # заполнить ячейку нулем
                list_of_moves.append(grid) # добавляем в ваш список ваш грид....
    return list_of_moves 


ЗЫ в def choice(grid): циклы явно лишние или я чегто не понимаю
достаточно вот так:
 def choice(grid):
        x=int(input())
        y=int(input())
        return x,y



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Янв. 11, 2017 14:18:29)

Офлайн

#3 Янв. 11, 2017 14:14:25

Geo166
Зарегистрирован: 2017-01-11
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

Крестики-нолики.

в том то и дело… ну тут явно надо что-то менять либо в minimax,либо в той самой ф-ции,но вот что именно.. не понимаю.Все варианты испробованы были уже.

Офлайн

#4 Янв. 11, 2017 14:42:32

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Крестики-нолики.

Geo166
Вы методом тыка программируете что ли? Вы написали функцию, вы же знаете что она должна делать? Что принимать и что возвращать? Расскажите нам об этом, и вам помогут.



Офлайн

#5 Янв. 11, 2017 14:47:08

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Крестики-нолики.

проблема в том что вы работаете с одниим глобальным списком grid и любые операции с этим списокм например ваше grid = value изменяют ваш глобальный список. Почитайте на досуге о пространсте имен http://pythoner.name/documentation/tutorial/classes/namespaces
и о том как рабтаю переменные и в частности списки
Для начала в функции вам не нужно работать с глобальным списком

 def possible_moves(grid, value):
    import copy
    list_of_moves = []
    grid2 = copy.deepcopy(grid)
    for row in range(3):
        for col in range(3):
            if grid[row][col] == '-':
                grid2[row][col] = value
                list_of_moves.append(copy.deepcopy(grid2))
    return list_of_moves
теперь ваша функция не модифицирует глобальный grid.Импорт можно вынести в начало скрипта
Хотя ХЗ как оно на самом деле должно у вас работать, написал чисто из того как у вас было написано только чтобы не затрагивало глобальный грид.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Янв. 11, 2017 14:52:45)

Офлайн

#6 Янв. 11, 2017 15:16:13

Geo166
Зарегистрирован: 2017-01-11
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

Крестики-нолики.

а я разве говорил,что не знаю?я лишгь сказал,что не знаю,как исправить. и все.
та ф-я возвращает список возможных ходов сначала для 0
потом для Х
а вот уже потом в minimax
он выбирает,какой ход лучше сделать из этого списка.

Отредактировано Geo166 (Янв. 11, 2017 15:18:45)

Офлайн

#7 Янв. 11, 2017 15:18:33

Geo166
Зарегистрирован: 2017-01-11
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

Крестики-нолики.

я делал с копией. Там программа тоже работала некорректно (вводил row и col и ничего не менялось,выводилась снова пустая сетка)

Офлайн

#8 Янв. 11, 2017 16:00:33

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Крестики-нолики.

М-да… честно сказать, вам бы пересмотреть ваш алгоритм целиком, там не только проблемы с possible_moves. И комментарии какиенить написать, какая функция что делает, что принимает что возвращает и нахрена это вообще нужно, тогда будет проще разбираться в вашем коде…
Подозреваю что ваша проблема в том что вы сами запутались в своем же коде.
В первом приближении както вот так вроде все более-менее работает, крестики-нолики ставяться, на выигрыш-проигрыш проверяется.

 import os
import sys
import time
import copy
WIN=10
LOSE=-10
def score(grid):
    if is_go(grid, 'O'):   #who wins if end
        return WIN, 'O'
    elif is_go(grid, 'X'):
        return LOSE, 'X'
    else:
        return 0, 0
def minimax(grid, depth, maximize):
    sc, choice = score(grid)
    if depth == 0 or sc == WIN or sc == LOSE:
        return sc, grid
    if maximize:
        best = LOSE
        moves = possible_moves(grid, 'O')
        for i in moves:
            v, move = minimax(i, depth-1, False)
            if v > best-1:
                br = i
                best = v
        return best, br
    else:
        best = WIN
        moves = possible_moves(grid, 'X')
        for i in moves:
            v, move = minimax(i, depth-1, True)
            if v <= best:
                br = i
                best = v
        return best, br                                 #best end and best brunch
def is_go(grid, value):
    if  grid[0][0] == value and \
        grid[0][1] == value and \
        grid[0][2] == value:
        return True
    if grid[1][0] == value and \
       grid[1][1] == value and \
       grid[1][2] == value:
        return True
    if grid[2][0] == value and \
       grid[2][1] == value and \
       grid[2][2] == value:
        return True
    if grid[0][0] == value and \
       grid[1][0] == value and \
       grid[2][0] == value:
        return True
    if grid[0][1] == value and \
       grid[1][1] == value and \
       grid[2][1] == value:
        return True
    if grid[0][2] == value and \
       grid[1][2] == value and \
       grid[2][2] == value:
        return True
    if grid[0][0] == value and \
       grid[1][1] == value and \
       grid[2][2] == value:
        return True
    if grid[0][2] == value and \
       grid[1][1] == value and \
       grid[2][0] == value:
        return True
    return False
def possible_moves(grid, value):
    list_of_moves = []
    #grid2 = copy.deepcopy(grid)
    for row in range(3):
        for col in range(3):
            grid2 = copy.deepcopy(grid)
            if grid[row][col] == '-':
                grid2[row][col] = value
                list_of_moves.append(copy.deepcopy(grid2))
    print('listOfMoves',list_of_moves)
    return list_of_moves
def next_m(grid):
    sc, game = minimax(grid, 2, True)
    if (game == None):
        final(sc, [])
    sc, value = score(game)
    return sc, 'xx', game
def final(sc, grid):
    if grid == []:
        print ('drawn')
    elif sc == LOSE:
        print ('You win')
    elif sc == WIN:
        print ('You lose')
def print_board(grid):
    for rows in grid:
        print (rows)
def choice():
    x=int(input('Enter row'))
    y=int(input('Enter column'))
    return x,y
def inst():
    print ("Players choice is X and my choice is O")
    time.sleep(1)
def init(grid):
    for r in range(3):
        for c in range(3):
            grid[r][c] = '-'
def main():
    grid = [['-','-','-'],['-','-','-'],['-','-','-']]
    inst()
    while True:
        print_board(grid)
        print ("(row, column)\n")
        row,col = choice() # вводим "координаты" Х
        if grid[row][col] != '-':
            print ("Choice filled")
            continue
        grid[row][col] = 'X'
        sc, value = score(grid)
        final(sc, grid) # проверяем условия выиграша
        sc, value, grid = next_m(grid) #Ход ИИ
        final(sc, grid) # проверяем условия выиграша
if __name__ == "__main__":
    main()
только чем вам это поможет, свои ошибки вы так и не поняли.
ЗЫ и не бойтесь отладки, даже банальный print(variable) может существенно прояснить ситуацию.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Янв. 11, 2017 16:55:00)

Офлайн

#9 Янв. 11, 2017 17:37:10

Geo166
Зарегистрирован: 2017-01-11
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

Крестики-нолики.

нет,я в принципе понял,что я изменяю,грубо говоря,исходную сетку…чего делать не нужно. Так?нужно работать с копией.В любом случае,большое спасибо,все работает.

Офлайн

#10 Янв. 11, 2017 18:18:42

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Крестики-нолики.

Не только, + у вас после(в) next_m собственно “базовый” grid никак не изменялся, я добавил “костыль” как мог. Заменил

 return sc, 'xx'
на
return sc, 'xx', game
и соответсвенно
 sc, value = next_m(grid)
заменил на
 sc, value, grid = next_m(grid)



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version