Sei sulla pagina 1di 20

INTRODUCCION

Como futuros ingenieros en informática es nuestro deber realizar proyectos funcionales


basados en casos de la vida real que nos permitan obtener la experiencia necesaria para salir
al mundo laboral, un videojuego no es un área muy alejada del campo laboral, muchos
ingenieros trabajan para empresas creadoras de videojuegos ya que el funcionamiento de los
mismo dependen de un programa, este proyecto requiere la realización de un bingo, juego
que a pesar de que al principio puede parecer un algoritmo fácil de realizar, este se puede
complicar dependiendo de la visión y el resultado esperado por el programador.

Un bingo requiere de aleatoriedad tema que ha causado caos en foros de programadores ya


que es muy difícil hacer que una computadora escoja un numero totalmente aleatorio, para
ello se crearon números pseudo aleatorios pero estos se deben controlar ya que pueden traer
problemas al momento de la ejecución, el diseño de interfaces también forma parte del
complejo problema de creación como desarrolladores debemos procurar que las aplicaciones
se vean lomas agradable posible para el usuario, una buena interfaz a pesar de no ser el factor
decisivo es algo que miles de usuarios toman en cuentan incluso si se tiene una interfaz mala
el usuario ni siquiera se molestara en revisar la aplicación creada. Este informe detalla toda
la documentación de la aplicación creada empezando por las estructuras y datos utilizados
recorriendo como se mezclaron para crear las distintas unciones encargadas de darle vida al
proyecto y finalizando en las contantes que facilitan la reutilización del programa. EL código
se a bordo de una forma que las funciones fueran reutilizables ya que un bingo es una
aplicación muy general por lo tanto este algoritmo no es totalmente estático y puede
cambiarse su diseño dependiendo de la visión del programador.
PLANTEAMIENTO DEL PROBLEMA

Los juegos de mesa, aquel conjunto de elementos, piezas, tableros, cartas etc, que con una
idea atractiva, innovadora y sobre todo divertida fueron los dominantes durante mucho
tiempo en muchas familias por una gran cantidad de tiempo hasta que la evolución de la
tecnología y sus avances comenzaron a reinar en la raza humana, a pesar de que aun se
producen muchos juegos de mesa estos no superan las ventas generadas por suscripciones a
videojuegos para computadora, por lo tanto se tuvo que idear algo, ¿Por qué no mezclar estos
juegos que por mucho tiempo fueron los preferidos con los programas de computadoras? Esta
idea revoluciono la forma de jugar a los juegos de mesa, y los desarrolladores se pusieron
manos a la obra a crear miles de versiones de los juegos de mesa ya existentes, desde póker
con apuestas en tiempo real, hasta monopolios que incluyen a varios países, la creación de
juegos de mesa para computadora, a pesar de que no es el mas consumido actualmente fue
una gran idea para ese entonces que puso a pensar a más de un programador.

El problema consiste en crear un juego de mesa, el bingo, el cual debe ser desarrollado
utilizando el lenguaje de programación C por lo tanto es una aplicación para computadoras,
se debe manejar un cartón o tablero, estas especificaciones dejan las puertas abiertas para que
los estudiantes expandan sus conocimientos ya que pueden indagar y tratar de mejorar el
proyecto dado tal y como se hizo en la creación de este programa detallado en capítulos
siguientes.
MARCO TEORICO

Para la realización del proyecto se utilizo el famoso paradigma de diseño “divide y vencerás”
añadiéndole el paradigma “top-down”. Primeramente, el problema se dividió en partes
sencillas (realizar un cartón, un menú, un elector de números aleatorios, y un comparador de
números con el fin de verificar si el número o ficha elegida estaba en el cartón). Luego cuando
se proponía a resolver o “atacar” los problemas enlistados los mismo se volvieron a redefinir
dividiéndolos nuevamente en partes cada vez mas sencillas con el fin de que en otro momento
las funciones se pudieran volver a utilizar o dicho de otro modo, hacer el código reutilizable.

