오델로, 리버시, Reversi게임
- # Reversi game
- # 리버시 게임 오델로 라고도 한다.
- # 가로8, 세로8로 도하 64개의 게임판 위에 흰색과 검은색 돌을 번갈아 놓는게임
- # 게임종료 후 판 위에 내 돌이 더 많이 있으면 승리하게 됨
- # 두 플레이어 모두 더 이상 상대방의 막대를 뒤집을 수 없을때 게임이 종료됨
- # 상대의 수를 먼저 읽는것이 유리한 바둑과 유사한 2인용 게임
- # 게임판 위의 네 모서리를 먼저 장악하는것이 승리요소임
- # 돌을 두었을 때, 상하좌우 혹은 대각선 방향으로 같은 색의 돌이 있으면,
- # 그 사이에 있는 상대방의 돌이 모두 자신의 돌로 바뀐다.
- # drawBoard(board) : 넘겨받은 보드를 출력한다.
- # resetBoard(board) : 넘겨 받은 보드를 시작 위치를 제외하고 리셋한다.
- # getNewBoard() : 비어있는 새 board 데이터 구조를 만든다.
- # isValidMove(board,tile,xstart,ystart) : 플레이어가 놓인 위치가 적절한 위치가 아니면 False를 반혼다.
- # 만약 적절한 위치면 플레이어가 놓은 위치에 따라 플레이어의 타일이 된 영역을 모두 리스트로 만들어 반환한다.
- # isOnBoard(x,y) : 보드에 좌표가 위치하면 True를 반환
- # getBoardWithValidMoves(board,tile) : 플레이어가 놓을 수 잇는 유효 위치에 '.'를 표시해 board를 반환한다.
- # getScoreOfBoard(board) : 타일을 세서 점수를 계산한다. 'X','O'로 된 딕셔너리를 반환한다.
- # enterPlayerTile() : 플레이어가 어떤 타일로 게임을 할 것인지 선택하도록 한다.
- # whoGoesFirst() : 누가 먼저 플레이할 것인지 임의로 정한다.
- # playAgain() : 플레이어가 재게임 진행 시 True반환, 아니면 False
- # makeMove(board,tile,xstart,ystart) : 보드에 xstart,ystart 위치에 타일을 놓고 상대편의 타일을 뒤집는다.
- # getBoardCopy(board) : 보드의 복사본을 만들어 복사본 반환
- # isonCorner(x,y) : 4개의 코너 중 하나이면 True반환
- # getPlayerMove(board,playerTile) : 플레이어에게 위치를 입력하여 [x,y]를 반환
- # getComputerMove(board,computerTile) : board와 computerTile을 받아 어디에 놓을 것인지 결정한 다음 위치를 [x,y]로 반환한다.
- # showPoints(playerTile,computerTile) : 현재 점수를 출력한다.
- import random
- import sys
- def drawBoard(board):
- # This function prints out the board that it was passed. Returns None.
- HLINE = ' +---+---+---+---+---+---+---+---+'
- VLINE = ' | | | | | | | | |'
- # print()함수에 자동 추가 문자를 붙이지 않을면 sys.stdout.write()함수를 써야한다.
- for x in range(8):
- def resetBoard(board):
- # Blanks out the board it is passed, except for the original starting position.
- for x in range(8):
- # Starting pieces:
- board[3][3] = 'X'
- board[3][4] = 'O'
- board[4][3] = 'O'
- board[4][4] = 'X'
- def getNewBoard():
- # Creates a brand new, blank board data structure.
- board = [] # board는 8개의 리스트로 된 리스트이며, 리스트는 8개의 문자열을 가지고 있다. 8*8
- 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 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
- board[xstart][ystart] = tile # temporarily set the tile on the board.
- if tile == 'X':
- otherTile = 'O'
- else:
- otherTile = 'X'
- tilesToFlip = [] # 움직임을 통해 뒤집힐 상대편 타일의 리스트를 반환한다.
- # 0. 순서대로 8방향을 조사한다.
- for xdirection, ydirection in [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]]:
- x, y = xstart, ystart
- # 1. 조사를 위해 각 방향으로 한칸 씩 움직여본다.
- x += xdirection # first step in the direction
- y += ydirection # first step in the direction
- # 2-1. x,y가 유효하며, 이동한 위치에 상대방 타일이 있을 경우 -> 상대방 타일을 뒤집을 수 있는지 조사한다.
- # There is a piece belonging to the other player next to our piece.
- # 3. 조사를 위해 각 방향으로 한칸 씩 움직여본다.
- x += xdirection
- y += ydirection
- # 3.1 x,y가 유효하지 않으면 #0으로 이동한다.
- continue
- # 3.2 상대방의 타일일 때까지 조사한다.
- x += xdirection
- y += ydirection
- # 4. x,y가 유효하지 않으면 while문을 종료한다.
- break
- # 3.3 x,y가 유효하지 않으면 #0으로 이동한다.
- continue
- # 3.4 조사를 위해 상대방의 타일 이후의 자신의 타일이 발견된다면,
- # 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
- # 5. x,y가 다시 시작 지점으로 이동했다면 while문 break
- break
- board[xstart][ystart] = ' ' # restore the empty space
- if len(tilesToFlip) == 0: # If no tiles were flipped, this is not a valid move.
- return False
- return tilesToFlip
- # Returns True if the coordinates are located on the board.
- def getBoardWithValidMoves(board, tile):
- # Returns a new board with . marking the valid moves the given player can make.
- # 플레이어에게 힌트를 주기위해 가능한 움직임을 board로 리턴한다.
- dupeBoard = getBoardCopy(board)
- 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):
- return validMoves # 가능한 위치를 8*8리스트(즉 보드)로 리턴한다.
- def getScoreOfBoard(board):
- # Determine the score by counting the tiles. Returns a dictionary with keys 'X' and 'O'.
- # score의 점수 매기는 것은 보드에서 각 플레이어당 타일의 개수이다.
- xscore = 0
- oscore = 0
- for x in range(8):
- xscore += 1
- oscore += 1
- 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 == 'X' or tile == 'O'):
- tile = input().upper() #플레이어의 타일을 고르도록한다.
- # the first element in the tuple is the player's tile, the second is the computer's tile.
- # 리스트로 반환한다.
- if tile == 'X':
- else:
- def whoGoesFirst():
- # Randomly choose the player who goes first.
- if random.randint(0, 1) == 0: # 랜덤수를 통해 누가 먼저할 지 결정한다.
- return 'computer'
- else:
- return 'player'
- def playAgain():
- # This function returns True if the player wants to play again, otherwise it returns False.
- 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:
- return True
- def getBoardCopy(board):
- # Make a duplicate of the board list and return the duplicate.
- dupeBoard = getNewBoard() # 보드를 복사해온다.
- for x in range(8):
- return dupeBoard
- # Returns True if the position is in one of the four corners.
- # 0~7의 인덱스중 사각형의 모서리 위치를 리턴한다.
- def getPlayerMove(board, playerTile):
- # Let the player type in their move.
- # Returns the move as [x, y] (or returns the strings 'hints' or 'quit')
- while True:
- move = 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: # 입력이 두 글자,1~8의 숫자일 경우
- continue
- else:
- break
- else: # 조건이 아니면 유효한 숫자가 아니다.
- 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) # 컴퓨터가 유효한 움직임을 리스트로 저장한다.
- # randomize the order of the possible moves
- random.shuffle(possibleMoves) # random모듈의 shuffle로 리스트를 섞는다.
- # 1. always go for a corner if available. 코너에 놓는 것이 가장 좋다.
- for x, y in possibleMoves:
- # 2. Go through all the possible moves and remember the best scoring move.
- # 가장 높은 점수를 받을 수 있는 위치에 대한 리스트를 생성한다.
- bestScore = -1
- dupeBoard = getBoardCopy(board)
- score = getScoreOfBoard(dupeBoard)[computerTile]
- if score > bestScore: # 최고 점수 갱신한다
- bestScore = score
- return bestMove
- def showPoints(playerTile, computerTile):
- # Prints out the current score.
- scores = getScoreOfBoard(mainBoard)
- print('You have %s points. The computer has %s points.' % (scores[playerTile], scores[computerTile]))
- while True:
- # Reset the board and game.
- mainBoard = getNewBoard()
- resetBoard(mainBoard)
- playerTile, computerTile = enterPlayerTile()
- showHints = False
- turn = whoGoesFirst()
- 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':
- 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)
- input('Press Enter to see the computer\'s move.')
- if getValidMoves(mainBoard, playerTile) == []:
- break
- else:
- turn = 'player'
- # Display the final score.
- drawBoard(mainBoard)
- scores = getScoreOfBoard(mainBoard)
- if scores[playerTile] > scores[computerTile]:
- print('You beat the computer by %s points! Congratulations!' % (scores[playerTile] - scores[computerTile]))
- elif scores[playerTile] < scores[computerTile]:
- print('You lost. The computer beat you by %s points.' % (scores[computerTile] - scores[playerTile]))
- else:
- if not playAgain():
- break
'Computer Language' 카테고리의 다른 글
03 Python 조건문 (0) | 2015.01.28 |
---|---|
02 Python 자료형 (0) | 2015.01.28 |
CaesarCiper.py (0) | 2015.01.16 |
SonarGame.py (0) | 2015.01.14 |
CartesianCorrdinateSystems.py (0) | 2015.01.14 |