package state import ( "fmt" "github.com/rs/xid" "go.uber.org/zap/zapcore" ) // HexMapRepresentation combines HexOrientation and LineParity to represent a map's display mode. type HexMapRepresentation struct { Orientation HexOrientation `json:"orientation"` IndentedLines LineParity `json:"indentedLines"` } func (h HexMapRepresentation) MarshalLogObject(encoder zapcore.ObjectEncoder) error { encoder.AddString("orientation", h.Orientation.String()) encoder.AddString("indentedLines", h.IndentedLines.String()) return nil } // HexCell contains data for a single cell of the map. type HexCell struct { // Color contains the color of the cell, in hex notation. Color HexColor `json:"color"` } func (h HexCell) MarshalLogObject(encoder zapcore.ObjectEncoder) error { encoder.AddString("color", h.Color.String()) return nil } // HexLine is a line of cells which are adjacent by flat sides in a vertical or horizontal direction. type HexLine []HexCell func (l HexLine) MarshalLogArray(encoder zapcore.ArrayEncoder) error { var finalErr error for _, cell := range l { err := encoder.AppendObject(cell) if err != nil && finalErr == nil { finalErr = err } } return finalErr } // Copy creates a deep copy of this HexLine. func (l HexLine) Copy() HexLine { duplicate := make(HexLine, len(l)) for index, value := range l { duplicate[index] = value } return duplicate } // HexLayer is a two-dimensional plane of cells which are arranged into lines. type HexLayer []HexLine func (l HexLayer) MarshalLogArray(encoder zapcore.ArrayEncoder) error { var finalErr error for _, line := range l { err := encoder.AppendArray(line) if err != nil && finalErr == nil { finalErr = err } } return finalErr } // GetCellAt returns a reference to the cell at the given coordinates. // If the coordinates are out of bounds for this map, an error will be returned. func (l HexLayer) GetCellAt(c StorageCoordinates) (*HexCell, error) { if int(c.Line) > len(l) { return nil, fmt.Errorf("line %d out of bounds (%d)", c.Line, len(l)) } line := l[c.Line] if int(c.Cell) > len(line) { return nil, fmt.Errorf("cell %d out of bounds (%d)", c.Cell, len(line)) } return &(line[c.Cell]), nil } // Copy creates a deep copy of this HexLayer. func (l HexLayer) Copy() HexLayer { duplicate := make(HexLayer, len(l)) for index, value := range l { duplicate[index] = value.Copy() } return duplicate } // HexMap contains the data for a map instance. type HexMap struct { // XID is the unique id of the HexMap, used to encourage clients not to blindly interact with a different map. XID xid.ID `json:"xid"` // Lines is the rough number of rows (in PointyTop orientation) or columns (in FlatTop orientation) in the map. // Because different lines will be staggered, it's somewhat hard to see. Lines uint8 `json:"lines"` // CellsPerLine is the rough number of columns (in PointyTop orientation) or rows (in FlatTop orientation). // This is the number of cells joined together, flat-edge to flat-edge, in each line. CellsPerLine uint8 `json:"cellsPerLine"` // DisplayMode is the orientation and line parity used to display the map. DisplayMode HexMapRepresentation `json:"displayMode"` // LineCells contains the actual map data. // LineCells itself is a slice with Lines elements, each of which is a line; // each of those lines is a slice of CellsPerLine cells. LineCells HexLayer `json:"lineCells"` } func (m HexMap) MarshalLogObject(encoder zapcore.ObjectEncoder) error { encoder.AddString("id", m.XID.String()) encoder.AddUint8("lines", m.Lines) encoder.AddUint8("cellsPerLine", m.CellsPerLine) displayModeErr := encoder.AddObject("displayMode", m.DisplayMode) lineCellsErr := encoder.AddArray("lineCells", m.LineCells) if displayModeErr != nil { return displayModeErr } else { return lineCellsErr } } // Copy creates a deep copy of this HexMap. func (m HexMap) Copy() HexMap { return HexMap{ XID: m.XID, Lines: m.Lines, CellsPerLine: m.CellsPerLine, DisplayMode: m.DisplayMode, LineCells: m.LineCells.Copy(), } }