Por ejemplo, al momento de realizar la función para que el programa dibujara el cartón, este
fue dividido en varias funciones que juntas ayudan a la construcción del cartón, por ejemplo
imprimir un línea, imprimir una línea en blanco, imprimir espacios del mismo modo el resto
de los problemas fueron atacados de forma similar.

ESTRUCTURAS DE DATOS UTILIZADAS

Las estructuras realizadas para la realización del proyecto fueron las siguientes:

ARREGLOS Y MATRICES: mayormente se utilizaron matrices especialmente para la


realización del cartón ya que una matriz simula de muy buena manera una tabla y los arreglos,
aunque no fueron utilizados para tareas relevantes, si se incluyen principalmente para las
cadenas de texto en conjunto con la librería String.h

HILOS O THREADS: Un hilo proceso ligero o subproceso es una secuencia de tareas


encadenadas muy pequeña que puede ser ejecutada por un sistema operativo. En si es
simplemente una tarea que puede ser ejecutada al mismo tiempo que otra tarea. Este proyecto
requirió la utilización de hilos ya que con ellos se pueden llamar a dos o mas funciones al
mismo tiempo, este tipo de estructura se empleó en el juego mientras la cuenta regresiva esta
activa, cuando el usuario o jugador se propone a elegir un cartón este puede presionar
cualquier tecla para cambiarlo o esperar 10 segundos para fijar el cartón visualizado y
proceder con el juego, esta parte del programa sería imposible de realizar sin la utilización
de hilos.
HANDLE: se conoce como handle a un tipo particular de punteros "inteligentes". Los
handles son utilizados cuando un programa hace referencia a bloques de memoria u objetos
controlados por otros sistemas, tales como una base de datos o un sistema operativo. Los
handle fueron utilizados para poder crear hilos o threads en conjuntos con la librería
Windows.h.

ESTRUCTURAS: Las estructuras fueron utilizadas al momento de crear los hilos ya que
una función propia de la librería de Windows requería que en un solo parámetro se le pasaran
varios en ese caso una estructura con mas datos dentro de ella es la opción correcta.

FUNCIONES

definePixel (int cantPixel, int pixelMode, int x, int y, int fillPixel):

Función utilizada para facilitar la realización del menú con ella se puede definir un “pixel” o
cuadro del tamaño que se requiera de modo que al hacer una letra esta se pueda hacer mas
grande o mas pequeña utilizando como “pixel” el código ascii 219 (█) se puede cambiar el
tamaño de una letra redefiniendo el pixel. Por ejemplo, en el programa se define un pixel con
una cantidad de dos (2) y un pixelMode de uno (1) de modo que el pixel seria

██

Funciones make + letra (int position_x, int position_y):

Con las funciones make y la función definePixel se puede dibujar una letra, con ellas se
puede dibujar letras del alfabeto por ahora solo están disponibles las letras B, I, N, G, O.
Los parámetros “position_x” y “int position_y” se utilizan para dibujarlos en cualquier
posición.

printfBox(int width, int heigth, int position_x, int position_y):

Imprime un cuadro o caja en la posición indicada por position_x y position_y, con la altura
y anchura que se quiera.

void printMatriz(int matriz[HEIGTH][WIDTH]):

Recibe una matriz y la imprime.


isTokenOnBoard(int token,int board[HEIGTH][WIDTH]):

Recibe una ficha o token y un cartón de modo que la función verifica si la ficha existe en el
tablero. La función retorna uno (1) si la ficha está en el tablero y cero (0) si la no está.

getToken():

Esta función simula la elección de una ficha utilizando una pseudo animación que
intercambie varios números hasta seleccionar uno especifico que será la ficha retornada y la
cual se marcara en el tablero.

printSpaces():

Imprime la cantidad de espacios indicada por la constante SPACE.

printnSpaces(int nSpace):

Imprime la cantidad de espacios que se indiquen a través de la variable nSpace.

printLine(char start, char end, char middle, int width, int x, int y):

