# Reversegam: a clone of Othello/Reversi import random import sys WIDTH = 8 # Board is 8 spaces wide HEIGHT = 8 # Board is 8 spaces tall def drawBoard(board): # This function prints the board that it was passed. Returns None. print(' 12345678') print(' +--------+') for y in range(HEIGHT): print('%s|' % (y+1), end='') for x in range(WIDTH): print(board[x][y], end='') print('|%s' % (y+1)) print(' +--------+') print(' 12345678') def getNewBoard(): # Creates a brand-new, blank board data structure. board = [] for i in range(WIDTH): board.append([' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']) return board def isValidMove(board, tile, xstart, ystart): # Returns False if the player's move on space xstart, ystart is invalid. # If it is a valid move, returns a list of spaces that would become the player's if they made a move here. if board[xstart][ystart] != ' ' or not isOnBoard(xstart, ystart): return False if tile == 'Х': otherTile = 'О' else: otherTile = 'Х' tilesToFlip = [] for xdirection, ydirection in [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]]: x, y = xstart, ystart x += xdirection # First step in the x direction y += ydirection # First step in the y direction while isOnBoard(x, y) and board[x][y] == otherTile: # Keep moving in this x & y direction. x += xdirection y += ydirection if isOnBoard(x, y) and board[x][y] == tile: # There are pieces to flip over. Go in the reverse direction until we reach the original space, noting all the tiles along the way. while True: x -= xdirection y -= ydirection if x == xstart and y == ystart: break tilesToFlip.append([x, y]) if len(tilesToFlip) == 0: # If no tiles were flipped, this is not a valid move. return False return tilesToFlip def isOnBoard(x, y): # Returns True if the coordinates are located on the board. return x >= 0 and x <= WIDTH - 1 and y >= 0 and y <= HEIGHT - 1 def getBoardWithValidMoves(board, tile): # Returns a new board with periods marking the valid moves the player can make. boardCopy = getBoardCopy(board) for x, y in getValidMoves(boardCopy, tile): boardCopy[x][y] = '.' return boardCopy def getValidMoves(board, tile): # Returns a list of [x,y] lists of valid moves for the given player on the given board. validMoves = [] for x in range(WIDTH): for y in range(HEIGHT): if isValidMove(board, tile, x, y) != False: validMoves.append([x, y]) return validMoves def getScoreOfBoard(board): # Determine the score by counting the tiles. Returns a dictionary with keys 'X' and 'O'. xscore = 0 oscore = 0 for x in range(WIDTH): for y in range(HEIGHT): if board[x][y] == 'Х': xscore += 1 if board[x][y] == 'О': oscore += 1 return {'Х':xscore, 'О':oscore} def enterPlayerTile(): # Lets the player type which tile they want to be. # Returns a list with the player's tile as the first item and the computer's tile as the second. tile = '' while not (tile == 'Х' or tile == 'О'): print('Вы играете за Х или О?') tile = input().upper() # The first element in the list is the player's tile, and the second is the computer's tile. if tile == 'Х': return ['Х', 'О'] else: return ['О', 'Х'] def whoGoesFirst(): # Randomly choose who goes first. if random.randint(0, 1) == 0: return 'computer' else: return 'player' def makeMove(board, tile, xstart, ystart): # Place the tile on the board at xstart, ystart, and flip any of the opponent's pieces. # Returns False if this is an invalid move; True if it is valid. tilesToFlip = isValidMove(board, tile, xstart, ystart) if tilesToFlip == False: return False board[xstart][ystart] = tile for x, y in tilesToFlip: board[x][y] = tile return True def getBoardCopy(board): # Make a duplicate of the board list and return it. boardCopy = getNewBoard() for x in range(WIDTH): for y in range(HEIGHT): boardCopy[x][y] = board[x][y] return boardCopy def isOnCorner(x, y): # Returns True if the position is in one of the four corners. return (x == 0 or x == WIDTH - 1) and (y == 0 or y == HEIGHT - 1) def getPlayerMove(board, playerTile): # Let the player enter their move. # Returns the move as [x, y] (or returns the strings 'hints' or 'quit'). DIGITS1TO8 = '1 2 3 4 5 6 7 8'.split() while True: print('Укажите ход, текст "выход" для завершения игры или "подсказка" для вывода подсказки.') move = input().lower() if move == 'выход' or move == 'подсказка': return move if len(move) == 2 and move[0] in DIGITS1TO8 and move[1] in DIGITS1TO8: x = int(move[0]) - 1 y = int(move[1]) - 1 if isValidMove(board, playerTile, x, y) == False: continue else: break else: print('Это недопустимый ход. Введите номер столбца (1-8) и номер ряда (1-8).') print('К примеру, значение 81 перемещает в верхний правый угол.') return [x, y] def getComputerMove(board, computerTile): # Given a board and the computer's tile, determine where to # move and return that move as a [x, y] list. possibleMoves = getValidMoves(board, computerTile) random.shuffle(possibleMoves) # randomize the order of the moves # Always go for a corner if available. for x, y in possibleMoves: if isOnCorner(x, y): return [x, y] # Find the highest-scoring move possible. bestScore = -1 for x, y in possibleMoves: boardCopy = getBoardCopy(board) makeMove(boardCopy, computerTile, x, y) score = getScoreOfBoard(boardCopy)[computerTile] if score > bestScore: bestMove = [x, y] bestScore = score return bestMove def printScore(board, playerTile, computerTile): scores = getScoreOfBoard(board) print('Ваш счет: %s. Счет компьютера: %s.' % (scores[playerTile], scores[computerTile])) def playGame(playerTile, computerTile): showHints = False turn = whoGoesFirst() #print('The ' + turn + ' will go first.') # Clear the board and place starting pieces. board = getNewBoard() board[3][3] = 'Х' board[3][4] = 'О' board[4][3] = 'О' board[4][4] = 'Х' while True: playerValidMoves = getValidMoves(board, playerTile) computerValidMoves = getValidMoves(board, computerTile) if playerValidMoves == [] and computerValidMoves == []: return board # No one can move, so end the game. elif turn == 'player': # Player's turn if playerValidMoves != []: #if showHints: # validMovesBoard = getBoardWithValidMoves(board, playerTile) # drawBoard(validMovesBoard) #else: #drawBoard(board) #printScore(board, playerTile, computerTile) move = getComputerMove(board, playerTile) #if move == 'quit': # print('Thanks for playing!') # sys.exit() # Terminate the program. #elif move == 'hints': # showHints = not showHints # continue #else: makeMove(board, playerTile, move[0], move[1]) turn = 'computer' elif turn == 'computer': # Computer's turn if computerValidMoves != []: #drawBoard(board) #printScore(board, playerTile, computerTile) #input('Press Enter to see the computer\'s move.') move = getComputerMove(board, computerTile) makeMove(board, computerTile, move[0], move[1]) turn = 'player' NUM_GAMES = 250 xWins = oWins = ties = 0 print('Приветствуем в игре "Реверси"!') ans = input("Вам показывать процесс или нет? д/н ") if ans == "д": pokaz = True else: pokaz = False playerTile, computerTile = ['Х', 'О'] #enterPlayerTile() for i in range(NUM_GAMES): #while True: finalBoard = playGame(playerTile, computerTile) # Display the final score. #drawBoard(finalBoard) scores = getScoreOfBoard(finalBoard) if pokaz == True: print('X набрал %s очков. O набрал %s очков.' % (scores['Х'], scores['О'])) if scores[playerTile] > scores[computerTile]: xWins += 1 #print('You beat the computer by %s points! Congratulations!' % (scores[playerTile] - scores[computerTile])) elif scores[playerTile] < scores[computerTile]: oWins += 1 #print('You lost. The computer beat you by %s points.' % (scores[computerTile] - scores[playerTile])) else: ties += 1 #print('The game was a tie!') else: if scores[playerTile] > scores[computerTile]: xWins += 1 # print('You beat the computer by %s points! Congratulations!' % (scores[playerTile] - scores[computerTile])) elif scores[playerTile] < scores[computerTile]: oWins += 1 # print('You lost. The computer beat you by %s points.' % (scores[computerTile] - scores[playerTile])) else: ties += 1 # print('The game was a tie!') #print('Do you want to play again? (yes or no)') #if not input().lower().startswith('y'): # break print('X победил: %s (%s%%)' % (xWins, round(xWins / NUM_GAMES * 100, 1))) print('O победил: %s (%s%%)' % (oWins, round(oWins / NUM_GAMES * 100, 1))) print('Ничьи: %s (%s%%)' % (ties, round(ties / NUM_GAMES * 100, 1)))