Friday, November 15, 2013

Reversi (11.11.13 - 11.15.13)

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, end=' ')
        for x in range(8):
            print('|%s'(board[x][y]),end=' ')
            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[4][4]='O'
    board[4][3]='O'
    board[4][4]='O'
def getNewBoard():
    #Creates a new blank board data structure
    board=[]
    for i in range(8):
        board.append([' ']*8)
    return board
def isValidMove(board, title, 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 Flalse
    board[xstart][ystart]=title #temporarialy sets title on the board
    if title=='X':
        otherTitle='O'
    else:
        otherTitle='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]==otherTitle:
            #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]==otherTitle:
                x+=xdirection
                y+=ydirection
                if not isOnBoard(x, y):
                    break
            if not isOnBoard(x, y):
                continue
            if board[x][y]==title:
                #There are pieces to filp over. Go reverse direction till we reach orig space, noting tiles along the way
                whiel 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, title):
    #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, title):
    #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 enterPlayerTitle():
    #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=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 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
    ramdom.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.'%(score[playerTile], score[cmoputerTile]))
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

So this is my reverse program. It still has a lot of errors. Like, don't even try running it. I ought to have it fixed by next week sometime.

If you want to know how many errors are in the program, see picture at top.





EDIT:
Here, I felt real bad like about not actually finishing anything this week, so I made a program that prints out Fibonacci numbers.

#Fibonacci
import time
fib=1
n=0
temp=0
#def nextNum():
#    print('Do you want to go the the next number in teh sequence? (y or n) '),
#    return raw_input().lower().startswith('y')
while True:
    n=fib+temp
    print n
    temp=fib
    fib=n
    #time.sleep(.01)

If you actually want to see any of the numbers, change #time.sleep(.01) to time.sleep(.5)


No comments:

Post a Comment