Der Befehl "clear" ist entweder falsch geschrieben oder konnte nicht gefunden werden.

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
DRAXX
User
Beiträge: 9
Registriert: Freitag 28. August 2020, 06:50

Hallo, ich habe an meinem Battleship Code weitergemacht und habe es meiner Meinung nach ziemlich verbessert. Ich bekomme jedoch eine Fehlermeldung: Der Befehl "clear" ist entweder falsch geschrieben oder
konnte nicht gefunden werden. Und obwohl diese Meldung nichts ausmacht und den Code nicht stoppt, nervt sie mich trotzdem. Deshalb will ich nur fragen, was ich da machen könnte?

Code: Alles auswählen

from random import randint
import os

NameInput = print(input("What is your Name?: "))
print("Ok, let's do this",NameInput, "!")
# Ship Class
class Ship:
    def __init__(self, size, orientation, location):
        self.size = size

        if orientation == 'horizontal' or orientation == 'vertical':
            self.orientation = orientation
        else:
            raise ValueError("Value must be 'horizontal' or 'vertical'.")

        if orientation == 'horizontal':
            if location['row'] in range(row_size):
                self.coordinates = []
                for index in range(size):
                    if location['col'] + index in range(col_size):
                        self.coordinates.append({'row': location['row'], 'col': location['col'] + index})
                    else:
                        raise IndexError("Column is out of range.")
            else:
                raise IndexError("Row is out of range.")
        elif orientation == 'vertical':
            if location['col'] in range(col_size):
                self.coordinates = []
                for index in range(size):
                    if location['row'] + index in range(row_size):
                        self.coordinates.append({'row': location['row'] + index, 'col': location['col']})
                    else:
                        raise IndexError("Row is out of range.")
            else:
                raise IndexError("Column is out of range.")

        if self.filled():
            print_board(board)
            print(" ".join(str(coords) for coords in self.coordinates))
            raise IndexError("A ship already occupies that space.")
        else:
            self.fillBoard()

    def filled(self):
        for coords in self.coordinates:
            if board[coords['row']][coords['col']] == 1:
                return True
        return False

    def fillBoard(self):
        for coords in self.coordinates:
            board[coords['row']][coords['col']] = 1

    def contains(self, location):
        for coords in self.coordinates:
            if coords == location:
                return True
        return False

    def destroyed(self):
        for coords in self.coordinates:
            if board_display[coords['row']][coords['col']] == 'O':
                return False
            elif board_display[coords['row']][coords['col']] == '*':
                raise RuntimeError("Board display inaccurate")
        return True


# Settings Variables
row_size = 9  # number of rows
col_size = 9  # number of columns
num_ships = 4
max_ship_size = 5
min_ship_size = 2
num_turns = 40

# Create lists
ship_list = []

board = [[0] * col_size for x in range(row_size)]

board_display = [["O"] * col_size for x in range(row_size)]


# Functions
def print_board(board_array):
    print("\n  " + " ".join(str(x) for x in range(1, col_size + 1)))
    for r in range(row_size):
        print(str(r + 1) + " " + " ".join(str(c) for c in board_array[r]))
    print()


def search_locations(size, orientation):
    locations = []

    if orientation != 'horizontal' and orientation != 'vertical':
        raise ValueError("Orientation must have a value of either 'horizontal' or 'vertical'.")

    if orientation == 'horizontal':
        if size <= col_size:
            for r in range(row_size):
                for c in range(col_size - size + 1):
                    if 1 not in board[r][c:c + size]:
                        locations.append({'row': r, 'col': c})
    elif orientation == 'vertical':
        if size <= row_size:
            for c in range(col_size):
                for r in range(row_size - size + 1):
                    if 1 not in [board[i][c] for i in range(r, r + size)]:
                        locations.append({'row': r, 'col': c})

    if not locations:
        return 'None'
    else:
        return locations


def random_location():
    size = randint(min_ship_size, max_ship_size)
    orientation = 'horizontal' if randint(0, 1) == 0 else 'vertical'

    locations = search_locations(size, orientation)
    if locations == 'None':
        return 'None'
    else:
        return {'location': locations[randint(0, len(locations) - 1)], 'size': size, \
                'orientation': orientation}


def get_row():
    while True:
        try:
            guess = int(input("Row Guess: "))
            if guess in range(1, row_size + 1):
                return guess - 1
            else:
                print("\nOops, that's not even in the ocean.")
        except ValueError:
            print("\nPlease enter a number")


