class OKing(OPawn): _sh_cross_bar = _so.ShBox(_vec3(0.06, 0.02, 0.02)) _shape = _so.ShCompound(( (OPawn._shape, _so.trans()), (_sh_cross_bar, _so.trans(_vec3(z=0.06 + _MagnetPawn.HEIGHT / 2))), (_sh_cross_bar, _so.trans(_so.matrix3(pitch=_math.pi / 2), _vec3(z=0.06 + _MagnetPawn.HEIGHT / 2))), )) _mass = 0.5 # 300g to 700g
class OPlate(_so.OSimple): _mass = 0.220 _sh_bar_x = _so.ShBox(_vec3(.170, .022, .022)/2) _sh_bar_y = _so.ShBox(_vec3(.022, .170, .022)/2) _shape = _so.ShCompound(( (_sh_bar_x, _so.trans(_vec3(0, -(.170-.022), .005)/2)), (_sh_bar_x, _so.trans(_vec3(0, (.170-.022), .005)/2)), (_sh_bar_y, _so.trans(_vec3(-(.170-.022), 0, .005)/2)), (_sh_bar_y, _so.trans(_vec3( (.170-.022), 0, .005)/2)), (_so.ShBox(_vec3(.170, .170, .005)/2), _so.trans(_vec3(0, 0, -.022/2))), )) def __init__(self): _so.OSimple.__init__(self, self._shape, self._mass) self.color = _eb.RAL[3015]
class Bac: """Collect bac.""" XY0 = _vec2(TABLE_SIZE.x-0.500, -TABLE_SIZE.y)/2 SIZE = _vec2(0.500, 0.300) WIDTH = 0.010 HEIGHT = 0.300 _band_side = _so.ShBox(_vec3(WIDTH, SIZE.y, WALL_HEIGHT)/2) _plexi_side = _so.ShBox(_vec3(WIDTH, SIZE.y, HEIGHT)/2) _band_back = _so.ShBox(_vec3(SIZE.x+2*WIDTH, WIDTH, WALL_HEIGHT)/2) _plexi_back = _so.ShBox(_vec3(SIZE.x+2*WIDTH, WIDTH, HEIGHT)/2) _plexi_front = _so.ShBox(_vec3(SIZE.x+2*WIDTH, WIDTH, HEIGHT-0.040)/2) _plexi_bottom = _so.ShBox(_vec3(SIZE.x+2*WIDTH, WIDTH+SIZE.y, WIDTH)/2) sh_band = _so.ShCompound(( (_band_side, _so.trans(_vec2(-SIZE.x-WIDTH, -SIZE.y)/2)), (_band_side, _so.trans(_vec2( SIZE.x+WIDTH, -SIZE.y)/2)), (_band_back, _so.trans(_vec2(0, -2*SIZE.y-WIDTH)/2)), )) sh_plexi = _so.ShCompound(( (_plexi_side, _so.trans(_vec3(-SIZE.x-WIDTH, -SIZE.y, 0)/2)), (_plexi_side, _so.trans(_vec3( SIZE.x+WIDTH, -SIZE.y, 0)/2)), (_plexi_back, _so.trans(_vec3(0, -2*SIZE.y-WIDTH, 0)/2)), (_plexi_front, _so.trans(_vec3(0, -WIDTH, -0.040)/2)), (_plexi_bottom, _so.trans(_vec3(0, -SIZE.y-WIDTH, -HEIGHT)/2)), )) def __init__(self, team): if team == 0: xy0 = self.XY0 elif team == 1: xy0 = self.XY0 * _vec2(-1,1) else: raise ValueError("invalid team") self.team = int(team) ob = _so.OSimple(self.sh_band) ob.pos = _vec3(0,0, WALL_HEIGHT/2) + xy0 ob.color = TEAM_COLORS[self.team] op = _so.OSimple(self.sh_plexi) op.pos = _vec3(0,0, -self.HEIGHT/2) + xy0 op.color = _so.Color.plexi self.band = ob self.plexi = op def contains(self, o): """Return True if the object is in the bac. Test is based on object's center of mass position. """ d = abs(o.pos - self.plexi.pos) return d.x < self.SIZE.x and d.y < self.SIZE.y and d.z < self.HEIGHT def addToWorld(self, ph): self.band.addToWorld(ph) self.plexi.addToWorld(ph) def removeFromWorld(self): self.band.removeFromWorld() self.plexi.removeFromWorld()
def prepare(self, fconf=None): if fconf is None: self.conf = self.Conf.random() else: self.conf = self.Conf(*fconf) ph = self.physics # Ground ground = OGround() ground.addToWorld(ph) self.ground = ground # Walls (N, S, E, W) color = _eb.RAL[9017] sh = _so.ShBox( _vec3(TABLE_SIZE.x + WALL_WIDTH, WALL_WIDTH, WALL_HEIGHT) / 2) o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(0, TABLE_SIZE.y + WALL_WIDTH, WALL_HEIGHT) / 2 o.color = color o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(0, -TABLE_SIZE.y - WALL_WIDTH, WALL_HEIGHT) / 2 o.color = color sh = _so.ShBox( _vec3(WALL_WIDTH, TABLE_SIZE.y + 2 * WALL_WIDTH, WALL_HEIGHT) / 2) o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(TABLE_SIZE.x + WALL_WIDTH, 0, WALL_HEIGHT) / 2 o.color = color o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(-TABLE_SIZE.x - WALL_WIDTH, 0, WALL_HEIGHT) / 2 o.color = color # Starting areas, inside borders sh = _so.ShBox(_vec3(ground.start_size, WALL_WIDTH, WALL_HEIGHT) / 2) o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(-TABLE_SIZE.x + ground.start_size, TABLE_SIZE.y - WALL_WIDTH - 2 * ground.start_size, WALL_HEIGHT) / 2 o.color = TEAM_COLORS[0] o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(TABLE_SIZE.x - ground.start_size, TABLE_SIZE.y - WALL_WIDTH - 2 * ground.start_size, WALL_HEIGHT) / 2 o.color = TEAM_COLORS[1] # Secured zones, borders (centered on surrounded squares) sh_wall = _so.ShBox(_vec3(WALL_WIDTH, 0.150, WALL_HEIGHT) / 2) sh_block = _so.ShBox(_vec3(0.700, 0.120, WALL_HEIGHT) / 2) sh = _so.ShCompound(( (sh_wall, _so.trans(_vec2(-SQUARE_SIZE + WALL_WIDTH / 2))), (sh_wall, _so.trans(_vec2(SQUARE_SIZE - WALL_WIDTH / 2))), (sh_block, _so.trans(_vec2(0, (-SQUARE_SIZE + 0.120) / 2))), )) o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(-2 * SQUARE_SIZE, -2.5 * SQUARE_SIZE, WALL_HEIGHT / 2) o.color = color o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(2 * SQUARE_SIZE, -2.5 * SQUARE_SIZE, WALL_HEIGHT / 2) o.color = color # Pawns on the field self.pawns = [self.addPiece(0, 0)] for j in RANDOM_POS[self.conf.line1]: y = (j - 2) * SQUARE_SIZE self.pawns.append(self.addPiece(-2 * SQUARE_SIZE, y)) self.pawns.append(self.addPiece(2 * SQUARE_SIZE, y)) for j in RANDOM_POS[self.conf.line2]: y = (j - 2) * SQUARE_SIZE self.pawns.append(self.addPiece(-1 * SQUARE_SIZE, y)) self.pawns.append(self.addPiece(1 * SQUARE_SIZE, y)) # Pieces in dispensing zones pos_king, pos_queen = RANDOM_POS[self.conf.kingqueen] x = (TABLE_SIZE.x - ground.start_size) / 2 for j in range(5): y = -TABLE_SIZE.y / 2 + (5 - j) * DISPENSING_DY if j == pos_king: self.kings = (self.addPiece(-x, y, OKing), self.addPiece(x, y, OKing)) elif j == pos_queen: self.queens = (self.addPiece(-x, y, OQueen), self.addPiece(x, y, OQueen)) else: self.pawns.append(self.addPiece(-x, y)) self.pawns.append(self.addPiece(x, y))
class OQueen(OPawn): _sh_figure = _so.ShSphere(0.16 / 2) _shape = _so.ShCompound( ((OPawn._shape, _so.trans()), (_sh_figure, _so.trans(_vec3(z=0.16 / 2 - 0.02))))) _mass = 0.5 # 300g to 700g
def prepare(self, fconf=None): if fconf is None: self.conf = self.Conf.random() else: self.conf = self.Conf(*fconf) ph = self.physics # Ground ground = OGround() ground.addToWorld(ph) self.ground = ground # Walls (N, S, E, W) color = _eb.RAL[5012] sh = _so.ShBox(_vec3(TABLE_SIZE.x+WALL_WIDTH, WALL_WIDTH, WALL_HEIGHT)/2) o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(0, TABLE_SIZE.y+WALL_WIDTH, WALL_HEIGHT)/2 o.color = color o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(0, -TABLE_SIZE.y-WALL_WIDTH, WALL_HEIGHT)/2 o.color = color sh = _so.ShBox(_vec3(WALL_WIDTH, TABLE_SIZE.y+2*WALL_WIDTH, WALL_HEIGHT)/2) o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(TABLE_SIZE.x+WALL_WIDTH, 0, WALL_HEIGHT)/2 o.color = color o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(-TABLE_SIZE.x-WALL_WIDTH, 0, WALL_HEIGHT)/2 o.color = color # Ship borders W = 0.018 # border width deck_angle = _math.atan2(0.4-0.325, TABLE_SIZE.y-ground.start_size-W) sh = _so.ShBox(_vec3(0.4, W, W)/2) for kx in (1, -1): o = _so.OSimple(sh) o.addToWorld(ph) o.color = _eb.RAL[8002] o.pos = _vec3(kx*(TABLE_SIZE.x-0.4)/2, TABLE_SIZE.y/2-ground.start_size-W/2, W/2) r = 0.75 sh = _so.ShBox(_vec3(W, r, W)/2) for kx in (1, -1): a = kx*deck_angle o = _so.OSimple(sh) o.addToWorld(ph) o.color = _eb.RAL[8002] o.trans = _so.trans( _so.quat(_vec3(0,0,1), a), # hacky offset, for better-looking result _vec3(kx*( TABLE_SIZE.x/2-(3*0.325+0.4)/4-W*_math.cos(a)/2 +0.002), (-TABLE_SIZE.y+r*_math.cos(a))/2, W/2 )) # Ship's hold covers # static for now (cannot be opened) ox = (TABLE_SIZE.x-0.340)/2 + 0.018 oy = -(TABLE_SIZE.y-0.610)/2 - 0.018 sh_barh = _so.ShBox(_vec3(0.340, 0.018, 0.018)/2) sh_barv = _so.ShBox(_vec3(0.018, 0.610, 0.018)/2) sh = _so.ShCompound(( (sh_barh, _so.trans(_vec3(0, 0.610-0.018, 0)/2)), (sh_barh, _so.trans(_vec3(0, -(0.610-0.018), 0)/2)), (sh_barv, _so.trans(_vec3(0.340-0.018, 0, 0)/2)), (sh_barv, _so.trans(_vec3(-(0.340-0.018), 0, 0)/2)), )) for kx in (1, -1): o = _so.OSimple(sh) o.addToWorld(ph) o.color = _eb.RAL[8002] o.pos = _vec3(kx*ox, oy, WALL_HEIGHT+0.018/2) sh = _so.ShBox(_vec3(0.340, 0.610, 0.001)/2) for kx in (1, -1): o = _so.OSimple(sh) o.addToWorld(ph) o.color = _so.Color.plexi o.pos = _vec3(kx*ox, oy, WALL_HEIGHT+0.018+0.001/2) # Palm-tree sh = _so.ShCylinderZ(_vec3(0.04, 0.04, 0.250)/2) o = _so.OSimple(sh) o.addToWorld(ph) o.color = _eb.RAL[8002] o.pos = _vec3(0, 0, 0.250/2) sh = _so.ShCylinderZ(_vec3(0.150, 0.150, 0.002)/2) o = _so.OSimple(sh) o.addToWorld(ph) o.color = _eb.RAL[6018] o.pos = _vec3(0, 0, 0.250+0.002/2) # Totems sh_trunk = _so.ShBox(_vec3(0.070, 0.070, 0.163)/2) sh_flat = _so.ShBox(_vec3(0.250, 0.250, 0.018)/2) sh = _so.ShCompound(( (sh_trunk, _so.trans()), (sh_flat, _so.trans(_vec3(0, 0, -0.0545-0.018))), (sh_flat, _so.trans(_vec3(0, 0, 0))), (sh_flat, _so.trans(_vec3(0, 0, +0.0545+0.018))), )) for kx in (1, -1): o = _so.OSimple(sh) o.addToWorld(ph) o.color = _eb.RAL[8002] o.pos = _vec3(kx*0.8, 0, 0.163)/2 # Treasure map #TODO map width is not known yet, centered on X map_width = 0.400 sh_back = _so.ShBox(_vec3(map_width, 0.258, 0.010)/2) sh_side = _so.ShBox(_vec3(0.018, 0.258, 0.018)/2) # origin is the nearest point to the table sh = _so.ShCompound(( (sh_back, _so.trans(_vec3(0, 0.258/2, 0.010/2))), (sh_side, _so.trans(_vec3(-(map_width-0.018)/2, 0.258/2, 0.010+0.018/2))), (sh_side, _so.trans(_vec3( (map_width-0.018)/2, 0.258/2, 0.010+0.018/2))), )) o = _so.OSimple(sh) o.addToWorld(ph) o.color = _eb.RAL[5012] a = _math.radians(35) o.trans = _so.trans( _so.quat(_vec3(1,0,0), a), _vec3(0, TABLE_SIZE.y/2, 0.315-(0.258+(0.018+0.10))*_math.sin(a)) ) # Bottle supports w = WALL_WIDTH sh_small = _so.ShBox(_vec3(0.089, w, w)/2) sh_large = _so.ShBox(_vec3(0.200, w, w)/2) sh = _so.ShCompound(( (sh_small, _so.trans(_vec3(-(0.089+w)/2, -w/2, w/2))), (sh_small, _so.trans(_vec3( (0.089+w)/2, -w/2, w/2))), (sh_large, _so.trans(_vec3(0, -w/2, w+w/2))), (sh_large, _so.trans(_vec3(0, -w-w/2, -w/2))), )) for x in (TABLE_SIZE.x/2-0.640, -(TABLE_SIZE.x/2-0.640-0.477)): for kx in (1, -1): o = _so.OSimple(sh) o.addToWorld(ph) o.color = _eb.RAL[5012] o.pos = _vec3(kx*x, -TABLE_SIZE.y/2, WALL_HEIGHT) # Bottle buttons # origin is the attache point on the border (y=WALL_HEIGHT) # reuse sh_large and w from bottle supports #TODO sh_buttonv Y size is not known sh_buttonh = _so.ShBox(_vec3(w, 2*w, w)/2) sh_buttonv = _so.ShBox(_vec3(w, w, 0.103)/2) sh = _so.ShCompound(( (sh_large, _so.trans(_vec3(0, -w-w/2, w/2))), (sh_buttonh, _so.trans(_vec3(0, 0, w/2))), (sh_buttonv, _so.trans(_vec3(0, w+w/2, -WALL_HEIGHT+0.003+0.103/2))), )) for x in (TABLE_SIZE.x/2-0.640, -(TABLE_SIZE.x/2-0.640-0.477)): for kx in (1, -1): o = _so.OSimple(sh, 0.100) o.addToWorld(ph) o.color = TEAM_COLORS[ 1 if kx == 1 else 0 ] o.pos = _vec3(kx*x, -TABLE_SIZE.y/2, WALL_HEIGHT) # Bullions bsize = OBullion.SIZE l = [] # x, y, z_bottom, angle_z l.append((0, -TABLE_SIZE.y/2+0.647, 0, 0)) for kx in (1, -1): # bullion along the deck v = _vec2(TABLE_SIZE.x/2-0.400-bsize.y/2, TABLE_SIZE.y/2-ground.start_size) v += _vec2(0, -0.285-bsize.x/2).rotate(deck_angle) l.append((kx*v.x, v.y, 0, _math.pi/2+kx*deck_angle)) # bullions on totems l.append((kx*0.8/2, (0.070+0.090)/2, 0.018+0.0545+0.018, 0)) l.append((kx*0.8/2, -(0.070+0.090)/2, 0.018+0.0545+0.018, 0)) for x,y,z0,a in l: o = OBullion() o.addToWorld(ph) o.trans = _so.trans( _so.quat(_vec3(0,0,1), a), _vec3(x, y, z0 + bsize.z/2 + ph.margin_epsilon) ) # Coins #XXX exact position of several coins is not known l = [ # (x>0, y, z_bottom, angle_z) (TABLE_SIZE.x/2-0.450, -TABLE_SIZE.y/2+0.300, 0, 0), (0.090, -TABLE_SIZE.y/2+0.300, 0, 0) ] for i in range(-3,4): a = i*_math.pi/4 ca = _math.cos(a) sa = _math.sin(a) l.append( (0.8/2+0.25*ca, 0.25*sa, 0, a) ) if i % 2 == 1: l.append( (0.8/2+0.100*ca, 0.110*sa, 0.018, a) ) l.append( (0.8/2+0.100*ca, 0.110*sa, 0.163, a) ) # group coins them by pairs for random picking of black coins lpairs = [( (0, -TABLE_SIZE.y/2+0.300+0.090, 0, _math.pi/2), (0, -TABLE_SIZE.y/2+0.300-0.090, 0, -_math.pi/2) )] for x,y,z0,a in l: lpairs.append(((x,y,z0,a), (-x,y,z0,-a+_math.pi))) # pick up random pairs which will be black import random black_pairs = random.sample(lpairs, 2) # last pair, never black lpairs.append(( ( TABLE_SIZE.x/2-0.5-0.5, TABLE_SIZE.y/2-0.5, 0, 0), (-(TABLE_SIZE.x/2-0.5-0.5), TABLE_SIZE.y/2-0.5, 0, _math.pi) )) # finally, created the coins for p in lpairs: white = p not in black_pairs for x,y,z0,a in p: o = OCoin(white) o.addToWorld(ph) o.trans = _so.trans( _so.quat(_vec3(0,0,1), a), _vec3(x, y, z0 + OCoin.CUBE_SIZE + ph.margin_epsilon) )
def prepare(self, fconf=None): if fconf is None: self.conf = self.Conf.random() else: self.conf = self.Conf(*fconf) ph = self.physics # Ground ground = OGround() ground.addToWorld(ph) self.ground = ground # Walls (N, S, E, W) color = _eb.RAL[9017] sh = _so.ShBox(_vec3(TABLE_SIZE.x+WALL_WIDTH, WALL_WIDTH, WALL_HEIGHT)/2) o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(0, TABLE_SIZE.y+WALL_WIDTH, WALL_HEIGHT)/2 o.color = color o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(0, -TABLE_SIZE.y-WALL_WIDTH, WALL_HEIGHT)/2 o.color = color sh = _so.ShBox(_vec3(WALL_WIDTH, TABLE_SIZE.y+2*WALL_WIDTH, WALL_HEIGHT)/2) o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(TABLE_SIZE.x+WALL_WIDTH, 0, WALL_HEIGHT)/2 o.color = color o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(-TABLE_SIZE.x-WALL_WIDTH, 0, WALL_HEIGHT)/2 o.color = color # Starting areas, inside borders sh = _so.ShBox(_vec3(ground.start_size, WALL_WIDTH, WALL_HEIGHT)/2) o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(-TABLE_SIZE.x+ground.start_size, TABLE_SIZE.y-WALL_WIDTH-2*ground.start_size, WALL_HEIGHT)/2 o.color = TEAM_COLORS[0] o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(TABLE_SIZE.x-ground.start_size, TABLE_SIZE.y-WALL_WIDTH-2*ground.start_size, WALL_HEIGHT)/2 o.color = TEAM_COLORS[1] # Secured zones, borders (centered on surrounded squares) sh_wall = _so.ShBox(_vec3(WALL_WIDTH, 0.150, WALL_HEIGHT)/2) sh_block = _so.ShBox(_vec3(0.700, 0.120, WALL_HEIGHT)/2) sh = _so.ShCompound(( (sh_wall, _so.trans(_vec2(-SQUARE_SIZE+WALL_WIDTH/2))), (sh_wall, _so.trans(_vec2( SQUARE_SIZE-WALL_WIDTH/2))), (sh_block, _so.trans(_vec2(0, (-SQUARE_SIZE+0.120)/2))), )) o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(-2*SQUARE_SIZE, -2.5*SQUARE_SIZE, WALL_HEIGHT/2) o.color = color o = _so.OSimple(sh) o.addToWorld(ph) o.pos = _vec3(2*SQUARE_SIZE, -2.5*SQUARE_SIZE, WALL_HEIGHT/2) o.color = color # Pawns on the field self.pawns = [ self.addPiece(0,0) ] for j in RANDOM_POS[self.conf.line1]: y = (j-2)*SQUARE_SIZE self.pawns.append( self.addPiece(-2*SQUARE_SIZE,y) ) self.pawns.append( self.addPiece( 2*SQUARE_SIZE,y) ) for j in RANDOM_POS[self.conf.line2]: y = (j-2)*SQUARE_SIZE self.pawns.append( self.addPiece(-1*SQUARE_SIZE,y) ) self.pawns.append( self.addPiece( 1*SQUARE_SIZE,y) ) # Pieces in dispensing zones pos_king, pos_queen = RANDOM_POS[self.conf.kingqueen] x = (TABLE_SIZE.x - ground.start_size)/2 for j in range(5): y = -TABLE_SIZE.y/2 + (5-j)*DISPENSING_DY if j == pos_king: self.kings = ( self.addPiece(-x, y, OKing), self.addPiece(x, y, OKing) ) elif j == pos_queen: self.queens = ( self.addPiece(-x, y, OQueen), self.addPiece(x, y, OQueen) ) else: self.pawns.append( self.addPiece(-x,y) ) self.pawns.append( self.addPiece( x,y) )