|
|
|
#!/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, numplayers=None):
|
|
|
|
self.__playground = None
|
|
|
|
self.__out = out
|
|
|
|
self.__color = color
|
|
|
|
if balanceserver is None:
|
|
|
|
self.__balanceserver = ('localhost', 4711)
|
|
|
|
else:
|
|
|
|
self.__balanceserver = balanceserver
|
|
|
|
self.__numplayers = numplayers
|
|
|
|
|
|
|
|
if color:
|
|
|
|
self.__dimension = blup.frame.FrameDimension(22, 16, 256, 3)
|
|
|
|
else:
|
|
|
|
self.__dimension = blup.frame.FrameDimension(18, 8, 2, 1)
|
|
|
|
|
|
|
|
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!')
|
|
|
|
balance_util_p1 = blup.balance_util.BalanceUtil(sock, 0)
|
|
|
|
balance_util_p2 = blup.balance_util.BalanceUtil(sock, 1)
|
|
|
|
while not balance_util_p1.get_player_ready():
|
|
|
|
print('waiting for player...')
|
|
|
|
time.sleep(1)
|
|
|
|
|
|
|
|
self.__players = []
|
|
|
|
self.__players.append(BalanceBoardPlayer(self.__playground, self.__playground.leftPaddle, balance_util_p1))
|
|
|
|
|
|
|
|
if self.__numplayers == 2:
|
|
|
|
self.__players.append(BalanceBoardPlayer(self.__playground, self.__playground.rightPaddle, balance_util_p2))
|
|
|
|
elif self.__numplayers is None:
|
|
|
|
for i in range(5):
|
|
|
|
frame = mk_logo_frame(self.__dimension, onePlayer)
|
|
|
|
self.__out.sendFrame(frame)
|
|
|
|
|
|
|
|
print('waiting for second player...')
|
|
|
|
if balance_util_p2.get_player_ready():
|
|
|
|
self.__players.append(BalanceBoardPlayer(self.__playground, self.__playground.rightPaddle,
|
|
|
|
balance_util_p2))
|
|
|
|
break
|
|
|
|
time.sleep(1)
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
if len(self.__players) == 1:
|
|
|
|
bot = pong.PongBot(self.__playground, self.__playground.rightPaddle, 3)
|
|
|
|
self.__players.append(bot)
|
|
|
|
|
|
|
|
while max(scoreLeft, scoreRight) < __MAX_SCORE__:
|
|
|
|
winner = self.__playground.play()
|
|
|
|
if winner is self.__players[0].ownPaddle:
|
|
|
|
scoreLeft += 1
|
|
|
|
else:
|
|
|
|
scoreRight += 1
|
|
|
|
pong.displayScore(self.__out, self.__dimension, scoreLeft, scoreRight, 3000)
|
|
|
|
|
|
|
|
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('--players', dest='players', type=int,
|
|
|
|
help='number of players (autodetect if unspecified)')
|
|
|
|
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,
|
|
|
|
numplayers=args.players)
|
|
|
|
p0ng.runGame()
|
|
|
|
|