import random
import sys
def drawBoard(board):
#prints the board that it was passed. returns none
HLINE=' +---+---+---+---+---+---+---+---+'
VLINE=' | | | | | | | | |'
print(' 1 2 3 4 5 6 7 8')
print(HLINE)
for y in range(8):
print(VLINE)
print(y+1),
for x in range(8):
print('| %s'%(board[x][y])),
print('|')
print(VLINE)
print(HLINE)
def resetBoard(board):
#Blanks out the board it is passed, except for th eoriginal starting position
for x in range(8):
for y in range(8):
board[x][y]=' '
#Starting pieces:
board[3][3]='X'
board[3][4]='O'
board[4][3]='O'
board[4][4]='X'
def getNewBoard():
#Creates a new blank board data structure
board=[]
for i in range(8):
board.append([' ']*8)
return board
def isValidMove(board, tile, xstart, ystart):
#returns false if the player's move on space xstart, ystart is invalid
#If it's valid, returns a list of spaces that would become players' if they made a move here.
if board[xstart][ystart]!=' ' or not isOnBoard(xstart, ystart):
return False
board[xstart][ystart]=tile #temporarialy sets tile on the board
if tile=='X':
otherTile='O'
else:
otherTile='X'
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 direction
y+=ydirection #first step in the direction
if isOnBoard(x, y) and board[x][y]==otherTile:
#There si a piece belonging to the other player next to our piece
x+=xdirection
y+=ydirection
if not isOnBoard(x, y):
continue
while board[x][y]==otherTile:
x+=xdirection
y+=ydirection
if not isOnBoard(x, y):
break
if not isOnBoard(x, y):
continue
if board[x][y]==tile:
#There are pieces to filp over. Go reverse direction till we reach orig space, noting tiles along the way
while True:
x-=xdirection
y-=ydirection
if x==xstart and y==ystart:
break
tilesToFlip.append([x, y])
board[xstart][ystart]=''#restore the empty space
if len(tilesToFlip)==0: #if no tiles were flipped, not a valid move
return False
return tilesToFlip
def isOnBoard(x, y):
#Retursn True if the coordinates are located on the board
return x>=0 and x<=7 and y>=0 and y<=7
def getBoardWithValidMoves(board, tile):
#Returns a new board with . marking teh valid moves the given player can make
dupeBoard=getBoardCopy(board)
for x, y in getValidMoves(dupeBoard, tile):
dupeBoard[x][y]='.'
return dupeBoard
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(8):
for y in range(8):
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 dict with keys 'X' and 'O'
xscore=0
oscore=0
for x in range(8):
for y in range(8):
if board[x][y]=='X':
xscore+=1
if board[x][y]=='O':
oscore+=1
return {'X':xscore, 'O':oscore}
def enterPlayerTile():
#Lets the player type which tile they wanna be
#Return a list with the player's tile as the first item, and teh computer's tile as the second
tile=''
while not (tile=='X' or tile=='O'):
print('Do you want to be X or O?'),
tile=raw_input().upper()
#the first element in the tuple is the player's tile, the second is the computer's
if tile=='X':
return ['X', 'O']
else:
return ['O', 'X']
def whoGoesFirst():
#randomly chooses the player who goes first
if random.randint(0, 1)==0:
return 'computer'
else:
return 'player'
def playAgain():
print('Do you want to play again?')
return raw_input().lower().startswith('y')
def makeMove(board, tile, xstart, ystart):
#Place tile on teh board at xstart, ystart, and flip any of the opponent's pieces
#Returns False if this is an invalid move, true if it's 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 the duplicate
dupeBoard=getNewBoard()
for x in range(8):
for y in range(8):
dupeBoard[x][y]=board[x][y]
return dupeBoard
def isOnCorner(x, y):
#Returns true if pos is in one of the corners
return (x==0 and y==0) or (x==7 and y==0) or (x==0 and y==7) or (x==y and y==7)
def getPlayerMove(board, playerTile):
#Let teh player type their move
#returns teh move as [x, y] (or returns strings 'hints' or 'quit'
DIGITS1TO8='1 2 3 4 5 6 7 8'.split()
while True:
print('Enter your move, or type quit to end the game, or hints to turn on/off hints.')
move=raw_input().lower()
if move=='quit':
return 'quit'
if move=='hints':
return 'hints'
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('That is not a valid move. Type the x digit (1-8), then the y digit (1-8).')
print('For example, 81 will be the top-right corner.')
return [x, y]
def getComputerMove(board, computerTile):
#Given a board and the computer's tile, determine where to move and return that move as an [x, y] list.
possibleMoves=getValidMoves(board, computerTile)
#Randomize the order of the possible moves
random.shuffle(possibleMoves)
#Always go for a corner if available
for x, y in possibleMoves:
if isOnCorner(x, y):
return [x, y]
#Go through all the possible moves and remember the best scoring move
bestScore=-1
for x, y in possibleMoves:
dupeBoard=getBoardCopy(board)
makeMove(dupeBoard, computerTile, x, y)
score=getScoreOfBoard(dupeBoard)[computerTile]
if score>bestScore:
bestMove=[x, y]
bestScore=score
return bestMove
def showPoints(playerTile, computerTile):
#Prints out the current score.
scores=getScoreOfBoard(mainBoard)
print('You have %s points. The cmoputer has %s points.'%(scores[playerTile], scores[computerTile]))
print('Welcome to Reversi!')
while True:
#Retet board and game
mainBoard=getNewBoard()
resetBoard(mainBoard)
playerTile, computerTile=enterPlayerTile()
showHints=False
turn=whoGoesFirst()
print('The '+turn+' will go first.')
while True:
if turn=='player':
#Player's turn
if showHints:
validMovesBoard=getBoardWithValidMoves(mainBoard, playerTile)
drawBoard(validMovesBoard)
else:
drawBoard(mainBoard)
showPoints(playerTile, computerTile)
move=getPlayerMove(mainBoard, playerTile)
if move=='quit':
print('Thanks for playing!')
sys.exit() #Terminate program
elif move=='hints':
showHints=not showHints
continue
else:
makeMove(mainBoard, playerTile, move[0], move[1])
if getValidMoves(mainBoard, computerTile)==[]:
break
else:
turn='computer'
else:
#computer's turn
drawBoard(mainBoard)
showPoints(playerTile, computerTile)
raw_input('Press Enter to see the computer\'s move.')
x, y=getComputerMove(mainBoard, computerTile)
makeMove(mainBoard, computerTile, x, y)
if getValidMoves(mainBoard, playerTile)==[]:
break
else:
turn='player'
#Display the final score
drawBoard(mainBoard)
scores=getScoreOfBoard(mainBoard)
print('X scored %s points. Y scored %s points.'%(scores['X'], scores['O']))
if scores[playerTile]>scores[computerTile]:
print('You won by %s points!' %(scores[playerTile]-scores[computerTile]))
elif scores[playerTile]<scores[computerTile]:
print('You lost by %s points.' %(scores[computerTile]-scores[playerTile]))
else:
print('The game was a tie!')
if not playAgain():
break

No comments:
Post a Comment