luni, 17 octombrie 2011

Primii pasi in programarea jocurilor

Am reusit sa scriu o carte care ofera o introducere in programarea jocurilor. Limbajul folosit e Python datorita faptului ca e foarte usor de invatat. Cartea este impartita in 3 capitole: 1. Introducere in Python; 2. Programare Orientata pe Obiecte; 3. Dragonul.

Dragonul este jocul descris.

Cartea poate fi descarcata gratuit de la urmatorul link: Oricine poate scrie un joc

vineri, 4 martie 2011

Client-Server Concurent in Python 2.6

Functiile socket din Python sunt foarte asemanatoare celor din C, dar programarea in general este mult mai rapida si mai simplu de inteles. Functiile thread-ului sunt simplificate fata de C. Bine-nteles, exista posibilitatea de a folosi socket-urile si thread-urile la nivel avansat la fel ca in C.

Pentru incepatori, idea modelului Client-Server este de a exista un program, numit server, care sa deserveasca alte programe, numite clienti. Este un model foarte folosit in lumea retelelor de calculatoare. Un exemplu potrivit este relatia browser-server web, unde browser-ul este clientul iar server-ul web este, desigur, server-ul; browser-ul transmite o cerere pentru o anumita pagina web, iar server-ul web returneaza browser-ului codul HTML al acelei pagini. Un alt exemplu bun este in domeniul jocurilor; atunci cand cel putin doi oameni vor sa se joace in retea, pe unul din calculatoare se deschide un server la care se conecteaza toti jucatorii.
Legatura Client-Server se face printr-un IP si un Port, clientul trebuie sa cunoasca IP-ul si portul serverului pentru a se putea conecta la server, iar mai departe serverul trebuie sa cunoasca IP-ul si portul clientului pentru ai returna raspuns cererii. Portul clientului este stabilit de sistemul de operare si, impreuna cu IP-ul si setul de date, este transmis server-ului. Transmisia datelor se poate face prin doua protocoale: TCP si UDP.

Tot pentru incepatori, Thread-urile sunt fire de executie asemanatoare proceselor si create de catre procese. Atunci cand se doreste ca o aplicatie sa execute mai multe functii in acelasi timp exista doua solutii: 1. deschide mai multe procese care executa functiile; 2. deschide mai multe thread-uri care executa functiile. De obicei sunt folosite thread-urile pentru ca au nevoie de mai putine resurse decat procesele pentru a parcurge acelasi set de instructiuni.


server.py
Aplicatia foloseste protocolul TCP. Pentru ca server-ul sa fie concurent, adica sa poata servi mai multi clienti in acelasi timp, am folosit thread-uri.

import socket, thread

def functionalitate(addr, conn):
    # functia thread-ului care returneaza un raspuns clientului
    # primul argument este adresa clientului
    # al doilea argument este socket-ul clientului 
    connected = True
    while connected:
        data = conn.recv(1024) # asteapta un mesaj
        if data == "STOP":
             # daca primeste mesajul STOP, inchide conexiunea 
             break
        conn.send(data) # trimite un mesaj
    conn.close()
    thread.exit()


running = True
HOST = ""    # sir de caractere null inseamna ca functioneaza pe orice adresa
PORT = 8891

# creaza un socket IPv4 (AF_INET) pe TCP (SOCK_STREAM)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))  # mapeaza socket-ul in sistemul de operare
s.listen(5)  # accepta maxim 5 conexiuni

print "Server is running."

while running:
     # accepta conectarea unui client si returneaza un socket si adresa clientului
     conn, addr = s.accept()
     # creeaza un thread care sa serveasca noul client
     thread.start_new_thread(functionalitate, (addr, conn))


client.py

import socket

# seteaza adresa si portul server-ului
HOST = "localhost"
PORT = 8891
running = True

# creaza un socket IPv4 pe TCP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# se conecteaza clientul la server
s.connect((HOST, PORT))

print "Client"
print "Type STOP to close the program."

while running:
    data = raw_input("Message: ")
    if data == "STOP":
        print "Closing connection."
        s.send("STOP")  # trimite STOP
        break
     s.send(data) # trimite un mesaj
     data = s.recv(1024)  # asteapta un mesaj
     print repr(data)

s.close()