Jump to content

[Python]Jogo Picross: Quebra-Cabeças


Berhart
 Share

Recommended Posts

Bom dia Comunidade.Apresento-vos aqui um programa de Python feito por mim que permite a um utilizador jogar o jogo Picross no computador. O que é o jogo Picross?

É um jogo de Quebra-Cabeças muito parecido com o Sudoku em que o objetivo é descobrir uma imagem de acordo com as regras do Jogo.

picross-toad.jpg

Para entenderem melhor o conceito do jogo poderão encontrá-lo na Net pesquisando pelo seu nome.

O código realizado tem por base os TAD(Tipos Abstratos de Dados) que permitem manipular mais facilmente a informação necessária no decorrer do jogo.

Para tal são definidas certas operações básicas cujas especificações vêm descritas no Enunciado em Anexo em conjunto com

casos-teste para testarem a funcionalidade das vossas funções e consequentemente dos vossos outputs.

Recomendo a utilização de um Ambiente de Desenvolvimento como o Wing IDE.

Código:

# --------------------------------------- TAD COORDENADA ------------------------------- ## Construtor:def cria_coordenada(l, c): ''' cria_coordenada: int x int -> coordenada cria_coordenada(l,c): construtor do tipo coordenada. Recebe dois argumentos do tipo inteiro, l e c, e devolve um elemento do tipo coordenada''' if isinstance(c, int) and isinstance (l, int) and (l > 0) and (c > 0): return (l, c) else: raise ValueError ("cria_coordenada: argumentos invalidos") # -- Fim: cria_coordenada -- # # Selectores:def coordenada_linha(t): ''' coordenada_linha: coordenada -> inteiro coordenada_linhas(t): seletor do tipo coordenada. Recebe uma coordenada t e devolve a linha respetiva da coordenada t''' if not ( e_coordenada(t) ): raise ValueError('coordenada_linha: argumentos invalidos') return t[0] # -- Fim: coordenada_linha -- #def coordenada_coluna(t): ''' coordenada_coluna: coordenada -> inteiro coordenada_coluna(t): seletor do tipo coordenada. Recebe uma coordenada t e devolve a coluna respetiva da coordenada t''' if not ( e_coordenada(t) ): raise ValueError('coordenada_coluna: argumentos invalidos') return t[1] # -- Fim: coordenada_coluna -- ## Reconhecedor:def e_coordenada(u): ''' e_coordenada: universal -> logico e_coordenada(u): reconhecedor do tipo coordenada. Recebe um elemento de qualquer tipo e diz-nos se o elemento u e do tipo coordenada.''' return isinstance(u, tuple) and len(u) == 2 \ and isinstance(u[0], int) \ and isinstance(u[1], int) \ and ( u[0] > 0 and u[1] > 0) # necessrio # # -- Fim: e_coordenada -- ## Teste:def coordenadas_iguais(c1, c2): ''' coordenada_iguais: coordenada x coordenada -> logico coordenada_iguais(c1, c2): recebe dois elementos do tipo coordenada, c1 e c2, e diz se sao iguais.''' if not ( e_coordenada(c1) ) or not (e_coordenada(c2)): raise ValueError('coordenada_coluna: argumentos invalidos') return ( coordenada_linha(c1) == coordenada_linha(c2) ) and ( coordenada_coluna(c1) == coordenada_coluna(c2) ) # -- Fim: coordenadas_iguais -- #def coordenada_para_cadeia(t): ''' coordenada_para_cadeia: coordenada -> string coordenada_para_cadeia(t): recebe como argumento um elemento do tipo coordenada, t, e devolve uma cadeia de caracteres que a represente''' if not ( e_coordenada(t) ): raise ValueError('coordenada_para_cadeia: argumentos invalidos') return "(" + str(coordenada_linha(t)) + " : " + str(coordenada_coluna(t)) + ")"# ------------------------------------ FIM TAD COORDENADA ------------------------------- ## -------------------------------------- TAD TABULEIRO ---------------------------------- ## Construtor:def cria_tabuleiro(e): ''' cria_tabuleiro: tuplo -> tabuleiro cria_tabuleiro(e) : Construtor do tipo tabuleiro. Recebe um tuplo (e) contendo as especificacoes de um tabuleiro, contruindo-o de acordo com as especificacoes.''' if len(e) != 2 or len(e[0]) != len(e[1]) or not isinstance(e, tuple): raise ValueError ('cria_tabuleiro: argumentos invalidos') for i in range(len(e)): if not isinstance(e,tuple): raise ValueError ('cria_tabuleiro: argumentos invalidos') for k in range(len(e)): if not isinstance(e[k], tuple): raise ValueError ('cria_tabuleiro: argumentos invalidos') for j in range(len(e[k])): if not isinstance(e[k][j], int): raise ValueError ('cria_tabuleiro: argumentos invalidos') if e[k][j] <= 0: raise ValueError ('cria_tabuleiro: argumentos invalidos') return [ [[0,] * len(e[0]) for x in range (len(e[1]))], e ]# -- Fim: cria_tabuleiro -- # def tabuleiro_dimensoes(t): ''' tabuleiro_dimensoes: tabuleiro -> tuplo tabuleiro_dimensoes(t): Seletor do tipo tabuleiro. Recebe um elemento do tipo tabuleiro (t) e retorna as suas dimensoes''' if not (e_tabuleiro(t)): raise ValueError('tabuleiro_dimensoes: argumentos invalidos') return (len(t[0]), len(t[0][0]))# -- Fim: tabuleiro_dimensoes -- #def tabuleiro_especificacoes(t): ''' tabuleiro_especificacoes: tabuleiro -> tuplo tabuleiro_especificacoes(t): Seletor do tipo tabuleiro. Recebe um tabuleiro (t) e retorna as suas especificacoes''' if not (e_tabuleiro(t)): raise ValueError('tabuleiro_especificacoes: argumentos invalidos') return t[1]# -- Fim: tabuleiro_especificacoes -- #def tabuleiro_completo(t): ''' tabuleior_completo: tabuleiro -> logico tabuleiro_completo(t): Reconhecedor do tipo tabuleiro. Recebe um tabuleiro (t) e verifica se o tabuleiro esta totalmente preenchido e de acordo com as suas especificacoes''' if not (e_tabuleiro(t)): raise ValueError('tabuleiro_completo: argumentos invalidos') cont = 0 k = 0 logico = True if tabuleiro_celulas_vazias(t) == True: return False for a in range(tabuleiro_dimensoes(t)[0]): for b in range(tabuleiro_dimensoes(t)[0]): if tabuleiro_celula(t, (a + 1, b + 1)) == 2: k += 1 for y in range(len(tabuleiro_especificacoes(t)[0])): cont = cont + tabuleiro_especificacoes(t)[0][y] logico = logico and (cont == k) cont = 0 k = 0 for i in range(tabuleiro_dimensoes(t)[0]): for x in range(tabuleiro_dimensoes(t)[0]): if tabuleiro_celula(t, (b + 1, a + 1)) == 2: k += 1 for y in range(len(tabuleiro_especificacoes(t)[1])): cont = cont + tabuleiro_especificacoes(t)[1][y] logico = logico and (cont == k) k = 0 cont = 0 return logico# Selectores:def tabuleiro_celula(t, c): ''' tabuleiro_celula: tabuleiro x coordenada -> {0, 1, 2} tabuleiro_celula(t, c): Seletor do tipo tabuleiro. Recebe um tabuleiro t e uma coordenada c e retorna o valor que esta na coordenada c do tabuleiro t.''' if not(e_coordenada©) or not (e_tabuleiro(t)): raise ValueError ('tabuleiro_celula: argumentos invalidos') if coordenada_linha© > tabuleiro_dimensoes(t)[0] or coordenada_coluna© > tabuleiro_dimensoes(t)[0]: raise ValueError ('tabuleiro_celula: argumentos invalidos') else: if t[0][coordenada_linha©-1][coordenada_coluna©-1] == 0: return 0 elif t[0][coordenada_linha©-1][coordenada_coluna©-1] == 1: return 1 elif t[0][coordenada_linha©-1][coordenada_coluna©-1] == 2: return 2 # -- Fim: tabuleiro_celula -- ## Modificadores: def tabuleiro_preenche_celula(t,c,n): ''' tabuleiro_preenche_celula: tabuleiro x coordenada x {0, 1, 2} -> tabuleiro tabuleiro_preenche_celula(t,c,n): Modificador do tipo tabuleiro. Recebe um tabuleiro, uma coordenada e um valor e insere o valor n na coordenada c do tabuleiro t indicados. ''' if not(e_coordenada©) or not (e_tabuleiro(t)): raise ValueError ('tabuleiro_preenche_celula: argumentos invalidos') if (n < 0) or (n > 2) or not isinstance(n, int): raise ValueError ('tabuleiro_preenche_celula: argumentos invalidos') if coordenada_linha© > tabuleiro_dimensoes(t)[0] or coordenada_coluna© > tabuleiro_dimensoes(t)[1]: raise ValueError ('tabuleiro_preenche_celula: argumentos invalidos') t[0][coordenada_linha© - 1][coordenada_coluna© - 1] = n return t# -- Fim: tabuleiro_preenche_celula -- #def e_tabuleiro(n): ''' e_tabuleiro: universal -> logico e_tabuleiro(n): Reconhecedor do tipo tabuleiro. Recebe qualquer elemento n e diz se o elemento e do tipo tabuleiro.''' if not isinstance(n, list) or (len(n) != 2) or not isinstance(n[0],list) or not isinstance(n[1], tuple): return False for i in range(len(n[0])): if not isinstance(n[0], list) or len(n[0]) != len(n[0]): return False for k in n[0]: if not isinstance(k,int) or not(k >= 0 and k <= 2): return False if (len(n[1]) != 2 ) or len(n[1][0]) != len(n[1][1]): return False for i in range(len(n[1])): if not isinstance(n[1], tuple): return False for k in range(len(n[1])): if not isinstance(n[1][k], tuple): return False for j in range(len(n[1][k])): if not isinstance(n[1][k][j], int): return False if n[1][k][j] <= 0: return False return True# -- Fim: e_tabuleiro -- #def tabuleiros_iguais(t1,t2): ''' tabuleiros_iguais: tabuleiro x tabuleiro -> logico tabuleiro_iguais(t1, t2): teste do tipo tabuleiro. Recebe dois tabuleiros t1 e t2 e diz se sao iguais.''' if not (e_tabuleiro(t1)) or not (e_tabuleiro(t2)): raise ValueError('tabuleiros_iguais: argumentos invalidos') return t1 == t2# -- Fim: tabuleiros_iguais -- #def escreve_tabuleiro(t): ''' escreve_tabuleiro: tabuleiro -> {} escreve_tabuleiro(t): escreve para o ecra a representacao externa do tabuleiro t de Picross''' if not ( e_tabuleiro(t) ): raise ValueError("escreve_tabuleiro: argumento invalido") colunas = aux_escreve_colunas(t) linhas = aux_escreve_linhas(t) for i in range(len(colunas[0])): for l in range(len(colunas)): if colunas[l] == (): print(' ', end='') if colunas[l] != (): print(' ',colunas[l], ' ', end='') print(' ', end='') print() for l in range(tabuleiro_dimensoes(t)[0]): for c in range(tabuleiro_dimensoes(t)[1]): if tabuleiro_celula(t,(cria_coordenada(l+1, c+1))) == 0: print('[ %s ]' % ('?'), sep='', end='') if tabuleiro_celula(t,(cria_coordenada(l+1, c+1))) == 1: print('[ %s ]' % ('.'), sep='', end='') if tabuleiro_celula(t,(cria_coordenada(l+1, c+1))) == 2: print('[ %s ]' % ('x'), sep='', end='') for i in range(len(linhas[0])): if linhas[l] != (): print('', linhas[l], end='') if linhas[l] == (): print('', end=' ') print('|', end='') print() print() return # -- Fim: escreve_tabuleiro -- ## -------------------------------------- FIM TAD TABULEIRO ------------------------------- ## -------------------------------------- FUNCOES ADICIONAIS ------------------------------ #def le_tabuleiro(fich): f1 = open(fich, "r") le = f1.readlines() f1.close() return eval(le[0])def pede_jogada(t): if not ( e_tabuleiro(t) ): raise ValueError ('pede_jogada: argumentos invalidos') print('Introduza a jogada') coordenada = input('- coordenada entre (1 : 1) e ' + coordenada_para_cadeia(cria_coordenada(tabuleiro_dimensoes(t)[0], tabuleiro_dimensoes(t)[1])) + ' >> ') valor = input('- valor >> ') if (len(coordenada) != 7) : return False try: int(coordenada[1]) and int(coordenada[5]) except ValueError: return False coordenada_tuplo = cria_coordenada(int(coordenada[1]), int(coordenada[5])) if coordenada_para_cadeia(coordenada_tuplo) != coordenada: return False if ((coordenada_linha(coordenada_tuplo) <= tabuleiro_dimensoes(t)[0]) and (coordenada_coluna(coordenada_tuplo) <= tabuleiro_dimensoes(t)[1])) == False: return False try: valor = int(valor) except: pass return cria_jogada(coordenada_tuplo, (valor))def jogo_picross (fich): esp = le_tabuleiro(fich) jogo = cria_tabuleiro(esp) print('JOGO PICROSS') while tabuleiro_celulas_vazias(jogo): # ERRO escreve_tabuleiro(jogo) jogada = pede_jogada(jogo) while jogada == False: print('Jogada invalida.') jogada = pede_jogada(jogo) tabuleiro_preenche_celula(jogo,jogada_coordenada(jogada),jogada_valor(jogada)) escreve_tabuleiro(jogo) if tabuleiro_completo(jogo): print('JOGO: Parabens, encontrou a solucao!') return True print('JOGO: O tabuleiro nao esta correto!') return False # ----------------------------------- FIM FUNCOES ADICIONAIS ----------------------------- ## ---------------------------------------- TAD JOGADA ------------------------------------ #def cria_jogada(c, v): if e_coordenada© and ( ( v == 1 ) or ( v == 2 ) ): return (c, v) raise ValueError("cria_jogada: argumentos invalidos")#seletordef jogada_coordenada(j): if not e_jogada(j): raise ValueError('jogada_coordenada: argumentos invalidos') return j[0]# fimdef jogada_valor(j): if not e_jogada(j): raise ValueError('jogada_valor: argumentos invalidos') return j[1]# fim#reconhecedordef e_jogada(u): return isinstance(u, tuple) and e_coordenada(u[0]) \ and ( (u[1] == 2) or (u[1] == 1) ) and len(u) == 2 #fim#testedef jogadas_iguais(j1,j2): if not e_jogada(j1) or not e_jogada(j2): raise ValueError('jogada_iguais: argumentos invalidos') return j1 == j2#fimdef jogada_para_cadeia(j): if not e_jogada(j): raise ValueError('jogada_para_cadeia: argumentos invalidos') return coordenada_para_cadeia(jogada_coordenada(j)) + " --> " + str(jogada_valor(j))# -------------------------------------- FIM TAD JOGADA ---------------------------------- ## ------------------------------------ FUNCOES AUXILIARES -------------------------------- #def pos_maior(tup): ''' pos_max : tuplo -> int pos_max(t) devolve a posicao da entrada do valor maximo do tuplo t inserido.''' maior = len(tup[0]) # defini-se que o maximo e igual a primeira entrada do tuplo pos_max = 0 # o valor maximo esta na posicao inicial para fazer a comparacao com as restantes for i in range(len(tup)): if len(tup) > maior: maior = len(tup) pos_max = i return maior def aux_escreve_colunas (t): aux = pos_maior(tabuleiro_especificacoes(t)[1]) new_t = () for i in range(len(tabuleiro_especificacoes(t)[1])): if len(tabuleiro_especificacoes(t)[1]) != aux: new_t = new_t + ((((),)*(aux - len(tabuleiro_especificacoes(t)[1])) + tabuleiro_especificacoes(t)[1]),) if len(tabuleiro_especificacoes(t)[1]) == aux: new_t = new_t + ((tabuleiro_especificacoes(t)[1]),) return new_tdef aux_escreve_linhas (t): aux = pos_maior(tabuleiro_especificacoes(t)[0]) new_t = () for i in range(len(tabuleiro_especificacoes(t)[0])): if len(tabuleiro_especificacoes(t)[0]) != aux: new_t = new_t + (tabuleiro_especificacoes(t)[0] + ((),)*(aux - len(tabuleiro_especificacoes(t)[0])),) if len(tabuleiro_especificacoes(t)[0]) == aux: new_t = new_t + ((tabuleiro_especificacoes(t)[0]),) return new_tdef tabuleiro_celulas_vazias(t): contador = 0 for l in range(tabuleiro_dimensoes(t)[0]): for c in range(tabuleiro_dimensoes(t)[0]): if tabuleiro_celula(t, cria_coordenada(l + 1, c + 1)) == 0: contador += 1 return (contador >= 1)# -------------------------------- FIM FUNCOES AUXILIARES -------------------------------- #

Picross.rar

Picross.rar

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share

×
×
  • Create New...