Imprime una línea para la realización del tablero. Las variables start y end son las esquinas
de la línea por lo que se pueden cambiar por cualquier carácter mientras que la variable
middle es el final de cada casilla. La línea se puede imprimir en cualquier posición utilizando
los argumentos x y y.

printBoard(int board[HEIGTH][WIDTH], int x, int y):

Recibe una matriz con números aleatorios y a cada numero lo coloca dentro de un tablero
seguidamente lo imprime en las posiciones que se indiquen a través de las posiciones x y y.

deleteArrayPosicion(int* array, int posicion, int* limit):

Elimina un elemento de un arreglo según se indique a través del argumento posición. La


función recibe un arreglo la posición del elemento a ser eliminado, la variable limit se pasa
por referencia para poder modificar el rango de números del arreglo.
getRandomSerie(int higherLimit, int lowerLimit, int* randomColumn, int* limit):

Esta función se utiliza para obtener una serie de números aleatorios que serán los números
que se utilizarán en el tablero, se le debe pasar un numero de inicio o limite inferior y un
número final o límite superior, un arreglo en donde se colocaran cierta cantidad de números
y un limite que indica cuantos números aleatorios tendrá el arreglo.

fillBoardWithRandomNumber(int (*board)[WIDTH], int numStart, int patron, int


numBox):

Esta función recibe un tablero que es una matriz de números enteros y los llena con números
aleatorios dependiendo de un patrón es decir si el patrón es dos (2) la función solo elegirá
números aleatorios entre uno (1) y dos (2). La variable numBox indica el número de casillas
que tendrá que llenar la función por columna, en realidad es una convección usada para
indicar el rango de números que tendrá el arreglo, por lo tanto si le pasamos como argumento
los números seis (6) para numBox y el numero quince (15) para patrón
fillBoardWithRandomNumber llenara una matriz con números aleatorios, la primera
columna tendrá seis (6) números entre uno (1) y quince (15) la segunda entre dieciséis (16)
y treinta (30) hasta completar el tablero siguiendo este patrón.

void text (char text[10], int space, int position_x, int position_y):

Esta función permite escribir un texto con las funciones make en una posición especifica y
con la cantidad de espacios determinada por la variable space, se usa para imprimir la palabra
bingo en el menú de inicio.

void clean():

Limpia la pantalla.

void setupBag(int lasToken, int magicBag[]):

esta función se encarga de inicializar la bolsa de fichas desde 0 hasta lasToken en este caso
se le pasa el número de fichas que queremos en el bingo (75).
void printfTextOnBox(int width, int heigth, char text[100], char lineUp[10], int x, int
y):

Este proceso funciona igual que la función cuadro de texto en Microsoft Word pero en la
consola, recibe una anchura una altura, el texto a ser impreso, y las posiciones donde se
imprimirá, la variable lineUp representa una propiedad de centrado, por ahora solo trabaja
con:

center: centra el texto en la caja.

top-center centra el texto en la parte de arriba de la caja.

void printBlankLine(int x, int y):

Imprime una línea en blanco para el cartón en las posiciones X, Y. Esta función es un
subproceso utilizado para la impresión del cartón.

void setupBoard(int board[POSIBLE][WIDTH]):

Esta función inicializa un cartón. El cartón desde la vista del programador en realidad tiene
16 filas, en la primera se imprime el texto bingo y en las otras 15 se inicializa una matriz
desde el 1 al 75 en cada columna se colocan sucesiones de 15 en 15 por lo que la primera
columna contendrá números del 1 al 15, la segunda del 16 al 30 y así sucesivamente hasta
que la última columna tenga los números desde el 60 al 75. El cartón desde la vista del usuario
tendrá 6 filas y 5 columnas.

void getRandomMatriz(int board[POSIBLE][WIDTH]):

