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.

235 lines
7.5 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):
# 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()