diff --git a/ttrs.py b/ttrs.py index d01a4b5..6576326 100755 --- a/ttrs.py +++ b/ttrs.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import socket +import struct import time import enum import math @@ -59,11 +60,15 @@ class Tetrimino(): return self.__calc_points() def __check_collision(self, newpoints): - if not self.playground.contains_points(newpoints): - raise InvalidMoveError('out of playground bounds') - print(self.playground.block_points) - print(self.playground.blocks) - print('new', newpoints) + #if not self.playground.contains_points(newpoints): + # raise InvalidMoveError('out of playground bounds') + #print(self.playground.block_points) + #print(self.playground.blocks) + #print('new', newpoints) + for newp in newpoints: + if ( newp.x >= self.playground.width or newp.x < 0 or + newp.y >= self.playground.height): + raise InvalidMoveError('out of playground bounds') if not self.playground.block_points.isdisjoint(newpoints): raise InvalidMoveError('new position already occupied') other_mino_points = self.playground.mino_points - self.points @@ -179,15 +184,24 @@ class Playground(): frame.setPixel(xpos + int(b.pos.x), ypos + int(b.pos.y), b.color) class TtrsPlayer(): - def __init__(self): - self.move = 0 - self.drop = False - self.rotate = False - self.quit = False + def __init__(self, playground): + pass + def get_move(self, minopos): + return 0 + + def get_drop(self): + return False + + def get_rotate(self): + return False + + def get_quit(self): + return False class TestTtrsPlayer(TtrsPlayer): - def __init__(self): + def __init__(self, playground): + self.playground = playground self.__move = 0 self.__drop = False self.__rotate = False @@ -219,24 +233,82 @@ class TestTtrsPlayer(TtrsPlayer): self.__rotate = False elif event.key == pygame.K_s: self.__drop = False - @property - def move(self): + + def get_move(self, minopos): self.__process_events() return self.__move - @property - def drop(self): + + def get_drop(self): self.__process_events() return self.__drop - @property - def rotate(self): + + def get_rotate(self): self.__process_events() return self.__rotate - @property - def quit(self): + + def get_quit(self): self.__process_events() return self.__quit +class BalanceTtrsPlayer(TtrsPlayer): + def __init__(self, playground, addr, player_id): + self.playground = playground + self.player_id = player_id + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.connect(addr) + + def __update_balance(self): + self.sock.send(b'a') + data = self.sock.recv(4) + p1x, p1y, p2x, p2y = struct.unpack('bbbb', data) + if self.player_id == 0: + self.xbal = p1x + self.ybal = p1y + elif self.player_id == 1: + self.xbal = p2x + self.ybal = p2y + + def reset_rotate(self): + self.__rotate_reset = True + self.__rotate = False + + def get_move(self, minopos): + self.__update_balance() + + #if p1x > 40: + # self.__move = 1 + #elif p1x < -40: + # self.__move = -1 + #elif p1x > -20 and p1x < 20: + # self.__move = 0 + MAX_Y_AMPLITUDE = 65 + bal = self.xbal + normbal = (bal + MAX_Y_AMPLITUDE) / (2 * MAX_Y_AMPLITUDE) + px = round(normbal * (self.playground.width - 1)) + print('player %d balance=%d pos=%d' % (self.player_id, bal, px)) + if minopos.x > px: + return -1 + elif minopos.x < px: + return 1 + else: + return 0 + + def get_drop(self): + self.__update_balance() + return (self.ybal < -50) + + def get_rotate(self): + self.__update_balance() + if self.ybal > 50 and not self.__rotate_reset: + return True + elif self.ybal < 35: + self.__rotate_reset = False + return False + + def get_quit(self): + self.__update_balance() + return (self.xbal == -128 or self.ybal == -128) class TtrsGame(): @@ -255,7 +327,7 @@ class TtrsGame(): mino = None TICK_TIME = 0.1 FALL_INTERVAL = 5 - MOVE_INTERVAL = 1 + MOVE_INTERVAL = 2 ticks = 0 lastfall = 0 lastmove = 0 @@ -265,7 +337,7 @@ class TtrsGame(): time.sleep(TICK_TIME) ticks += 1 - if self.player.quit: + if self.player.get_quit(): self.running = False break @@ -273,21 +345,28 @@ class TtrsGame(): newminocls = random.choice(Tetrimino.__subclasses__()) mino = newminocls(self.playground, spawnpos) self.playground.minos = {mino} + + #print(mino.pos) + to_remove = set() for y in range(self.playground.height): row = { Point(x, y) for x in range(self.playground.width) } if row.issubset(self.playground.block_points): - for b in list(self.playground.blocks): - if b.pos.y == y: - self.playground.blocks.remove(b) - elif b.pos.y < y: - self.playground.blocks.remove(b) - newb = Block(b.pos + Point(0, 1), b.color) - self.playground.blocks.add(newb) + to_remove.add(y) + if len(to_remove) > 0: + for b in list(self.playground.blocks): + if b.pos.y in to_remove: + self.playground.blocks.remove(b) + for b in list(self.playground.blocks): + o = len(list(filter(lambda y: y > b.pos.y, to_remove))) + if o > 0: + self.playground.blocks.remove(b) + newb = Block(b.pos + Point(0, o), b.color) + self.playground.blocks.add(newb) - if ticks - lastfall >= FALL_INTERVAL or self.player.drop: + if ticks - lastfall >= FALL_INTERVAL or self.player.get_drop(): lastfall = ticks try: mino.move(Point(0, 1)) @@ -297,16 +376,18 @@ class TtrsGame(): self.playground.minos = set() continue - if ticks - lastmove >= MOVE_INTERVAL and self.player.move != 0: + move = self.player.get_move(mino.pos) + if ticks - lastmove >= MOVE_INTERVAL and move != 0: lastmove = ticks try: - mino.move(Point(self.player.move, 0)) + mino.move(Point(move, 0)) except InvalidMoveError: pass - if self.player.rotate: + if self.player.get_rotate(): try: mino.rotate() + self.player.reset_rotate() except InvalidMoveError: pass @@ -324,7 +405,7 @@ if __name__ == '__main__': dim = blup.frame.FrameDimension(w, h, 256, 3) frame = blup.frame.Frame(dim) - out = blup.output.getOutput('e3blp') + out = blup.output.getOutput('e3blp:blinkenbunt:2342') pg = Playground(10, 16) pg.paint(frame, 0, 0) @@ -335,7 +416,8 @@ if __name__ == '__main__': pg.paint(frame, 0, 0) out.sendFrame(frame) - player = TestTtrsPlayer() + #player = TestTtrsPlayer(pg) + player = BalanceTtrsPlayer(pg, ('blinkenbunt', 4711), 0) game = TtrsGame(pg, player) game.add_tick_callback(repaint) game.run()