Commit b483dfcd authored by Ralf's avatar Ralf
Browse files

make walls a thing

parent 9d20f69f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ import random
class Game:
	def __init__(self, labyrinthFileName, adminPW, logFileName=None, port=1234):
		self.players = []
		self.admins = []
		with open(labyrinthFileName,'r') as f:
			self.labyrinth = labyrinth.Labyrinth(game=self,stream=f)
		self.sock = socket.socket()
@@ -16,7 +17,6 @@ class Game:
		self.sel.register(self.sock, selectors.EVENT_READ, self.accept)
		self.logFile = None if logFileName is None else open(logFileName, 'a')
		self.adminPW = adminPW
		self.admins = []
	
	# low-level functions
	def accept(self, sock, mask):
@@ -57,6 +57,7 @@ class Game:
			print(*args, file=self.logFile, flush=True)
	
	def showAdmins(self):
		if not self.admins: return
		lab = self.labyrinth.writelab()
		for admin in self.admins:
			admin.send(lab)
+45 −39
Original line number Diff line number Diff line
# class for the labyrinth

from enum import Enum
import itertools
from functools import reduce
from wall import Wall

directions = {"north": (-1, 0), "east": (0, 1), "west": (0, -1), "south": (1, 0)}
directions_inv = {v:k for k, v in directions.items()}

class Labyrinth:
	class GroundType(Enum):
		FLOOR = 1
		WALL  = 2
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 Field:
		def __init__(self,groundtype,column,row,labyrinth):
		def __init__(self,column,row,labyrinth):
			# please only read from these members
			self.groundtype = groundtype
			self.column = column
			self.row = row
			self.labyrinth = labyrinth
@@ -23,25 +30,15 @@ class Labyrinth:
		def _removeThing(self,thing):
			self.things.remove(thing)
		def _addThing(self,thing):
			assert self.things.count(thing) == 0
			assert self.groundtype != Labyrinth.GroundType.WALL
			assert thing not in self.things
			self.things.append(thing)
		def neighbor(self,dy,dx):
			return self.labyrinth.getTileAt(self.row + dy, self.column + dx)
		def isWalkable(self):
			# this may be more complicated in the future
			return self.groundtype == Labyrinth.GroundType.FLOOR
		def __str__(self):
			# always starts with there is/there are
			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()
			for thing in self.things:
				if thing.blocksMove():
					return False
			return True
	
	# constructor for a completely read labyrinth
	def __init__(self,game=None,width=None,height=None,stream=None):
@@ -49,7 +46,7 @@ class Labyrinth:
		if width is not None: # empty labyrinth of given size
			assert height is not 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:
			assert False # width None, height not
		elif stream is not None:
@@ -60,11 +57,17 @@ class Labyrinth:
		tiles = []
		for rownum,line in enumerate(stream):
			row = []
			for colnum,char in enumerate(line):
			for colnum,char in enumerate(line[:-1]):
				field = Labyrinth.Field(colnum,rownum,self)
				if char in [' ','0','_']:
					row.append(Labyrinth.Field(Labyrinth.GroundType.FLOOR,colnum,rownum,self))
					pass
				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)
		return tiles
	
@@ -72,13 +75,10 @@ class Labyrinth:
		result = ""
		for row in self.tiles:
			for field in row:
				if field.groundtype == Labyrinth.GroundType.WALL:
					result += "#"
				else:
				if not field.things:
					result += "."
				elif len(field.things) == 1:
						result += field.things[0].asChar()
					result += repr(field.things[0])
				else:
					result += "+"
			result += "\n"
@@ -103,12 +103,18 @@ class Labyrinth:
		return reduce(lambda x,y:x+y, self.tiles)
	
	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 = ""
		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)]]):
			descr += "In the "+name+" "+("there is a wall" if field is None else str(field))+".\n"
		local = list(filter(lambda thing: thing != player, player.field.things))
		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
	
	def moveThing (self, thing, newField, beforeFinish=None):
@@ -130,7 +136,7 @@ class Labyrinth:
	def createThing (self, thing, field):
		thing.field = field
		field._addThing(thing)
		thing.onMove(field)
		if thing.onMove(field):
			thing.afterMove(field)
		self.game.showAdmins()
	
+2 −2
Original line number Diff line number Diff line
@@ -132,8 +132,8 @@ class Player(Thing):
			self.send("I don't know what you are talking about")
	
	def afterMove(self, oldField):
		desc = self.game.labyrinth.getDescription(self.field)
		desc = self.game.labyrinth.getDescription(self)
		self.send(desc, end="")
	
	def asChar(self):
	def __repr__(self):
		return "P"
+4 −1
Original line number Diff line number Diff line
@@ -8,5 +8,8 @@ class Thing():
	def afterMove(self, oldField):
		pass
	
	def asChar(self):
	def blocksMove(self):
		return False
	
	def __repr__(self):
		return "?"

wall.py

0 → 100644
+17 −0
Original line number Diff line number Diff line
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 "#"