Python game programming (seven) Sonar Treasure Hunt

Here we will introduce the use of a sonar to find the treasure of the game.

First, let's look at some of the concepts involved in this game and how the game is played.

table of Contents

 

(A) Game Description

(B) introducing module

(C) getNewBoard ():

(四)drawBoard(board):

(五) getRandomChests (numChests)

(六)isOnBoard(x, y):

(七)makeMove(board, chests, x, y):

(八)enterPlayerMove(previousMoves):

(九)showInstructions():

(J) the game loop


(A) Game Description

First to understand some simple concepts

Cartesian coordinate system: the so-called Cartesian coordinate system is a common xoy plane rectangular coordinate system.

Data structures: the data structure is a permutation and combination of certain values stored represent something. This game uses a complex variable such as a list of lists data structures.

Sonar: Sonar is a technique used to locate the ship submarine objects. The game of "sonar" device will tell the player how far from the nearest treasure, but will not tell in which direction the player Cataclysm Database.

game rules:

The player to collect three Tibetan chest, while only 16 players sonar device can be used to find them.

 

 

The following analysis of the game's source code, it will be divided into several parts.

 

(B) introducing module

In the beginning of the program, we import random, sys and math modules:

#Sonar Treasure Hunt

import random
import sys
import math

We should introduce the sys module. sys module contains the exit () function, which immediately terminates execution of a program. After sys.exit () call, there is no line to run the code.

 

Since some functions will be defined below.

(C) getNewBoard ():

Through this function the demolition of the function keys of a new version of the game, contains a list of lists. Achieved by nested loops in the loop, and () function randomly drawing a symbol by random, sea configuration.

#创建一个新的游戏板,Sonar游戏的游戏版是周围由X轴和Y轴坐标包围这的一个ASCII字符图“海洋”。
#                       board数据结构是字符串的列表的一个列表。
def getNewBoard():
    #Create a new 60x15 board date structure.
    board = []
    for x in range(60):
        #The main list is a list of 60 lists.
        board.append([])
        for y in range(15):
            #Each list in the main list has 15 single-caracter string.
            #Use different character for the ocean to make it more readable.
            if random.randint(0, 1) == 0:
                board[x].append('~')
            else:
                board[x].append('`')
    return board

 

(四)drawBoard(board):

() Function print version of the game by drawBoard. Version of the game is a Cartesian coordinate system.

#绘制游戏板
def drawBoard(board):
    #Draw the board data structure.
    tensDigitsLine = ' '#Initial space for the numbers down the left side of the board.
    for i in range(1, 6):
        tensDigitsLine += (' ' * 9) + str(i)
        
    #Print the numbers across the top of the board.
    print(tensDigitsLine)
    print('  ' + ('0123456789' * 6))
    print()
    
    # Print each of the 15 rows.
    for row in range(15):
        #Single-digit numbers need to be padded with an extra space.
        if row < 10:
            extraSpace = ' '
        else:
            extraSpace = ''
            
        # Creat the string for this row on the board.
        boardRow = ''
        for column in range(60):
            boardRow += board[column][row]
            
        print('%s%s %s %s' % (extraSpace, row, boardRow, row))
        
    # Print the numbers across the bottom of the board.
    print()
    print(' ' + ('0123456789' * 6))
    print(tensDigitsLine)

This function will run if the print version of the game as follows:

          1         2         3         4         5
  012345678901234567890123456789012345678901234567890123456789

 0 ```~~~`~~`~`~~~~```~~~`~~`~``~~~~~~~~``~~``~``~~``~~``~`~``` 0
 1 ~~~``~~````~`~~`~~~~~~`~~~~```~`~~``~~``~~`~``~`~``~``~~~~~` 1
 2 ~`~~~```~~~~```~``~`~~`~~~`~`~``~``~~``~`~~~~`~``~~```~``~~~ 2
 3 ~~`~`~~``~`~~~``~~~~`~``~`~`~~~~`~`~~`~~`~````~`~``~~`~`~`~~ 3
 4 ~~~~~`~`~~``~`~~~`~``~`~~```~`~```~~~~~``~~~`````~`~`~````~~ 4
 5 ~~`~`~~``~~`~`~`~~~`~`~`~~~`~~~`~~`~~`~````~``~````~~~~`~~~` 5
 6 ~~`````~`~````~`~`~```~`~~~~~~~`~~``~````~``~```~`~~~```~~~` 6
 7 ~````~~`~~~`~````~```~`~`~`~~``~`~~~~``~`~```~``~~~~~```~`~~ 7
 8 `~~```~~~~`~~`~`~~`~~```~~`~~~~~```~~~~~~````~~``~`````~~`~~ 8
 9 ``~``~~~``~`~`~~~~`````~~``~~`~`~`~```~`~~~~`~````~``~~``~~~ 9
