¿Qué os parece este proyecto? Tres en raya...

Hola a todos. Estoy aprendiendo python como hobby, porque me gusta esto de programar y tal, y que he hecho un tres en raya. Me gustaría que dierais vuestra opinión. No soy un experto programador, todo lo contrario, un novato bigsmile pero espero que os guste. Teneis que abrirlo, dandole a ejecutar en una terminal, porque el ganador se da por consola.
http://informaticafacil.atwebpages.com/descargas/tres_en_raya_beta.tar.g...
P.D.: Instalad el paquete python-pygame para poder ejecutarlo.
¡¡¡Saludos!!! No seais muy duros conmigo jejeje que estoy empezando.

goku@julio:~/archivos_bajados/Tres en raya$ ./tres_en_raya.py
Traceback (most recent call last):
  File "./tres_en_raya.py", line 25, in ?
    import pygame
ImportError: No module named pygame

ese import pygame es un archivo o un modulo bueno no me ejecuta
P.D (no se phython pero quería probarlo )

Tienes que instalar el paquete python-pygame

gracias por responder
en efecto faltaba ese paquete

goku@julio:~/archivos_bajados/Tres en raya$ ./tres_en_raya.py
¡¡¡HA GANADO EL JUGADOR 2!!!
goku@julio:~/archivos_bajados/Tres en raya$

debo darte una buena critica lo veo ordenado y identado , pense que el problema era que me faltaba agregar un modulo pero gracias con eso funciono pefecto

un estube probabdo que dice cuando nadie gana y dice que hay un empate me parece que con una canción agregada quedaría mejor

rafahack95 escribió:

Hola a todos. Estoy aprendiendo python como hobby, porque me gusta esto de programar y tal, y que he hecho un tres en raya. Me gustaría que dierais vuestra opinión. No soy un experto programador, todo lo contrario, un novato bigsmile pero espero que os guste. Teneis que abrirlo, dandole a ejecutar en una terminal, porque el ganador se da por consola.
http://informaticafacil.atwebpages.com/descargas/tres_en_raya_beta.tar.g...
P.D.: Instalad el paquete python-pygame para poder ejecutarlo.
¡¡¡Saludos!!! No seais muy duros conmigo jejeje que estoy empezando.

Lindo código!! Respetas casi siempre el ancho de linea!! (es una buena costumbre casi olvidada). Iba a aplicar unos cambios... sobretodo optimizaciones lógicas, pero entonces me dí cuenta de que para cambiar una función debía cambiar otra, y otra... y había unas globales cruzadas... y otras... y un error aquí y halla al pasarlas por referencia. Se nota que tienes buenas costumbres en la programación, solo que no encapsulas bien el código. Sabe a espagueti. También noté que editaste el programa usando varios editores distintos (o pegando código de otra fuente), lo sé porque mezclas distintos anchos de identación, incluso <#tab>s y espacios.

Paso el archivo como quedó antes de que me fuera a dormir:

#!/usr/bin/python
# -*- coding: iso-8859-1 -*-

"""Utilidad: Este archivo, contiene el programa principal de el juego
# del tres en raya."""

__Licencia = """Este archivo de código se puede redistribuir y modificar,
siguiendo la licencia GPLv3, que es la que se ha decidido asignar a
este poyecto. Para más información, lea el archivo licence incluido
con este juego."""
__Autores = """Autor: Rafael Álvarez García, también conocido como RAGPacho o
rafahack95 en la red.
Agradecimientos especiales: Ha Hugo Rusticci, y al proyecto
Losers Juegos en general. Pueden visitar su sitio web en:
http://www.losersjuegos.com.ar También quiero dar un agradecimiento
especial a David Ramírez (dvd), también miembro de este proyecto,
por responderme siempre a mis dudas, junto con Juanxo, que incluso
me ha ayudado a remodelar el código del programa para hacerlo más
breve."""

import pygame
from pygame.locals import *
import sys

def crea_matriz_nula(filas, columnas):
    """devuelve una matriz nula, con el número de filas y columnas que le
pasemos como parámetro."""
    matriz = []
    for i in range(filas):
        matriz.append([None] * columnas)
    return matriz

