Versión preliminar de Tetris en Python
Con el tiempo me he dado cuenta que no soy nada bueno con los títulos, bueno tampoco soy bueno con los comentarios, y tampoco bueno con las entradas
, pero bueno que vamos a hacer.
En esta ocasión les traigo mi versión ultra-hiper básica de un tetris implementado utilizando Python, Numpy y Pygame. Este es mi primer intento y puede que más adelante me de la rabia y lo vuelva a re-hacer de cero. Como les iba diciendo esta versión se encuentra aún en pañales pero hace lo básico.
Esta el tablero dibujado, lanza piezas al azar que nosotros podemos ir rotando, permite acelerar la caída de la pieza, muestra siguiente pieza, reconoce otras piezas que están en el tablero, detecta fila completa y la procesa. Que faltaría, añadir un contador de tiempo, mostrar puntaje, permitir re-dimensionar el tablero, reiniciar juego y acelerar la caída de las piezas al cumplir n filas completadas; creo que eso es todo por el momento.
Espero tener pronto una versión más refinada, pero igual les dejo mi código para que lo prueben y utilicen con total libertad. Quedo dividido en 3 archivos: tetris.py(archivo principal), figure.py y board.py.
Para ejecutar: python tetris.py
tetris.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Filename: tetris.py
# Developer by: @itrogeno
# Date: 29-03-2011
# Version: 0.4a
'''Programando una version personalizada de Tetris
para Python 2.6. Utilizando las librerias
Numpy y Pygame.'''
# Cargamos las librerias
import pygame
import numpy
from board import Board
from figure import Figure
# Constantes
TITLE = 'Tetris'
VERSION = '0.2a'
WIDTH, HEIGHT = SIZE = (600, 420) # definimos el tamano de la ventana
CENTER_X = WIDTH/2
FRAMERATE = 30
# Tablero
ROWS, COLS = SHAPE = (20, 10)
PIXEL = 20
# No se utilizaran los colores Negro(0, 0, 0), ni blanco(255, 255, 255)
# que se utilizan respectivamente como color de fondo y para dibujar
# el tablero. Utilice el comando len(COLORS) para obtener el numero
# de colores disponibles.
BG_COLOR = ( 0, 0, 0) # Negro
FG_COLOR = (255, 255, 255) # Blanco
COLORS = {
0 : BG_COLOR,
1 : ( 0, 0, 255), # Azul
2 : ( 0, 255, 0), # Verde
3 : ( 0, 255, 255), # Aqua
4 : (255, 0, 0), # Rojo
5 : (255, 0, 255), # Magenta
6 : (255, 255, 0), # Amarillo
7 : (200, 200, 200), # Gris
8 : FG_COLOR,
9 : BG_COLOR,
10 : FG_COLOR
}
# Variables
screen, clock, running, board, figure, row = None, None, None, None, None, None
lock, speed = False, 1.0
def events(events):
'''Procesa todos los eventos producidos en el
juego.'''
global running, figure, row, lock, speed
for event in events:
if event.type == pygame.QUIT:
# Finalizamos la ejecucion del juego
# cuando el usuario cierra la ventana.
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
# Finalizamos la ejecución del juego
# cuando el usuario presiona la tecla
# escape.
running = False
if event.key == pygame.K_DOWN and not lock:
#Bloquear teclas
speed = 10.0
lock = True
if event.key == pygame.K_UP and not lock:
# Rotar la figura
figure.rotate()
if event.key == pygame.K_LEFT and not lock:
# Mover la figura a la izquierda
figure.move(-1)
if event.key == pygame.K_RIGHT and not lock:
# Mover la figura a la derecha
figure.move(1)
if event.key == pygame.K_c:
# Limpiar tablero
board.clear()
del figure
row = 0
figure = Figure(board.get_board())
# Desde donde empezamos a dibujar el tablero
X, Y = CENTER_X - (PIXEL*COLS/2), 10
def get_xy(col, row, x=None, y=None):
x = X if x is None else x
y = Y if y is None else y
return x + (col * PIXEL), y + (row * PIXEL)
def draw_line(screen, col, row, X=0, Y=0, x=None, y=None):
x, y = get_xy(col, row, x, y)
pygame.draw.line(screen, FG_COLOR, (x, y), (x+X, y+Y))
def draw_rect(screen, color, col, row, x=None, y=None):
x, y = get_xy(col, row, x, y)
pygame.draw.rect(screen, COLORS[color], (x, y, PIXEL, PIXEL))
def draw_board(board):
rows, cols = board.shape
'''Dibujamos el tablero'''
for col in range(cols):
for row in range(rows):
draw_rect(screen, board[row, col], col, row)
draw_line(screen, col, row, X=PIXEL)
draw_line(screen, col, row, Y=PIXEL)
draw_line(screen, 0, row+1, X=PIXEL*cols)
draw_line(screen, col+1, 0, Y=PIXEL*rows)
def draw_figure(figure, color):
x, y, = 450, 10
rows, cols = figure.shape
'''Dibujamos la figura'''
for col in range(cols):
for row in range(rows):
if figure[row, col] != 0:
draw_rect(screen, color, col, row, x=x, y=y)
#draw_line(screen, col, row, X=PIXEL, x=x, y=y)
#draw_line(screen, col, row, Y=PIXEL, x=x, y=y)
#draw_line(screen, 0, row+1, X=PIXEL*cols, x=x, y=y)
#Sdraw_line(screen, col+1, 0, Y=PIXEL*rows, x=x, y=y)
def refresh(board, framerate):
draw_board(board.get_board())
pygame.display.flip()
clock.tick(framerate)
def init():
'''Este metodo permite inicializar las librerias y
variables del juegos.'''
global screen, clock, running, board
running = True
board = Board(SHAPE)
pygame.init()
screen = pygame.display.set_mode(SIZE)
clock = pygame.time.Clock()
pygame.display.set_caption('%s v%s' % (TITLE, VERSION))
def main():
global row, figure, lock, speed
'''Metodo Principal'''
init()
row = 0
completed = 0
rows = 0
figure = Figure(board.get_board())
next = Figure(board.get_board())
while running:
screen.fill(BG_COLOR)
draw_figure(next.get_figure(), next.nro_figure)
figure.clear(board.get_board())
events(pygame.event.get())
if not figure.forward(int(row)):
figure.update(board.get_board())
del figure
figure = next
row = 0
while board.evaluate(8):
completed += 1
refresh(board, FRAMERATE/4)
board.evaluate(9)
refresh(board, FRAMERATE/4)
board.evaluate(10)
refresh(board, FRAMERATE/4)
board.evaluate(0)
refresh(board, FRAMERATE/4)
board.update()
refresh(board, FRAMERATE/4)
next = Figure(board.get_board())
figure.set_board(board.get_board())
speed = 1.0
lock = False
figure.update(board.get_board())
refresh(board, FRAMERATE)
row += (speed/FRAMERATE) * 2.0
print 'Fin del Juego.'
if __name__ == '__main__':
main()
figure.py
# -*- coding: utf-8 -*-
# Filename: figure.py
# Developer by: @itrogeno
# Date: 29-03-2011
# Version: 0.4a
import random
import numpy
class Figure():
# Definimos las diferentes figuras
FIGURES = {
1: ('0 0 0 0; 0 1 1 0; 0 1 1 0; 0 0 0 0',),
2: ('0 0 0 0; 1 1 1 1; 0 0 0 0; 0 0 0 0',
'0 0 1 0; 0 0 1 0; 0 0 1 0; 0 0 1 0'),
3: ('0 0 0 0; 0 0 1 1; 0 1 1 0; 0 0 0 0',
'0 0 1 0; 0 0 1 1; 0 0 0 1; 0 0 0 0'),
4: ('0 0 0 0; 0 1 1 0; 0 0 1 1; 0 0 0 0',
'0 0 0 1; 0 0 1 1; 0 0 1 0; 0 0 0 0'),
5: ('0 0 0 0; 0 1 1 1; 0 1 0 0; 0 0 0 0',
'0 0 1 0; 0 0 1 0; 0 0 1 1; 0 0 0 0',
'0 0 0 1; 0 1 1 1; 0 0 0 0; 0 0 0 0',
'0 1 1 0; 0 0 1 0; 0 0 1 0; 0 0 0 0'),
6: ('0 0 0 0; 0 1 1 1; 0 0 0 1; 0 0 0 0',
'0 0 1 1; 0 0 1 0; 0 0 1 0; 0 0 0 0',
'0 1 0 0; 0 1 1 1; 0 0 0 0; 0 0 0 0',
'0 0 1 0; 0 0 1 0; 0 1 1 0; 0 0 0 0'),
7: ('0 0 0 0; 0 1 1 1; 0 0 1 0; 0 0 0 0',
'0 0 1 0; 0 0 1 1; 0 0 1 0; 0 0 0 0',
'0 0 1 0; 0 1 1 1; 0 0 0 0; 0 0 0 0',
'0 0 1 0; 0 1 1 0; 0 0 1 0; 0 0 0 0')
}
ROWS_FIGURE = 4
COLS_FIGURE = 4
CLS_FIGURE = 0
angle = 0 # angulo inicial
def __init__(self, board):
self.set_board(board)
self.rows, self.cols = self.shape = self.board.shape
self.nro_row = -1
self.nro_col = (self.cols / 2) -1
self.nro_figure = random.randint(1, len(self.FIGURES))
print 'Figura: %i' % self.nro_figure
def set_board(self, board):
self.board = board.copy()
def get_figure(self, angle=None):
angle = self.angle if angle is None else angle
figure = numpy.matrix(self.FIGURES[self.nro_figure][angle])
return figure
def forward(self, mov):
if self.nro_row == mov or\
self.__evaluate(mov, self.nro_col, self.get_figure()):
self.nro_row = mov
return True
else:
return False
def move(self, mov):
if self.__evaluate(self.nro_row, self.nro_col+mov, self.get_figure()):
self.nro_col += mov
def rotate(self):
nro_col = self.nro_col
angle = self.__next_angle()
i = 3
while i >= 0:
if self.__evaluate(self.nro_row, nro_col, self.get_figure(angle)):
self.angle = angle
self.nro_col = nro_col
i = 0
else:
nro_col = self.nro_col -1 if i == 1 else nro_col + 1
i -= 1
def update(self, board, clear=False):
figure = self.get_figure()
nro_row, nro_col = self.nro_row, self.nro_col
for x in range(self.ROWS_FIGURE):
tmp_col = nro_col
for y in range(self.COLS_FIGURE):
if self.__is_valid(nro_row, tmp_col) and\
figure[(self.ROWS_FIGURE - x)-1, y] != 0:
if nro_row >= 0:
board[nro_row, tmp_col] = self.CLS_FIGURE if clear else self.nro_figure
tmp_col += 1
nro_row -= 1
def clear(self, board):
self.update(board, True)
def __is_valid(self, nro_row, nro_col):
return nro_row < self.rows and\
nro_col >= 0 and nro_col < self.cols
def __evaluate(self, nro_row, nro_col, figure):
for x in range(self.ROWS_FIGURE):
tmp_col = nro_col
for y in range(self.COLS_FIGURE):
if not self.__is_valid(nro_row, tmp_col) and\
figure[(self.ROWS_FIGURE - x)-1, y] != 0:
return False
if self.__is_valid(nro_row, tmp_col) and nro_row >= 0 and\
figure[(self.ROWS_FIGURE - x)-1, y] != 0 and\
self.board[nro_row, tmp_col] != 0:
return False
tmp_col += 1
nro_row -= 1
return True
def __next_angle(self):
angle = self.angle + 1
return 0 if angle >= len(self.FIGURES[self.nro_figure]) else angle
board.py
# -*- coding: utf-8 -*-
# Filename: board.py
# Developer by: @itrogeno
# Date: 29-03-2011
# Version: 0.4a
import numpy
class Board():
def __init__(self, shape):
self.array = numpy.zeros(shape, numpy.int)
def clear(self):
self.array.fill(0)
def get_board(self):
return self.array
def evaluate(self, color):
rows, cols = self.array.shape
for y in range(rows):
row = self.array[(rows-y)-1]
complete = True
for x in range(len(row)):
if row[x] == 0:
complete = False
break
if complete:
for x in range(len(row)):
row[x] = color
return True
return False
def update(self):
rows, cols = self.array.shape
for y in range(rows):
row = self.array[(rows-y)-1]
if row.sum() == 0:
if (rows-(y+1))-1 >= 0:
self.array[(rows-y)-1] = self.array[(rows-(y+1))-1]
self.array[(rows-(y+1))-1] = numpy.zeros(cols, numpy.int)
Bueno, esto es todo por hoy y no olviden si tienen cualquier duda o comentario no duden en Realizar.
Adiós.
Python: Arból Binario
A pasado 1 año 10 meses desde mi última publicación que en tiempo informático debe ser como un siglo
. Lo que hace más de un año una idea, un código era aceptado; puede que ahora este en retirada (esto solo es una apreciación personal y puede que este equivocado) y del poco código que había llegado a publicar alguno haya quedado obsoleto.
Y dado el tiempo trascurrido y de mucho reflexionar creo que ha llegado el momento de ponerme serio y retribuir todo lo que he aprendido durante estos años gracias a Internet y poder transformarme en un aporte más.
Bueno y de que mejor forma que volver a partir con un viejo conocido, el Árbol Binario, pero esta vez implementado con Python, que se ha convertido en uno de mis lenguajes favoritos en la actualidad (el otro es Javascript).
¿Y qué trae esta versión?
Esta versión permite hacer las siguientes tareas: Añadir, Eliminar, Buscar y Listar.
# -*- coding: utf-8 -*-
#
# Python version: 2.6.6
# Developer by: @itrogeno
# Date: 24-05-2011
# Description: Implementacion de un Arbol Binario en Python.
class Tree():
'''Arbol Binario'''
left = None
right = None
data = []
def __init__(self, value):
self.value = value
def append(self, value):
'''Metodo recursivo que permite anadir nuevos valores al
arbol binario.
Si el nuevo valor es mayor que el valor actual se
inserta en la rama derecha, si es menor se inserta en
la rama izquierda.'''
self.__append(['left', 'right'][value > self.value],
value)
def __append(self, name, value):
'''Metodo privado que anade un nuevo nodo'''
node = getattr(self, name, value)
if node is None:
node = Tree(value)
else:
node.append(value)
setattr(self, name, node)
def get_data(self):
'''Devuelve una lista ordernada en forma ascendente
con todos los valores ingresados.'''
self.data[:] = []
self.__order_data(self)
return self.data
def get_data_inverse(self):
'''Devuelve una lista ordenada en forma descendente
con todos los valores ingresados.'''
return self.get_data()[::-1]
def __order_data(self, node):
'''Metodo recursivo privado'''
def a(n):
if n is not None: self.__order_data(n)
a(node.left)
self.data.append(node.value)
a(node.right)
def search(self, value):
'''Permite buscar valores existentes en el arbol.
Devuelve un objeto Tree() si encuentra el valor, de
lo contrario devuelve un None.'''
parent, node = self.__search(None, self, value)
return node
def __search(self, parent, node, value):
'''Metodo recursivo privado que permite buscar valores
existentes en el arbol.'''
if node is None: return None, None
if value == node.value:
return parent, node
parent, result = self.__search(node, node.left, value)
if result is not None:
return parent, result
parent, result = self.__search(node, node.right, value)
if result is not None:
return parent, result
return None, None
def delete(self, value):
'''Permite eliminar valores del arbol binario.'''
parent, node = self.__search(None, self, value)
if node is None:
return
# Seleccionamos uno de los dos nodos hijos, por defecto
# siempre se utiliza el nodo derecho, pero si no existe
# se utiliza el nodo izquierdo.
child = getattr(node, ['left', 'right'][node.right
is not None])
if parent is not None:
# Si el nodo tiene padre, quiere decir que no es el
# nodo raiz.
# Reemplazamos el nodo con su nodo hijo, por defecto
# se utiliza el nodo derecho si no tiene se utiliza
# el nodo izquierdo.
direction = ['left', 'right'][parent.right is node]
setattr(parent, direction, child)
# Si se reemplazo por el nodo hijo derecho y tenia
# hijos en el nodo izquierdo estos son heredados al
# nodo hijo derecho, insertandolos al nivel mas bajo
# de la rama izquierda.
if node.left is not None and node.right is not None:
root.__insert_left(node.right, node.left)
del node
else:
# En esta implementacion es imposible eliminar el
# nodo padre, para ello en vez de reemplazarlo con
# el nodo hijo, solo heredamos los valores del hijo.
# Una vez hecho eso eliminamos el nodo hijo.
if node.left is not None and node.right is not None:
child.__insert_left(node.right, node.left)
node.value = child.value
node.left = child.left
node.right = child.right
del child
def __insert_left(self, parent, node):
if parent.left is None:
parent.left = node
else:
self.__insert_left(parent.left, node)
def __str__(self):
return 'Value: %i' % self.value
def main():
print "1° Insertamos datos al arbol"
tree = Tree(2)
tree.append(3)
tree.append(1)
tree.append(5)
tree.append(4)
tree.append(0)
tree.append(-1)
tree.append(-4)
tree.append(-3)
tree.append(-2)
tree.append(-5)
print ''
print '2° Listamos los datos ordenados'
print tree.get_data()
print ''
print '3° Listamos los datos inversos'
print tree.get_data_inverse()
print ''
print '4° Buscamos los datos en forma individual'
print '5 %s' % tree.search(5)
print '1 %s' % tree.search(1)
print '3 %s' % tree.search(3)
print '4 %s' % tree.search(4)
print '2 %s' % tree.search(2)
print '6 %s' % tree.search(6)
print ''
print '5° Eliminamos el numero 2'
tree.delete(2)
print ''
print '6° Volvemos a listar los datos'
print tree.get_data()
print tree.get_data_inverse()
print ''
print '7° Añadimos el numero 6 y -6'
tree.append(6)
tree.append(-6)
print ''
print '8° Volvemos a listar los datos'
print tree.get_data()
print tree.get_data_inverse()
print ''
print '9° Eliminamos el numero 4'
tree.delete(4)
print ''
print '10° Volvemos a listar los datos'
print tree.get_data()
print tree.get_data_inverse()
if __name__ == '__main__':
main()
Bueno creo que eso es todo por hoy y si alguien tiene alguna sugerencia o duda con el código no dude en preguntar que estaré encantado en responder.
Gracias
C#: Bosquejo de un ActiveRecord con Insert y Select
Aburrido en una noche de primavera comence a escribir un pequeño programa que era el bosquejo básico pero bien básico un ActiveRecord llegando sólo a implementar las funciones Insert y Select, aun tengo pendiente las funciones Update y Delete.
Este código se conecta a un base de datos Postgres a la tabla test con los campos id, nombre, apellidos y edad, primero inserta y luego lista el dato ingresado.
Antes de probar el código, deben crear la tabla y las columnas en minuscula.
Program.cs
using System;
using System.Collections.Generic;
namespace MiActiveRecord
{
public class Program
{
static void Main(string[] args)
{
Test test = new Test() {Nombre="Alexis",
Apellidos="Nuñez Riquelme"};
test.Save();
IList<Test> tests = Test.GetAll();
foreach (Test item in tests)
{
Console.WriteLine("{0,2} - {1, 10} - {2, 15} - {3, 2}",
item.Id, item.Nombre, item.Apellidos, item.Edad);
}
}
public class Test : Base<Test>
{
public string Nombre { get ; set; }
public string Apellidos { get; set; }
public int? Edad { get; set; }
}
}
}
Base.cs
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Reflection;
using System.Text;
using Npgsql;
namespace MiActiveRecord
{
public class Base<T> : BaseSQL<T>
{
public long Id { get; set; }
public static IList<T> GetAll()
{
IList<T> lst = new List<T>();
using (NpgsqlConnection sqlCnn = new NpgsqlConnection("User ID=postgres; Password=postgres; Host=localhost; Port=5432; Database=MiActiveRecord"))
{
sqlCnn.Open();
StringBuilder sql = GetSelect();
NpgsqlDataReader reader = new NpgsqlCommand(sql.ToString(), sqlCnn).ExecuteReader();
while (reader.Read())
{
T item = (T)typeof(T).Assembly.CreateInstance(typeof(T).FullName);
(item as Base<T>).LoadValues(reader);
lst.Add(item);
}
reader.Close();
sqlCnn.Close();
}
return lst;
}
public void LoadValues(NpgsqlDataReader reader)
{
for (int i = 0; i < reader.FieldCount; i++)
{
foreach (PropertyInfo property in (this).GetType().GetProperties())
{
if (property.Name.ToUpper() == reader.GetName(i).ToUpper())
{
if (reader[reader.GetName(i).ToUpper()] is DBNull)
property.SetValue(this, null, null);
else
property.SetValue(this, reader[reader.GetName(i).ToUpper()], null);
break;
}
}
}
}
public void Save()
{
using (NpgsqlConnection sqlCnn = new NpgsqlConnection("User ID=postgres; Password=postgres; Host=localhost; Port=5432; Database=MiActiveRecord"))
{
StringBuilder strSQL = GetInsert();
sqlCnn.Open();
NpgsqlCommand sqlcmd = new NpgsqlCommand(strSQL.ToString(), sqlCnn);
sqlcmd.ExecuteNonQuery();
sqlCnn.Close();
}
}
}
}
BaseSQL.cs
using System.Text;
using System.Reflection;
using System.Collections.Generic;
using System;
namespace MiActiveRecord
{
public class BaseSQL<T>
{
internal StringBuilder GetInsert()
{
StringBuilder sql = new StringBuilder("INSERT INTO ")
.AppendFormat("{0} (", this.GetType().Name);
foreach (PropertyInfo property in Base<T>.GetProperties(this.GetType(), true))
{
if (property.GetValue(this, null) != null)
sql.AppendFormat("{0}, ", property.Name);
}
sql.Remove(sql.Length - 2, 2);
sql.Append(") VALUES (");
foreach (PropertyInfo property in Base<T>.GetProperties(this.GetType(), true))
{
if (property.GetValue(this, null) != null)
{
if (property.PropertyType == typeof(string) || property.PropertyType == typeof(char))
sql.AppendFormat("'{0}', ", property.GetValue(this, null));
else
sql.AppendFormat("{0}, ", property.GetValue(this, null));
}
}
sql.Remove(sql.Length - 2, 2);
sql.Append(")");
return sql;
}
internal static StringBuilder GetSelect()
{
StringBuilder sql = new StringBuilder("SELECT ");
foreach (PropertyInfo property in Base<T>.GetProperties(typeof(T), false))
{
sql.AppendFormat("{0}, ", property.Name);
}
sql.Remove(sql.Length - 2, 2);
sql.AppendFormat(" FROM {0}", typeof(T).Name);
return sql;
}
private static IList<PropertyInfo> GetProperties(Type type, bool skipBase)
{
IList<PropertyInfo> properties = new List<PropertyInfo>();
bool exist;
foreach (PropertyInfo proItem in type.GetProperties())
{
exist = false;
if (skipBase)
{
foreach (PropertyInfo proBase in typeof(Base<T>).GetProperties())
{
if (proBase.Name == proItem.Name)
{
exist = true;
break;
}
}
}
if (!exist)
properties.Add(proItem);
}
return properties;
}
}
}
C#: Añandiendo descripciones a un Enum
Este código muy simple y nos permite añadir descripciones a nuestros Enum:
using System;
using System.Reflection;
namespace Enum
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(EnumDes.Descripcion<Navegadores>(Navegadores.Firefox));
Console.WriteLine(EnumDes.Nombre<Navegadores>("Mozilla Firefox"));
Navegadores valor = (Navegadores)EnumDes.Valor<Navegadores>("Mozilla Firefox");
if (valor == Navegadores.Firefox)
{
Console.WriteLine("Es Firefox... :)");
}
}
}
public enum Navegadores
{
[EnumDes("Mozilla Firefox")]
Firefox,
[EnumDes("Opera Browser")]
Opera
}
// Esta clase se crea como Atributo para insentar descripciones en cualquier enum
public class EnumDes : Attribute
{
private string _descripcion;
// Constructor
public EnumDes(string descripcion)
{
_descripcion = descripcion;
}
// Este método recupera la descripción del enum utilizando Reflection.
public static string Descripcion<T>(T _enum)
{
FieldInfo info = typeof(T).GetField(_enum.ToString(), BindingFlags.Public |
BindingFlags.Static);
foreach (object obj in info.GetCustomAttributes(false))
{
if (obj.GetType() == typeof(EnumDes))
{
return obj.ToString();
}
}
return "No se encontró la descripción";
}
public static FieldInfo Buscar<T>(string descripcion)
{
FieldInfo[] infos = typeof(T).GetFields(BindingFlags.Public |
BindingFlags.Static);
foreach (FieldInfo item in infos)
{
foreach (object attribute in item.GetCustomAttributes(false))
{
if (attribute.ToString() == descripcion)
{
return item;
}
}
}
return null;
}
public static string Nombre<T>(string descripcion)
{
FieldInfo info = Buscar<T>(descripcion);
return (info == null ? "No se encontró el valor" : info.Name);
}
public static object Valor<T>(string descripcion)
{
FieldInfo info = Buscar<T>(descripcion);
return (info == null ? null : info.GetValue(typeof(T)));
}
/* Se sobrescribe el método ToString() para retornar la descripción
* ingresada a través de su constructor.
*/
public override string ToString()
{
return _descripcion;
}
}
}
Cuando no aceptar un Proyecto
En mi poca experiencia como desarrollador puedo rescatar algunos puntos que uno debe analizar para no aceptar un proyecto:
- Es la herencia de alguien más (Persona o Empresa), si es la herencia de otra empresa atente a las consecuencias.
- El sistema tiene un framework propietario/cerrado con nula documentación. Peor es si el framework pertenece a la empresa que anteriormente desarrollaba el proyecto.
- El sistema no tiene documentación/auto-documentación.
- El sistema tiene abundante código spaguetti.
- No tengas contacto con la persona o empresa que desarrollaba el proyecto.
- O si tienes contacto no sepan lo que hicieron.
- El proyecto venga con el regalo de un Jefe de Proyecto y/o Analista(s) incompetente(s).
- Al aceptar el proyecto puedas quedar amarrado eternamente a este.
Python: Mi propia versión de Mario Bros.
Quede con gusto a poco después de realizar mi primer juego en python y pygame, así pasaron varias semanas hasta que navegando por Internet me entere que alguien había desarrollado un Mario Bros. en javascript, el cuál lo había encontrado genial, con este hecho encontré mi inspiración para crear mi propia versión de Mario Bros.
Durante 3 semanas me dedique a programar mi propia versión. Obtuve los sprites desde Internet y con lo aprendido programando mi primer juego empece mi odisea.
Al finalizar las 3 semanas pude realizar lo siguiente:
- Crear una parte del primer nivel.
- Añadir un tipo de enemigo.
- Logre mover el fondo, lo cuál me costo mucho trabajo.
- Realizar los movimientos de Mario.
- Lograr que Mario aplaste a su enemigo
- Hacer que Mario interactue con su ambiente.
No es mucho lo que pude hacer pero trabajando sólo de noche y cansado. Bueno acá les dejo una imagen de como quedo el juego y un enlace con los fuentes.

