From 5542ac14d7771d74387e7accedf45d8fc2cd7504 Mon Sep 17 00:00:00 2001 From: Artur Savitskiy Date: Mon, 27 May 2024 20:12:58 +0200 Subject: [PATCH] Lesson results commit --- HNS/MB/ShipField.py | 71 +++++++++++++------------ HNS/MB/ShipView.py | 9 ++++ HNS/MB/main.py | 124 +++++++++++++++++++++----------------------- 3 files changed, 102 insertions(+), 102 deletions(-) create mode 100644 HNS/MB/ShipView.py diff --git a/HNS/MB/ShipField.py b/HNS/MB/ShipField.py index 04fd698..66edf5b 100644 --- a/HNS/MB/ShipField.py +++ b/HNS/MB/ShipField.py @@ -5,6 +5,7 @@ from ShipDirection import ShipDirection class ShipField: + field_size = 10 def __init__(self): self.field = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', @@ -19,7 +20,6 @@ class ShipField: ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '] self.ships = [4, 3, 3, 2, 2, 2, 1, 1, 1, 1] - self.field_size = 10 self.field_mode = ShipMode.PUT self.ship_size = 4 self.ship_direction = ShipDirection.VERTICAL @@ -27,7 +27,6 @@ class ShipField: def from_json(self, obj): self.field = obj['field'] self.ships = obj['ships'] - self.field_size = obj['field_size'] self.field_mode = ShipMode.from_string(obj['field_mode']) self.ship_size = obj['ship_size'] self.ship_direction = ShipDirection.from_string(obj['ship_direction']) @@ -65,18 +64,18 @@ class ShipField: if self.ship_direction == ShipDirection.VERTICAL: for r in range(row, row + self.ship_size): if self.ship_size in self.ships: - self.field[r * self.field_size + col] = "p" + self.field[r * ShipField.field_size + col] = "p" else: - self.field[r * self.field_size + col] = "r" + self.field[r * ShipField.field_size + col] = "r" if self.ship_direction == ShipDirection.HORIZONTAL: for c in range(col, col + self.ship_size): if self.ship_size in self.ships: - self.field[row * self.field_size + c] = "p" + self.field[row * ShipField.field_size + c] = "p" else: - self.field[row * self.field_size + c] = "r" + self.field[row * ShipField.field_size + c] = "r" else: - self.field[row * self.field_size + col] += "+" + self.field[row * ShipField.field_size + col] += "+" def clear_marker(self): for i in range(0, len(self.field)): @@ -87,44 +86,44 @@ class ShipField: self.field[i] = self.field[i].replace("+", "") def set_ship(self, row, col): - if row < 0 or row > self.field_size: + if row < 0 or row > ShipField.field_size: return - if col < 0 or col > self.field_size: + if col < 0 or col > ShipField.field_size: return - index = row * self.field_size + col + index = row * ShipField.field_size + col if self.ship_direction == ShipDirection.VERTICAL: - if self.field_size - row < self.ship_size: + if ShipField.field_size - row < self.ship_size: return for r in range(row, row + self.ship_size): - index = r * self.field_size + col + index = r * ShipField.field_size + col self.field[index] = "1" if self.ship_direction == ShipDirection.HORIZONTAL: - if self.field_size - col < self.ship_size: + if ShipField.field_size - col < self.ship_size: return for c in range(col, col + self.ship_size): - index = row * self.field_size + c + index = row * ShipField.field_size + c self.field[index] = "1" if self.ship_size in self.ships: self.ships.remove(self.ship_size) def get_ship(self, row, col): - if row < 0 or row > self.field_size: + if row < 0 or row > ShipField.field_size: return - if col < 0 or col > self.field_size: + if col < 0 or col > ShipField.field_size: return - self.field[row * self.field_size + col] = '' + self.field[row * ShipField.field_size + col] = '' ship_size = 1 ship_direction = ShipDirection.UNKNOWN # check vertical - for r in range(row + 1, self.field_size): + for r in range(row + 1, ShipField.field_size): if self.check_ship(r, col): ship_size += 1 ship_direction = ShipDirection.VERTICAL - self.field[r * self.field_size + col] = '' + self.field[r * ShipField.field_size + col] = '' else: break @@ -132,17 +131,17 @@ class ShipField: if self.check_ship(r, col): ship_size += 1 ship_direction = ShipDirection.VERTICAL - self.field[r * self.field_size + col] = '' + self.field[r * ShipField.field_size + col] = '' else: break if ship_direction == ShipDirection.UNKNOWN: # check horizontal - for c in range(col + 1, self.field_size): + for c in range(col + 1, ShipField.field_size): if self.check_ship(row, c): ship_size += 1 ship_direction = ShipDirection.HORIZONTAL - self.field[row * self.field_size + c] = '' + self.field[row * ShipField.field_size + c] = '' else: break @@ -150,21 +149,21 @@ class ShipField: if self.check_ship(row, c): ship_size += 1 ship_direction = ShipDirection.HORIZONTAL - self.field[row * self.field_size + c] = '' + self.field[row * ShipField.field_size + c] = '' else: break self.set_ship_direction(ship_direction) - self.set_ship_size(self.ship_size) + self.set_ship_size(ship_size) - self.ships.append(self.ship_size) + self.ships.append(ship_size) def shoot(self, row, col): - if row < 0 or row > self.field_size - 1: + if row < 0 or row > ShipField.field_size - 1: return ShootResult.UNDEFINED - if col < 0 or col > self.field_size - 1: + if col < 0 or col > ShipField.field_size - 1: return ShootResult.UNDEFINED - index = row * self.field_size + col + index = row * ShipField.field_size + col if (self.field[index]).strip() == "": self.field[index] = "0" return ShootResult.EMPTY @@ -175,18 +174,18 @@ class ShipField: return ShootResult.UNDEFINED def check_ship(self, row, col): - return self.field[row * self.field_size + col].strip() == '1' + return self.field[row * ShipField.field_size + col].strip() == '1' def check_possible(self, row, col): if self.ship_direction == ShipDirection.VERTICAL: - if self.field_size - row >= self.ship_size: + if ShipField.field_size - row >= self.ship_size: for r in range(row, row + self.ship_size): if not self.check_blocked(r, col): return False return True if self.ship_direction == ShipDirection.HORIZONTAL: - if self.field_size - col >= self.ship_size: + if ShipField.field_size - col >= self.ship_size: for c in range(col, col + self.ship_size): if not self.check_blocked(row, c): return False @@ -197,8 +196,8 @@ class ShipField: def check_blocked(self, row, col): for r in range(row - 1, row + 2): for c in range(col - 1, col + 2): - if 0 <= r < self.field_size and 0 <= c < self.field_size: - cell = (self.field[r * self.field_size + c]).strip() + if 0 <= r < ShipField.field_size and 0 <= c < ShipField.field_size: + cell = (self.field[r * ShipField.field_size + c]).strip() if cell != '' and cell != 'p': return False return True @@ -237,12 +236,12 @@ class ShipField: self.field_mode = ShipMode.PUT def print_field(self): - for r in range(0, self.field_size): + for r in range(0, ShipField.field_size): blocked_string = "" ship_string = "" - for c in range(0, self.field_size): + for c in range(0, ShipField.field_size): blocked_string += str(self.check_blocked(r, c))[0] + ", " - ship_string += self.field[r * self.field_size + c] + ', ' + ship_string += self.field[r * ShipField.field_size + c] + ', ' print(blocked_string[:-2] + ' ' + ship_string[:-2]) print("********************************************************************") diff --git a/HNS/MB/ShipView.py b/HNS/MB/ShipView.py new file mode 100644 index 0000000..eab26e2 --- /dev/null +++ b/HNS/MB/ShipView.py @@ -0,0 +1,9 @@ +from tkinter import StringVar + + +class ShipView: + + def __init__(self, ship_field, buttons): + self.ship_field = ship_field + self.buttons = buttons + self.remaining_ships_text = StringVar() diff --git a/HNS/MB/main.py b/HNS/MB/main.py index 24f530c..3472d8f 100644 --- a/HNS/MB/main.py +++ b/HNS/MB/main.py @@ -1,32 +1,33 @@ import json import os -import time from tkinter import filedialog from tkinter import * from ShipField import ShipField +from ShipView import ShipView -my_field = ShipField() -enemy_field = ShipField() - -active_field = my_field -active_text = {} +active_view = {} -def draw_field(window, field, col_offset=0, row_offset=0): +def create_view(window, col_offset=0, row_offset=0): + field = ShipField() buttons = [] + view = ShipView(field, buttons) + for r in range(0, field.field_size): for c in range(0, field.field_size): btn = Button(window, text='', width=5, height=2) btn.grid(column=c + col_offset, row=r + row_offset) - btn.bind('', lambda e, x=r, y=c: left_button_click(buttons, x, y)) - btn.bind('', right_button_click) - btn.bind('', lambda e, x=r, y=c: button_enter(buttons, x, y)) + btn.bind('', lambda e, x=r, y=c: left_button_click(view, x, y)) + btn.bind('', lambda e: right_button_click(view)) + btn.bind('', lambda e, x=r, y=c: button_enter(view, x, y)) buttons.append(btn) - colorize(field, buttons) - return buttons + + colorize(view) + return view -def colorize(field, buttons): +def colorize(view): + field = view.ship_field for i in range(len(field.field)): bg = "white" if field.field[i] == "1": @@ -41,79 +42,73 @@ def colorize(field, buttons): bg = 'red' if "+" in field.field[i]: bg = 'orange' - buttons[i].configure(bg=bg) + + view.buttons[i].configure(bg=bg) + + refresh_remaining_ships_label(view) def keypress_handler(e): - global active_field + global active_view if e.keysym.isnumeric(): - active_field.set_ship_size(int(e.keysym)) + active_view.ship_field.set_ship_size(int(e.keysym)) else: if e.keysym == 'm': - active_field.toggle_field_mode() + active_view.ship_field.toggle_field_mode() -def left_button_click(buttons, row, col): - global active_field - global active_text - - active_field.action(row, col) - colorize(active_field, buttons) - - refresh_remaining_ships_label(active_field, active_text) +def left_button_click(view, row, col): + view.ship_field.action(row, col) + colorize(view) -def right_button_click(d): - global active_field - active_field.toggle_ship_direction() +def right_button_click(view): + view.ship_field.toggle_ship_direction() + colorize(view) -def button_enter(buttons, row, col): - global active_field - global active_text +def button_enter(view, row, col): + global active_view + active_view = view - if buttons == my_buttons: - active_field = my_field - active_text = my_remainingShipsText - enemy_field.clear_marker() - my_field.target(row, col) + if view == my_view: + enemy_view.ship_field.clear_marker() + my_view.ship_field.target(row, col) - elif buttons == enemy_buttons: - active_field = enemy_field - active_text = enemy_remainingShipsText - my_field.clear_marker() - enemy_field.target(row, col) + elif view == enemy_view: + my_view.ship_field.clear_marker() + enemy_view.ship_field.target(row, col) - colorize(my_field, my_buttons) - colorize(enemy_field, enemy_buttons) + colorize(my_view) + colorize(enemy_view) -def savebutton_click(field): +def savebutton_click(view): file_path = filedialog.asksaveasfilename(filetypes=[("JSON files", "*.json")]) if file_path: with open(file_path, 'w') as f: - json.dump({'shipField': field}, f, default=ShipField.convert_to_json) + json.dump({'shipField': view.ship_field}, f, default=ShipField.convert_to_json) -def loadbutton_click(field, buttons): +def loadbutton_click(view): file_path = filedialog.askopenfilename(filetypes=[("JSON files", "*.json")]) if os.path.isfile(file_path): with open(file_path) as lines: - field.from_json(json.load(lines)["shipField"]) + view.ship_field.from_json(json.load(lines)["shipField"]) - colorize(field, buttons) + colorize(view) -def refresh_remaining_ships_label(field, stringvar): +def refresh_remaining_ships_label(view): text = '' for i in range(1, 5): - count = field.ships.count(i) + count = view.ship_field.ships.count(i) if count > 0: text += f'{"[]" * i}: {count}, ' - stringvar.set(text[:-2]) + view.remaining_ships_text.set(text[:-2]) window = Tk() @@ -121,22 +116,19 @@ window.title("Ship Craft!") window.geometry('1020x540') window.bind_all('', keypress_handler) -my_remainingShipsText = StringVar() -enemy_remainingShipsText = StringVar() - start_column_my_field = 1 start_row_my_field = 1 -start_column_enemy_field = start_column_my_field + my_field.field_size + 1 +start_column_enemy_field = start_column_my_field + ShipField.field_size + 1 start_row_enemy_field = start_row_my_field -col_vertical_separator = start_column_my_field + my_field.field_size -row_horizontal_separator = start_row_my_field + my_field.field_size +col_vertical_separator = start_column_my_field + ShipField.field_size +row_horizontal_separator = start_row_my_field + ShipField.field_size -load_button_row = start_row_my_field + my_field.field_size + 1 +load_button_row = start_row_my_field + ShipField.field_size + 1 -my_buttons = draw_field(window, my_field, start_column_my_field, start_row_my_field) -enemy_buttons = draw_field(window, enemy_field, start_column_enemy_field, start_row_enemy_field) +my_view = create_view(window, start_column_my_field, start_row_my_field) +enemy_view = create_view(window, start_column_enemy_field, start_row_enemy_field) if start_column_my_field > 0: lbl_left_vertical = Label(window, text='', width=5, height=2) @@ -149,22 +141,22 @@ if start_row_my_field > 0: lbl_upper_horizontal = Label(window, text='', width=5, height=2) lbl_upper_horizontal.grid(column=start_column_my_field, row=start_row_my_field - 1) -lbl_lower_horizontal = Label(window, text='', width=50, height=2, textvariable=my_remainingShipsText) +lbl_lower_horizontal = Label(window, text='', width=50, height=2, textvariable=my_view.remaining_ships_text) lbl_lower_horizontal.grid(column=start_column_my_field, row=row_horizontal_separator, columnspan=10) -lbl_lower_enemy_horizontal = Label(window, text='', width=50, height=2, textvariable=enemy_remainingShipsText) +lbl_lower_enemy_horizontal = Label(window, text='', width=50, height=2, textvariable=enemy_view.remaining_ships_text) lbl_lower_enemy_horizontal.grid(column=start_column_enemy_field, row=row_horizontal_separator, columnspan=10) -savebutton = Button(window, text='Save', width=20, height=2, command=lambda: savebutton_click(my_field)) +savebutton = Button(window, text='Save', width=20, height=2, command=lambda: savebutton_click(my_view)) savebutton.grid(column=start_column_my_field, row=load_button_row, columnspan=4) -loadbutton = Button(window, text='Load', width=20, height=2, command=lambda: loadbutton_click(my_field, my_buttons)) +loadbutton = Button(window, text='Load', width=20, height=2, command=lambda: loadbutton_click(my_view)) loadbutton.grid(column=start_column_my_field + 6, row=load_button_row, columnspan=4) -savebutton_enemy = Button(window, text='Save', width=20, height=2, command=lambda: savebutton_click(enemy_field)) +savebutton_enemy = Button(window, text='Save', width=20, height=2, command=lambda: savebutton_click(enemy_view)) savebutton_enemy.grid(column=start_column_enemy_field, row=load_button_row, columnspan=4) -loadbutton_enemy = Button(window, text='Load', width=20, height=2, command=lambda: loadbutton_click(enemy_field, enemy_buttons)) +loadbutton_enemy = Button(window, text='Load', width=20, height=2, command=lambda: loadbutton_click(enemy_view)) loadbutton_enemy.grid(column=start_column_enemy_field + 6, row=load_button_row, columnspan=4)