Esta función es la que se encarga de mezclar las posiciones de la matriz o cartón inicializado
por setupBoard, básicamente realiza permutaciones a las columnas de la matriz, una
permutación es la variación del orden o de la disposición de los elementos de un conjunto
ordenado o una tupla sin elementos repetidos. Esta forma de obtener una matriz aleatoria es
una implementación sencilla ya que gracias a la propiedad de permutación y a setupBoard
que inicializa la matriz en orden y con el patrón deseado, no se debe preocupar acerca de la
repetición de números en un cartón, aunque puede que al cambiar de cartón existan
posiciones que no cambien pero este problema no suele suceder a menudo y el usuario puede
volver a cambiar el carton si no es de su agrado.
changeBoard(int board[][WIDTH], int token, int whereToPrintX, int whereToPrintY):

Esta función es la que se encargar de verificar si una ficha existe en un cartón, recibe un
cartón y una ficha y verifica si dicha ficha existe en la matriz, si esta condición se cumple
cambia el valor de esa posición de la matriz donde esta la ficha por un cero (0) numero que
no existe en un juego de bingo, y si la matriz tiene una posición con el elemento 0 lo cambiara
por una marca determinada por la constante BINGO_MARCA, esta última operación es
realizada por printfBoard. Los argumentos whereToPrint indican donde se imprimirá el
cartón cambiado.

isWinner(int board[HEIGTH][WIDTH]):

Este proceso contiene la mayoría de las formulas ganadoras de en un juego de bingo y


determina si en un cartón existe un ganador en ese caso el valor retornado será 1 y de modo
contrario será 0, se le debe pasar el cartón para analizarlo y decidir si tiene o no ganadores,
las formulas ganadoras definidas hasta ahora son por filas, por columnas y por diagonales.

controlMenu (int limitYUP, int limitYDOWN, int howMuchYouWantItGoesDown,int


startKeyX, int* opt):

Esta función permite controlar un menú vertical recibe los límites del menú (limitYUP,
limitYDOWN) de modo que se valide los limites donde el menú no debe funcionar, de igual
forma recibe la cantidad de espacios que se quiere que el selector o flecha baje y suba, este
numero siempre es el mismo y por ende las opciones del menú siempre estén separadas por
una “distancia” constante, se le debe pasar una variable por referencia que se modificara
dependiendo de la opción elegida empezando desde 1, por último se le debe pasar la posición
en X a la cual el menú debe empezar.

void deleteSection(int start_x, int start_Y, int end_X,int end_Y):

Esta función borra una sección o parte de la consola dependiendo de las posiciones iniciales
y finales tanto en X como en Y que son pasadas como parámetros.

void controlMenuHorizontally (int limitXUP, int limitXDOWN, int


howMuchYouWantItGoesDown, int startKeyY, int *opt):
Este proceso funciona igual que la función controlMenu la única diferencia es que permite
controlar un menú dispuesto de forma horizontal. Recibe los límites del menú al igual que la
controlMenu. pero esta vez en el eje X el resto de los parámetros siguen siendo los mismos
pero la posición de inicio debe ser dada en función del eje y.

void printParagraphCenter(int position_y, int lineHeigth, int nargs,...):

Esta función imprime una cierta cantidad de textos y los centra en la pantalla, los textos son
pasados como argumentos opcionales de modo que puede imprimir la cantidad de texto que
el usuario desee.

Position_Y: Representa la posición en Y en donde empezara el párrafo.

lineHeigth: Es el interlineado entre un párrafo.

Nargs: Cantidad de textos que se desea imprimir es la variable que define cuantos
argumentos opcionales tendrá la función.

Luego de estos tres parámetros se le deben pasar los textos a imprimir como una cadena, cada
argumento opcional representa una línea.

void desingBingoWindow():

Función encargada de crear el encabezado durante una partida.

void shuffleBag(int deckStart, int deckEnd,int array[], int downBound, int upBound):

Esta función actúa como una persona que mueve las fichas dentro de una bolsa durante un
juego de bingo, esto lo realiza por medio de un arreglo, el cual fue iniciado por la función
setup bag, y lo que hace es cambiar o permutar el arreglo intercambiando los elementos en
las posiciones inicializadas, cada vez que se obtiene una ficha esta función es llamada para
volver a mezclar o batir el arreglo “bolsa”.