P.D.: Si tienen algún problema para descar el código fuente me avisan.
Python: Mi primer juego
Mi primer acercamiento a la informática fue hace unos 17 años aproximadamente, en esa época sólo tenía un computador atari con el Basic como lenguaje de programación. Lo único que me interesaba más que jugar con los juegos que tenía era programar mis propios juegos, pasaba días enteros programando mis juegos, mientras soñaba con trabajar como programador de juegos, pero la realidad fue otra y termine haciendo aburridos sistemas para empresas.
Pero no fue hasta hace unos meses atrás que empece a interesarme en Python y toda su filosofía de vida, y leyendo algunos blogs mostraban la simplicidad que tenia el lenguaje para desarrollar juegos, sólo debía instalar la librería pygame y manos a la obra.
Así que le dedique varias noches a programar mi primer juego y al cabo de 2 semanas ya lo tenía armado. Es un simple juego de naves donde uno se puede mover por toda la pantalla disparando y tratando de matar a las naves enemigas mientras van apareciendo desde arriba de la pantalla.

Si lo quieren probar acá les dejo el código fuente comprimido.
C#: Ordenando una lista genérica
El siguiente código muestra el ordenamiento de una lista genérica, siendo necesario que los objetos implementen la interfaz Icomparable.
using System;
using System.Collections.Generic;
namespace nitrogeno
{
class Program
{
static void Main(string[] args)
{
IList<string> list1 = new List<string>();
list1.Add("Casa"); // 1
list1.Add("Auto"); // 2
list1.Add("Arbol"); // 3
list1.Add("Sapo"); // 4
list1.Add("Nuevo"); // 5
SortList.Bubble<string>(list1);
foreach (string item in list1)
Console.WriteLine("{0}", item);
Console.WriteLine();
IList<int> list2 = new List<int>();
list2.Add(5); // 1
list2.Add(2); // 2
list2.Add(3); // 3
list2.Add(1); // 4
list2.Add(4); // 5
SortList.Bubble<int>(list2);
foreach (int item in list2)
Console.WriteLine("{0}", item);
}
}
public class SortList
{
public static IList<T> Bubble<T>(IList<T> list)
where T : IComparable
{
T tmp;
for (int i = 0; i < list.Count; i++)
{
for (int x = 0; x < list.Count - (i + 1); x++)
{
if (list[x].CompareTo(list[x + 1]) > 0)
{
tmp = list[x + 1];
list[x + 1] = list[x];
list[x] = tmp;
}
}
}
return list;
}
}
}
C#: Árbol Binario Genérico
Este árbol binario lo desarrolle en un momento de aburrimiento en el trabajo y nunca lo temine, por eso me faltó implementar el método eliminar, asi que espero añadirlo en un futuro próximo.
Lo interesante de este código es que permite utilizar los tipos de datos char, string, datetime, int, decimal, o cual otro objeto que tenga implementado la interfaz Icomparable. Porque el árbol binario hace uso del método CompareTo de la interfaz Icomparable, para ir comparando el nuevo nodo con los nodos existentes y asi saber que camino debe tomar.
using System.Collections.Generic;
namespace ArbolBinarioGenerico
{
class Program
{
static void Main(string[] args)
{
ArbolBinario<int> arbol = new ArbolBinario<int>(8); //1
arbol.Insertar(ref arbol, 7); //2
arbol.Insertar(ref arbol, 5); //3
arbol.Insertar(ref arbol, 3); //4
arbol.Insertar(ref arbol, 4); //5
arbol.Insertar(ref arbol, 0); //6
arbol.Insertar(ref arbol, 2); //7
arbol.Insertar(ref arbol, 6); //8
arbol.Insertar(ref arbol, 9); //9
arbol.Insertar(ref arbol, 1); //10
foreach(int valor in arbol.Listar(arbol, new List<int<()))
Console.WriteLine(valor);
}
}
public class ArbolBinario<T> where T : IComparable
{
private T valor;
private ArbolBinario<T> nodoIzq = null; // nodo derecho
private ArbolBinario<T> nodoDer = null; // nodo izquierdo
public ArbolBinario(T valor) // constructor
{
this.valor = valor;
}
public void Insertar(ref ArbolBinario<T> nodo, T valor)
{
if (nodo == null)
nodo = new ArbolBinario<T>(valor);
else
{
if (nodo.valor.CompareTo(valor) > 0)
Insertar(ref nodo.nodoIzq, valor);
else
Insertar(ref nodo.nodoDer, valor);
}
}
public List<T> Listar(ArbolBinario<T> nodo, List<T> arbol)
{
if (nodo.nodoIzq != null)
Listar(nodo.nodoIzq, arbol);
arbol.Add(nodo.valor);
if (nodo.nodoDer != null)
Listar(nodo.nodoDer, arbol);
return arbol;
}
}
}