You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
7.4 KiB
234 lines
7.4 KiB
#!/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): |
|
bal = self.__balance_util.get_raw_2dir_y() |
|
|
|
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() |
|
|
|
|