int getToken(int *lastPosition, int bag[]):

Esta función es la que se encarga de sacar u obtener una ficha en conjunto con función
shuffleBag e imprimirla por pantalla.
void getTokenAnimation():

Esta función realiza una animación antes de obtener una ficha durante una partida.

RUTINAS

mainMenu(int *opt):

Esta función contiene las rutinas del menú principal, recibe una opción por referencia que
permite controlar el menú principal.

void userGuide():

Esta función contiene las rutinas del menú de instrucciones.

secundaryMenu(int* opt):

Contiene la rutina del menú secundario donde se elige el modo de juego, por lo tanto, recibe
una opción para controlar el menú.

ingameRoutine(int bag[], int board1[POSIBLE][WIDTH], int


board2[POSIBLE][WIDTH], int players):

Esta función contiene la rutina utilizada dentro de una partida recibe dos cartones, el número
de jugadores (1 o 2 únicamente) y una bolsa o arreglo de fichas para poder comenzar la
partida.

newGame():

Rutina encargada de empezar un juego o partida nueva.


CONSTANTES

NOMBRE USO
RIGTH_TOP 187 //"╗" Cada una de estas constantes se usan para construir un
RIGTH_BOTTOM 188//"╝" cartón o un cuadro de texto, son constantes numéricas
RIGTH_VERTICAL 185 //"╣" a pesar de que se imprimen como caracteres, los
LEFT_TOP 201//"╔" números de las mismas son el respectivo código ascii
LEFT_BOTTOM 200//"╚" del código comentado, se realizo de esta manera
LEFT_VERTICAL 204 //"╠" debido a que Windows no permitía imprimir este tipo
HORIZONTAL 186 ///"║" de caracteres directamente.
VERTICAL 205 //"═"
TOP 203//"╦"
CENTER 206 //"╬"
BOTTOM 202 // "╩"
CLT 201 //"╔"
CLB 200 //"╚"
CRT 187 //"╗"
CRB 188 //"╝"
H 205 //"═"
V 186 //"║"

Representa las casillas por columnas de un cartón, ya


WIDTH 5
que un cartón tiene 5 cuadros o casillas por columna
esta vale 5.
Representa la máxima cantidad de números posibles
POSIBLE 15 que debe que tener un cartón de bingo por filas es decir
15, ya que cada columna va aumentada de 15 en 15
unidades.
Representa las casillas por filas de un cartón, ya que
HEIGTH 6
un cartón tiene 6 cuadros o casillas filas esta vale 6.
(son 6 casillas ya que en la primera fila se imprime la
palabra bingo).
Constantes utilizadas para imprimir un cartón Space
SPACE 2 es la separación entre una casilla y un número. Y value
VALUE 2 es usada para completar los dígitos de un solo numero
con 0 ejemplo: En vez de imprimir el numero “2”
gracia a Value se imprime “02”.
BINGO_H "BINGO" Constante usada como arreglo para poder imprimir la
palabra bingo.
BINGO_MARCA 'X' Carácter usado para marcar las fichas coincidentes en
un carton.
Constante utilizada para poder centrar el membrete
BINGO_FONT_WIDTH 78
“BINGO” del menú principal.
AMOUNT_OF_NUMBER 75 Constantes utilizadas para inicializar los cartones y la
TOKEN_NUMBERS 76 bolsa de fichas.

WHERETOPRINTX 24 Constantes que representan la posición en donde se


WHERETOPRINTY 11 debe imprimir un cartón de modo que estos se vean
WHERETOPRINTX1 5 centrado.
WHERETOPRINTY1 11
WHERETOPRINTX2 43
WHERETOPRINTY2 11

SCREEN_WIDTH 82 Altura y anchura de la sección de la consola usada


