#!/usr/bin/env python3 import time import argparse import threading import sys import os import configparser import socket import struct import blup.balance_util import blup.frame import blup.output import pong import subprocess logo = [ [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [1,1,1,0,1,1,1,1,0,1,0,0,1,0,0,1,1,0], [1,0,1,0,1,0,0,1,0,1,1,0,1,0,1,0,0,1], [1,0,1,0,1,0,0,1,0,1,0,1,1,0,1,0,0,0], [1,1,1,0,1,0,0,1,0,1,0,0,1,0,1,0,1,1], [1,0,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1], [1,0,0,0,1,1,1,1,0,1,0,0,1,0,0,1,1,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ] logo_go = [ [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0], [0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,0,0], [0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0], [0,0,0,0,1,0,1,1,0,1,0,0,1,0,0,0,0,0], [0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,0,0], [0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ] onePlayer = [ [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0], [0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,0,1,0], [0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0], [0,0,0,1,0,0,1,1,1,1,0,0,0,0,1,0,0,0], [0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0], [0,0,1,1,1,0,1,0,0,0,0,0,0,0,1,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ] __MAX_SCORE__ = 5 def mk_logo_frame(dimension, logo): frame = blup.frame.Frame(dimension) color = pong.getRandomColor(dimension.depth - 1) xoffs = (dimension.width - len(logo[0])) // 2 yoffs = (dimension.height - len(logo)) // 2 for x in range(len(logo[0])): for y in range(len(logo)): if logo[y][x] == 1: frame.setPixel(xoffs + x, yoffs + y, color) return frame def convertPixels(dimension, pixels, invert=False): p = [] maxval = dimension.depth - 1 color = pong.getRandomColor(maxval) for i in range(len(pixels)): row = [] for j in range(len(pixels[i])): if pixels[i][j] == (1 if not invert else 0): row.append(color) else: row.append((0,0,0)) p.append(row) return p class BalanceBoardPlayer(object): def __init__(self, playground, own_paddle, balance_util): self.__playground = playground self.__ownPaddle = own_paddle self.__ready = False self.__playground.addGameTickCallback(self.gametickcb) self.__balance_util = balance_util @property def ownPaddle(self): return self.__ownPaddle @property def ready(self): return true def gametickcb(self): # TODO: add CLI option to select axis bal = self.__balance_util.get_raw_2dir_x() if bal == -128: print("player %d has quit" % self.__balance_util.player_id) self.__balance_util.socket.close() sys.exit(1) bal = -bal MAX_AMPLITUDE = 65 if bal < -MAX_AMPLITUDE: bal = -MAX_AMPLITUDE elif bal > MAX_AMPLITUDE: bal = MAX_AMPLITUDE bal += MAX_AMPLITUDE pos = int((bal / (2 * MAX_AMPLITUDE)) * self.__playground.height) print("player %d pos=%d" % (self.__balance_util.player_id, pos)) if self.__ownPaddle.ypos > pos: self.__ownPaddle.nextMoveUp() elif self.__ownPaddle.ypos < pos: self.__ownPaddle.nextMoveDown() class B4lancePong(object): def __init__(self, out, balanceserver=None, color=True): self.__playground = None self.__out = out self.__color = color if balanceserver is None: self.__balanceserver = ('localhost', 4711) else: self.__balanceserver = balanceserver if color: self.__dimension = blup.frame.FrameDimension(22, 16, 256, 3) else: self.__dimension = blup.frame.FrameDimension(18, 8, 2, 1) def gametickcb(self): for i, p in enumerate(self.__players): if isinstance(p, pong.PongBot): print('bot in game') if (isinstance(p, pong.PongBot) and \ self.__bplayers[i].get_player_ready()): print('second player joined, cancelling current game') self.__playground.cancel() def runGame(self): print('starting a game...') scoreLeft = 0 scoreRight = 0 self.__playground = pong.Playground(self.__dimension.width, self.__dimension.height, 5) pp = pong.PlaygroundPainter(out, self.__dimension, self.__playground) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(self.__balanceserver) print('connected!') self.__bplayers = [ blup.balance_util.BalanceUtil(sock, 0), blup.balance_util.BalanceUtil(sock, 1) ] while not (self.__bplayers[0].get_player_ready() or self.__bplayers[1].get_player_ready()): time.sleep(0.1) for i in range(5): frame = mk_logo_frame(self.__dimension, onePlayer) self.__out.sendFrame(frame) print('waiting for second player...') if (self.__bplayers[0].get_player_ready() and self.__bplayers[1].get_player_ready()): break time.sleep(1) self.__players = [] for i in [0, 1]: paddle = self.__playground.leftPaddle if i == 0 else \ self.__playground.rightPaddle if self.__bplayers[i].get_player_ready(): player = BalanceBoardPlayer(self.__playground, paddle, self.__bplayers[i]) else: player = pong.PongBot(self.__playground, paddle, 3) self.__players.append(player) frame = mk_logo_frame(self.__dimension, logo) self.__out.sendFrame(frame) time.sleep(2) #def blib(obj): # if isinstance(obj, pong.Paddle): # subprocess.Popen(['mplayer','pongblib1.wav']) #self.__playground.ball.addHitCallback(blib) frame = mk_logo_frame(self.__dimension, logo_go) self.__out.sendFrame(frame) time.sleep(1) self.__playground.addGameTickCallback(self.gametickcb) while (max(scoreLeft, scoreRight) < __MAX_SCORE__ and not self.__playground.cancelled): winner = self.__playground.play() if winner is self.__playground.leftPaddle: scoreLeft += 1 else: scoreRight += 1 pong.displayScore(self.__out, self.__dimension, scoreLeft, scoreRight, 3000) if not self.__playground.cancelled: for i in range(3): frame = blup.frame.Frame(self.__dimension) self.__out.sendFrame(frame) time.sleep(0.5) pong.displayScore(self.__out, self.__dimension, scoreLeft, scoreRight, 500) frame = blup.frame.Frame(self.__dimension) self.__out.sendFrame(frame) self.__playground = None self.__players = [] sock.close() if __name__ == '__main__': parser = argparse.ArgumentParser(description='Blinkenbunt Pong!') parser.add_argument('--balance', dest='balance', type=str, metavar='HOST:PORT', help='use balance input') parser.add_argument('--out', dest='out', type=str, metavar='OUTPUT', default='e3blp', help='blup output specification') args = parser.parse_args() out = blup.output.getOutput(args.out) bhost, bport = args.balance.split(':') p0ng = B4lancePong(out, balanceserver=(bhost, int(bport)), color=True) p0ng.runGame()