def modifica_matriz_y_cierra(matriz, casillas, le_toca_a_jugador1,
    le_toca_a_jugador2):
    """comprueba donde esta el ratón en pantalla y, dependiendo del botom
pulsado modifica la matriz. También gestiona los eventos de cierre deljuego."""
    posicion_raton = pygame.mouse.get_pos()
    boton_pulsado = None

    for evento in pygame.event.get():

        if evento.type == MOUSEBUTTONDOWN:
            boton_pulsado = evento.button

        if evento.type == pygame.QUIT:
            sys.exit(0)
    raton = [posicion_raton[0], posicion_raton[1], boton_pulsado]
    filas = len(matriz)
    columnas = len(matriz[0])
    casilla = 0

    for fila in range(filas):

        for columna in range(columnas):

            if raton[0] >= casillas[casilla].left and raton[0] <=\
            casillas[casilla].right and raton[1] >= casillas[casilla]\
            .top and raton[1] <= casillas[casilla].bottom and raton[2]\
             == 1 and matriz[fila][columna] == None:

                if le_toca_a_jugador1:
                    matriz[fila][columna] = 1
                    le_toca_a_jugador1 = False
                    le_toca_a_jugador2 = True

                elif le_toca_a_jugador2:
                    matriz[fila][columna] = 2
                    le_toca_a_jugador2 = False
                    le_toca_a_jugador1 = True

            casilla += 1
           

def actualiza_fichas(jugador1, jugador2, matriz, screen):
    """dependiendo de el valor de la matriz, imprima en pantalla las fichas"""
    filas = len(matriz)
    columnas = len(matriz[0])

    for fila in range(filas):

        for columna in range(columnas):

            if matriz[fila][columna] == 1:
                screen.blit(jugador1, (200 * columna + 9, 200 * fila \
                + 9))

            elif matriz[fila][columna] == 2:
                screen.blit(jugador2, (200 * columna + 9, 200 * fila \
                + 9))
    # Ahora actualizamos la pantalla.
    pygame.display.flip()

   
def ganador(tablero, pos):
    """Verifica si al colocar una pieza en pos el jugador ha ganado la partida"""
    pos = pos[0] - 3, pos[1] - 3
    direcciones = [
        ((-1, -1), (1,  1)), # Diagonal ascendente
        ((-1,  0), (1,  0)), # Horizontal
        (( 0, -1), (0,  1)), # Vertical
        ((-1,  1), (1, -1)), # Diagonal descendente
    ]

    suma = lambda pos1, pos2: (pos1[0] + pos2[0], pos1[1] + pos2[1])
    cas = lambda pos: tablero[pos[0]][pos[1]]

    for dir in direcciones:
        if cas(suma(pos, dir[0])) is cas(pos) is cas(suma(pos, dir[1])):
            pass

def ganador(matriz, jugador):
    """comprueba en el tablero todas las posibles maneras de ganar, y si
alguien a ganado."""
    ha_ganado = False
    if (matriz[0][0] == jugador and matriz[1][0] == jugador and matriz\
    [2][0] == jugador) or (matriz[0][1] == jugador and matriz[1][1] ==\
     jugador and matriz[2][1] == jugador) or (matriz[0][2] == jugador \
     and matriz [1][2] == jugador and matriz [2][2] == jugador) or\
      (matriz[0][0] == jugador and matriz [0][1] == jugador and \
      matriz[0][2] == jugador) or (matriz[1][0] == jugador and \
      matriz[1][1] == jugador and matriz[1][2] == jugador) or \
      (matriz[2][0] == jugador and matriz[2][1] == jugador and matriz\
      [2][2] == jugador) or (matriz[0][0] == jugador and matriz[1][1] \
      == jugador and matriz [2][2] == jugador) or (matriz[0][2] == \
      jugador and matriz[1][1] == jugador and matriz[2][0] == jugador):
          ha_ganado = True
    return ha_ganado
   
def hay_empate(matriz):
    """devulbve True si el tablero está lleno y no hay un ganador."""
    empate = True
    filas = len(matriz)
    columnas = len(matriz[0])

    for fila in range(filas):
        for columna in range(columnas):
            if matriz[fila][columna] == None:
                empate = False
                break

    return empate           