def get_col():
    while True:
        try:
            guess = int(input("Column Guess: "))
            if guess in range(1, col_size + 1):
                return guess - 1
            else:
                print("\nOops, that's not even in the ocean.")
        except ValueError:
            print("\nPlease enter a number")


# Create the ships

temp = 0
while temp < num_ships:
    ship_info = random_location()
    if ship_info == 'None':
        continue
    else:
        ship_list.append(Ship(ship_info['size'], ship_info['orientation'], ship_info['location']))
        temp += 1
del temp

# Play Game
os.system('clear')
print_board(board_display)

for turn in range(num_turns):
    print("Turn:", turn + 1, "of", num_turns)
    print("Ships left:", len(ship_list))
    print()

    guess_coords = {}
    while True:
        guess_coords['row'] = get_row()
        guess_coords['col'] = get_col()
        if board_display[guess_coords['row']][guess_coords['col']] == 'X' or \
                board_display[guess_coords['row']][guess_coords['col']] == '*':
            print("\nYou guessed that one already.")
        else:
            break

    os.system('clear')

    ship_hit = False
    for ship in ship_list:
        if ship.contains(guess_coords):
            print("Hit!")
            ship_hit = True
            board_display[guess_coords['row']][guess_coords['col']] = 'X'
            if ship.destroyed():
                print("Ship Destroyed!")
                ship_list.remove(ship)
            break
    if not ship_hit:
        board_display[guess_coords['row']][guess_coords['col']] = '*'
        print("You missed!")

    print_board(board_display)

    if not ship_list:
        break

# End Game
if ship_list:
    print("You lose!")
else:
    print("All the ships are sunk. You win", NameInput, "!")
    
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Der Befehl heißt "cls".
Benutzeravatar
__blackjack__
User
Beiträge: 14032
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Janie: Nee:

Code: Alles auswählen

In [295]: os.system('cls')                                                      
sh: 1: cls: not found
Out[295]: 32512
@DRAXX: Wirf die Zeile einfach raus.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Sirius3
User
Beiträge: 18266
Registriert: Sonntag 21. Oktober 2012, 17:20

@DRAXX: die os.system-Zeilen solltest Du ganz löschen, und das aus mehreren Gründen. os.system ist schon lange durch subprocess.run erstetzt worden. Entweder willst Du ein einfaches Konsolenprogramm schreiben (dann nervt das löschen des Bildschirms) oder Du willst eine Text-UI schreiben, dann brauchst Du spezielle Pakete, die Systemabhängig sind.

Der Code insgesamt ist total unübersichtlich. Funktionsdefinitionen wechseln sich mit ausführbarem Code. Letzteres sollte sowieso nicht auf oberster Ebene existieren.
Variablennamen, Funktionen und Methoden schreibt man komplett klein, Konstanten dagegen KOMPLETT GROSS.

Der Rückgabewert von `print` ist immer None.
`board` ist eine globale Variable, das sollte nicht sein. Wenn Du Wahrheitswerte willst, benutze nicht 0 und 1, sondern False und True.

In print_board: `board_array` ist eigentlich kein Array. Man iteriert nicht über einen Index, wenn man über die Liste direkt iterieren kann.


In `search_locations` gibst Du entweder einen String oder eine Liste zurück. Eine Funktion sollte aber nur einen Typ zurückgeben, zumal eine leere Liste genau den gleichen Effekt hat.

Warum sind die Koordinaten Wörterbücher, Tuple wären einfacher.

Eine erste Überarbeitung könnte so aussehen:

Code: Alles auswählen

from random import randint, choice

# Settings Variables
ROW_SIZE = 9  # number of rows
COL_SIZE = 9  # number of columns
NUM_SHIPS = 4
MAX_SHIP_SIZE = 5
MIN_SHIP_SIZE = 2
NUM_TURNS = 40


