player.py 2.39 KB
Newer Older
1
from util import *
Ralf's avatar
Ralf committed
2
3
from thing import Thing
from labyrinth import directions as directionOffsets
4

Ralf's avatar
Ralf committed
5
6
goVerbs = ['go', 'walk']
sayVerbs = ['say', 'talk', 'scream']
7
leaveVerbs = ['leave', 'quit', 'exit', 'suicide']
Ralf's avatar
Ralf committed
8
9

class Player(Thing):
Ralf's avatar
Ralf committed
10
	def __init__(self, game, conn):
Constantin's avatar
Constantin committed
11
		super().__init__()
Ralf's avatar
Ralf committed
12
13
14
15
16
		self.buffer = b""
		self.game = game
		self.conn = conn
	
	# low-level functions
17
	def send(self, data, end='\n'):
Ralf's avatar
Ralf committed
18
		assert type(data) == str
19
		send_async(self.conn, (data+end).encode('utf-8'))
Ralf's avatar
Ralf committed
20
21
22
	
	def close(self): # only to be called by Game - it has to remove us from its list
		self.conn.close()
23
		return self.conn
Ralf's avatar
Ralf committed
24
25
26
27
28
29
30
	
	def read(self, conn, mask):
		assert self.conn == conn, "The player's connection changed?"
		data = conn.recv(1024)  # Should be ready
		if data:
			self.buffer += data
			pos = self.buffer.find(b'\n')
Ralf's avatar
Ralf committed
31
			while pos >= 0:
Ralf's avatar
Ralf committed
32
33
				cmd = self.buffer[:pos]
				self.buffer = self.buffer[pos+1:]
34
35
36
37
				try:
					self.readCmd(cmd.decode('utf-8'))
				except UnicodeDecodeError:
					self.send("These are bad bytes...")
Ralf's avatar
Ralf committed
38
39
				# maybe we got several lines?
				pos = self.buffer.find(b'\n')
Ralf's avatar
Ralf committed
40
41
42
		else:
			self.game.removePlayer(self)
	
Ralf's avatar
Ralf committed
43
	def __str__(self):
Constantin's avatar
Constantin committed
44
45
		return "another player"
	
Ralf's avatar
Ralf committed
46
47
	# high(er)-level functions
	def readCmd(self, cmd):
Ralf's avatar
Ralf committed
48
		self.game.log("Someone wrote '{0}'".format(cmd))
Ralf's avatar
Ralf committed
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
		words = cmd.lower().split()
		if not words:
			self.send("What did you mean?")
			return
		verb = words[0]
		if verb in goVerbs:
			if len(words) >= 3 and words[1:3] == ["to", "the"]:
				direction = words[3:]
			else:
				direction = words[1:]
			if len(direction) != 1 or direction[0] not in directionOffsets:
				self.send("Where do you want to go?")
				return
			dy, dx = directionOffsets.get(direction[0])
			target = self.field.neighbor(dy=dy, dx=dx)
			if target is None or not target.isWalkable():
				self.send("Sorry, you cannot go there")
				return
			self.game.labyrinth.moveThing(self, target)
		elif verb in sayVerbs:
			msg = " ".join(words[1:])
			for dx, dy in [(0, 0)]+directionOffsets.values():
				for thing in self.field.neighbor(dx=dx, dy=dy):
					if isinstance(thing, Player) and thing != self:
						thing.send("You hear someone saying: "+msg)
			self.send("You say: "+msg)
75
76
77
78
79
		elif verb in leaveVerbs:
			self.send("Good Bye!")
			self.game.removePlayer(self)
		else:
			self.send("I don't know what you are talking about")
Ralf's avatar
Ralf committed
80
	
Constantin's avatar
Constantin committed
81
82
	def afterMove(self, oldField):
		desc = self.game.labyrinth.getDescription(self.field)
83
		self.send(desc, end="")