def main():
# Vamos a definir algunos aspectos de la pantalla y las matrices que
# que usaremos en el juego.
    ancho_pantalla = 600
    alto_pantalla = 600
    screen = pygame.display.set_mode((ancho_pantalla, alto_pantalla))
    pygame.display.set_caption('Tres en... ¡¡¡rock!!!')
    matriz = crea_matriz_nula(3, 3)

# Ahora creemos el escenario, con sus casillas, etc. Para las lineas
# que dividen las distintas casillas, vamos a dejar un espacio sin nada
# colocado en el, porque como el fondo de la pantalla es negro,
# parecerá que hemos dibujado lineas. Cuando veais el resultado,
# entendereis mejor a que me refiero.
    tamanyo_casillas = 199
# Ahora, vamos a dar valor a otra variable, para que el escenario quede
# perfecto, probad a darle valor 199 en vez de 200 y vereis a que me
# refiero.
    tamanyo_casillas_especial = 200
    casillas_color = (255, 255, 255)
    casilla1 = pygame.Rect(0, 0, tamanyo_casillas, tamanyo_casillas)
    casilla2 = pygame.Rect(200, 0, tamanyo_casillas, tamanyo_casillas)
    casilla3 = pygame.Rect(400, 0, tamanyo_casillas_especial, tamanyo_casillas)
    casilla4 = pygame.Rect(0, 200, tamanyo_casillas, tamanyo_casillas)
    casilla5 = pygame.Rect(200, 200, tamanyo_casillas, tamanyo_casillas)
    casilla6 = pygame.Rect(400, 200, tamanyo_casillas_especial,
        tamanyo_casillas)
    casilla7 = pygame.Rect(0, 400, tamanyo_casillas, tamanyo_casillas_especial)
    casilla8 = pygame.Rect(200, 400, tamanyo_casillas,
        tamanyo_casillas_especial)
    casilla9 = pygame.Rect(400, 400, tamanyo_casillas_especial,
        tamanyo_casillas_especial)
    casillas = [casilla1, casilla2, casilla3, casilla4, casilla5,\
     casilla6, casilla7, casilla8, casilla9]
    for i in xrange(len(casillas)):
        screen.fill(casillas_color, casillas[i])

# Ahora vamos  a cargar las imágenes que usaremos en el juego.
    jugador1 = pygame.image.load('img/jugador1.png')
    jugador2 = pygame.image.load('img/jugador2.png')

    le_toca_a_jugador1 = True
    le_toca_a_jugador2 = False
    ha_ganado_jugador1 = False
    ha_ganado_jugador2 = False

# ---------------------------------------------------------------------
# CÓDIGO TEMPORAL PARA PROBAR EL PROGRAMA
# ---------------------------------------------------------------------

    while True:
        modifica_matriz_y_cierra(matriz, casillas, le_toca_a_jugador1,
            le_toca_a_jugador2)
        actualiza_fichas(jugador1, jugador2, matriz, screen)
        if ganador(matriz, 1):
            print '¡¡¡HA GANADO EL JUGADOR 1!!!'
            pygame.time.delay(2000)
            return 0
        elif ganador(matriz, 2):
            print '¡¡¡HA GANADO EL JUGADOR 2!!!'
            pygame.time.delay(2000)
            return 0
        elif hay_empate(matriz):
            print '¡¡¡HA HABIDO UN EMPATE!!!'
            pygame.time.delay(2000)
            return 0

if __name__ == "__main__":
    sys.exit(main())

Los principales cambios son:

  • Quité las identaciones combinadas
  • Reemplacé todas las apariciones de <#tab> por " "
  • Intenté eliminar el uso de globales, al hacerlo dañé el cambio de jugador
  • Cambié comentarios por documentación donde correspondía
  • Encapsule main
  • Eliminé salidas del programa innecesarias, las reemplacé por returns
  • Maquete una nueva función ganador, no pude añadirla al flujo del programa aún
  • Cambié "==" por "is" donde tenía sentido la optimización
  • Separé bloques lógicos con saltos de linea