10 `~~~``~~```~``~`~~````~`````~~~``~``~``~~~~~~`~``~```~`~`~`~ 10
11 `~~`~`~`~~~`~`~~`~~~```~~``~~`~``~~~`~``~````````~~~```~`~`` 11
12 ~```~`~~~`~```~~~~`~``~~``~~`~~~````````~~~~~`~`~`~~~`~``~`` 12
13 `~~~~`~`~`~`~``~~```~````~~~~``~`~``~``~`~~`~~~~~~`~~~`~`~`` 13
14 ~`~``~`~~`~~~``~`~``~``~~`~~~~``~```~`~~~``~`~`~`~`~~~~```~` 14

 

(五) getRandomChests (numChests)

The game will randomly decide where to hide hidden chest with a list contains a list of two integers to represent the treasure chest. These two integers are X and Y coordinates of hidden treasure chest.

#创建随机的藏宝箱
def getRandomChests(numChests):
    # Create a list of chest data structures (two-item lists of x, y int coordinates ).
    chests = []
    while len(chests) < numChests:
        newChest = [random.randint(0, 59), random.randint(0, 14)]
        # Make sure a chest is not already here
        if newChest not in chests:
            chests.append(newChest)
    return chests

 

(六)isOnBoard(x, y):

When the game get coordinates entered by the user, the user input to ensure that the digital version of the game in the coordinate system range.

#判断一次移动是否有效
def isOnBoard(x, y):
    # Return True if the coordinates are on the board; otherwise, return False.
    return x >= 0 and x <= 59 and y >= 0 and y <= 14

 

(七)makeMove(board, chests, x, y):

In the game Sonar, by updating the version of the game, dropped for each sonar device displays a number representing how far it is from the nearest treasure chest. So, when a player through to the program X and Y coordinates to a move, the game version will make modifications based on the location of the hidden chest.

makeMove () function takes four parameters: the game version data structure, the data structure hidden chest, X and Y coordinates.

makeMove () function returns a character string describing how to respond to movement;

#在游戏板上进行一次移动
def makeMove(board, chests, x, y):
    # Change the board data structure with a sonar device character.
    # Remove treasure chests from the chests list as they are found.
    # Return False if this is an invalid move.
    # Otherwise, return the string of the result of this move.
    smallestDistance = 100    # Any chest will be closer than 100.
    for cx, cy in chests:
        distance = math.sqrt((cx - x) * (cx - x) + (cy - y) * (cy - y))
        
        # We want the closest treasure chest.
        if distance < smallestDistance:
            
            smallestDistance = distance
    
    smallestDistance = round(smallestDistance)
    
    if smallestDistance == 0:
        # xy is directly on a treasure chest!
        chests.remove([x, y])
        return 'You have found a sunken treasure chest!'
    else:
        if smallestDistance < 10:
            board[x][y] = str(smallestDistance)
            return 'Treasure detected at a distance of %s from the sonar device.' % (smallestDistance)
        else:
            board[x][y] = 'X'
            return 'Sonar did not detect anything. All treasure chests out of range.'

 

(八)enterPlayerMove(previousMoves):

previousMoves parameter is a list of two integers, which represents the position of the player previously placed sonar equipment. This function will use this information so that the player will not be able to sonar equipment has been placed into the position of a sonar device.

while loop will always ask the player next move, knowing the players enter a valid mobile, you can enter quit to quit the game, this is the band oh with sys.exit () to quit the game.

