Nombre: David Fron Ayala Especialidad: Eléctricidad Grupo: G12 Puesto: 02 Practica: D2 Program Vida_y_muerte; Uses crt; const max_casillas=20; encendida=1; apagada=0; cadena_guiones='-------------------------------------------------------------------------------'; type tablero=array [1..max_casillas,1..max_casillas] of byte; var t_vida:tablero; max_matriz:byte; opcion:byte; tecla:char; Mediante esta parte de codigo declaro las variables del programa principal. Las cosntantes principales son: max_casillas=20-------> 20 sera el maximo lado de la matriz cuadrada. encendida, apagada----> los valores son 0 o 1 dependiendo de como este viva o muerta. cadena_guiones--------> lo empleo para dibujar el menu de elección. Por otra parte esta tablero que es la matriz que va desde 1 al lado del cuadrado que el usuario introduzca por teclado. function obtener_probabilidad: real; Función que devuelve la probabiliadad entre 0 y 1 con un decimal. Si quisieramos obtener mas decimales bastaria con dividir entre 100, 1000, 10000..respectivamente...Como el enunciado no nos dice cuantos decimales debemos poner, se ha elegio el caso mas simple. var num: real; t:byte; begin num:=random(9); num:=num/10; obtener_probabilidad:=num; end; function Pedir_Opcion(min,max,x,y:byte): byte; Función que valida y devuelve un número a partir de los parametros min y max, que son el minimo y maximo permitido en cada caso, además a partir de los parametros x e y, en caso de error, se posiciona en la pantalla para volver a pedir que introduzca el número. Esta función de validad nos es empleada en muchas partes del programa, por eso se decidio crear una funcion que nos sirviera siempre. var valor: integer; begin {$I-} Pedir_Opcion:= 0; gotoxy(x,y);read(valor); while ((IORESULT <> 0) OR ((IORESULT = 0) AND ((valor > max) OR (valor 0) OR ((IORESULT = 0) AND ((valor > 1) or (valor<0)))) do begin gotoxy(01,25);write('Incorrecto debe ser numerico y entre 0 y 1'); gotoxy(27,1);read(valor); end; Pedir_probabilidad:=valor; {$I+} end; function obtener_encendidas(var v:tablero;minf,maxf,minc,maxc:byte): byte; Función que devuelve el número celdas encendidas entre un intervalo de filas y columnas que se se pasan por los parametros minf,maxf,minc,maxc a partir de la tabla v que se pasa por referencia para no sobrecargar la memoria. var fila,columna,n:byte; begin obtener_encendidas:=0; n:=0; for fila:= minf to maxf do for columna:=minc to maxc do if (v[fila,columna]=encendida) then n:=n+1; if (v[minf+1,minc+1]=encendida) then n:=n-1; obtener_encendidas:=n; end; function cargar_mundo(nombreFich: string): string; Función que devuelve una cadena de caracteres a partir de un fichero, a esta funición se le ha agregado robustez y la letra F para saber el fin de la cadena. Lo demas se ha dejado igual, aunque mundo yo creo que tendria que haber sido de string[255], pero me imagino que el creador de la función tendra sus motivos. var fichero:text; linea:string; mundo:String[200]; begin {$I-} mundo:=''; assign(fichero,nombreFich); Reset(fichero); if IORESULT <> 0 then begin; clrscr; gotoxy(1,1);writeln('Error grave'); halt; end; while not eof(fichero) do begin Readln(fichero,linea); mundo:=mundo+linea+'|'; end; {$I+} close(fichero); mundo:=mundo+'F'; cargar_mundo:=mundo; end; procedure Mostrar_Menu; Procedimiento del muestra el menu general, llamamos a la constante cadena_guiones para evitar, escribirlo todo el rato. begin clrscr; gotoxy(01,08);write(cadena_guiones); gotoxy(01,09);write('| |'); gotoxy(01,10);write('| |'); gotoxy(01,11);write('| 1. Generar mundo aleatorio |'); gotoxy(01,12);write('| 2. Ejecuci¢n |'); gotoxy(01,13);write('| 3. Cargar Estado inicial |'); gotoxy(01,14);write('| 4. Salir |'); gotoxy(01,15);write('| |'); gotoxy(01,16);write('| |'); gotoxy(01,17);write('| Opci¢n: |'); gotoxy(01,18);write(cadena_guiones); end; procedure Mostrar_Menu_Defecto; Procedimiento del muestra el menu de parametrización, de iguales caracteristicas constructivas que el anterior procedimiento. begin clrscr; gotoxy(01,08);write(cadena_guiones); gotoxy(01,09);write('| |'); gotoxy(01,10);write('| |'); gotoxy(01,11);write('| 1. Parametrizaci¢n por defecto X=3,Y=2,Z=3 |'); gotoxy(01,12);write('| 2. Parametrizaci¢n por usuario |'); gotoxy(01,13);write('| |'); gotoxy(01,14);write('| |'); gotoxy(01,15);write('| |'); gotoxy(01,16);write('| |'); gotoxy(01,17);write('| Opci¢n: |'); gotoxy(01,18);write(cadena_guiones); end; procedure Mostrar_Menu_Modo; Procedimiento del muestra el menu de modo de ejecución, de iguales caracteristicas constructivas que los 2 anteriores procedimientos. begin clrscr; gotoxy(01,08);write(cadena_guiones); gotoxy(01,09);write('| |'); gotoxy(01,10);write('| |'); gotoxy(01,11);write('| 1. Ver paso a paso |'); gotoxy(01,12);write('| 2. Ver el final |'); gotoxy(01,13);write('| |'); gotoxy(01,14);write('| |'); gotoxy(01,15);write('| |'); gotoxy(01,16);write('| |'); gotoxy(01,17);write('| Opci¢n: |'); gotoxy(01,18);write(cadena_guiones); end; function opcion_defecto: char; Función que devuelve la Opción introducida por el usuario en el menu parametrización. En esta función se llama a la funcion pedir_opcion (Explicada arriba) var valor: byte; begin Mostrar_menu_defecto; valor:=Pedir_Opcion(1,2,11,17); if valor=1 then opcion_defecto:='D' else opcion_defecto:='P'; end; function opcion_modo: char; Función que devuelve la Opciónn introducida por el usuario en el menu modo de ejecución. En esta función se llama a la funcion pedir_opcion (Explicada arriba) var valor: byte; begin Mostrar_menu_modo; valor:=Pedir_Opcion(1,2,11,17); if valor=1 then opcion_modo:='P' else opcion_modo:='F'; end; procedure dibujar_cuadro(var v:tablero;m:byte;t:integer); Procedimiento que dibuja el cuadro a partir del parametro v (tablero) que se pasa por referencia para no sobrecargar la memoria, además se pasan los parametros m(lado del cuadrado) y t (turno de ejecución) por valor. var fila,columna:byte; c:char; begin clrscr; for fila:= 1 to m do begin; gotoxy(1,fila); for columna:= 1 to m do begin; write(v[fila,columna]); end; end; gotoxy(01,25); if t=0 then write('Cuadro Inicial.Pulse una tecla para continuar ') else if t=999 then write('Cuadro Final.Pulse una tecla para continuar ') else write('Cuadro en ejecuci¢n ',t,'.Pulse una tecla para continuar '); c:=readkey; end; procedure inicializar_cuadro(var x:tablero); Procedimiento que el parametro x de tipo tablero se pasa por referencia para poder modificarlo con inicialización de celdas apagadas. var fila,columna:byte; begin for fila:= 1 to max_casillas do for columna:= 1 to max_casillas do X[fila,columna]:=apagada; end; procedure obtener_nuevo_cuadro(var v:tablero;m,a,b,c:byte); Procedimiento que el parametro v de tipo tablero se pasa por referencia para poder modificarlo para obtener el nuevo cuadro a partir de la parametrización y reglas de juego. Ademas se introducen como valor los siguientes parametros: - m:lado de la matriz - a:parametro X para las celdas apagadas - b y c: parametros Y y Z para las celdas encendidas var fila,columna,num_encendidas:byte; aux:tablero; begin inicializar_cuadro(aux); for fila:= 1 to m do for columna:= 1 to m do aux[fila,columna]:=v[fila,columna]; inicializar_cuadro(v); for fila:= 1 to m do for columna:= 1 to m do begin; if ((fila<>1) and (fila<>m) and (columna<>1) and (columna<>m)) then begin; num_encendidas:=obtener_encendidas(aux,fila-1,fila+1,columna-1,columna+1); if aux[fila,columna]=encendida then begin; if ((num_encendidas>=b) and (num_encendidas<=c)) then v[fila,columna]:=encendida else v[fila,columna]:=apagada; end else begin; if num_encendidas=a then v[fila,columna]:=encendida else v[fila,columna]:=apagada; end; end; end; end; procedure generar_mundo_aleatorio(var x:tablero;m:byte;prob_usu:real); Procedimiento que el parametro x de tipo tablero se pasa por referencia para poder modificarlo para obtener el nuevo cuadro a partir de la probabilidad introducida por el usuario, aplicandose las reglas juego. Se introducen como valor los siguientes parametros: - m:lado de la matriz - prob_usu:probabiliadad de usuario var probabilidad_casilla:real; fila,columna:byte; begin for fila:= 1 to m do for columna:= 1 to m do begin; if ((fila<>1) and (fila<>m) and (columna<>1) and (columna<>m)) then begin; probabilidad_casilla:=obtener_probabilidad; if probabilidad_casilla <= prob_usu then x[fila,columna]:=encendida else x[fila,columna]:=apagada; end else x[fila,columna]:=apagada; end; end; procedure cuadro_usuario(var x:tablero;var m:byte); Procedimiento que el parametro x de tipo tablero se pasa por referencia para poder modificarlo para la inicializaci¢n de la opci¢n 1 del men£ general a partir de los datos que se piden al usuario. Introduzco como valor el parametro m de tipo byte que es el lado de la matriz. var probabilidad:real; begin clrscr; gotoxy(01,01);write('Tama¤o del tablero entre 4 y 20: '); m:=Pedir_Opcion(4,20,34,1); clrscr; gotoxy(01,01);write('Probabilidad del usuario: '); probabilidad:=Pedir_probabilidad; generar_mundo_aleatorio(x,m,probabilidad); end; procedure cuadro_fichero(var x:tablero;var m:byte); Procedimiento que el parametro x de tipo tablero se pasa por referencia para poder modificarlo para la carga a partir de fichero (opciónn 3 del menu general). Ademas se introduce como referencia el parametro m de tipo byte para informar el lado de la matriz. Yo en mis pruebas efectuadas en casa como ruta he puesto c:\mundo.txt, pero como en la hoja del enunciado poneis que se ponga estadoinicial.txt.Al final he dejado c:\mundo.txt. Tambien he observado que poniendo estadoinicial.txt el programa no pilla el archivo, eso creo que es porque tiene una extension muy grande. De todas formas como supongo que vosotros tendreis una forma de ejecutarlo..lo he dejado como lo pone en el algoritmo que dejasteis colgado en el add y añadiendo c:\ que es la ruta. Si no funciona la solución es poner cargar_mundo('c:\ estadoinicial.txt') ó (c:\mundo.txt), dependiendo de donde querais ejecutarlo. var mundo:string[200]; i,retorno,valor:integer; fila,columna:byte; begin clrscr; mundo:=cargar_mundo('mundo.txt'); fila:=1; columna:=0; m:=0; for i:=1 to 200 do begin; if mundo[i]='|' then begin; fila:=fila+1; columna:=0; if fila=2 then m:=i-1; end else begin if mundo[i]='F' then exit else begin; columna:=columna+1; Val(mundo[i],valor,retorno); if retorno<>0 then begin; gotoxy(1,1);writeln('Error grave'); halt; end else x[fila,columna]:=valor; end; end; end; end; procedure parametrizar(var t:byte;var o:char;var a,b,c:byte;var m:char); Procedimiento que que se usa para obtener los datos de la paramtrización introducida por el usuario, todos los parametros son por referencia para poder modificarlos a parir de los datos del usuario: - t: de tipo byte para obtener el n£mero de turnos. - o: de tipo char para saber si usa parametrizaci¢n por defecto ¢ no - a: de tipo byte para obtener el parametro X para las celdas apagadas - b y c: de tipo byte para obtener los parametros Y y Z para las celdas encendidas - m: de tipo byte para obtener el modo de ejecución begin clrscr; gotoxy(01,01);write('Numero de turnos a ejecutar entre 1-255: '); t:=Pedir_Opcion(1,255,42,1); o:=Opcion_defecto; if (o='D') then begin; a:=3;b:=2;c:=3; end else begin; clrscr; gotoxy(01,01);write('Introduzca X entre 0 y 8: '); a:=Pedir_Opcion(0,8,27,1); clrscr; gotoxy(01,01);write('Introduzca Y entre 0 y 7: '); b:=Pedir_Opcion(0,7,27,1); clrscr; gotoxy(01,01);write('Introduzca Z entre ',b+1,' y 8: '); c:=Pedir_Opcion(b+1,8,27,1); end; m:=Opcion_modo; end; procedure ejecucion_juego(var v:tablero;m:byte); Procedimiento que el parametro v de tipo tablero se pasa por referencia para poder modificarlo para la ejeci¢n del juego, para la opción 2 del menú general. Además se introducen como valor el parametro m de tipo byte que es el lado de la matriz. Escojo byte en este punto y en anteriores porque es un dato simple y no merece la pena gastar mas memoria. var turnos,x,y,z,i:byte; opcion_val,modo:char; begin clrscr; parametrizar(turnos,opcion_val,x,y,z,modo); dibujar_cuadro(v,m,0); for i:=1 to turnos do begin; obtener_nuevo_cuadro(v,m,x,y,z); if ((i<>turnos) and (modo='P')) then dibujar_cuadro(v,m,i); end; dibujar_cuadro(v,m,999); end; begin randomize; max_matriz:=0; repeat clrscr; Mostrar_Menu; opcion:= pedir_Opcion(1,4,11,17); case opcion of 1: begin clrscr; max_matriz:=0; inicializar_cuadro(t_vida); cuadro_usuario(t_vida,max_matriz); end; 2: begin IF max_matriz<>0 THEN ejecucion_juego(t_vida,max_matriz) ELSE BEGIN; gotoxy(01,25); write('No se ha generado ¢ cargado mundo.Pulse una tecla para continuar'); tecla:=readkey; END; end; 3: begin; max_matriz:=0; inicializar_cuadro(t_vida); cuadro_fichero(t_vida,max_matriz); end; end; until (opcion=4); end. Este es el cuerpo principal del programa y dependiendo de la opción introducida por el usuario el programa hara una cosa u otra. En esta parte vamos llamando a los procediemintos y funciones dependiendo de la opción elegida por el usuario.EL randomize lo ponemos en el programa principal para que se ejecute de manera correcta ya que sino...queda semilla. Tecleando la opción 4 el programa temina. ---------------------------- (añadido tras someter) ---------------------------- 17:58:54 11/12/09 -> Segun los datos introducidos los ficheros son: G12P02D2 -> Los autores del trabajo son: Fron Ayala, David Nombres originales de los archivos entregados -> VIDA3FIN.PAS, documVIDA3FIN.txt