# encoding: utf-8 # frozen_string_literal: true require_relative './util/constants' require_relative 'game_state' require_relative 'field' # Ein Spielbrett fuer Ostseeschach class Board include Constants # @!attribute [r] fields # @note Besser über die {#field} Methode auf Felder zugreifen. # @return [Array<Array<Field>>] Ein Feld wird an der Position entsprechend # seiner x und y Coordinates im Array gespeichert. attr_reader :fields # Erstellt ein neues leeres Spielbrett. def initialize(fields = []) @fields = Board.empty_game_field fields.each { |f| add_field(f) } end # @return [Array] leere Felder entsprechend des Spielbrettes angeordnet def self.empty_game_field (0...BOARD_SIZE).to_a.map do |x| (0...BOARD_SIZE).to_a.map do |y| Field.new(x, y) end end end # Entfernt alle Felder des Spielfeldes def clear @fields = [] end # @return [Array] Liste aller Felder def field_list @fields.flatten.reject(&:nil?) end # Vergleicht zwei Spielbretter. Gleichheit besteht, wenn zwei Spielbretter die # gleichen Felder enthalten. def ==(other) field_list == other.field_list end # Fügt ein Feld dem Spielbrett hinzu. Das übergebene Feld ersetzt das an den # Koordinaten bestehende Feld. # # @param field [Field] Das einzufügende Feld. def add_field(field) @fields[field.x][field.y] = field end # Zugriff auf die Felder des Spielfeldes # # @param x [Integer] Die X-Koordinate des Feldes. # @param y [Integer] Die Y-Koordinate des Feldes. # @return [Field] Das Feld mit den gegebenen Koordinaten. Falls das Feld nicht # exisitert, wird nil zurückgegeben. def field(x, y) fields.dig(x, y) # NOTE that #dig requires ruby 2.3+ end # Zugriff auf die Felder des Spielfeldes über ein Koordinaten-Paar. # # @param coordinates [Coordinates] X- und Y-Koordinate als Paar, sonst wie # bei {Board#field}. # # @return [Field] Wie bei {Board#field}. # # @see #field def field_at(coordinates) field(coordinates.x, coordinates.y) end def fields_of_color(color) fields = [] (0...BOARD_SIZE).to_a.map do |x| (0...BOARD_SIZE).to_a.map do |y| f = field(x,y) if (f.color == color) fields << f end end end fields end # @param it [Coordinates] Die zu untersuchenden Koordinaten # @return [Boolean] Ob die gegebenen Koordinaten auf dem Board liegen oder nicht def in_bounds?(it) it.x >= 0 && it.y >= 0 && it.x < BOARD_SIZE && it.y < BOARD_SIZE end # @return eine unabhaengige Kopie des Spielbretts def clone Marshal.load(Marshal.dump(self)) end # @param coords [Coordinates] Die Koordinaten des Felds # @return Das Feld an den gegebenen Koordinaten def [](coords) field_at(coords) end # Gibt eine textuelle Repräsentation des Spielbrettes aus. def to_s "\n" + (0...BOARD_SIZE).to_a.map do |y| (0...BOARD_SIZE).to_a.map do |x| @fields[x][y].to_s end.join(' ') end.join("\n") end # @param position [Coordinates] Die zu überprüfenden Koordinaten # @return Ob die gegebenen Koordinaten auf dem board liegen def self.contains(position) position.x >= 0 && position.x < BOARD_SIZE && position.y >= 0 && position.y < BOARD_SIZE end end