#获取玩家的移动
def enterPlayerMove(previousMoves):
    # Let the player enter their move. Return a two-item of int xy coordinates.
    print('Where do you want to drop the next sonar device? (0 - 59 0 - 14) (or type quit)')
    while True:
        move = input()
        if move.lower() == 'quit':
            print('Thanks for playing!')
            sys.exit()
            
        move = move.split()
        if len(move) == 2 and move[0].isdigit() and move[1].isdigit() and isOnBoard(int(move[0]), int(move[1])):
            if [int(move[0]), int(move[1])] in previousMoves:
                print('You alresdy moved there.')
                continue
            return [int(move[0]), int(move[1])]
        
        print('Enter a number from 0 to 59, a space, then a number from 0 to 14.')

 

(九)showInstructions():

Print out the instructions game

# 为玩家打印出游戏说明
def showInstructions():
    
    print('''Instructions:
 You are the captain of the Simon, a treasure-hunting ship. Your current
   mission
 is to use sonar devices to find three sunken treasure chests at the
   bottom of
 the ocean. But you only have cheap sonar that finds distance, not
   direction.

 Enter the coordinates to drop a sonar device. The ocean map will be
   marked with
 how far away the nearest chest is, or an X if it is beyond the sonar
   device's
 range. For example, the C marks are where chests are. The sonar device
   shows a
 3 because the closest chest is 3 spaces away.

                     1         2         3
           012345678901234567890123456789012

         0 ~~~~`~```~`~``~~~``~`~~``~~~``~`~ 0
         1 ~`~`~``~~`~```~~~```~~`~`~~~`~~~~ 1
         2 `~`C``3`~~~~`C`~~~~`````~~``~~~`` 2
         3 ````````~~~`````~~~`~`````~`~``~` 3
         4 ~`~~~~`~~`~~`C`~``~~`~~~`~```~``~ 4

           012345678901234567890123456789012
                     1         2         3
(In the real game, the chests are not visible in the ocean.)

Press enter to continue...
    ''')
    input()
    
    

    print('''When you drop a sonar device directly on a chest, you
       retrieve it and the other
 sonar devices update to show how far away the next nearest chest is. The
   chests
 are beyond the range of the sonar device on the left, so it shows an X.

                     1         2         3
           012345678901234567890123456789012

         0 ~~~~`~```~`~``~~~``~`~~``~~~``~`~ 0
         1 ~`~`~``~~`~```~~~```~~`~`~~~`~~~~ 1
         2 `~`X``7`~~~~`C`~~~~`````~~``~~~`` 2
         3 ````````~~~`````~~~`~`````~`~``~` 3
         4 ~`~~~~`~~`~~`C`~``~~`~~~`~```~``~ 4

           012345678901234567890123456789012
                     1         2         3

 The treasure chests don't move around. Sonar devices can detect treasure
   chests
 up to a distance of 9 spaces. Try to collect all 3 chests before running
   out of
 sonar devices. Good luck!

 Press enter to continue...''')
    input()

 

(J) the game loop

 

print('S O N A R !')
print()
print('Would you like to view the instructions? (yes/no)')
if input().lower().startswith('y'):
    showInstructions()
    
# 游戏循环
while True:
    # Game setup
    sonarDevices = 20
    theBoard = getNewBoard()
    theChests = getRandomChests(3)
    drawBoard(theBoard)
    previousMoves = []
    
    while sonarDevices > 0:
        
        # Show sonar device and chest statuses.
        print('You have %s sonar device(s) left. %s treasure chest(s)remaining.' % (sonarDevices, len(theChests)))

        x, y = enterPlayerMove(previousMoves)
        previousMoves.append([x, y]) # We must track all moves so that sonar devices can be updated.

        moveResult = makeMove(theBoard, theChests, x, y)
        if moveResult == False:
            continue
        else:
            if moveResult == 'You have found a sunken treasure chest!':
                
                # Update all the sonar devices currently on the map.
                for x, y in previousMoves:
                    
                    makeMove(theBoard, theChests, x, y)
            drawBoard(theBoard)
            print(moveResult)

        if len(theChests) == 0:
            print('You have found all the sunken treasure chests! Congratulations and good game!')
            break

        sonarDevices -= 1

    if sonarDevices == 0:
        
        print('We\'ve run out of sonar devices! Now we have to turn the ship around and head')
        print('for home with treasure chests still out there! Gameover.')
        print('    The remaining chests were here:')
        
        for x, y in theChests:
            print('    %s, %s' % (x, y))

    print('Do you want to play again? (yes or no)')
    if not input().lower().startswith('y'):
        
        sys.exit() # 使用该函数使程序终止

 

 

