Commit b483dfcd authored by Ralf's avatar Ralf

make walls a thing

parent 9d20f69f
...@@ -7,6 +7,7 @@ import random ...@@ -7,6 +7,7 @@ import random
class Game: class Game:
def __init__(self, labyrinthFileName, adminPW, logFileName=None, port=1234): def __init__(self, labyrinthFileName, adminPW, logFileName=None, port=1234):
self.players = [] self.players = []
self.admins = []
with open(labyrinthFileName,'r') as f: with open(labyrinthFileName,'r') as f:
self.labyrinth = labyrinth.Labyrinth(game=self,stream=f) self.labyrinth = labyrinth.Labyrinth(game=self,stream=f)
self.sock = socket.socket() self.sock = socket.socket()
...@@ -16,7 +17,6 @@ class Game: ...@@ -16,7 +17,6 @@ class Game:
self.sel.register(self.sock, selectors.EVENT_READ, self.accept) self.sel.register(self.sock, selectors.EVENT_READ, self.accept)
self.logFile = None if logFileName is None else open(logFileName, 'a') self.logFile = None if logFileName is None else open(logFileName, 'a')
self.adminPW = adminPW self.adminPW = adminPW
self.admins = []
# low-level functions # low-level functions
def accept(self, sock, mask): def accept(self, sock, mask):
...@@ -57,6 +57,7 @@ class Game: ...@@ -57,6 +57,7 @@ class Game:
print(*args, file=self.logFile, flush=True) print(*args, file=self.logFile, flush=True)
def showAdmins(self): def showAdmins(self):
if not self.admins: return
lab = self.labyrinth.writelab() lab = self.labyrinth.writelab()
for admin in self.admins: for admin in self.admins:
admin.send(lab) admin.send(lab)
......
# class for the labyrinth # class for the labyrinth
from enum import Enum from enum import Enum
import itertools
from functools import reduce from functools import reduce
from wall import Wall
directions = {"north": (-1, 0), "east": (0, 1), "west": (0, -1), "south": (1, 0)} directions = {"north": (-1, 0), "east": (0, 1), "west": (0, -1), "south": (1, 0)}
directions_inv = {v:k for k, v in directions.items()} directions_inv = {v:k for k, v in directions.items()}
def describeThings(things):
# always starts with there is/there are
if len(things) == 0:
return "there is nothing"
elif len(things) == 1:
return "there is "+str(things[0])
else:
return "there are "+(", ".join([x.toString() for x in things[:-1]]))+" and "+things[-1].toString()
class Labyrinth: class Labyrinth:
class GroundType(Enum):
FLOOR = 1
WALL = 2
class Field: class Field:
def __init__(self,groundtype,column,row,labyrinth): def __init__(self,column,row,labyrinth):
# please only read from these members # please only read from these members
self.groundtype = groundtype
self.column = column self.column = column
self.row = row self.row = row
self.labyrinth = labyrinth self.labyrinth = labyrinth
...@@ -23,25 +30,15 @@ class Labyrinth: ...@@ -23,25 +30,15 @@ class Labyrinth:
def _removeThing(self,thing): def _removeThing(self,thing):
self.things.remove(thing) self.things.remove(thing)
def _addThing(self,thing): def _addThing(self,thing):
assert self.things.count(thing) == 0 assert thing not in self.things
assert self.groundtype != Labyrinth.GroundType.WALL
self.things.append(thing) self.things.append(thing)
def neighbor(self,dy,dx): def neighbor(self,dy,dx):
return self.labyrinth.getTileAt(self.row + dy, self.column + dx) return self.labyrinth.getTileAt(self.row + dy, self.column + dx)
def isWalkable(self): def isWalkable(self):
# this may be more complicated in the future for thing in self.things:
return self.groundtype == Labyrinth.GroundType.FLOOR if thing.blocksMove():
def __str__(self): return False
# always starts with there is/there are return True
if self.groundtype == Labyrinth.GroundType.WALL:
return "there is a wall"
else:
if len(self.things) == 0:
return "there is nothing"
elif len(self.things) == 1:
return "there is "+str(self.things[0])
else:
return "there are "+(", ".join([x.toString() for x in self.things[:-1]]))+" and "+self.things[-1].toString()
# constructor for a completely read labyrinth # constructor for a completely read labyrinth
def __init__(self,game=None,width=None,height=None,stream=None): def __init__(self,game=None,width=None,height=None,stream=None):
...@@ -49,7 +46,7 @@ class Labyrinth: ...@@ -49,7 +46,7 @@ class Labyrinth:
if width is not None: # empty labyrinth of given size if width is not None: # empty labyrinth of given size
assert height is not None assert height is not None
assert stream is None assert stream is None
self.tiles = [[Labyrinth.Field(Labyrinth.GroundType.FLOOR,col,row,self) for col in range(width)] for row in range(height)] self.tiles = [[Labyrinth.Field(col,row,self) for col in range(width)] for row in range(height)]
elif height is not None: elif height is not None:
assert False # width None, height not assert False # width None, height not
elif stream is not None: elif stream is not None:
...@@ -60,11 +57,17 @@ class Labyrinth: ...@@ -60,11 +57,17 @@ class Labyrinth:
tiles = [] tiles = []
for rownum,line in enumerate(stream): for rownum,line in enumerate(stream):
row = [] row = []
for colnum,char in enumerate(line): for colnum,char in enumerate(line[:-1]):
field = Labyrinth.Field(colnum,rownum,self)
if char in [' ','0','_']: if char in [' ','0','_']:
row.append(Labyrinth.Field(Labyrinth.GroundType.FLOOR,colnum,rownum,self)) pass
elif char in ['W','w','#','1']: elif char in ['W','w','#','1']:
row.append(Labyrinth.Field(Labyrinth.GroundType.WALL,colnum,rownum,self)) wall = Wall()
wall.field = field
field._addThing(wall)
else:
raise Exception("Unexpected character '{0}'".format(char))
row.append(field)
tiles.append(row) tiles.append(row)
return tiles return tiles
...@@ -72,15 +75,12 @@ class Labyrinth: ...@@ -72,15 +75,12 @@ class Labyrinth:
result = "" result = ""
for row in self.tiles: for row in self.tiles:
for field in row: for field in row:
if field.groundtype == Labyrinth.GroundType.WALL: if not field.things:
result += "#" result += "."
elif len(field.things) == 1:
result += repr(field.things[0])
else: else:
if not field.things: result += "+"
result += "."
elif len(field.things) == 1:
result += field.things[0].asChar()
else:
result += "+"
result += "\n" result += "\n"
return result return result
...@@ -103,12 +103,18 @@ class Labyrinth: ...@@ -103,12 +103,18 @@ class Labyrinth:
return reduce(lambda x,y:x+y, self.tiles) return reduce(lambda x,y:x+y, self.tiles)
def getFreeTiles (self): def getFreeTiles (self):
return list(filter(lambda f: f.groundtype == Labyrinth.GroundType.FLOOR and len(f.things) == 0 ,self.getTiles())) return list(filter(Labyrinth.Field.isWalkable, self.getTiles()))
def getDescription (self, field): def getDescription (self, player):
descr = "" descr = ""
for name,field in zip(["North","South","West","East"], [self.getTileAt(field.row+row,field.column+column) for row,column in [(-1,0),(1,0),(0,-1),(0,1)]]): local = list(filter(lambda thing: thing != player, player.field.things))
descr += "In the "+name+" "+("there is a wall" if field is None else str(field))+".\n" if local:
descr += "Next to you, "+describeThings(local)+"\n"
for direction, (dy,dx) in directions.items():
field = player.field.neighbor(dx=dx, dy=dy)
if field is None: continue
if field.things:
descr += "In the "+direction+", "+describeThings(field.things)+"\n"
return descr return descr
def moveThing (self, thing, newField, beforeFinish=None): def moveThing (self, thing, newField, beforeFinish=None):
...@@ -130,8 +136,8 @@ class Labyrinth: ...@@ -130,8 +136,8 @@ class Labyrinth:
def createThing (self, thing, field): def createThing (self, thing, field):
thing.field = field thing.field = field
field._addThing(thing) field._addThing(thing)
thing.onMove(field) if thing.onMove(field):
thing.afterMove(field) thing.afterMove(field)
self.game.showAdmins() self.game.showAdmins()
def removeThing(self, thing): def removeThing(self, thing):
......
...@@ -132,8 +132,8 @@ class Player(Thing): ...@@ -132,8 +132,8 @@ class Player(Thing):
self.send("I don't know what you are talking about") self.send("I don't know what you are talking about")
def afterMove(self, oldField): def afterMove(self, oldField):
desc = self.game.labyrinth.getDescription(self.field) desc = self.game.labyrinth.getDescription(self)
self.send(desc, end="") self.send(desc, end="")
def asChar(self): def __repr__(self):
return "P" return "P"
...@@ -8,5 +8,8 @@ class Thing(): ...@@ -8,5 +8,8 @@ class Thing():
def afterMove(self, oldField): def afterMove(self, oldField):
pass pass
def asChar(self): def blocksMove(self):
return False
def __repr__(self):
return "?" return "?"
from thing import Thing
class Wall(Thing):
def __init__(self):
super().__init__()
def onMove(self, newField):
return False
def blocksMove(self):
return True
def __str__(self):
return "a wall"
def __repr__(self):
return "#"
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