Si puedo termino de aplicar mi idea mañana. También puedo ofrecerte una clase para usar gifs animados que se me ocurrió te podría resultar útil.

Por cierto, me gustó el juego, solo falta un pequeño menú para comenzar a jugar de nuevo, ayuda, cartel de ganador, partida finalizada... y esos detalles.

¡Gracias! Lo del ancho de línea, es uan manía, por que me gusta que todo este bien ordenadito jajaja. Veo que a ti también te agrada. respecto a lo de usar varios editores, suelo usar geany, pero creo haber usado también gedit en algún momento.
Lo de usar las variables globales, ya me recomendaron que no lo hiciera, pero es que no se me ocurrió otra manera de hacerlo. Agradezco que me ayudes a corregirlo.
El menú del juego, tengo pensado hacerlo más adelante, es que de momento solo he tenido la posibilidad de aprender la programación estructurada, y el menú lo quería hacer usando objetos, pero tengo que aprender todavía esa rama de la programación smile .
Ahh, y estaría encantado de que me enseñaras a usar los gifs animados.
¡¡¡Sañudos a la comunidad!!!

rafahack95 escribió:

¡Gracias! Lo del ancho de línea, es uan manía, por que me gusta que todo este bien ordenadito jajaja. Veo que a ti también te agrada. respecto a lo de usar varios editores, suelo usar geany, pero creo haber usado también gedit en algún momento.
Lo de usar las variables globales, ya me recomendaron que no lo hiciera, pero es que no se me ocurrió otra manera de hacerlo. Agradezco que me ayudes a corregirlo.
El menú del juego, tengo pensado hacerlo más adelante, es que de momento solo he tenido la posibilidad de aprender la programación estructurada, y el menú lo quería hacer usando objetos, pero tengo que aprender todavía esa rama de la programación smile .
Ahh, y estaría encantado de que me enseñaras a usar los gifs animados.
¡¡¡Sañudos a la comunidad!!!

No me refería a ese tipo de clase... sino a una clase hablando en poo (class). La terminé... ha quedado bastante prolija para haber sido escrita a fuerza de café...:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import Image
import sys
import pygame
from pygame.locals import *
import time

INICIO = time.time()

def debug(*args):
    global INICIO
    sys.stderr.writelines("%6.2f" % (time.time() - INICIO) + " "
        + " ".join([str(e) for e in args]) + "\n")

class clase_animacion():

    def __init__(self, archivo, velocidad=1):
        self.inicio = time.time() * 1000
        self.velocidad = float(velocidad)

        imagen = Image.open(archivo)
        imagen.seek(0)
        self.size = imagen.size

        convert = lambda x: [x[i:i + 3] for i in xrange(0, len(x), 3)]

        try:
            paleta_base = convert(imagen.getpalette())
        except TypeError:
            paleta_base = None

        self.frames = []
        delays = []

        all_keys = set()
        while True:
            if imagen.tile:
                all_keys.add(imagen.tile[0][3][0])

            try:
                imagen.seek(imagen.tell() + 1)
            except EOFError:
                break

        imagen.seek(0)

        while True:
            tile = imagen.tile

            if tile and len(tile[0][1]) == 4:
                rect = tile[0][1]
            else:
                rect = (0, 0) + imagen.size

            rect = rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]

            acumulador = pygame.Surface(imagen.size, SRCALPHA)

            paleta = None

            debug(tile)

            if all_keys == set((7, 8)):
                paleta = convert(imagen.getpalette())

            if all_keys == set([6]) or all_keys == set([7]) or 2 in all_keys:
                paleta = convert(imagen.getpalette())
                for frame in self.frames:
                    acumulador.blit(frame, (0, 0))

            if 8 in all_keys:
                paleta = convert(imagen.getpalette())

            if not paleta:
                paleta = paleta_base

            this_frame = pygame.image.frombuffer(imagen.tostring(),
                imagen.size, imagen.mode)

            this_frame.set_palette(paleta)

            if "transparency" in imagen.info:
                this_frame.set_colorkey(imagen.info.get('transparency', 0))

            acumulador.blit(this_frame, rect[:2], rect)
            self.frames.append(acumulador)

            delays.append(imagen.info.get("duration", 100))

            try:
                imagen.seek(imagen.tell() + 1)
            except EOFError:
                break

        self.count = len(self.frames)
        self.duration = sum(delays)
        self.delays = [sum(delays[:i + 1]) for i in xrange(len(delays))]

    def current_frame(self):
        tiempo = ((time.time() * 1000 * self.velocidad - self.inicio) % self.duration)
       
        for i in xrange(len(self.delays)):
            if tiempo < self.delays[i]:
                break
       
        return self.frames[i]