Source:

#Sonar Treasure Hunt

import random
import sys
import math

#创建一个新的游戏板,Sonar游戏的游戏版是周围由X轴和Y轴坐标包围这的一个ASCII字符图“海洋”。
#                       board数据结构是字符串的列表的一个列表。
def getNewBoard():
    #Create a new 60x15 board date structure.
    board = []
    for x in range(60):
        #The main list is a list of 60 lists.
        board.append([])
        for y in range(15):
            #Each list in the main list has 15 single-caracter string.
            #Use different character for the ocean to make it more readable.
            if random.randint(0, 1) == 0:
                board[x].append('~')
            else:
                board[x].append('`')
    return board

#绘制游戏板
def drawBoard(board):
    #Draw the board data structure.
    tensDigitsLine = ' '#Initial space for the numbers down the left side of the board.
    for i in range(1, 6):
        tensDigitsLine += (' ' * 9) + str(i)
        
    #Print the numbers across the top of the board.
    print(tensDigitsLine)
    print('  ' + ('0123456789' * 6))
    print()
    
    # Print each of the 15 rows.
    for row in range(15):
        #Single-digit numbers need to be padded with an extra space.
        if row < 10:
            extraSpace = ' '
        else:
            extraSpace = ''
            
        # Creat the string for this row on the board.
        boardRow = ''
        for column in range(60):
            boardRow += board[column][row]
            
        print('%s%s %s %s' % (extraSpace, row, boardRow, row))
        
    # Print the numbers across the bottom of the board.
    print()
    print(' ' + ('0123456789' * 6))
    print(tensDigitsLine)
    
#创建随机的藏宝箱
def getRandomChests(numChests):
    # Create a list of chest data structures (two-item lists of x, y int coordinates ).
    chests = []
    while len(chests) < numChests:
        newChest = [random.randint(0, 59), random.randint(0, 14)]
        # Make sure a chest is not already here
        if newChest not in chests:
            chests.append(newChest)
    return chests

#判断一次移动是否有效
def isOnBoard(x, y):
    # Return True if the coordinates are on the board; otherwise, return False.
    return x >= 0 and x <= 59 and y >= 0 and y <= 14

#在游戏板上进行一次移动
def makeMove(board, chests, x, y):
    # Change the board data structure with a sonar device character.
    # Remove treasure chests from the chests list as they are found.
    # Return False if this is an invalid move.
    # Otherwise, return the string of the result of this move.
    smallestDistance = 100    # Any chest will be closer than 100.
    for cx, cy in chests:
        distance = math.sqrt((cx - x) * (cx - x) + (cy - y) * (cy - y))
        
        # We want the closest treasure chest.
        if distance < smallestDistance:
            
            smallestDistance = distance
    
    smallestDistance = round(smallestDistance)
    
    if smallestDistance == 0:
        # xy is directly on a treasure chest!
        chests.remove([x, y])
        return 'You have found a sunken treasure chest!'
    else:
        if smallestDistance < 10:
            board[x][y] = str(smallestDistance)
            return 'Treasure detected at a distance of %s from the sonar device.' % (smallestDistance)
        else:
            board[x][y] = 'X'
            return 'Sonar did not detect anything. All treasure chests out of range.'
        
#获取玩家的移动
def enterPlayerMove(previousMoves):
    # Let the player enter their move. Return a two-item of int xy coordinates.
    print('Where do you want to drop the next sonar device? (0 - 59 0 - 14) (or type quit)')
    while True:
        move = input()
        if move.lower() == 'quit':
            print('Thanks for playing!')
            sys.exit()
            
        move = move.split()
        if len(move) == 2 and move[0].isdigit() and move[1].isdigit() and isOnBoard(int(move[0]), int(move[1])):
            if [int(move[0]), int(move[1])] in previousMoves:
                print('You alresdy moved there.')
                continue
            return [int(move[0]), int(move[1])]
        
        print('Enter a number from 0 to 59, a space, then a number from 0 to 14.')
   