class Ship:
    def __init__(self, board, size, orientation, location):
        self.board = board
        self.size = size

        if orientation == 'horizontal' or orientation == 'vertical':
            self.orientation = orientation
        else:
            raise ValueError("Value must be 'horizontal' or 'vertical'.")

        self.coordinates = []
        location_row, location_col = location
        if orientation == 'horizontal':
            if location_row not in range(ROW_SIZE):
                raise IndexError("Row is out of range.")
            if location_col not in range(COL_SIZE - size + 1):
                raise IndexError("Column is out of range.")
            for index in range(size):
                self.coordinates.append((location_row, location_col + index))
        elif orientation == 'vertical':
            if location_col not in range(COL_SIZE):
                raise IndexError("Column is out of range.")
            if location_row not in range(ROW_SIZE - size + 1):
                raise IndexError("Row is out of range.")

            for index in range(size):
                self.coordinates.append((location_row + index, location_col))

        if self.filled():
            print_board(self.board)
            print(" ".join(str(coords) for coords in self.coordinates))
            raise IndexError("A ship already occupies that space.")
        self.fill_board()

    def filled(self):
        return any(
            self.board[row][col]
            for row, col in self.coordinates
        )

    def fill_board(self):
        for row, col in self.coordinates:
            self.board[row][col] = True

    def contains(self, location):
        return any(coord == location for coord in self.coordinates)

    def destroyed(self, board_display):
        for row, col in self.coordinates:
            if board_display[row][col] == 'O':
                return False
            elif board_display[row][col] == '*':
                raise RuntimeError("Board display inaccurate")
        return True


# Functions
def print_board(board):
    print("\n  " + " ".join(str(x) for x in range(1, len(board[0]) + 1)))
    for r, row in enumerate(board, 1):
        print(f"{r} {' '.join(row)}")
    print()


def search_locations(board, size, orientation):
    locations = []

    if orientation != 'horizontal' and orientation != 'vertical':
        raise ValueError("Orientation must have a value of either 'horizontal' or 'vertical'.")

    if orientation == 'horizontal':
        for r in range(ROW_SIZE):
            for c in range(COL_SIZE - size + 1):
                if not any(board[r][c:c + size]):
                    locations.append((r, c))
    elif orientation == 'vertical':
        for c in range(COL_SIZE):
            for r in range(ROW_SIZE - size + 1):
                if not any(board[i][c] for i in range(r, r + size)):
                    locations.append((r,c))
    return locations


def set_ship_on_random_location(board):
    while True:
        size = randint(MIN_SHIP_SIZE, MAX_SHIP_SIZE)
        orientation = choice(['horizontal', 'vertical'])
        locations = search_locations(board, size, orientation)
        if locations:
            break
    return Ship(board, size, orientation, choice(locations))


def get_row():
    while True:
        try:
            guess = int(input("Row Guess: "))
            if guess in range(1, ROW_SIZE + 1):
                return guess - 1
            else:
                print("\nOops, that's not even in the ocean.")
        except ValueError:
            print("\nPlease enter a number")


def get_col():
    while True:
        try:
            guess = int(input("Column Guess: "))
            if guess in range(1, COL_SIZE + 1):
                return guess - 1
            else:
                print("\nOops, that's not even in the ocean.")
        except ValueError:
            print("\nPlease enter a number")


def main():
    player_name = input("What is your Name?: ")
    print(f"Ok, let's do this {player_name}!")

    board = [[False] * COL_SIZE for _ in range(ROW_SIZE)]
    board_display = [["O"] * COL_SIZE for _ in range(ROW_SIZE)]

    ships = [
        set_ship_on_random_location(board)
        for _ in range(NUM_SHIPS)
    ]

    # Play Game
    print_board(board_display)

    for turn in range(NUM_TURNS):
        print(f"Turn: {turn + 1} of {NUM_TURNS}")
        print(f"Ships left: {len(ships)}")
        print()

        while True:
            row, col = (get_row(), get_col())
            if board_display[row][col] not in ('X', '*'):
                break
            print("\nYou guessed that one already.")

        ship_hit = next((ship for ship in ships if ship.contains((row, col))), None)
        if ship_hit:
            board_display[row][col] = 'X'
            if ship_hit.destroyed(board_display):
                print("Ship Destroyed!")
                ships.remove(ship_hit)
        else:
            board_display[row][col] = '*'
            print("You missed!")

        print_board(board_display)

        if not ships:
            print(f"All the ships are sunk. You win {player_name}!")
            break
    else:
        # End Game
        print("You lose!")

if __name__ == '__main__':
    main()
    
DRAXX
User
Beiträge: 9
Registriert: Freitag 28. August 2020, 06:50

Danke für die Antworten, hat sehr geholfen.
Antworten