def main():
    screen = pygame.display.set_mode((1, 1))

    if len(sys.argv) == 2:
        velocidad = 1
    elif len(sys.argv) == 3:
        velocidad = sys.argv[2]
    else:
        debug("""Debe pasarse, como argumento, el nombre del archivo a abrir,\
opcionalmente puede pasar un multiplicador de velocidad que puede ser positivo\
o negativo.

python gifs.py archivo [velocidad]""")
        return 1

    animacion = clase_animacion(sys.argv[1], velocidad)
    screen = pygame.display.set_mode(animacion.size)

    while True:
        screen.fill((0, 255, 0))
        screen.blit(animacion.current_frame(), (0, 0))
        pygame.display.flip()
        pygame.time.delay(25)

if __name__ == "__main__":
    sys.exit(main())

Su uso típico, como modulo, sería algo así:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import pygame
from gifs import clase_animacion

screen = pygame.display.set_mode((300, 300))

animacion = clase_animacion(sys.argv[1], velocidad)
while True:
    screen.fill((0, 255, 0))
    screen.blit(animacion.current_frame(), (0, 0))
    pygame.display.flip()
    pygame.time.delay(25)

También lo puedes usar como un reproductor de gifs.. a fines de probar el programa:

python gifs.py mi_animacion.gif # Lo reproduce normalmente
python gifs.py mi_animacion.gif -1 # Lo reproduce en reversa
python gifs.py mi_animacion.gif 5 # Lo reproduce muy rapido
python gifs.py mi_animacion.gif .2 # Lo reproduce muy lento

Más tarde intento arreglar el desorden que hice en tu código. Si consigues algunas imágenes animadas para las fichas de los jugadores o para el menú sería bueno así vamos integrando.

bueno point parece que eres el mas adecuado para hacerle esta pregunta has trabajado con sockets en phyton? , hace tiempo tenia curiosidad por aprender phython por donde me recomiendas empezar?
saludos

pipis384mix escribió:

bueno point parece que eres el mas adecuado para hacerle esta pregunta has trabajado con sockets en phyton? , hace tiempo tenia curiosidad por aprender phython por donde me recomiendas empezar?
saludos

Te recomiendo este libro para comenzar con Python. Te enseña a programar y Python, por lo que te será muy útil si es la primera vez que programas.
Respecto a lo de la clase, hubo un malentendido meparto . El problema es que no se usar la programación orientada a objetos, pero bueno, intentaré aprender algo.
¡¡¡Saludos a todos!!!

pipis384mix escribió:

bueno point parece que eres el mas adecuado para hacerle esta pregunta has trabajado con sockets en phyton? , hace tiempo tenia curiosidad por aprender phython por donde me recomiendas empezar?
saludos

Es muy difícil esa pregunta... y no porque no haya buenos libros y tutoriales, sino por todo lo opuesto. Hay tantos y tan buenos que se me hace muy difícil pensar en cual es el mejor. Pero creo que me quedo con "Aprenda a pensar como programador con Python" aunque no lo leí completo y te recomiendo que dejes de leerlo donde sientas que puedes seguir solo y, entonces, te manejes con bibliografia especifica.

rafahack95 escribió:

Respecto a lo de la clase, hubo un malentendido meparto . El problema es que no se usar la programación orientada a objetos, pero bueno, intentaré aprender algo.
¡¡¡Saludos a todos!!!

Oh vamos, tampoco es tannnnn complicado, y te será muy útil. Me lamento porque la mejoré un poco esta mañana, pero con las prisas por llegar a casa dejé la nueva versión en mi trabajo sin enviarmela ni copiarla en el pendrive... pero ahora me concentraré en ayudarte a darle estabilidad a tu código.