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
print(q)
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):
super().__init__(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)
else:
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
self.relocate()
\ 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())
self.labyrinth.createThing(treasure,ttile)
euclid = Euclid(self)
etile = random.choice(self.labyrinth.getFreeTiles())
self.labyrinth.createThing(euclid,etile)
self.sock = socket.socket()
self.sock.bind(('0.0.0.0', port))
self.sock.listen(100)
......
......@@ -62,7 +62,7 @@ class Labyrinth:
if char in [' ','0','_']:
pass
elif char in ['W','w','#','1']:
wall = Wall()
wall = Wall(self.game)
wall.field = field
field._addThing(wall)
else:
......@@ -147,3 +147,21 @@ class Labyrinth:
field = thing.field
field.things.remove(thing)
self.game.showAdmins()
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:
continue
for thing in neighborField.things:
if thing is teller:
continue
receivers.append(thing)
thing.tell(teller,verb,message)
for admin in self.game.admins:
if hasattr(teller,'uid'):
admin.send("player {0} {1}s: {2}".format(teller.uid, verb, message))
else:
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)
else:
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)
else:
return resp
def __init__ (self, game, initialDialogLevel):
super().__init__(game)
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(self.game.labyrinth.getFreeTiles())
assert isinstance(newfield, Labyrinth.Field)
self.game.labyrinth.moveThing(self,newfield)
def afterAnswering(self):
pass
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:
self.game.labyrinth.tell(self, newverb, newmsg)
else:
teller.tell(self, "does not react", "")
self.afterAnswering()
\ 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
super().__init__()
super().__init__(game)
self.buffer = b""
self.game = 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 self.game.admins:
admin.send("{0} says: {1}".format(self.uid, msg))
receivers = self.game.labyrinth.tell(self,verb,msg)
someoneClose = any(isinstance(thing,Player) or isinstance(thing,Npc) for thing in receivers)
if someoneClose:
self.send("You say: "+msg)
else:
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.")
else:
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!")
self.game.removePlayer(self)
......@@ -190,11 +191,14 @@ class Player(Thing):
if self.game.isAdmin(self):
msg = " ".join(words[1:])
for player in self.game.players:
player.send("Though Hearest A Voice Sayin': "+msg)
player.send("Though hearest a godly voice sayin': "+msg)
else:
self.send("Who Do Though Think Though Are?")
self.send("Only gods can do that")
else:
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 = self.game.labyrinth.getDescription(self)
......
class Thing():
def __init__(self):
def __init__(self, game):
self.field = None
self.game = game
def onMove(self, newField):
return True
......@@ -11,5 +12,8 @@ class Thing():
def blocksMove(self):
return False
def tell(self,teller,verb,message):
pass
def __repr__(self):
return "?"
from thing import Thing
class Wall(Thing):
def __init__(self):
super().__init__()
def __init__(self,game):
super().__init__(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