SCREEN_HEIGTH 41 como pantalla. Gracias a ellas se realizan los cálculos
necesarios para centrar algunos elementos.
PIXEL_ARRIBA 223 Son constantes cuyo valor numérico representan los
PIXEL_ABAJO 220 siguientes caracteres de la tabla ascii “▀”, “▄”, “█”
DOS_PIXEL 219 respectivamente se usan para definir los pixeles que
dibujan el membrete del menú principal.
PIXEL_AMOUNT 2 Constantes usadas para definir pixeles para dibujar

PIXEL_MODE 1 mediante la función definePixel.


VARIABLES DEL PROGRAMA PRINCIPAL

NOMBRE TIPO UTILIDAD


DE
DATO
Opt, opt1 int Almacenan las opciónes utilizada por el usuario para los
distintos menus lo cual permite controlar el flujo del
programa
switcher int Variable bandera utilizada para salir o permanecer en
el programa
Board1[][], int Son los tableros del juego tratados por varias funciones.
board2[][]
Bag[] int Arreglo utilizado para crear la bolsa de números o
fichas.
i,j,k int iteradores
RESTRICCIONES DEL PROYECTO

Debido a las especificaciones del proyecto y a la poca experiencia como


programadores este proyecto tiene una cierta cantidad de limitaciones:

1.-Al ser realizado bajo consola la impresión y reimpresión de algunos elementos pueden
verse ralentizada debido al excesivo uso de la función gotoxy.

2.-Este mismo problema trae consigo que la interfaz grafica no sea la mas agradable a la
vista de todas.

3.-Al no usar ninguna estructura de memoria dinámica el programa tampoco es el mas


optimo y dinámico de todos.

4.-Este mismo problema trae consigo que el bingo no se pueda jugar con una n cantidad de
jugadores y los jugadores solo pueden tener hasta un cartón a diferencia del juego en la vida
real.

5.-El programa no tiene limites de entrada de datos el usuario puede presionar cualquier tecla,
pero solo las teclas validadas por el programa permitirán el buen curso del algoritmo, la
aplicación funciona por medio de las flechas del teclado y la tecla enter y algunos sub menús
permiten la salida por medio de caracteres alfabéticos.

6.-El algoritmo no permite la guardar datos a| largo plazo como por eejemplo, cerrar la partida
y reanudarla cuando se vuelva abrir el programa.

7.-debido a otros proyectos y demás actividades algunas funciones pueden no estar 100%
validadas.

8.-El programa solo puede correr en Windows ya que para que corra en linu se requiere la
instalación de librerías y ciertos programas que no fueron permitidos de instalar en el
laboratorio, sin embargo, alguien con experiencia en Linux puede fácilmente implementar
una versión del programa para dicho sistema operativo.
MANUAL DE USUARIO

PANTALLA DEL MENU PRINCIPAL.

Al iniciar el programa la primera pantalla que vera el usuario será el menú principal, el
jugador debe moveré mediante el uso de las flechas del teclado a través de alguna de las
opciones la primera iniciara el menú secundario la tercera es una guía dentro del programa
con las instrucciones del mismo y la tercera permite la finalización de la ejecución del
programa. Seguidamente se selecciona una opción.
z

PANTALLA DEL MENU SECUNDARIO

Desde el menú secundario el usuario puede seleccionar cuantas personas jugaran con un
máximo de dos. Se debe seleccionar una opción para continuar la ejecución siempre teniendo
en cuenta que se puede volver al menú principal.
PANTALLA DE LA EJECUCION DEL MODO 2 JUGADORES

El programa permite al usuario cambiar un cartón si este no le gusta luego de que ambos
hayan seleccionado el cartón de su agrado el juego comenzara.
PANTALLA DESPUES DE HABER INICIADO EL JUEGO

Una vez una ficha es obtenida esta se marca automáticamente el uuario puede elegir si
desea continuar la partida o finalizarla.
Cuando existe un ganador el programa mostrara un mensaje con el respectivo ganador si no
hubo ganador el programa imprimirá un mensaje adecuado. Al presionar cualquier tecla el
usuario vuelve al menú de inicio a la espera de las decisiones del usuario, el modo de un solo
jugador funciona igual que el modo de dos jugadores.