Ara que ja tenim el taulell, anem a fer el programa per poder jugar al tres en línia. Abans de res, cal definir les imatges que corresponen a les fitxes i al cursor. Atès que en aquest joc les fitxes es situen en posicions determinades, de les quals no es bellugaran, podíem haver optat per definir quatre rajoles que definissin una casella amb fitxa d'un color, unes altres quatre per a l'altre color i unes darreres quatre per la casella amb el cursor al damunt. Però, atès que aquest exemple ha de servir com a base per poder fer altres jocs, ens ha semblat més oportú definir les fitxes com a sprites. Caldrà, doncs, afegir al fitxer tres imatges: fitxa vermella, fitxa verda i cursor. En el fitxer ens quedaran encara set posicions lliures, a les quals posarem el color de fons. Una d'elles la podem fer servir, si ens cal, com a sprite completament transparent. El nou fitxer d'imatge tile1.bmp és aquest:
Per entendre com el farem servir, el trossejarem en les corresponents rajoles de 16 ⨯ 16 píxels; només per a les deu que farem servir.
![]() |
![]() |
![]() |
![]() |
![]() |
||||
![]() |
![]() |
![]() |
![]() |
![]() |
Els números que corresponen a cada rajola són:
| Índex | Utilització |
| 0 | Fons de la barra lateral |
| 1 | Cantonada superior esquerra d'una casella |
| 2 | Cantonada superior dreta d'una casella |
| 3 | Cantonada inferior dreta d'una casella |
| 4 | Cantonada inferior esquerra d'una casella |
| 5 | Vora del taulell |
| 6 | Fitxa verda |
| 7 | Fitxa vermella |
| 8 | Cursor |
| 9 | Sprite transparent |
La figura següent mostra l'estat del taulell en un moment donat de la partida, amb les fitxes i el cursor.

