Files
pythonCoolGames/sokrovisha/ohotnikZaSokrovishami.py
BarsTigerMeowcat b01c9d869f Initial commit
2020-01-26 12:46:16 +02:00

206 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Охотник за сокровищами
import random
import sys
import math
def getNewBoard():
# Создать структуру данных нового игрового поля размером 60х15.
board = []
for x in range(60): # Главный список из 60 списков.
board.append([])
for y in range(15): # Каждый список в главном списке содержит 15 односимвольных строк.
# Для создания океана используем разные символы, чтобы сделать его реалистичнее.
if random.randint(0, 1) == 0:
board[x].append('~')
else:
board[x].append('`')
return board
def drawBoard(board):
# Изобразить структуру данных игрового поля.
tensDigitsLine = ' ' # Создать место для чисел вниз по левой стороне поля.
for i in range(1, 6):
tensDigitsLine += (' ' * 9) + str(i)
# Вывести числа в верхней части поля.
print(tensDigitsLine)
print('' + ('0123456789' * 6))
print()
# Вывести каждый из 15 рядов.
for row in range(15):
# К однозначным числам нужно добавить дополнительный пробел.
if row < 10:
extraSpace = ' '
else:
extraSpace = ''
# Создать строку для этого ряда на игровом поле.
boardRow = ''
for column in range(60):
boardRow += board[column][row]
print('%s%s %s %s' % (extraSpace, row, boardRow, row))
# Вывести числа в нижней части поля.
print()
print('' + ('0123456789' * 6))
print(tensDigitsLine)
def getRandomChests(numChests):
# Создать список структур данных сундука (двухэлементные списки целочисленных координат x и y)).
chests = []
while len(chests) < numChests:
newChest = [random.randint(0, 59), random.randint(0, 14)]
if newChest not in chests: # Убедиться, что сундука здесь еще нет.
chests.append(newChest)
return chests
def isOnBoard(x, y):
# Возвращать True, если координаты есть на поле; в противном случае возвращать False.
return x >= 0 and x <= 59 and y >= 0 and y <= 14
def makeMove(board, chests, x, y):
# Изменить структуру данных поля, используя символ гидролокатора. Удалить сундуки
# с сокровищами из списка с сундуками, как только их нашли. Вернуть False, если это
# недопустимый ход. В противном случае, вернуть строку с результатом этого хода.
smallestDistance = 100 # Все сундуки будут расположены ближе, чем на расстоянии в 100 единиц.
for cx, cy in chests:
distance = math.sqrt((cx - x) * (cx - x) + (cy - y) * (cy - y))
if distance < smallestDistance: # Нам нужен ближайший сундук с сокровищами.
smallestDistance = distance
smallestDistance = round(smallestDistance)
if smallestDistance == 0:
# Координаты xy попали прямо в сундук с сокровищами!
chests.remove([x, y])
return 'Вы нашли сундук с сокровищами на затонувшем судне!'
else:
if smallestDistance < 10:
board[x][y] = str(smallestDistance)
return 'Сундук с сокровищами обнаружен на расстоянии %s от гидролокатора.' % (smallestDistance)
else:
board[x][y] = 'Х'
return 'Гидролокатор ничего не обнаружил. Все сундуки с сокровищами вне пределов досягаемости.'
def enterPlayerMove(previousMoves):
# Позволить игроку сделать ход. Вернуть двухэлементный список с целыми координатами x и y.
print('Где следует опустить гидролокатор? (координаты: 0-59 0-14) (или введите "выход")')
while True:
move = input()
if move.lower() == 'выход':
print('Спасибо за игру!')
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('Здесь вы уже опускали гидролокатор.')
continue
return [int(move[0]), int(move[1])]
print('Введите число от 0 до 59, потом пробел, а затем число от 0 до 14.')
def showInstructions():
print('''Инструктаж:
Вы - капитан корабля, плывущего за сокровищами. Ваша задача - с помощью
гидролокаторов найти три сундука с сокровищами в затонувших судах на дне океана.
Но гидролокаторы очень просты и определяют только расстояние, но не направление.
Введите координаты, чтобы опустить гидролокатор в воду. На карте будет показано
число, обозначающее, на каком расстоянии находится ближайший сундук. Или будет
показана буква Х, обозначающая, что сундук в области действия гидролокатора неИгра «Охотник за сокровищами» 225
обнаружен. На карте ниже метки C - это сундуки.
Цифра 3 обозначает, что ближайший сундук находится на отдалении в 3 единицы.
1 2 3
012345678901234567890123456789012
0 ~~~~`~```~`~``~~~``~`~~``~~~``~`~ 0
1 ~`~`~``~~`~```~~~```~~`~`~~~`~~~~ 1
2 `~`C``3`~~~~`C`~~~~`````~~``~~~`` 2
3 ````````~~~`````~~~`~`````~`~``~` 3
4 ~`~~~~`~~`~~`C`~``~~`~~~`~```~``~ 4
012345678901234567890123456789012
1 2 3
(Во время игры сундуки на карте не обозначаются!)
Нажмите клавишу Enter, чтобы продолжить...''')
input()
print('''Если гидролокатор опущен прямо на сундук, вы сможете поднять
сундук. Другие гидролокаторы обновят данные о расположении ближайшего сундука.
Сундуки ниже находятся вне диапазона локатора, поэтому отображается буква X.
1 2 3
012345678901234567890123456789012
0 ~~~~`~```~`~``~~~``~`~~``~~~``~`~ 0
1 ~`~`~``~~`~```~~~```~~`~`~~~`~~~~ 1
2 `~`X``7`~~~~`C`~~~~`````~~``~~~`` 2
3 ````````~~~`````~~~`~`````~`~``~` 3
4 ~`~~~~`~~`~~`C`~``~~`~~~`~```~``~ 4
012345678901234567890123456789012
1 2 3
Сундуки с сокровищами не перемещаются. Гидролокаторы определяют сундуки
на расстоянии до 9 единиц. Попробуйте поднять все 3 сундука до того, как все
гидролокаторы будут опущены на дно. Удачи!
Нажмите клавишу Enter, чтобы продолжить...''')
input()
print('О х о т н и к з а с о к р о в и щ а м и !')
print()
print('Показать инструктаж? (да/нет) ')
if input().lower().startswith('д'):
showInstructions()
while True:
# Настройка игры
sonarDevices = 20
theBoard = getNewBoard()
theChests = getRandomChests(3)
drawBoard(theBoard)
previousMoves = []
while sonarDevices > 0:
# Показать гидролокаторные устройства и сундуки с сокровищами.
print("Осталось гидролокаторов: %s Осталось сундуков с сокровищами: %s" % (sonarDevices, len(theChests)))
x, y = enterPlayerMove(previousMoves)
previousMoves.append([x, y]) # Мы должны отслеживать все ходы, чтобы гидролокаторы могли обновляться.
moveResult = makeMove(theBoard, theChests, x, y)
if moveResult == False:
continue
else:
if moveResult == 'Вы нашли сундук с сокровищами на затонувшем судне!':
# Обновить все гидролокаторные устройства, в настоящее время находящиеся на карте.
for x, y in previousMoves:
makeMove(theBoard, theChests, x, y)
drawBoard(theBoard)
print(moveResult)
if len(theChests) == 0:
print('Вы нашли все сундуки с сокровищами на затонувших судах! Поздравляем и приятной игры!')
break
sonarDevices -= 1
if sonarDevices == 0:
print('Все гидролокаторы опущены на дно! Придется разворачивать корабль и')
print('отправляться домой, в порт! Игра окончена.')
print('Вы не нашли сундуки в следующих местах:')
for x, y in theChests:
print(' %s, %s' % (x, y))
print('Хотите сыграть еще раз? (да или нет)')
if not input().lower().startswith('д'):
sys.exit()