-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjuego.py
163 lines (138 loc) · 5.94 KB
/
juego.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# -*- coding: cp1252 -*-
import curses
import actores
import errores
from mapa import Mapa
import sys
class Juego(object):
def __init__(self, nombre_mapa):
"""Carga el mapa del juego a partir del archivo mapas/<nombre_mapa>.map."""
with open("mapas/{}.map".format(nombre_mapa)) as f:
filas = [ linea.strip() for linea in f ]
mapa, heroe = self.crear_mapa(filas)
self.mapa = mapa
self.heroe = heroe
self.juego_terminado = False
# El historial de mensajes es simplemente una lista de strings.
self.mensajes = []
def agregar_goblin(self,mapa,x,y):
"""Agrega un goblin al mapa"""
goblin = actores.Goblin()
mapa.agregar_actor(goblin,x,y)
def agregar_orco(self,mapa,x,y):
"""Agrega un orco al mapa"""
orco = actores.Orco()
mapa.agregar_actor(orco,x,y)
def agregar_pared(self,mapa,x,y):
"""Agrega una pared al mapa"""
pared = actores.Pared()
mapa.agregar_actor(pared,x,y)
def agregar_salida(self,mapa,x,y):
"""Agrega una salida al mapa"""
salida = actores.Salida()
mapa.agregar_actor(salida,x,y)
def crear_mapa(self, filas):
"""Crea el Mapa a partir de la definicion provista por parametro (`filas`),
y devuelve una tupla con el mapa y el actor que representa al heroe del juego.
`filas` es una lista de strings, que corresponde con el contenido completo
del archivo .map.Se presupone que en el mapa se proporciona una salida para
poder finalizar el juego, y si se proporciona algun caracter que no corresponde
a ningun personaje, se lo reemplaza por una celda vacía automáticamente.
Si hay mas de un heroe en la definicion del mapa, o bien si
no hay ningun heroe, la funcion lanza una excepcion, si el mapa no tiene
el formato correcto(debe ser rectangular), también
"""
dic_funciones = {"#":Juego.agregar_pared,
"o":Juego.agregar_orco,
"g":Juego.agregar_goblin,
"<":Juego.agregar_salida
}
ALTO = len(filas)
ANCHO = len(filas[0])
if ANCHO == 0: raise IndexError("Linea vacia")
mapa = Mapa(ANCHO,ALTO)
x = 0
y = -1
heroe = None
cantidad_heroes = 0
for fila in filas:
if len(fila) != ANCHO:
raise errores.MapaIncorrectoError("la linea",fila,"no contiene la misma cantidad de caracteres que la primer linea del archivo")
x = 0
y+= 1
for caracter in fila:
if caracter == "@":
# Lo necesitamos ya que, debemos definir heroe para poder devolverlo
heroe = actores.Heroe()
mapa.agregar_actor(heroe,x,y)
cantidad_heroes+=1
if cantidad_heroes > 1:
raise errores.DemasiadosHeroesError("Se esta añadiendo",cantidad_heroes-1,"heroes de mas")
elif caracter in dic_funciones:
dic_funciones[caracter](self,mapa,x,y)
x+=1
if heroe == None:
raise errores.NoHayHeroeError("No hay ningun heroe(@) en el mapa")
return mapa, heroe
def turno(self, evento):
"""Llama al metodo jugar_turno() del heroe. Si el heroe hizo algo,
llama al metodo jugar_turno() para el resto de los actores"""
if self.juego_terminado:
return
if not self.heroe.jugar_turno_heroe(evento, self):
# El heroe no hizo nada
return
# El resto de los actores juegan su turno
for actor in self.mapa.actores:
if not actor.es_heroe():
actor.jugar_turno(self)
self.mapa.eliminar_actores_muertos()
def terminar(self):
"""Marcar que el juego ha terminado."""
self.juego_terminado = True
def msg(self, *args):
"""Agregar un mensaje al historial."""
self.mensajes.append(" ".join(args))
def dibujar_mensajes(self, ventana, cantidad):
"""Dibujar los ultimos `cantidad` mensajes del historial en la ventana provista."""
for y, mensaje in enumerate(self.mensajes[-cantidad:]):
ventana.addstr(y, 0, mensaje)
def main(self):
"""Bucle principal del juego."""
try:
pantalla = curses.initscr()
# No imprimir la entrada del teclado:
curses.noecho()
# Cursor invisible:
curses.curs_set(0)
# Habilitar las flechas para moverse
pantalla.keypad(1)
self.msg("Has ingresado en el calabozo! Podras escapar?")
self.msg("Flechas para moverse, Q para salir")
while True:
pantalla.clear()
self.mapa.dibujar(pantalla.derwin(0, 0))
self.dibujar_mensajes(pantalla.derwin(0, self.mapa.ancho() + 2), self.mapa.alto())
evento = pantalla.getch()
if evento == ord("q"):
break
self.turno(evento)
finally:
# devolver el estado de la consola (por ejemplo la visibilidad del cursor)
curses.endwin()
# Mapa por defecto:
nombre_mapa = 'nivel1'
if len(sys.argv) > 1:
nombre_mapa = sys.argv[1]
try:
Juego(nombre_mapa).main()
except errores.NoHayHeroeError:
print "Debe haber un heroe representado por '@' para que juege el usuario."
except errores.MapaIncorrectoError:
print "Formato del mapa incorrecto, debe ser rectangular"
except errores.DemasiadosHeroesError:
print "Se estan añadiendo heroes de mas, solo puede haber uno"
except IOError:
print "Archivo del mapa o directorio inexistentes, o no se tienen los permisos necesarios."
except IndexError:
print "Mapa vacio, o no esta alineado en la izquierda superior del archivo"