En esta asignatura soy responsable de
parte de un grupo de teoría y de dos de prácticas.
En
mi grupo de teoría utilizo estos apuntes.
Además
he preparado una colección de problemas cuyos enunciados están
disponibles aquí. Dada la
importante cantidad de ejercicios de examen de que se dispone, se
hará un uso marginal de este documento.
Para trabajar
en casa puedes utilizar dev-cpp
como Entorno Integrado de Desarrollo. Es gratuito y ocupa menos de
20MB. He preparado unos apuntes que
explican a nivel introductorio el funcionamiento de este programa. No
imprimir este documento, se ampliará a lo largo del curso. Las
capturas de pantalla se ven mucho mejor en la versión
en html del mismo documento.
Aquí iré
publicando los ejercicios que se hagan en clase y cualquier otro
material que vaya surgiendo a lo largo del curso.
Exámenes de otros años.
Luis
Junco tiene en su página
los exámenes de otros años recopilados en varios
ficheros comprimidos.
En la misma página hay
materiales interesantes en la zona de
descargas.
2003-2004.
2004-2005.
2005-2006.
Teoría:
Por petición popular incluyo aquí los materiales que usé el año pasado y esta año en al parte que estoy impartiendo.
Transparencias:
Introducción, para imprimir, para ver en el ordenador.
Estructuras básicas de algoritmos y de datos, parte I, para imprimir, para ver en el ordenador.
Estructuras básicas de algoritmos y de datos, parte II, para imprimir, para ver en el ordenador.
Estructuras básicas de algoritmos y de datos, parte III, para imprimir, para ver en el ordenador.
Programa de ejemplo. Fuente, para imprimir: pdf a dos columnas.
Definición de acciones no primitivas, parte I, para imprimir, para ver en el ordenador.
Definición de acciones no primitivas, parte II (Recursividad y un par de cosas más), para imprimir, para ver en el ordenador.
Definición de nuevos tipos de datos, parte I, para imprimir, para ver en el ordenador.
PROBLEMAS:
Ejemplos para if-else switch:
Resolver una ecuación de segundo grado considerando todos los casos posibles, si la ecuación tiene la forma ax^2+bx+c=0, se piden a, b y c por el teclado y:
Si a es cero, se resuelve la ecuación que en realidad es lineal. Además si b es cero entonces no hay solución.
Si a no es cero se analiza el valor del discriminante y en función de este habrá solución real doble, dos soluciones reales o dos soluciones complejas conjugadas. En este último caso, calcular la parte real e imaginaria por separado y mostrarlas por la pantalla en notación cartesiana.
Pedir tres números por el teclado y mostrarlos por la pantalla ordenados de mayor a menor, intercambiando los valores de las variables adecuadas.
Mostrar la fecha siguiente a una dada.
Implementar una calculadora básica de números complejos, con las operaciones aritméticas habituales. Cuidar la presentación de los resultados de modo que:
Si el resultado es i no se muestre 0+1i
Si el resultado es 0 no se muestre 0+0i
Si el resultado es a-bi no se muestre a+-bi
etc.
Los dos últimos ejercicios en un mismo pdf a dos columnas.
Ejemplos de bucles:
Ejemplos iniciales.
Sumar las cifras de un número entero. sumacifras.cpp
Invertir el orden de las cifras de un número entero. reves.cpp
Averiguar si un número es capicúa o no. capicua.cpp
Convertir un número de decimal a binario. d2b.cpp
Obtener los 20 primeros términos de la sucesión de Fibonacci. fibo20.cpp
Aproximación de e^x por una serie, finaliza cuando se alcanza un máximo número de iteraciones o una determinada precisión, lo que suceda antes. Intentar realizar el mínimo número de cálculos posible. ex.cpp
Ejemplos con bucles anidados.
Mostrar los n primeros capicúas, n se pide por el teclado. ncapicua.cpp
Determinar los números menores que 1000 tales que aparecen al final de su cuadrado (ejercicio de examen). xy2xyz.cpp
Determinar cual es la fracción que se aproxima más a PI con el numerador y el denominador menores que 500 (ejercicio de examen). PI1.cpp
Descomponer un número en factores primos.factoresprimos.cpp
Buscar el mayor número
entero (menor que 45000 por cuestiones de rango) cuyo cuadrado se
escriba con dígitos distintos. (Ejercicio de examen)
Ejemplos
de cuadrados que cumplen esa condición : 13^2 = 169
286^2=81796 32043^2=1026753849. cuadrado_digitos_distintos.cpp
Un número perfecto es aquel que coincide con la suma de todos sus divisores, incluyendo el 1 pero no el propio número (por ejemplo 6 = 1+2+3, 28 = 1+2+4+7+14). Escribir un programa que muestre por la pantalla los números perfectos menores que 100. (Ejercicio de examen) perfectos.cpp
Todos los ejemplos anteriores en un pdf a dos columnas ejercicios_bucles.pdf
Ejemplos de vectores.
Suma de los elementos de un vector. sumavector.cpp
Suma vectorial de dos vectores. sumavectorial.cpp
Producto escalar de dos vectores. productoescalar.cpp
Módulo de un vector. modulo.cpp
Máximo de los elementos de un vector. maximov.cpp
Suma de dos matrices. sumamat.cpp
Producto de dos matrices. prodmat.cpp
Tipificar una matriz. tipificamat.cpp
Ejemplos preliminares para entender el siguiente, vectores maximov2.cpp y matrices maximofilcol.cpp.
Determinar la posición del punto de silla de una matriz. silla.cpp
Los ejemplos anteriores en un pdf a dos columnas ejercicios_vectores.pdf
Ejemplos introductorios de funciones.
Mostrar los n primeros capicúas, n se pide por el teclado. ncapicua_f.cpp
Mostrar los n primeros números que contienen la cifra x. ncontienex_f.cpp
Buscar el mayor número entero (menor que 45000 por
cuestiones de rango) cuyo cuadrado se escriba con dígitos
distintos. (Ejercicio de examen, versión con
funciones)
Ejemplos de cuadrados que cumplen esa condición
: 13^2 = 169 286^2=81796 32043^2=1026753849.
cuadrado_digitos_distintos_f.cpp
Más ejemplos de funciones, relacionados con los temas de los apuntes "Mecanismos de paso de argumentos" y "Semántica del paso de argumentos". De alguna forma todos han caído en algún examen.
Escribir una función que expurgue las repeticiones de los elementos de un vector de enteros. Varias versiones, usando o no push_back, devolviendo el resultado con return o a través de una referencia no constante. unicos.cpp
Sobrecarga de los operadores *, >> y << para matrices. matop.cpp
Mezcla (merge) de dos vectores ordenados produciendo un tercer vector, también ordenado. mezcla.cpp
Máximo de la suma de elementos contiguos de un vector. suma_maxima_segmento.cpp
Función que comprime un vector de enteros "casi vacío" y su contrapartida, descomprime un vector "casi vacío" (ejercicio de examen). Un vector "casi vacío" es aquel que contiene mayoritariamente elementos nulos. Para ahorrar espacio se guarda el tamaño del vector y (alternativamente) la posición y el contenido de los elementos no nulos en un vector de enteros convencional. Por ejemplo el vector {0,0,0,1,0,0,-7,0,0} se podría guardar como {9,3,1,6,-7}. La función comprime se ha escrito usando push_back y sin usarla. comprime.cpp
Función que devuelve true si la paridad de un vector de booleanos es par, false en caso contrario. La paridad es par si el número de elementos a true es par. vector_par.cpp
Los ejercicios anteriores en un mismo pdf a dos columnas. ejercicios_funciones.pdf
Ejemplos de enumeraciones, estructuras y clases.
Programa que muestra las 40 cartas de la baraja española en orden aleatorio (barajadas). Se definen enumeraciones para la figura y para el palo y cada carta es una estructura cuyos campos son enumeraciones de los tipos anteriores. barajaf.cpp. El ejercicio tal y como se llevó a clase baraja.pdf.
Esquema general de implementación y uso de una clase, sin utilizar y utilizando el operador de resolución de ámbito, es decir definiendo las funciones miembro dentro de la clase esquema_clase.pdf y declarando las funciones dentro y definiéndolas fuera esquema_clase_scope.pdf.
Ejemplos de un problema resuelto sin funciones (complejos_pelado.cpp), con funciones (complejos_con_funciones.cpp), con estructuras (complejos_con_estructuras.cpp) y con clases (complejos_con_clases.cpp). Este último se irá refinando en clases sucesivas, a medida que se impartan los conocimientos necesarios para ello. El objetivo es comprender la ventaja que proporciona al programador/a el uso de clases.
Los ejercicios tal y como se llevaron a clase complejos_gradual.pdf.
Puntero this. explica_this.pdf
Ejemplos para ilustrar el concepto de interfaz pública de una clase. complejos_interfaz_publica.pdf
Ejercicios de examen sencillos. Enunciados enunciados_clases_sencillos.pdf y soluciones ejercicios_clases_sencillos.pdf.
Ejemplos y explicación para destructores, operador de asignación, constructor de copia, cuando se usa memoria dinamica.
Ejemplo de tipo paramétrico (template) clase par de T1 y T2.
Ejemplo de composición (examen), clase punto2d y clase segmento.
Ejemplo de composición (examen), clase punto2d y clase circunferencia.
Ejemplo de composición (examen), intervaloR e intervaloR2.
Los ejemplos de composición en el mismo pdf a dos columnas.
Ejemplo explicativo de herencia. Clase electrodoméstico. Probablemente esté basado en algún ejemplo de los apuntes de la Universidad de Navarra que no es pública, "Aprenda C++ como si estuviera en primero".
Ejemplo con algo más de sentido, por supuesto se le ocurrió a Luis Junco. Clase abstracta función con un método que calcula la integral definida entre dos valores numéricamente. De ella deriva la función polinomio de segundo grado.
NUEVO: clase polinomio, ejercicio de examen ampliado.
Guiones de prácticas:
Práctica 0: Toma de contacto con el IDE. Escribir un programa que resuelva una ecuación de segundo grado.
Práctica 1: Ejercicios de bucles sencillos.
Escribir un programa que pida un entero por el teclado y muestre por la pantalla sus divisores.
Escribir un programa que pida un entero por el teclado y muestre por la pantalla la suma de los divisores del número.
Escribir un programa que pida un entero por el teclado y muestre por la pantalla si el número es perfecto o no. Un número es perfecto si es igual a la suma de sus divisores (incluyendo el 1 pero no el propio número).
Escribir un programa que pida un entero por el teclado y muestre por la pantalla un mensaje indicando si el número es primo o no.
Práctica 2: Ejercicios de bucles anidados.
Escribir un programa que muestre por la pantalla los números primos menores que n, que se pide por el teclado.
Escribir un programa que muestre por la pantalla los n primeros primos, n se pide por el teclado. Se puede utilizar el siguiente esquema:
#include<iostream> using namespace std; int main() { //n es el numero de primos que se desean //conta es el contador de primos //actual es cada uno de los enteros //que se comprueban si son o no primos int conta,n,actual; //inicializar conta y actual ...; ...; //pedir el numero de primos que se desean ...; //mientras el numero de primos ENCONTRADOS //sea menor que el que nos piden while(...) { //declarar e inicializar es_primo bool ...; //comprobar si existe algun divisor for (...) { //si se encuentra un divisor if (...) //es falso que sea primo ...; } //si (finalmente) es primo if (...) { //mostrarlo por la pantalla ...; //contarlo ...; } //en cualquier caso, actualizar actual ...; } }
Escribir un programa que muestre por la pantalla los n primeros números perfectos. Utilizar un esquema similar al anterior.
Práctica 3: Finalizando el tema de los bucles anidados, algunos ejercicios más:
Escribir un programa que pida un entero "numero" por el teclado y una cifra "c" y que muestre por la pantalla si el entero contiene dicha cifra. Se puede usar este esquema, no siendo óptimo, es más fácil de reutilizar en el ejercicio que va a continuación. Es necesario añadir las directivas del preprocesador y demás detalles.
//esqueleto para el primer ejercicio de la práctica 3 ... int main() { //numero es el número en donde se busca c int numero,c,copia; bool encontrada; //pedir los datos ... //inicialmente no se ha encontrado la cifra ... //se copia el numero ... //mientras queden cifras en copia y no haya encontrado la cifra while(...) { //si la encuentro if(...) //marco que la he encontrado (cambiar el valor de "encontrada" ... //quito la cifra del numero ...; } //acabado el while, si la he encontrado //muestro el resultado if(...) ... else ... }
Escribir un programa que pida un entero "n" por el teclado y una cifra "c", mostrando por la pantalla los "n" primeros números naturales que contienen a esa cifra. Usar un esquema similar al del segundo ejercicio de la práctica anterior.
Práctica 4: Funciones. Ejercicio 1 del examen de Junio de 2009.
Un número n es de Aquiles si es un número poderoso (existen a y b tales que a^2*b^3=n) pero no es una potencia perfecta (NO existen m y k tales que m^k=n, con k>1)
- Escribir una función booleana que devuelva true si un número que se pasa como parámetro es
poderoso, false en caso contrario.
- Escribir una función booleana que devuelva true si un número que se pasa como parámetro es
potencia perfecta, false en caso contrario.
- Utilizar las dos anteriores para escribir una función que devuelva true si un número es de Aquiles,
false en caso contrario.
Ejemplo:
108 es un número de Aquiles, 108=2^2*3^3 y además no existen m y k / m^k=108
NOTA 1: escribir un programa para probar cada una de las funciones que se han escrito. Enviar ese programa por correo. Aunque no se pide, escriba o copie de los apuntes la función int potencia(int,int); que eleva un número entero a un exponente también entero.
NOTA 2: aunque no se pide, puede escribir o copiar de los apuntes la función int potencia(int,int); que eleva un número entero a un exponente también entero, puede serle útil.
NOTA 3: para probar si existen x e y tales que cumplan una determinada propiedad (si no nos interesan los valores que tomen, sólo si existen o no) se pueden utilizar dos bucles for anidados:
for (int x=limInfX;x<limSupX;x++)
for (int y=limInfY;y<limSupY;y++)
{
//probar si se cumple la condición
...
//si se cumple retornar true
}
//si se llega a este punto (fuera de los bucles)
//no se han encontrado
//retornar false
...
Práctica 5: Funciones. Ejercicio 1 del examen de Septiembre de 2009.
Un número altamente compuesto es aquel que tiene más divisores (contabilizando como tales el 1 y el propio número) que cualquier número entero positivo menor que el.
Escribir una función que reciba un entero positivo y devuelva su número de divisores. Ejemplo, si el entero es 6 la función devolverá 4 ya que los divisores de 6 son 1, 2, 3 y 6. Escribir un programa de prueba y enviarlo por correo.
Usando la anterior, escribir una función booleana que reciba un entero positivo y devuelva true si es altamente compuesto, false en caso contrario. Escribir un programa de prueba y enviarlo por correo.
Ejemplo, si el entero es 6 la función devuelve true porque 5 tiene 2 divisores, 4 tiene 3, 3 tiene 2, 2
tiene 2 y 1 tiene 1. Por el contrario, si el entero es 5 la función devuelve false.
Si acaba con tiempo, puede escribir un programa que muestre los x primeros números altamente compuestos, x se pide por el teclado y enviarlo por correo. Aquí puede comprobarse el resultado.
Práctica 6: Funciones y vectores, operadores.
Tomando como punto de partida el código de ejemplo que figura al final del enunciado, ampliarlo, añadiendo las operaciones indicadas. A elección del alumno, usando funciones u operadores, salvo en los casos en los que se especifique una alternativa concreta..
Suma de matrices, operador o función.
Resta de matrices, operador o función.
Traspuesta de una matriz, función.
Tipificar una matriz (sustituir cada elemento de una fila por la media de los elementos de esa fila), función.
Escribir un programa que utilice las operaciones anteriores para efectuar el cálculo que se expresa a continuación en notación algebraica:
tipifica(A*B+C'-D)
y que muestre el resultado por la pantalla. A, B, C, D son matrices de dimensiones 3x4, 4x3, 3x3, 3x3 respectivamente. Comprobar el resultado utilizando Matlab o calculadora. Seleccionar el resultado de la ejecución del programa y pegarlo en el cuerpo del mensaje en donde se adjunte el código fuente del programa.
Añadir las operaciones básicas con vectores:
Multiplicar un vector por una matriz.
Multiplicar una matriz por un vector.
Multiplicar un escalar por una matriz
Multiplicar una matriz por un escalar.
Multiplicar dos vectores escalarmente.
Sumar y restar vectores.
Idear una expresión adecuada para probar todas las funciones/operadores implementados. Escibir un programa en el que se calcule el valor de dicha expresión para unos valores escogidos por ud.
NOTA 1: de cara a la corrección, me es indiferente que las funciones devuelvan el resultado con return o se utilice un argumento pasado por referencia no constante. Evidentemente el cálculo pedido se escribirá de forma distinta.
NOTA 2: para mayor comodidad se han sobrecargado >> y << para vector<vector<float> >. Si no se hubiese hecho, no se podrían utilizar estos operadores con matrices.
Código de ejemplo:
#include<iostream> using namespace std; #include<vector> //sobrecarga del operador * para matrices vector<vector<float> > operator*(const vector<vector<float> > &a, const vector<vector<float> > &b) { //el vector resultado tiene de dimensiones el numero de filas //de a y el numero de columnas de b vector<vector<float> > c(a.size(),vector<float>(b[0].size())); //se recorre la matriz resultado for (int i=0;i<a.size();i++) for (int j=0;j<b[0].size();j++) { //se inicializa el elemento i j del resultado a cero c[i][j]=0; //se recorre la fila i de a y la columna j de b //multiplicandolas escalarmente for (int k=0;k<a[0].size();k++) c[i][j]+=a[i][k]*b[k][j]; } return c; } //sobrecarga del operador << para matrices //se pasa por referencia no constante un flujo de salida //se devuelve el flujo de salida modificado ostream& operator<<(ostream& o,const vector<vector<float> > &a) { for (int i=0;i<a.size();i++) { for (int j=0;j<a[0].size();j++) //se insertan el elemento en el flujo de salida o<<a[i][j]<<' '; o<<endl; } //se devuelve el flujo de salida return o; } //sobrecarga del operador >> para matrices //se pasa por referencia no constante un flujo de entrada //se devuelve el flujo de entrada modificado istream& operator>>(istream& in, vector<vector<float> > &a) { for (int i=0;i<a.size();i++) { for (int j=0;j<a[0].size();j++) { cout<<'['<<i<<"]["<<j<<"]="; //se extrae el elemento del flujo de entrada in>>a[i][j]; } } //se devuelve el flujo de entrada return in; } int main() { int fa,ca,cb; cout<<"filas de a, columnas de a, columnas de b:"; cin>>fa>>ca>>cb; vector<vector<float> > a(fa,vector<float>(ca)),b(ca,vector<float>(cb)); //esto solo se puede hacer si se han sobrecargado //los operadores correspondientes cin>>a; cin>>b; cout<<a*b; }
Práctica 7: Sokoban o "Mueve la caja."
//juego del sokoban (tb conocido como "mueve la caja") //consiste en empujar una serie de cajas u objetos dispuestas en el tablero //con el fin de situarlas encima de unas marcas //el juego termina cuando se situan todas las cajas encima de //las marcas. Por lo tanto tiene que haber tancas cajas como marcas. //No se puede: //"Tirar" de las cajas, solo empujar //Mover una caja pegada al borde del tablero //no se pueden empujar dos o mas cajas #include<iostream> #include<vector> using namespace std; //devuelve true si todas las marcas estan cubiertas //por los objetos. Se pueden contar las marcas descubiertas //y retornar true si son cero o leer las transparencias de vectores bool fin(vector<vector<bool> > marcas, vector<vector<bool> > objetos) { ... } //inicializaTablero asigna el tama$-3õ½o a los vector<vector<bool> > //que representan las marcas y los objetos //situa las marcas y los objetos en el tablero //y al protagonista del juego en determinada posicion //por ejemplo, en esta situacion: // +-+-+-+-+-+ // |*| | | | | // +-+-+-+-+-+ // | |X|#| | | // +-+-+-+-+-+ // | | | | | | // +-+-+-+-+-+ // | | | | | | // +-+-+-+-+-+ // | | | | | | // +-+-+-+-+-+ // marcas[1][1] es true (se muestra como una X) // objetos[1][2] es true (se muestra como una #) // el protagonista esta en 0,0 luego i_p es 0 y // j_p es tambien 0. El personaje se representa por un * void inicializaTablero(vector<vector<bool> > &marcas, vector<vector<bool> > &objetos, int &i_p, int &j_p) { ... } //mover recibe como parametro la direccion, un caracter //que puede ser u,d,l,r denotando arriba abajo izq o dcha //se pueden utilizar variables de tipo entero d_i y d_j //para representar los incrementos que se le dan a la posicion //del personaje, si el caracter es u el incremento seria -1 //ya que para "subir" se decrementa la fila (i_p) en donde esta //el personaje. De forma similar para las otras direcciones. //Por lo tanto, si el movimiento es posible se modifica la //posicion del protagonista y si este empuja una caja que se puede //mover, se modifica de forma conveniente el atributo objetos. void mover(char direccion, vector<vector<bool> > &marcas, vector<vector<bool> > &objetos,int &i_p, int &j_p) { ... } //muestra el tablero de modo que: //si coinciden personaje y marca se ve el personaje //si coinciden objeto y marca se ve el objeto void muestra(const vector<vector<bool> > &marcas, const vector<vector<bool> > &objetos, int i_p, int j_p) { ... } int main() { //marcas es un vector de bool del tama$-3õ½o del tablero //true significa que ahi hay que poner un objeto vector<vector<bool> > marcas; //objetos es un vector de bool del tama$-3õ½o del tablero //representa los objetos y sus posiciones vector<vector<bool> > objetos; //estos dos enteros representan la posicion del protagonista //del juego int i_p,j_p; //declarar variable para pedir direccion char direccion; //inicializar el tablero ... //mientras no esten todas las marcas //cubiertas con objetos while(...) { //mostrar el tablero ... //pedir movimiento ... //actualizar tablero, llamar a mover con //direccion como parametro ... } //mostrar el tablero como queda al final ... system("PAUSE"); } //Ejemplo de ejecucion: // //+-+-+-+-+-+ //|*| | | | | //+-+-+-+-+-+ //| |X|#| | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //Introduce movimiento r // //+-+-+-+-+-+ //| |*| | | | //+-+-+-+-+-+ //| |X|#| | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //Introduce movimiento r // //+-+-+-+-+-+ //| | |*| | | //+-+-+-+-+-+ //| |X|#| | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //Introduce movimiento r // //+-+-+-+-+-+ //| | | |*| | //+-+-+-+-+-+ //| |X|#| | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //Introduce movimiento d // //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| |X|#|*| | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //Introduce movimiento l // //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| |#|*| | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //Presione una tecla para continuar . . .
Práctica 8: Sokoban o "Mueve la caja." Con clases. Por simplicidad se definen inline las funciones.
//juego del sokoban (tb conocido como "mueve la caja")
//con clases #include<iostream> #include<vector> using namespace std; class tablero{ //marcas es un vector de bool del tama�o del tablero //true significa que ahi hay que poner un objeto vector<vector<bool> > marcas; //objetos es un vector de bool del tama�o del tablero //representa los objetos y sus posiciones vector<vector<bool> > objetos; //estos dos enteros representan la posicion del protagonista //del juego int i_p,j_p; public: //el constructor por defecto asigna el tama�o a los atributos //de tipo vector, situa las marcas y los objetos en el tablero //y al protagonista del juego en determinada posicion //por ejemplo, en esta situacion: // +-+-+-+-+-+ // |*| | | | | // +-+-+-+-+-+ // | |X|#| | | // +-+-+-+-+-+ // | | | | | | // +-+-+-+-+-+ // | | | | | | // +-+-+-+-+-+ // | | | | | | // +-+-+-+-+-+ // marcas[1][1] es true (se muestra como una X) // objetos[1][2] es true (se muestra como una #) // el protagonista esta en 0,0 luego i_p es 0 y // j_p es tambien 0. El personaje se representa por un * tablero() { //... } //devuelve true si todas las marcas estan cubiertas //por los objetos. Se pueden contar las marcas descubiertas //y retornar true si son cero o bien PENSAR bool fin(void) { //... } //mover recibe como parametro la direccion, un caracter //que puede ser u,d,l,r denotando arriba abajo izq o dcha //se pueden utilizar variables de tipo entero d_i y d_j //para representar los incrementos que se le dan a la posicion //del personaje, si el caracter es u el incremento seria -1 //ya que para "subir" se decrementa la fila (i_p) en donde esta //el personaje. De forma similar para las otras direcciones. //Por lo tanto, si el movimiento es posible se modifica la //posicion del protagonista y si este empuja una caja que se puede //mover, se modifica de forma conveniente el atributo objetos. void mover(char direccion) { ... } //muestra el tablero de modo que: //si coinciden personaje y marca se ve el personaje //si coinciden objeto y marca se ve el objeto void muestra(void) { //... } }; int main() { //declarar variable para pedir direccion ... ...; //declarar tablero ... ...; //mientras no esten todas las marcas //cubiertas con objetos //llamada a fin while(...) { //mostrar el tablero //llamada a muestra //... //pedir movimiento cout<<"Introduce movimiento "; cin>>...; //actualizar tablero, llamar a mover con //direccion como parametro //... } //mostrar el tablero como queda al final //llamada a muestra //... system("PAUSE"); } //Una ejecucion completa de ejemplo: // //+-+-+-+-+-+ //|*| | | | | //+-+-+-+-+-+ //| |X|#| | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //Introduce movimiento r // //+-+-+-+-+-+ //| |*| | | | //+-+-+-+-+-+ //| |X|#| | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //Introduce movimiento r // //+-+-+-+-+-+ //| | |*| | | //+-+-+-+-+-+ //| |X|#| | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //Introduce movimiento r // //+-+-+-+-+-+ //| | | |*| | //+-+-+-+-+-+ //| |X|#| | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //Introduce movimiento d // //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| |X|#|*| | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //Introduce movimiento l // //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| |#|*| | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //| | | | | | //+-+-+-+-+-+ //Presione una tecla para continuar . . .