add hangman (buggy)
This commit is contained in:
parent
ae423d4e76
commit
be69a44dfe
|
@ -0,0 +1,313 @@
|
||||||
|
import socket, time
|
||||||
|
from PIL import Image, ImageFont, ImageDraw
|
||||||
|
import sys, os
|
||||||
|
import fileinput
|
||||||
|
from random import randint
|
||||||
|
|
||||||
|
|
||||||
|
class Hangman(object):
|
||||||
|
'''
|
||||||
|
classdocs
|
||||||
|
'''
|
||||||
|
|
||||||
|
global C_BLACK
|
||||||
|
global C_WHITE
|
||||||
|
global C_BG
|
||||||
|
global C_TEXT
|
||||||
|
global C_HM
|
||||||
|
global FPS
|
||||||
|
global FONT_SIZE_word
|
||||||
|
|
||||||
|
C_BLACK = 0
|
||||||
|
C_WHITE = 255
|
||||||
|
C_BG=C_WHITE
|
||||||
|
C_TEXT=C_BLACK
|
||||||
|
C_HM=C_TEXT
|
||||||
|
FPS=2
|
||||||
|
FONT_SIZE_word=9 #was 9
|
||||||
|
|
||||||
|
#hangman/alterebro-pixel-font.ttf size=14, -2 and 6
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self, udphost, udpport, img_size=(80,16)):
|
||||||
|
'''
|
||||||
|
Constructor
|
||||||
|
'''
|
||||||
|
|
||||||
|
self._udphost = udphost
|
||||||
|
if not type(udpport) is int or udpport > 65536:
|
||||||
|
raise TypeError('port has to be int and > 65536 !!')
|
||||||
|
self._udpport = udpport
|
||||||
|
self._img_size = img_size
|
||||||
|
self._fo_word= (15, -1) #(15, -1)
|
||||||
|
self._fo_word2= (15, 7) #(15,7)
|
||||||
|
#self._wordlist="/home/pi/mqtt-to-flipdot/hangman/nomenliste_de.txt"
|
||||||
|
self._wordlist="/home/pi/mqtt-to-flipdot/hangman/crodict_nomen.txt"
|
||||||
|
self._gamestate=0# 0=start 1=ingame 2=lose 3=win
|
||||||
|
self._g_word="test" #word
|
||||||
|
self._g_displword="" #display word
|
||||||
|
self._g_chars="" #used characters
|
||||||
|
|
||||||
|
self._hmdir="/home/pi/mqtt-to-flipdot/hangman/stdhm/"
|
||||||
|
|
||||||
|
self._hmimg=[]
|
||||||
|
self._maxfails=len( os.listdir(self._hmdir))-1 -1 #maxfails defined by files in directory, -1 -1 because win image
|
||||||
|
print("Maxfails="+str(self._maxfails))
|
||||||
|
|
||||||
|
for i in range(self._maxfails+1):
|
||||||
|
self._hmimg.append(Image.open(open(self._hmdir+"f"+str(i)+".png", 'rb')) ) #load hangmans
|
||||||
|
|
||||||
|
self._winimg=Image.open(open(self._hmdir+"win.png", 'rb'))
|
||||||
|
|
||||||
|
self._minwlen=4
|
||||||
|
self._maxwlen=26
|
||||||
|
|
||||||
|
self._words=[]
|
||||||
|
fobj = open(self._wordlist)
|
||||||
|
for line in fobj:
|
||||||
|
string=line.rstrip()
|
||||||
|
if (self._validateWord(string)==1):
|
||||||
|
if (len(string)>=self._minwlen and len(string)<=self._maxwlen):
|
||||||
|
self._words.append(string)
|
||||||
|
fobj.close()
|
||||||
|
print("loaded "+str(len(self._words))+" words")
|
||||||
|
|
||||||
|
self._sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||||
|
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
print("Hangman setup")
|
||||||
|
rand=randint(0,len(self._words)-1)
|
||||||
|
self._g_word=self._words[rand]
|
||||||
|
self._g_chars=""
|
||||||
|
self._generateDisplword()
|
||||||
|
self._g_gamestate=1
|
||||||
|
self._sock.sendto(bytes(self._array2packet(self._draw())), (self._udphost, self._udpport))
|
||||||
|
|
||||||
|
|
||||||
|
def _list2byte(self, l):
|
||||||
|
byte = 0
|
||||||
|
i = 0
|
||||||
|
for i in range(8):
|
||||||
|
byte += 2**(7-i) if l[i] else 0
|
||||||
|
return byte
|
||||||
|
|
||||||
|
def _array2packet(self, a):
|
||||||
|
return [self._list2byte(a[i*8:i*8+8]) for i in range(int(len(a)/8))]
|
||||||
|
|
||||||
|
|
||||||
|
def _str2array(self,s):
|
||||||
|
image = Image.new("RGBA", self._img_size, C_BLACK)
|
||||||
|
draw = ImageDraw.Draw(image)
|
||||||
|
draw.fontmode = "1" # No AA
|
||||||
|
#font = ImageFont.load_default()
|
||||||
|
font = ImageFont.truetype("/usr/share/fonts/Retro Computer_DEMO.ttf", FONT_SIZE)
|
||||||
|
#/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf
|
||||||
|
|
||||||
|
draw.text(FONT_OFFSET, s, font=font, fill=C_WHITE)
|
||||||
|
|
||||||
|
|
||||||
|
def _validateWord(self,s): #returns 1 if chars are only abc...xyz or ABC...XYZ, else 0
|
||||||
|
for c in range(0,len(s)):
|
||||||
|
oc=ord(s[c])
|
||||||
|
#print s+":ord="+str(oc)
|
||||||
|
if (oc>=65 and oc<=90) : #A-Z
|
||||||
|
a=s#nonesense
|
||||||
|
elif (oc>=97 and oc<=122):#a-z
|
||||||
|
a=s
|
||||||
|
elif (oc>=48 and oc<=57 and G_ALLOWNUMERIC==1):#0-9
|
||||||
|
a=s
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def _generateDisplword(self):
|
||||||
|
|
||||||
|
self._g_displword=""
|
||||||
|
|
||||||
|
for i in range(0,len(self._g_word)):
|
||||||
|
cha=self._g_word[i] #current character
|
||||||
|
show=0
|
||||||
|
for c in range(0,len(self._g_chars)):
|
||||||
|
if cha.lower()==self._g_chars[c]: #if current char is opened
|
||||||
|
show=1
|
||||||
|
|
||||||
|
if show==1: #if character cha is opened
|
||||||
|
self._g_displword+=cha #show
|
||||||
|
else:
|
||||||
|
self._g_displword+="-" #do not show
|
||||||
|
|
||||||
|
def _countFails(self):
|
||||||
|
fails=0
|
||||||
|
for c in range(0,len(self._g_chars)):
|
||||||
|
used=0
|
||||||
|
for i in range(0,len(self._g_word)):
|
||||||
|
if self._g_chars[c]==self._g_word[i].lower():
|
||||||
|
used=1
|
||||||
|
if used==0: #if current char was never used in g_word
|
||||||
|
fails+=1
|
||||||
|
return fails
|
||||||
|
|
||||||
|
def _computeInput(self,strinput):
|
||||||
|
if ((len(strinput)==1) and (self._validateWord(strinput[:len(strinput)-1])==1) ): #only one character and only alphabet
|
||||||
|
newchar=strinput[0].lower()
|
||||||
|
used=0
|
||||||
|
for c in range(0,len(self._g_chars)):
|
||||||
|
if self._g_chars[c]==newchar:
|
||||||
|
used=1
|
||||||
|
|
||||||
|
if used==0:
|
||||||
|
self._g_chars+=newchar #add new character
|
||||||
|
else: #if character already entered
|
||||||
|
print("Character already entered!")
|
||||||
|
else:
|
||||||
|
print("Wrong input!!11!")
|
||||||
|
|
||||||
|
|
||||||
|
def _checkWord(self):
|
||||||
|
#print "fails="+str(countFails())+" max="+str(maxfails)
|
||||||
|
if self._countFails()>=self._maxfails:
|
||||||
|
self._g_gamestate=2
|
||||||
|
if self._g_displword==self._g_word:
|
||||||
|
self._g_gamestate=3
|
||||||
|
|
||||||
|
|
||||||
|
def _draw(self):
|
||||||
|
image = Image.new("RGBA", self._img_size, C_BG)
|
||||||
|
draw = ImageDraw.Draw(image)
|
||||||
|
draw.fontmode = "1" # No AA
|
||||||
|
|
||||||
|
if self._g_gamestate==1:
|
||||||
|
self._drawGameScreen(draw)
|
||||||
|
elif self._g_gamestate==2:
|
||||||
|
self._drawLoseScreen(draw)
|
||||||
|
elif self._g_gamestate==3:
|
||||||
|
self._drawWinScreen(draw)
|
||||||
|
|
||||||
|
imgmap = []
|
||||||
|
|
||||||
|
for pixel in image.getdata():
|
||||||
|
r, g, b, a = pixel
|
||||||
|
if r == 255:
|
||||||
|
imgmap.append(1)
|
||||||
|
else:
|
||||||
|
imgmap.append(0)
|
||||||
|
return imgmap
|
||||||
|
|
||||||
|
def _drawHangman(self,draw):
|
||||||
|
dimg=self._hmimg[self._countFails()]
|
||||||
|
#self._draw.ImageDraw(hmimg[countFails()])
|
||||||
|
self._drawImage(dimg,0,0,draw)
|
||||||
|
|
||||||
|
def _drawWinImage(self,draw):
|
||||||
|
dimg=self._winimg
|
||||||
|
#self._draw.ImageDraw(hmimg[countFails()])
|
||||||
|
self._drawImage(dimg,0,0,draw)
|
||||||
|
|
||||||
|
|
||||||
|
def _drawImage(self,img,xv,yv,draw):
|
||||||
|
w=img.size[0]
|
||||||
|
h=img.size[1]
|
||||||
|
i=0
|
||||||
|
for pixel in img.getdata():
|
||||||
|
#r, g, b, a = pixel
|
||||||
|
if pixel[0]==255:
|
||||||
|
draw.point( (xv+i%w,yv+i/w), fill=C_HM)
|
||||||
|
i+=1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _drawGameScreen(self,draw):
|
||||||
|
|
||||||
|
#font = ImageFont.truetype("/usr/share/fonts/truetype/fonts-japanese-gothic.ttf", FONT_SIZE_word)
|
||||||
|
#font = ImageFont.truetype("hangman/alterebro-pixel-font.ttf", FONT_SIZE_word)
|
||||||
|
font = ImageFont.truetype("/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf", FONT_SIZE_word)
|
||||||
|
|
||||||
|
|
||||||
|
if (self._g_gamestate!=3):
|
||||||
|
self._drawHangman(draw)
|
||||||
|
else:
|
||||||
|
self._drawWinImage(draw)
|
||||||
|
|
||||||
|
x=len(self._g_displword)
|
||||||
|
l=draw.textsize(self._g_displword[:x]+"E", font=font)[0] #concat one char because textsize is one char short (somehow)
|
||||||
|
while (l>(80-14-4)) and (x>0): #80-14-18
|
||||||
|
|
||||||
|
x-=1
|
||||||
|
l=draw.textsize(self._g_displword[:x]+"E", font=font)[0]
|
||||||
|
|
||||||
|
|
||||||
|
s1=self._g_displword[:x]
|
||||||
|
s2=self._g_displword[x:]
|
||||||
|
|
||||||
|
#for i in range(0,len(s1)):
|
||||||
|
# draw.text((fo_word[0]+i*5, fo_word[1]), s1[i], font=font, fill=C_TEXT)
|
||||||
|
|
||||||
|
#for i in range(0,len(s2)):
|
||||||
|
# draw.text((fo_word2[0]+i*5, fo_word2[1]), s2[i], font=font, fill=C_TEXT)
|
||||||
|
|
||||||
|
draw.text(self._fo_word, s1.upper(), font=font, fill=C_TEXT)
|
||||||
|
draw.text(self._fo_word2, s2.upper(), font=font, fill=C_TEXT)
|
||||||
|
|
||||||
|
def _drawLoseScreen(self,draw):
|
||||||
|
self._drawGameScreen(draw)
|
||||||
|
|
||||||
|
|
||||||
|
def _drawWinScreen(self,draw):
|
||||||
|
self._drawGameScreen(draw)
|
||||||
|
|
||||||
|
|
||||||
|
def step(self,strinput): #returns 0 if game ended
|
||||||
|
|
||||||
|
if self._g_gamestate==0: #game ended
|
||||||
|
return 0
|
||||||
|
|
||||||
|
elif self._g_gamestate==1:
|
||||||
|
#strinput = sys.stdin.readline()
|
||||||
|
self._computeInput(strinput)
|
||||||
|
|
||||||
|
|
||||||
|
self._generateDisplword()
|
||||||
|
|
||||||
|
|
||||||
|
#draw() #test
|
||||||
|
self._sock.sendto(bytes(self._array2packet(self._draw())), (self._udphost, self._udpport))
|
||||||
|
print("Display:"+self._g_displword)
|
||||||
|
print("Used:"+self._g_chars)
|
||||||
|
print("fails:"+str(self._countFails()))
|
||||||
|
|
||||||
|
self._checkWord()
|
||||||
|
|
||||||
|
if self._g_gamestate==2:
|
||||||
|
#c_t=C_TEXT #backup
|
||||||
|
#C_TEXT=C_BG #invert text
|
||||||
|
#C_BG=c_t #invert text
|
||||||
|
self._g_displword=self._g_word
|
||||||
|
self._sock.sendto(bytes(self._array2packet(self._draw())), (self._udphost, self._udpport))
|
||||||
|
print("verloren, das Wort war:"+self._g_word)
|
||||||
|
self._g_gamestate=0
|
||||||
|
return 2
|
||||||
|
|
||||||
|
|
||||||
|
elif self._g_gamestate==3:
|
||||||
|
self._sock.sendto(bytes(self._array2packet(self._draw())), (self._udphost, self._udpport))
|
||||||
|
print("gewonnen")
|
||||||
|
self._g_gamestate=0
|
||||||
|
return 3
|
||||||
|
|
||||||
|
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
hangman= Hangman("2001:67c:275c:a9::c", 2323)
|
||||||
|
hangman.setup()
|
||||||
|
running=1
|
||||||
|
while running==1:
|
||||||
|
running=hangman.step(sys.stdin.readline())
|
||||||
|
time.sleep(1.0/FPS)
|
||||||
|
|
||||||
|
|
|
@ -3,18 +3,26 @@ import time
|
||||||
import paho.mqtt.client as mqtt
|
import paho.mqtt.client as mqtt
|
||||||
from FlipdotSender import FlipdotSender
|
from FlipdotSender import FlipdotSender
|
||||||
import time
|
import time
|
||||||
|
from hangman import Hangman
|
||||||
|
|
||||||
|
global mode
|
||||||
|
mode="standby"
|
||||||
|
|
||||||
def on_connect(client, userdata, flags, rc):
|
def on_connect(client, userdata, flags, rc):
|
||||||
print("Connected with result code " + str(rc))
|
print("Connected with result code " + str(rc))
|
||||||
client.subscribe("raum2/flipdot/text")
|
client.subscribe("raum2/flipdot/#")
|
||||||
client.subscribe("raum2/flipdot/scroll")
|
#client.subscribe("raum2/flipdot/text")
|
||||||
client.subscribe("raum2/flipdot/image")
|
#client.subscribe("raum2/flipdot/scroll")
|
||||||
|
#client.subscribe("raum2/flipdot/image")
|
||||||
|
|
||||||
|
|
||||||
def on_message(client, userdata, msg):
|
def on_message(client, userdata, msg):
|
||||||
print(msg.topic + " " + str(msg.payload.decode("utf-8")))
|
print(msg.topic + " " + str(msg.payload.decode("utf-8")))
|
||||||
|
global mode
|
||||||
|
|
||||||
if msg.topic == "raum2/flipdot/scroll":
|
if mode=="standby":
|
||||||
|
|
||||||
|
if msg.topic == "raum2/flipdot/scroll/set":
|
||||||
payload = msg.payload.decode("utf-8")
|
payload = msg.payload.decode("utf-8")
|
||||||
|
|
||||||
if (payload[0]).isdigit():
|
if (payload[0]).isdigit():
|
||||||
|
@ -25,17 +33,48 @@ def on_message(client, userdata, msg):
|
||||||
text = payload
|
text = payload
|
||||||
|
|
||||||
flipdot.send_marquee(text, speed)
|
flipdot.send_marquee(text, speed)
|
||||||
if msg.topic == "raum2/flipdot/text":
|
if msg.topic == "raum2/flipdot/text/set":
|
||||||
payload = msg.payload.decode("utf-8")
|
payload = msg.payload.decode("utf-8")
|
||||||
flipdot.send_text(payload)
|
flipdot.send_text(payload)
|
||||||
|
|
||||||
if msg.topic == "raum2/flipdot/image":
|
if msg.topic == "raum2/flipdot/image/set":
|
||||||
payload = msg.payload.decode("utf-8")
|
payload = msg.payload.decode("utf-8")
|
||||||
print(payload)
|
print(payload)
|
||||||
flipdot.send_bytes(payload)
|
flipdot.send_bytes(payload)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if msg.topic == "raum2/flipdot/hangman/set":
|
||||||
|
payload = msg.payload.decode("utf-8")
|
||||||
|
|
||||||
|
if payload=="#start":
|
||||||
|
hangman.setup()
|
||||||
|
client.publish("raum2/flipdot/hangman","started")
|
||||||
|
mode="hangman"
|
||||||
|
|
||||||
|
elif (mode=="hangman") and (len(payload)>0): #try entered character
|
||||||
|
trychar=payload[-1]
|
||||||
|
gamestatus=hangman.step(trychar)
|
||||||
|
if gamestatus!=1: #game has ended
|
||||||
|
mode="standby"
|
||||||
|
if gamestatus==2: #gameover
|
||||||
|
client.publish("raum2/flipdot/hangman","gameover")
|
||||||
|
elif gamestatus==3: #won
|
||||||
|
client.publish("raum2/flipdot/hangman","won")
|
||||||
|
elif gamestatus==0: #ended in another way
|
||||||
|
client.publish("raum2/flipdot/hangman","ended")
|
||||||
|
|
||||||
|
|
||||||
|
if payload=="#stop":
|
||||||
|
mode="standby"
|
||||||
|
client.publish("raum2/flipdot/hangman","ended")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
flipdot = FlipdotSender("2001:67c:275c:a9::c", 2323)
|
flipdot = FlipdotSender("2001:67c:275c:a9::c", 2323)
|
||||||
|
hangman= Hangman("2001:67c:275c:a9::c", 2323)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
client = mqtt.Client()
|
client = mqtt.Client()
|
||||||
client.on_connect = on_connect
|
client.on_connect = on_connect
|
||||||
|
|
Loading…
Reference in New Issue