Commit a047cdf4 authored by Constantin's avatar Constantin
Browse files

Merge branch 'npctest'

parents 9406eed0 cca602b1
from npc import Npc
import random
def testQuestion(qpair):
q,ac = qpair
a = input("> ")
print("Is correct: ",ac(a))
class Euclid (Npc):
questions = [
("Imagine there is a circle. The origin and the point (4,0) are on the circle. The circle is symmetric with respect to the line x=y. Where is its center? ", lambda x: "2,2" in ("".join(x.split())).strip("()[]{}")),
("In a rectangular triangle, if the two shortest sides have lengths 3 meters and 4 meters, how long is the longest side?", lambda x: "5m" in ("".join(x.split())).replace("meters","m").replace("meter","m")),
("What is the fifth decimal digit of π?",lambda x: "9" == "".join(list(filter(lambda x:x.isdigit(),x)))),
("What is the determinant of the following matrix?\n/ 2 0 \\\n\\ 3 4 /",lambda x: "8" == "".join(list(filter(lambda x:x.isdigit(),x)))),
("How many bytes are there in a MiB?",lambda x: "1048576" == "".join(list(filter(lambda x:x.isdigit(),x)))),
("What does a mine turtle have on its back?",lambda x: "button" in x.lower() or "trigger" in x.lower()),
class DLevel(Npc.DialogLevel):
def __init__ (self,euclid):
self.question, self.answerChecker = random.choice(Euclid.questions)
self.questionAsked = False
def checkStandardRequests(self, teller, verb, message):
resp = super().checkStandardRequests(teller, verb, message)
if resp is not None:
assert len(resp) == 3
return resp
if not self.questionAsked:
self.questionAsked = True
return ("asks", self.question, None)
if self.answerChecker(message):
# correct answer
self.npc.correctAnswerGiven = True
newq, newac = random.choice(Euclid.questions)
return ("says", "That answer is correct. I will go annoy people somewhere else. Good Bye.", Euclid.DLevel(self.npc))
else: # wrong answer
return ("shouts", "WRONG!", None)
def __init__(self,game):
super().__init__(game, Euclid.DLevel(self))
self.correctAnswerGiven = False
def __str__ (self):
return "Euclid"
def __repr__ (self):
return "E"
def afterAnswering(self):
if self.correctAnswerGiven:
self.correctAnswerGiven = False
\ No newline at end of file
......@@ -6,6 +6,7 @@ import random
import sys
from util import log_file
from treasure import Treasure
from euclid import Euclid
class Game:
def __init__(self, labyrinthFileName, adminPW, logFileName=None, port=1234):
......@@ -13,9 +14,12 @@ class Game:
self.admins = []
with open(labyrinthFileName,'r') as f:
self.labyrinth = labyrinth.Labyrinth(game=self,stream=f)
treasure = Treasure()
treasure = Treasure(self)
ttile = random.choice(self.labyrinth.getFreeTiles())
euclid = Euclid(self)
etile = random.choice(self.labyrinth.getFreeTiles())
self.sock = socket.socket()
self.sock.bind(('', port))
......@@ -62,7 +62,7 @@ class Labyrinth:
if char in [' ','0','_']:
elif char in ['W','w','#','1']:
wall = Wall()
wall = Wall(
wall.field = field
......@@ -147,3 +147,21 @@ class Labyrinth:
field = thing.field
def tell(self,teller,verb,message):
sourceField = teller.field
receivers = []
for neighborField in [sourceField.neighbor(dy,dx) for dy,dx in directions.values()]:
if neighborField is None:
for thing in neighborField.things:
if thing is teller:
for admin in
if hasattr(teller,'uid'):
admin.send("player {0} {1}s: {2}".format(teller.uid, verb, message))
admin.send("{0} {1}s: {2}".format(str(teller), verb, message))
return receivers
\ No newline at end of file
from thing import Thing
import random
from labyrinth import Labyrinth
class Npc (Thing):
class DialogLevel:
def __init__(self, npc, notunderstandable=None):
assert isinstance(npc,Npc)
self.npc = npc
if notunderstandable is None:
notunderstandable = ["I don't quite understand you.","What do you mean?","Excuse me?","Can you re-phrase that?"]
self.notunderstandable = notunderstandable
def analyzeComeWithMe(self, teller, verb, message):
return ("say", "No, I won't join you.", None)
def analyzeLetPass(self, teller, verb, message):
return ("say", "I won't let you pass so easily.", None)
def checkStandardRequests(self, teller, verb, message):
# if you overwrite this, call super first. You should only do something different if it returns None
msg = message.lower()
if ("come" in msg or "join" in msg or "protect" in msg or "help" in msg) and "me" in msg:
return self.analyzeComeWithMe(teller, verb, message)
elif ("let me" in msg and ("pass" in msg or "through" in msg or "go" in msg)) or ("away" in msg):
return self.analyzeLetPass(teller, verb, message)
return None
def analyzeAnswer(self, teller, verb, message):
# return
# 1. what should be said, if None: do not react
# 2. the saying verb (say, shout...) if saying anything
# 3. a new DialogLevel instance for further use if you want change
resp = self.checkStandardRequests(teller,verb,message)
if resp is None: # didn't understand
return ("say",random.choice(self.notunderstandable),None)
return resp
def __init__ (self, game, initialDialogLevel):
assert isinstance(initialDialogLevel,Npc.DialogLevel)
self.currentDialogLevel = initialDialogLevel
def __repr__ (self):
return "N"
def __str__(self):
return "an NPC"
# convenience function: randomly teleports the npc to a free location
def relocate(self):
newfield = random.choice(
assert isinstance(newfield, Labyrinth.Field),newfield)
def afterAnswering(self):
def tell(self, teller, verb, message):
assert isinstance(self.currentDialogLevel,Npc.DialogLevel)
analresp = self.currentDialogLevel.analyzeAnswer(teller, verb, message)
assert len(analresp) == 3
newmsg, newverb, newdialvl = analresp
if newdialvl is not None:
assert isinstance(newdialvl,Npc.DialogLevel)
self.currentDialogLevel = newdialvl
assert (newmsg is None) == (newverb is None)
if newmsg is not None:, newverb, newmsg)
teller.tell(self, "does not react", "")
\ No newline at end of file
......@@ -4,9 +4,14 @@ import treasure
from labyrinth import directions as directionOffsets
from labyrinth import directions_inv as directions_t
import random
from wall import Wall
from npc import Npc
goVerbs = ['go', 'walk', 'run', 'stroll']
sayVerbs = ['say', 'talk', 'scream', 'whisper']
normalSayVerbs = ['say', 'talk', 'whisper']
loadSayVerbs = ['scream', 'shout', ]
askingSayVerbs = ['request','appeal','plead','beg','ask','bid']
sayVerbs = normalSayVerbs+loadSayVerbs+askingSayVerbs
announceVerbs = ['announce']
leaveVerbs = ['leave', 'quit', 'exit', 'suicide']
grabVerbs = ['grab', 'get', 'investigate', 'examine', 'check', 'pick', 'pickup']
......@@ -30,9 +35,8 @@ playerUID = 0
class Player(Thing):
def __init__(self, game, conn):
global playerUID
self.buffer = b"" = game
self.conn = conn
self.uid = playerUID
self.obstinacy = 0
......@@ -145,19 +149,16 @@ class Player(Thing):
elif verb in sayVerbs:
msg = " ".join(words[1:])
someoneClose = False
for dx, dy in directionOffsets.values():
for thing in self.field.neighbor(dx=dx, dy=dy).things:
assert thing != self
if isinstance(thing, Player):
someoneClose = True
thing.send("You hear someone saying: "+msg)
for admin in
admin.send("{0} says: {1}".format(self.uid, msg))
receivers =,verb,msg)
someoneClose = any(isinstance(thing,Player) or isinstance(thing,Npc) for thing in receivers)
if someoneClose:
self.send("You say: "+msg)
self.send("You want to say something, but then you realize nobody's caring anyway. Get over it!")
wallClose = any(isinstance(thing,Wall) for thing in receivers)
if wallClose:
self.send("You are talking to the walls. This is usually not very effective.")
self.send("If you say something, but nobody is there to listen to you, is there a sound at all? We don't know and it doesn't matter.")
elif verb in leaveVerbs:
self.send("Good Bye!")
......@@ -190,11 +191,14 @@ class Player(Thing):
msg = " ".join(words[1:])
for player in
player.send("Though Hearest A Voice Sayin': "+msg)
player.send("Though hearest a godly voice sayin': "+msg)
self.send("Who Do Though Think Though Are?")
self.send("Only gods can do that")
self.send("I don't know what you are talking about")
self.send("I don't know what you are talking about.\nWhat do you want to do?")
def tell(self, teller, verb, message):
self.send("You hear someone %s: \"%s\"" % (verb,message))
def afterMove(self, oldField):
desc =
class Thing():
def __init__(self):
def __init__(self, game):
self.field = None = game
def onMove(self, newField):
return True
......@@ -11,5 +12,8 @@ class Thing():
def blocksMove(self):
return False
def tell(self,teller,verb,message):
def __repr__(self):
return "?"
from thing import Thing
class Wall(Thing):
def __init__(self):
def __init__(self,game):
def onMove(self, newField):
return False
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment