0
0 комментариев
import numpy as np
import random
from operator import itemgetter
 
board = np.array([['_', '_', '_'],
                  ['_', '_', '_'],
                  ['_', '_', '_']], dtype=str)
 
SIGN = {0: 'X', 1: 'O'}
 
MATRIX = np.array([[0,1,2],
                  [3,4,5],
                  [6,7,8]])
 
def board_print(board):
    """Эта функция отображает поле с заполнеными клетками"""
 
    print('--------------')
    print('| {} | {} | {} |'.format(board[0,0], board[0,1], board[0,2]))
    print('| {} | {} | {} |'.format(board[1,0], board[1,1], board[1,2]))
    print('| {} | {} | {} |'.format(board[2,0], board[2,1], board[2,2]))
    print('--------------')
 
def choice_sign():
    """Выбор крестика или нолика"""
    sign = input("""Выберите свой знак:
                0 - крестик,
                1 - нолик)\n""")
    user_sign = SIGN[int(sign)]
    comp_sign = SIGN[0] if int(sign) == 1 else SIGN[1]
 
    return user_sign, comp_sign
 
def choice_step():
    """Выбор первого хода, 0 - человек, 1 -компьютер"""
    step = random.randint(0,1)
    if step == 0:
        print('Поздравляю, Вы ходите первым!')
        return True
    else:
        print('Первым выпал шанс ходить компьютеру')
        return False
 
def choice_cell(board):
    """Выбирает клетку для хода"""
    board_print(board)
    print('Выберите строку и столбец, где будет стоять ваш знак')
    while True:
        cell = input("""Вам нужно ввести два числа. Первое - строка, второе - столбец:
                      1 - первая строка или столбец
                      2 - вторая строка или столбце
                      3 - третья строка или столбец
                      будьте внимательны, ячейки могут быть заняты
                    \n""")
        if len(cell) != 2:
            print('Введите не одно, а два числа')
            continue
        # в pythone нумерация начинается с 0
        row = int(cell[0]) - 1
        column = int(cell[1]) - 1
 
        if row in range(0, 3) and \
                column in range(0,3) and \
                board[row, column] == '_':
            break
        else:
            print('Неверно выбрана ячейка проверьте внимательно')
    return row, column
 
 
 
class GameState:
    def __init__(self, board, comp_sign, user_sign):
        self.board = board
        self.comp_sign = comp_sign
        self.user_sign = user_sign
        self.winning_combos = [((0,0), (0,1), (0,2)), ((1,0), (1,1), (1,2)), #(0,1,2) (3,4,5)
                              ((2,0), (2,1), (2,2)), ((0,0), (1,0), (2,0)), #(6,7,8) (0,3,6)
                                ((0,1), (1,1), (2,1)), ((0,2), (1,2), (2,2)), #(1,4,7) (2,5,8)
                              ((0,0), (1,1), (2,2)), ((0,2), (1,1), (2,0))]   #(0,4,8) (2,4,6)
 
    def get_winner(self):
        '''Возвращает None если игра всё ещё продолжается, иначе оценка с точки зрения компьютера (1=победа, 0=ничья, -1=проигрыщ)'''
        if np.count_nonzero(self.board == '_') == 0: #если не осталось пустых полей
            return 0
        for combo in self.winning_combos:
            if (self.board[combo[0]] == self.comp_sign and
                self.board[combo[1]] == self.comp_sign and
                self.board[combo[2]] == self.comp_sign):
                return 1
            if (self.board[combo[0]] == self.user_sign and
                self.board[combo[1]] == self.user_sign and
                self.board[combo[2]] == self.user_sign):
                return 1
        return None
 
    def get_possible_moves(self):
        '''Возвращает все возможные ячейки для размещения символов'''
        return [index for index, square in np.ndenumerate(self.board) if square == '_']
 
    def get_next_state(self, move, our_turn):
        '''Возвращает состояние игры после заполнения ячейки'''
        copy_array = np.copy(self.board)
        copy_array[move] = self.comp_sign if our_turn else self.user_sign
        return GameState(copy_array, self.comp_sign, self.user_sign)
 
def play(game_state, our_turn):
    '''Если игра закончена, возвращает (None, score), в противном случае рекурсивно находит лучший ход и возвращает его и счёт'''
    score = game_state.get_winner() # может быть None, 0, 1, -1
    if score != None:
        return None, score
    moves = ((move,
              play(game_state.get_next_state(move, our_turn), not our_turn)[1])
             for move in game_state.get_possible_moves())
    return (max if our_turn else min)(moves, key=itemgetter(1))
 
def main():
    print('Начинаем игру')
    user_sign, comp_sign = choice_sign() #игрок выбирает знак
 
    start_game_state = GameState(board, comp_sign, user_sign)
 
    if choice_step():
        # игрок выбирает куда поставить знак
        # choice_cell возвращает кортеж, а сам принимает текущую доску
        start_game_state.board[choice_cell(start_game_state.board)] = user_sign
 
    board_print(start_game_state.board)
    # Ищет лучший ход и очки
    move, score = play(start_game_state, True)
 
    start_game_state.board[move] = comp_sign
 
    while score != 1 or score != 0:
        if score == 0:
            word = 'TIE'
        elif score == 1:
            word = 'WIN'
        else:
            word = 'LOSS, who rigged the board?!?'
        print('X should go at index #', move, 'Which will always result in a ' + word)
        start_game_state.board[choice_cell(start_game_state.board)] = user_sign
        move, score = play(start_game_state, True)
        print('SCORE',score)
        #if score == -1:
            #break
        start_game_state.board[move] = comp_sign
    board_print(start_game_state.board)
 
 
 
main()

Здравствуйте, подскажите пожалуйста, как доработать игру крестики-нолики, а то у меня после последнего крестика всё поле вдруг становится ноликами ((


Добавить комментарий