Notice
Recent Posts
Recent Comments
Today
Total
05-21 05:41
Archives
관리 메뉴

Jeongchul Kim

SonarGame.py 본문

Computer Language

SonarGame.py

김 정출 2015. 1. 14. 16:05
  1. # Sonar Game
  2. # drawBoard(board) : 좌표를 받아서 게임보드를 화면에 출력한다.
  3. # getNewBoard() : 보드 데이터 구조를 만든다.
  4. # getRow(board,row) : 행의 가로 상태 알아내기
  5. # getRandomChests(numChests) : 게임 보드에 임의로 흩어져 있는 보물상자 데이터 구조를 만든다.
  6. # isValidMove(x,y) : x,y좌표를 받아 이 좌표가 게임 보드에 있는지 검사한다.
  7. # enterPlayerMove() : 어디에 놓을 건지 X,Y좌표를 받고, 유효한 좌표를 입력할때 까지 계속 묻는다.
  8. # makeMove(board,chests,x,y) : 게임보드에 음파 탐지기를 놓고, 상황을 문자열로 출력한다.
  9. # playAgain() : 게임을 또 할 것인지 묻는다.
  10. # showInstruction() : 게임 방법을 보여준다.
  11.  
  12. import random
  13. import sys
  14. # sys모듈은 exit()함수를 가지고 있다.
  15. # sys.exit()함수 : 프로그램을 바로 종료한다.
  16.  
  17. def drawBoard(board):
  18.     # Draw the board data structure.
  19.  
  20.     # hline -> 공백을 만든다.
  21.     hline = '    ' # initial space for the numbers down the left side of the board
  22.     for i in range(16):
  23.         hline += (' ' * 9) + str(i)
  24.  
  25.     # print the numbers across the top
  26.     print(hline)
  27.     print('   ' + ('0123456789' * 6))
  28.     print()
  29.  
  30.     # print each of the 15 rows
  31.     for i in range(15):
  32.         # single-digit numbers need to be padded with an extra space
  33.         if i < 10:
  34.             extraSpace = ' '
  35.         else:
  36.             extraSpace = ''
  37.         print('%s%s %s %s' % (extraSpace, i, getRow(board, i), i))
  38.  
  39.     # print the numbers across the bottom
  40.     print()
  41.     print('   ' + ('0123456789' * 6))
  42.     print(hline)
  43.  
  44.  
  45. def getRow(board, row):
  46.     # Return a string from the board data structure at a certain row.
  47.     boardRow = ''
  48.     for i in range(60):
  49.         boardRow += board[i][row]
  50.     return boardRow
  51.  
  52. def getNewBoard():
  53.     # Create a new 60x15 board data structure.
  54.     # 여기서는 60행*15열
  55.     board = []
  56.     for x in range(60)# the main list is a list of 60 lists
  57.         board.append([])
  58.         for y in range(15)# each list in the main list has 15 single-character strings
  59.             # use different characters for the ocean to make it more readable.
  60.             # 바다 모양 만들기
  61.             if random.randint(01) == 0# 랜덤함수를 통해 만든다.
  62.                 board[x].append('~')
  63.             else:
  64.                 board[x].append('`')
  65.     return board
  66.  
  67. def getRandomChests(numChests):
  68.     # Create a list of chest data structures (two-item lists of x, y int coordinates)
  69.     chests = []
  70.     for i in range(numChests)# 보물의 갯수만큼
  71.         chests.append([random.randint(059), random.randint(014)])
  72.         # x축은 0~59까지, y축은 0~14까지 임의의 랜덤 수를 chests리스트에 붙인다.
  73.     return chests
  74.  
  75. def isValidMove(x, y):
  76.     # Return True if the coordinates are on the board, otherwise False.
  77.     # 전체 사이즈 안에 있어야 유효한 움직임이다.
  78.     return x >= 0 and x <= 59 and y >= 0 and y <= 14
  79.  
  80. def makeMove(board, chests, x, y):
  81.     # Change the board data structure with a sonar device character. Remove treasure chests
  82.     # from the chests list as they are found. Return False if this is an invalid move.
  83.     # Otherwise, return the string of the result of this move.
  84.     if not isValidMove(x, y):
  85.         return False
  86.  
  87.     smallestDistance = 100 # any chest will be closer than 100.
  88.     for cx, cy in chests: # 보물의 x,y를 비교한다.
  89.         if abs(cx - x) > abs(cy - y)# 절대값 중 큰 값이 거리가 된다.
  90.             distance = abs(cx - x)
  91.         else:
  92.             distance = abs(cy - y)
  93.  
  94.         if distance < smallestDistance: # we want the closest treasure chest.
  95.             smallestDistance = distance
  96.  
  97.     if smallestDistance == 0# 거리가 0이 되면 정답이다.
  98.         # xy is directly on a treasure chest!
  99. # 리스트 remove(@)메소드 : 리스트의 원소 값 중 파라미터 @값을 찾아 제거한다.
  100. # 단, 지울 값이 없으면 에러가 발생한다.
  101.         chests.remove([x, y]) # 정답을 맞췄으므로 보물 리스트에서 지운다.
  102.         return 'You have found a sunken treasure chest!'
  103.     else:
  104.         if smallestDistance < 10# 음파 탐지기의 최대 제한 탐지 값이다.
  105.             board[x][y] = str(smallestDistance) # 탐지 값 안에 있으면 거리 값을 출력한다.
  106.             return 'Treasure detected at a distance of %s from the sonar device.' % (smallestDistance)
  107.         else:
  108.             board[x][y] = 'O' # 탐지기에 잡히지 않으면 O를 출력한다.
  109.             return 'Sonar did not detect anything. All treasure chests out of range.'
  110.  
  111.  
  112. def enterPlayerMove():
  113.     # Let the player type in her move. Return a two-item list of int xy coordinates.
  114.     print('Where do you want to drop the next sonar device? (0-59 0-14) (or type quit)')
  115.     while True:
  116.         move = input()
  117.         if move.lower() == 'quit'# 입력 값이 quit일 경우 프로그램을 종료한다.
  118.             print('Thanks for playing!')
  119.             sys.exit() #sys모듈의 exit()함수 : 프로그램을 종료
  120.  
  121.         move = move.split() # 공백을 분할하여 리스트로 저장한다.
  122.  
  123.         # 문자열 메소드 isdigit() : 문자열이 모두 숫자로 되어 있으면 True를 반환한다.
  124.         if len(move) == 2 and move[0].isdigit() and move[1].isdigit() and isValidMove(int(move[0])int(move[1])):
  125.             # 리스트의 길이는 2(x,y 값 2개이므로), 각 문자열은 숫자로만 이뤄져야 한다. 각 숫자들은 움직임에 유효해야 한다.
  126.             return [int(move[0])int(move[1])]
  127.             # 현재 문자열이므로 정수형으로 캐스팅하여 반환한다.
  128.         print('Enter a number from 0 to 59, a space, then a number from 0 to 14.')
  129.  
  130.  
  131. def playAgain():
  132.     # This function returns True if the player wants to play again, otherwise it returns False.
  133.     print('Do you want to play again? (yes or no)')
  134.     return input().lower().startswith('y')
  135.  
  136.  
  137. def showInstructions()# 플레이어 에게 게임 방법을 보여준다.
  138.     print('''Instructions:
  139. You are the captain of the Simon, a treasure-hunting ship. Your current mission
  140. is to find the three sunken treasure chests that are lurking in the part of the
  141. ocean you are in and collect them.
  142.  
  143. To play, enter the coordinates of the point in the ocean you wish to drop a
  144. sonar device. The sonar can find out how far away the closest chest is to it.
  145. For example, the d below marks where the device was dropped, and the 2's
  146. represent distances of 2 away from the device. The 4's represent
  147. distances of 4 away from the device.
  148.  
  149.    444444444
  150.    4       4
  151.    4 22222 4
  152.    4 2   2 4
  153.    4 2 d 2 4
  154.    4 2   2 4
  155.    4 22222 4
  156.    4       4
  157.    444444444
  158. Press enter to continue...''')
  159.     input()
  160.  
  161.     print('''For example, here is a treasure chest (the c) located a distance of 2 away
  162. from the sonar device (the d):
  163.  
  164.    22222
  165.    c   2
  166.    2 d 2
  167.    2   2
  168.    22222
  169.  
  170. The point where the device was dropped will be marked with a 2.
  171.  
  172. The treasure chests don't move around. Sonar devices can detect treasure
  173. chests up to a distance of 9. If all chests are out of range, the point
  174. will be marked with O
  175.  
  176. If a device is directly dropped on a treasure chest, you have discovered
  177. the location of the chest, and it will be collected. The sonar device will
  178. remain there.
  179.  
  180. When you collect a chest, all sonar devices will update to locate the next
  181. closest sunken treasure chest.
  182. Press enter to continue...''')
  183.    input()
  184.    print()
  185.  
  186.  
  187. print('S O N A R !')
  188. print()
  189. print('Would you like to view the instructions? (yes/no)')
  190. if input().lower().startswith('y'):
  191.    showInstructions()
  192.  
  193. while True:
  194.    # game setup
  195.    sonarDevices = 30 # 음파 탐지기의 개수
  196.    theBoard = getNewBoard()
  197.    theChests = getRandomChests(3) # 보물의 개수
  198.    drawBoard(theBoard)
  199.    previousMoves = []
  200.  
  201.    while sonarDevices > 0:
  202.        # Start of a turn:
  203.  
  204.        # sonar device/chest status
  205.        if sonarDevices > 1: extraSsonar = 's' # 개수의 단/복수를 표현하기 위해 s를 붙이는 지의 유무
  206.        else: extraSsonar = ''
  207.        if len(theChests) > 1: extraSchest = 's'
  208.        else: extraSchest = ''
  209.        print('You have %s sonar device%s left. %s treasure chest%s remaining.' % (sonarDevices, extraSsonar, len(theChests), extraSchest))
  210.  
  211.        x, y = enterPlayerMove()
  212.        previousMoves.append([x, y]) # 모든 움직임을 기록한다.
  213.        # we must track all moves so that sonar devices can be updated.
  214.  
  215.        moveResult = makeMove(theBoard, theChests, x, y)
  216.        if moveResult == False:
  217.            continue
  218.        else:
  219.            if moveResult == 'You have found a sunken treasure chest!':
  220.                # update all the sonar devices currently on the map.
  221.                for x, y in previousMoves:
  222.                    makeMove(theBoard, theChests, x, y)
  223.            drawBoard(theBoard)
  224.            print(moveResult)
  225.  
  226.        if len(theChests) == 0:
  227.            print('You have found all the sunken treasure chests! Congratulations and good game!')
  228.            break
  229.  
  230.        sonarDevices -= 1
  231.  
  232.    if sonarDevices == 0:
  233.        print('We\'ve run out of sonar devices! Now we have to turn the ship around and head')
  234.         print('for home with treasure chests still out there! Game over.')
  235.         print('    The remaining chests were here:')
  236.         for x, y in theChests:
  237.             print('    %s, %s' % (x, y))
  238.  
  239.     if not playAgain():
  240.         sys.exit()
  241.  


'Computer Language' 카테고리의 다른 글

ReversiGame.py  (0) 2015.01.16
CaesarCiper.py  (0) 2015.01.16
CartesianCorrdinateSystems.py  (0) 2015.01.14
BaseBallGame.py  (0) 2015.01.13
BaglesGame.py  (0) 2015.01.13
Comments