Al lateral del taulell se'ns indica a quin jugador li correspon tirar en cada moment.
Podíem haver definit els nou sprites que corresponen a les fitxes fent servir línies independents, una per a cada un, com a l'exemple dels tres sprites en moviment, però ens ha semblat millor fer servir una metodologia (basada en un bucle) que serveixi per a qualsevol nombre d'sprites; ja que pot ser més útils per a jocs amb més elements.
Tenim diverses funcions. La primera d'elles comprova si s'ha acabat la partida; primer mira si ja està el taulell ple i després mira si hi ha tres fitxes iguals en les fileres, columnes o diagonals. Ho fa en aquest ordre perquè si el taulell està ple tant pot ser que hi hagi un guanyador com que hi hagi empat. Hi ha una funció per amagar totes les fitxes (per a l'inici d'una partida) i una que permet mostrar una fitxa concreta del color que correspongui. També hi ha una funció per mostrar a qui li toca tirar. Per al cursor hi ha tres funcions, una que busca una casella buida per situar-lo, una que el posa en la posició desitjada i una que serveix per mostrar-lo o amagar-lo. Hi ha dues funcions més, una per dibuixar el taulell i una per inicialitzar la partida.
S'ha organitzat el programa al voltant de tres possibles estats: inicialització, jugant i fi de la partida; per a cada un hi ha un if que posa les coses a lloc i un while per desenvolupar el funcionament i gestionar la interacció de l'usuari.
La partida comença quan es prem el botó start. Cada jugador, quan li toca, situa el cursor (amb els botons de desplaçament) on vol situar la fitxa i pica el botó select. Quan acaba la partida s'indica al lateral qui ha guanyat i cal prémer el botó start per poder tornar a començar.
A la primera partida (després de la posada en marxa) comença el jugador verd; a les següents comença el guanyador de l'anterior. En cas d'empat, començarà el verd.
El programa és el següent:
import ugame import stage import time
banc = stage.Bank.from_bmp16("tile1.bmp")
fons = stage.Grid(banc, 10, 8) # 16 * 10 = 160
# 16 * 8 = 128
# Creem un sprite per al fons i un per a l'indicador de torn
cursor = stage.Sprite(banc, 9, 24, 24) # Inici a (24, 24)
torn = stage.Sprite(banc, 9, 136, 56)
# Creem les 9 fitxes, inicialment invisibles
fitxes = []
for i in range(3):
for j in range(3):
xf = 24 + 32 * i
yf = 24 + 32 * j
fitxes = fitxes + [stage.Sprite(banc, 9, xf, yf)]
joc = stage.Stage(ugame.display, 12)
# Llista on guardarem les posicions de les fitxes # 0 = lliure 1 = verd 2 = vermell caselles = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] coord_curs = [1, 1] estat = 0 # Per començar, l'estat inicial abans = 0 # Lectura anterior dels polsadors jugador = 1 # El primer jugador és el verd
# Funcio que comprova si ja hem acabat
# Torna el jugador que ha guanyat o 3 si hi ha empat
def comprova():
acabat = 0
suma = 0
for xa in range(3):
for ya in range(3):
if caselles[xa][ya] > 0:
suma += 1
if suma == 9:
acabat = 3
for jg in range(1, 3):
for k in range(3):
if caselles[k][0] == jg and caselles[k][1] == jg and caselles[k][2] == jg:
acabat = jg # Columna k
for k in range(3):
if caselles[0][k] == jg and caselles[1][k] == jg and caselles[2][k] == jg:
acabat = jg # Filera k
if caselles[0][0] == jg and caselles[1][1] == jg and caselles[2][2] == jg:
acabat = jg # Diagonal
if caselles[2][0] == jg and caselles[1][1] == jg and caselles[0][2] == jg:
acabat = jg # Diagonal
return acabat
# Fi de la funcio
# Funcio que amaga les fitxes
# 0 = invisible 1 = verd 2 = vermell
def amaga_fitxes():
for i in range(9):
fitxes[i].set_frame(9, 0)
# Fi de la funcio
# Funcio que mostra les fitxes
# 0 = invisible 1 = verd 2 = vermell
def mostra_fitxa(x, y, jug):
ind = 3 * x + y
if jug == 0:
torn.set_frame(9, 0)
elif jug < 3:
fitxes[ind].set_frame(jug + 5, 0)
# Fi de la funcio
# Funcio que mostra a qui li toca tirar
# 0 = no mostra 1 = verd 2 = vermell
def mostra_jugador(vis):
if vis == 0:
torn.set_frame(9, 0)
elif vis < 3:
torn.set_frame(vis + 5, 0)
# Fi de la funcio
# Funcio que mostra o amaga el cursor
# Si el paràmetre és 0 no es veura
def mostra_cursor(vis):
if vis == 0:
cursor.set_frame(9, 0)
else:
cursor.set_frame(8, 0)
# Fi de la funcio
# Funcio que situa el cursor en una casella buida
# Retorna la posicio del cursor
def busca_pos_cursor():
cc = [0, 0]
for xa in range(3):
for ya in range(3):
if caselles[xa][ya] == 0:
cc[0] = xa
cc[1] = ya
return cc
# Fi de la funcio
# Funcio que situa el cursor en una casella buida
def situa_cursor(coord):
xyc = [0, 0]
xyc[0] = 24 + 32 * coord[0]
xyc[1] = 24 + 32 * coord[1]
cursor.move(xyc[0], xyc[1])
return xyc
# Fi de la funcio
# Funcio que reinicia la partida
def nova_partida():
for i in range(3):
for j in range(3):
caselles[i][j] = 0
# Fi de la funcio
# Funcio que dibuixa el taulell
def dib_taulell():
tau = [ [5, 5, 5, 5, 5, 5, 5, 5, 0, 0],
[5, 1, 2, 1, 2, 1, 2, 5, 0, 0],
[5, 4, 3, 4, 3, 4, 3, 5, 0, 0],
[5, 1, 2, 1, 2, 1, 2, 5, 1, 2],
[5, 4, 3, 4, 3, 4, 3, 5, 4, 3],
[5, 1, 2, 1, 2, 1, 2, 5, 0, 0],
[5, 4, 3, 4, 3, 4, 3, 5, 0, 0],
[5, 5, 5, 5, 5, 5, 5, 5, 0, 0] ]
for i in range(8): # 8 fileres
for j in range(10): # 10 columnes
fons.tile(j, i, tile=tau[i][j])
# Fi de la funcio
joc.layers = [cursor, torn] + fitxes + [fons]
dib_taulell()
while True:
if estat == 0: # Situacio inicial
amaga_fitxes()
nova_partida()
mostra_jugador(0)
joc.render_block()
while estat == 0: # Esperem que es premi Start
boto = ugame.buttons.get_pressed() # Lectura actual dels polsadors
# A cada if ens assegurem que el boto s'havia deixat anar
if not abans & ugame.K_START and boto & ugame.K_START:
estat = 1 # Inici del joc
abans = boto
if estat == 1: # Partida
# Mostrem el cursor
coord_curs = [1,1]
situa_cursor(coord_curs)
mostra_jugador(jugador)
mostra_cursor(1)
joc.render_block()
while estat == 1:
# Indiquem qui juga
mostra_jugador(jugador)
# Mirem els polsadors per moure el cursor
boto = ugame.buttons.get_pressed() # Lectura actual dels polsadors
# A cada if ens assegurem que el boto s'havia deixat anar
if not abans & ugame.K_RIGHT and boto & ugame.K_RIGHT and coord_curs[0] < 2:
coord_curs[0] += 1
if not abans & ugame.K_LEFT and boto & ugame.K_LEFT and coord_curs[0] > 0:
coord_curs[0] -= 1
if not abans & ugame.K_DOWN and boto & ugame.K_DOWN and coord_curs[1] < 2:
coord_curs[1] += 1
if not abans & ugame.K_UP and boto & ugame.K_UP and coord_curs[1] > 0:
coord_curs[1] -= 1
situa_cursor(coord_curs)
joc.render_block()
# El botó SELECT posa la fitxa, si es pot
if not abans & ugame.K_SELECT and boto & ugame.K_SELECT:
if caselles[coord_curs[0]][coord_curs[1]] == 0:
caselles[coord_curs[0]][coord_curs[1]] = jugador
mostra_fitxa(coord_curs[0], coord_curs[1], jugador)
jugador +=1
if jugador > 2:
jugador = 1
# Resituem el cursor
coord_curs = busca_pos_cursor()
situa_cursor(coord_curs)
joc.render_block()
# Mirem si ja ha acabat
guanya = comprova()
if guanya > 0:
estat = 2
abans = boto
if estat == 2: # Final
mostra_cursor(0)
if guanya == 3:
jugador = 1 # El proper jugador és el verd
ja = 1
jb = 2
else:
jugador = guanya # El proper jugador és el guanyador
ja = guanya
jb = 0
while estat == 2:
#Mostra el guanyador intermitent
mostra_jugador(ja)
joc.render_block()
time.sleep(0.5)
mostra_jugador(jb)
joc.render_block()
time.sleep(0.5)
# Esperem START per tornar a l'inici
boto = ugame.buttons.get_pressed() # Lectura actual dels polsadors
# A cada if ens assegurem que el boto s'havia deixat anar
if not abans & ugame.K_START and boto & ugame.K_START:
estat = 0 # Inici del joc
abans = boto

Esta obra de Oriol Boix está licenciada bajo una licencia no importada Creative Commons Reconocimiento-NoComercial-SinObraDerivada 3.0.