# 为玩家打印出游戏说明
def showInstructions():
    
    print('''Instructions:
 You are the captain of the Simon, a treasure-hunting ship. Your current
   mission
 is to use sonar devices to find three sunken treasure chests at the
   bottom of
 the ocean. But you only have cheap sonar that finds distance, not
   direction.

 Enter the coordinates to drop a sonar device. The ocean map will be
   marked with
 how far away the nearest chest is, or an X if it is beyond the sonar
   device's
 range. For example, the C marks are where chests are. The sonar device
   shows a
 3 because the closest chest is 3 spaces away.

                     1         2         3
           012345678901234567890123456789012

         0 ~~~~`~```~`~``~~~``~`~~``~~~``~`~ 0
         1 ~`~`~``~~`~```~~~```~~`~`~~~`~~~~ 1
         2 `~`C``3`~~~~`C`~~~~`````~~``~~~`` 2
         3 ````````~~~`````~~~`~`````~`~``~` 3
         4 ~`~~~~`~~`~~`C`~``~~`~~~`~```~``~ 4

           012345678901234567890123456789012
                     1         2         3
(In the real game, the chests are not visible in the ocean.)

Press enter to continue...
    ''')
    input()
    
    

    print('''When you drop a sonar device directly on a chest, you
       retrieve it and the other
 sonar devices update to show how far away the next nearest chest is. The
   chests
 are beyond the range of the sonar device on the left, so it shows an X.

                     1         2         3
           012345678901234567890123456789012

         0 ~~~~`~```~`~``~~~``~`~~``~~~``~`~ 0
         1 ~`~`~``~~`~```~~~```~~`~`~~~`~~~~ 1
         2 `~`X``7`~~~~`C`~~~~`````~~``~~~`` 2
         3 ````````~~~`````~~~`~`````~`~``~` 3
         4 ~`~~~~`~~`~~`C`~``~~`~~~`~```~``~ 4

           012345678901234567890123456789012
                     1         2         3

 The treasure chests don't move around. Sonar devices can detect treasure
   chests
 up to a distance of 9 spaces. Try to collect all 3 chests before running
   out of
 sonar devices. Good luck!

 Press enter to continue...''')
    input()



print('S O N A R !')
print()
print('Would you like to view the instructions? (yes/no)')
if input().lower().startswith('y'):
    showInstructions()
    
# 游戏循环
while True:
    # Game setup
    sonarDevices = 20
    theBoard = getNewBoard()
    theChests = getRandomChests(3)
    drawBoard(theBoard)
    previousMoves = []
    
    while sonarDevices > 0:
        
        # Show sonar device and chest statuses.
        print('You have %s sonar device(s) left. %s treasure chest(s)remaining.' % (sonarDevices, len(theChests)))

        x, y = enterPlayerMove(previousMoves)
        previousMoves.append([x, y]) # We must track all moves so that sonar devices can be updated.

        moveResult = makeMove(theBoard, theChests, x, y)
        if moveResult == False:
            continue
        else:
            if moveResult == 'You have found a sunken treasure chest!':
                
                # Update all the sonar devices currently on the map.
                for x, y in previousMoves:
                    
                    makeMove(theBoard, theChests, x, y)
            drawBoard(theBoard)
            print(moveResult)

        if len(theChests) == 0:
            print('You have found all the sunken treasure chests! Congratulations and good game!')
            break

        sonarDevices -= 1

    if sonarDevices == 0:
        
        print('We\'ve run out of sonar devices! Now we have to turn the ship around and head')
        print('for home with treasure chests still out there! Gameover.')
        print('    The remaining chests were here:')
        
        for x, y in theChests:
            print('    %s, %s' % (x, y))

    print('Do you want to play again? (yes or no)')
    if not input().lower().startswith('y'):
        
        sys.exit() # 使用该函数使程序终止
     
        
 

 

 

 

 

 

 

Released nine original articles · won praise 1 · views 413

Guess you like

Origin blog.csdn.net/weixin_45755966/article/details/104259753