#!/usr/bin/env python # # A generic model for a tri-tetraflexagon # # Copyright (C) 2018 Antonio Ospite # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from math import pi class Tile(object): def __init__(self, square, index): self.square = square self.index = index @staticmethod def calc_plan_coordinates(side, i, j): xoffset = side / 2 + j * side yoffset = side / 2 + i * side return xoffset, yoffset @staticmethod def calc_angle_in_plan(i, j): """The angle of a tile in the tetraflexagon plan.""" return pi * (i > 1) def __str__(self): return "%d,%d" % (self.square.index, self.index) class Square(object): def __init__(self, index): self.index = index self.tiles = [] for i in range(4): tile = Tile(self, i) self.tiles.append(tile) def __str__(self): output = "" for i in range(0, 4): output += str(self.tiles[i]) output += "\t" return output class TriTetraflexagon(object): def __init__(self): self.squares = [] for i in range(0, 3): square = Square(i) self.squares.append(square) # A plan is described by a mapping of the tiles in the squares, # repositioned on a 2d grid. # # In the map below, the grid has two rows, each element of the grid is # a pair (s, t), where 's' is the index of the square, and 't' is the # index of the tile in that square. plan_map = [ [(2, 0), (2, 1), (0, 1), None, None], [None, None, (0, 3), (1, 2), (1, 3)], [None, None, (2, 3), (2, 2), (0, 2)], [(0, 0), (1, 1), (1, 0), None, None], ] # Preallocate a bi-dimensional array for an inverse mapping, this is # useful to retrieve the position in the plan given a tile. self.plan_map_inv = [[-1 for t in h.tiles] for h in self.squares] self.plan = [] for i, plan_map_row in enumerate(plan_map): plan_row = [] for j, mapping in enumerate(plan_map_row): if mapping: square_index, tile_index = mapping square = self.squares[square_index] tile = square.tiles[tile_index] self.plan_map_inv[square_index][tile_index] = (i, j) else: tile = None plan_row.append(tile) self.plan.append(plan_row) def get_tile_plan_position(self, tile): return self.plan_map_inv[tile.square.index][tile.index] def __str__(self): output = "" for row in self.plan: for tile in row: output += "%s\t" % str(tile) output += "\n" return output def test(): tritetraflexagon = TriTetraflexagon() print(tritetraflexagon) if __name__ == "__main__": test()