Torres de Hanoi 1.0
Publicado por Washington Luis de O Santos (última atualização em 25/10/2018)
[ Hits: 4.105 ]
Jogo de Quebra Cabeça feito para rodar em um terminal com o Python 3.
É bom para quem quer aprender um pouco sobre o uso do módulo 'curse' no Python
#!/usr/bin/env python # -*- coding:UTF-8 -*- #coding: cp1252 #coding: latin1 u''' Torres de Hanoi version 1.0 - Program Este programa, primeiro, foi desenvolvido em clipper 5.2 por mim em novembro de 1994 e agora foi convertido e adaptado para o python3 com o uso do módulo 'curses' Copyright (c) 2002-2004 Washington Luis de O. Santos < owashington[arroba]terra.com.br > This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. POR: Washington Luis de Oliveira Santos Taubaté - SP, de 7 a 10 de outubro de 2018 ''' import sys import os import random import time import curses # janela principal screen = curses.initscr() screen.notimeout(False) screen.keypad(True) screen.clear() #screen.set_title('T O R R E S D E H A N O I') # iniciando cores curses.start_color() curses.init_pair( 1, curses.COLOR_RED, curses.COLOR_WHITE) curses.init_pair( 2, curses.COLOR_GREEN, curses.COLOR_WHITE) curses.init_pair( 3, curses.COLOR_YELLOW, curses.COLOR_WHITE) curses.init_pair( 4, curses.COLOR_BLUE, curses.COLOR_WHITE) curses.init_pair( 5, curses.COLOR_MAGENTA, curses.COLOR_WHITE) curses.init_pair( 6, curses.COLOR_CYAN, curses.COLOR_WHITE) curses.init_pair( 7, curses.COLOR_RED, curses.COLOR_WHITE) curses.init_pair( 8, curses.COLOR_GREEN, curses.COLOR_WHITE) curses.init_pair( 9, curses.COLOR_YELLOW, curses.COLOR_WHITE) curses.init_pair(10, curses.COLOR_MAGENTA, curses.COLOR_WHITE) # Define cor das Colunas e da Base da Torre (azul e branco) curses.init_pair(11, curses.COLOR_BLUE, curses.COLOR_WHITE) # Define cor da Barra de Status (branco e cyan) curses.init_pair(12, curses.COLOR_WHITE, curses.COLOR_CYAN) curses.init_pair(13, curses.COLOR_GREEN, curses.COLOR_WHITE) curses.init_pair(14, curses.COLOR_BLUE, curses.COLOR_WHITE) curses.init_pair(15, curses.COLOR_WHITE, curses.COLOR_BLUE) curses.init_pair(16, curses.COLOR_BLACK, curses.COLOR_WHITE) curses.init_pair(17, curses.COLOR_BLACK, curses.COLOR_BLUE) curses.init_pair(18, curses.COLOR_BLACK, curses.COLOR_WHITE) curses.cbreak() # Não retorna caracteres na tela curses.noecho() # esconde o cursor do mouse e do terminal curses.curs_set(0) # Define Constantes K_CTRL_Q = 17 K_ESC = 27 K_F1 = 59 # Win K_1 = 49 K_2 = 50 K_3 = 51 N_DISCOS = 10 PG_CODE = 9440 # Define Constantes usadas como caracteres especiais # Single-line # Chr( 218 ) + Chr( 196 ) + Chr( 191 ) ┌ ─ ┐ # Chr( 179 ) + Chr( 32 ) + Chr( 179 ) │ │ # Chr( 192 ) + Chr( 196 ) + Chr( 217 ) └ ─ ┘ c_032 = 32 c_168 = 9608 c_177 = 9617 c_178 = 9618 c_179 = 9474 c_191 = 9488 c_192 = 9492 c_196 = 9472 c_217 = 9496 c_218 = 9484 c_219 = 9604 c_223 = 9600 # Determina a posicao inicial da torre que contera os discos de forma aleatoria pos_0 = random.randint( 1, 3 ) pos_1 = 2 if pos_0 == 1 else 1 pos_2 = 2 if pos_0 == 3 else 3 TORRE = {} TORRE[pos_0] = [1,2,3,4,5,6,7,8,9,10] TORRE[pos_1] = [] TORRE[pos_2] = [] COR = {} #COR[pos_0] = [ 1, 2, 3, 4, 5, 6, 7, 8, 9,10] COR[pos_0] = random.sample( range(1,11), 10) COR[pos_1] = [] COR[pos_2] = [] # Esta é uma tentativa de manter o prg compativel com o python 2.7 # para isto comente as duas linhas abaixo def unichr(ch): return chr(ch) def Hchr(strhex): ''' Funcao para transformar uma cadeia de valores em hexadecimal para uma cadeia de caracteres ''' STRING = '' for pos in strhex.split(','): i = int(pos, 16) if i < 128: STRING = STRING + unichr(i) else: STRING = STRING + unichr(i + PG_CODE) return (STRING) DISCO = {} DISCO[ 1] = Hchr('20,20,20,20,20,20,20,20,20,B1,B2,B1,20,20,20,20,20,20,20,20,20') DISCO[ 2] = Hchr('20,20,20,20,20,20,20,20,B1,B1,B2,B1,B1,20,20,20,20,20,20,20,20') DISCO[ 3] = Hchr('20,20,20,20,20,20,20,B1,B1,B1,B2,B1,B1,B1,20,20,20,20,20,20,20') DISCO[ 4] = Hchr('20,20,20,20,20,20,B1,B1,B1,B1,B2,B1,B1,B1,B1,20,20,20,20,20,20') DISCO[ 5] = Hchr('20,20,20,20,20,B1,B1,B1,B1,B1,B2,B1,B1,B1,B1,B1,20,20,20,20,20') DISCO[ 6] = Hchr('20,20,20,20,B1,B1,B1,B1,B1,B1,B2,B1,B1,B1,B1,B1,B1,20,20,20,20') DISCO[ 7] = Hchr('20,20,20,B1,B1,B1,B1,B1,B1,B1,B2,B1,B1,B1,B1,B1,B1,B1,20,20,20') DISCO[ 8] = Hchr('20,20,B1,B1,B1,B1,B1,B1,B1,B1,B2,B1,B1,B1,B1,B1,B1,B1,B1,20,20') DISCO[ 9] = Hchr('20,B1,B1,B1,B1,B1,B1,B1,B1,B1,B2,B1,B1,B1,B1,B1,B1,B1,B1,B1,20') DISCO[10] = Hchr('B1,B1,B1,B1,B1,B1,B1,B1,B1,B1,B2,B1,B1,B1,B1,B1,B1,B1,B1,B1,B1') if 0: DISCO[ 1] = (' #T# ') DISCO[ 2] = (' ##T## ') DISCO[ 3] = (' ###T### ') DISCO[ 4] = (' ####T#### ') DISCO[ 5] = (' #####T##### ') DISCO[ 6] = (' ######T###### ') DISCO[ 7] = (' #######T####### ') DISCO[ 8] = (' ########T######## ') DISCO[ 9] = (' #########T######### ') DISCO[10] = ('##########T##########') def pause(tempo): # Atualiza a tela screen.refresh() # Pausa por um tempo time.sleep(tempo) #****************************************** #* FUNCAO PARA IMPRIMIR A TELA DE ABERTURA #* def autor(): DispBox_Shadow(2,10,21,68, 11) screen.addstr( 3, 22, ' _____', curses.color_pair(13)) screen.addstr( 4, 22, '|_ _|__ _ __ _ __ ___ ___', curses.color_pair(13)) screen.addstr( 5, 22, ' | |/ _ \\| \'__| \'__/ _ \\/ __|', curses.color_pair(13)) screen.addstr( 6, 22, ' | | (_) | | | | | __/\\__ \\', curses.color_pair(13)) screen.addstr( 7, 22, ' |_|\\___/|_| |_| \\___||___/', curses.color_pair(13)) screen.addstr( 8, 22, ' _', curses.color_pair(13)) screen.addstr( 9, 22, ' __| | ___', curses.color_pair(13)) screen.addstr(10, 22, ' / _` |/ _ \\', curses.color_pair(13)) screen.addstr(11, 22, ' | (_| | __/', curses.color_pair(13)) screen.addstr(12, 22, ' _ _ \\__,_|\\___| _', curses.color_pair(13)) screen.addstr(13, 22, ' | | | | __ _ _ __ ___ (_)', curses.color_pair(13)) screen.addstr(14, 22, ' | |_| |/ _` | \'_ \\ / _ \\| |', curses.color_pair(13)) screen.addstr(15, 22, ' | _ | (_| | | | | (_) | |', curses.color_pair(13)) screen.addstr(16, 22, ' |_| |_|\\__,_|_| |_|\\___/|_|', curses.color_pair(13)) screen.addstr(11, 52, 'Versão 1.0', curses.color_pair(18)) screen.addstr(18, 15, 'Autor: Washington Luis de Oliveira Santos', curses.color_pair(11)) screen.addstr(19, 15, 'End. : Av. Campinas, 749 - Chácara do Visconde', curses.color_pair(11)) screen.addstr(20, 28, 'Taubaté - São Paulo', curses.color_pair(11)) def Hprompt(): while True: key = screen.getch() #curses.getmouse() ''' if key = K_LBUTTONUP // botao esquerdo pressionado // Verifica em que posicao foi pressionado if TST_BOTAO(04,03,20,23) return 1 elif TST_BOTAO(04,29,20,49) return 2 elif TST_BOTAO(04,55,20,75) return 3 ''' if key in (K_ESC, K_CTRL_Q): # encerra o programa ENCERRA(True) elif key in (curses.KEY_F1, ord('h'), ord('H')): # help acionado autor() screen.addstr(24, 1, ' ' * 80, curses.color_pair(12)) screen.addstr(24, 1, ' Tecle algo para sair...', curses.color_pair(12) | curses.A_BOLD) screen.getch() pause(.05) display_tela() return 0 elif key == K_1: return 1 elif key == K_2: return 2 elif key == K_3: return 3 def bt_press(n_bt): ''' desenha os botoes acionados n_bt = numero do botao ''' screen.addstr(20, n_bt*26-15, '{:^7}'.format(n_bt), curses.color_pair(14) | curses.A_BOLD) #screen.addstr(20, n_bt*26-15, '{:^7}'.format(n_bt), curses.color_pair(1) | curses.A_BOLD) screen.addstr(20, n_bt*26-16, ' ', curses.color_pair(15)) screen.addstr(21, n_bt*26-15, ' ' * 7, curses.color_pair(15)) def bt_solto(n_bt): ''' desenha os botoes não acionados n_bt = numero do botao ''' screen.addstr(20, n_bt*26-16, '{:^7}'.format(n_bt), curses.color_pair(16)) #screen.addstr(20, n_bt*26-16, '{:^7}'.format(n_bt), curses.color_pair(3)) screen.addstr(20, n_bt*26- 9, unichr(c_219), curses.color_pair(17)) screen.addstr(21, n_bt*26-15, unichr(c_223) * 7, curses.color_pair(17)) def Box(lt,ce,lb,cd, cor): for x in range(lt,lb): screen.addstr(x, ce, ' ' * (cd-ce+1), curses.color_pair(cor)) def DispBox(lt,ce,lb,cd, cor): Box(lt,ce,lb,cd, cor) screen.addstr(lt, ce, unichr(c_196) * (cd-ce), curses.color_pair(cor)) screen.addstr(lt, ce, unichr(c_218), curses.color_pair(cor)) screen.addstr(lt, cd, unichr(c_191), curses.color_pair(cor)) screen.addstr(lb, ce, unichr(c_196) * (cd-ce), curses.color_pair(cor)) screen.addstr(lb, ce, unichr(c_192), curses.color_pair(cor)) screen.addstr(lb, cd, unichr(c_217), curses.color_pair(cor)) for x in range(lt+1,lb): screen.addstr(x, ce, unichr(c_179), curses.color_pair(cor)) screen.addstr(x, cd, unichr(c_179), curses.color_pair(cor)) def DispBox_Shadow(lt,ce,lb,cd, cor): DispBox(lt,ce,lb,cd, cor) #Desenha a Sombra da Caixa for x in range(lt+1,lb+1): screen.addstr(x, cd+1, unichr(c_168), curses.color_pair(18)) screen.addstr(lb+1, ce+1, unichr(c_168) * (cd-ce+1), curses.color_pair(18)) def display_tela(): #Cria uma quadro na tela com char azul e fundo branco DispBox( 1,1,18,80, 11) #Escreve o titulo screen.addstr(3, 24, 'T O R R E S D E H A N O I', curses.color_pair(11) | curses.A_BOLD) #Desenha a base screen.addstr(18, 1, unichr(c_178) * 80, curses.color_pair(11)) #Desenha as colunas for i in range(0,11): screen.addstr(i+7, 13, unichr(c_178), curses.color_pair(11)) screen.addstr(i+7, 65, unichr(c_178), curses.color_pair(11)) screen.addstr(i+7, 39, unichr(c_178), curses.color_pair(11)) #Apaga/Muda a cor na parte de baixo da tela Box(19,1,24,80, 15) #Desenha os discos for pos_x in range(1,4): col = 26 * pos_x - 23 lin = len(TORRE[pos_x]) nd = 9-(10-lin) for y in range(lin): screen.addstr(17-y, col, DISCO[TORRE[pos_x][nd-y]], curses.color_pair(COR[pos_x][nd-y])) pause(0.03) def ENCERRA(abortado): if abortado: screen.addstr(24, 1, ' Jogo abortado... ', curses.color_pair(12) | curses.A_BOLD) pause(2) else: screen.addstr(24, 1, ' Meus parabéns... você conseguiu!!!', curses.color_pair(12) | curses.A_BOLD) pause(.5) screen.getch() #Restaura a cor do terminal screen.refresh() screen.clear() screen.keypad(False) curses.nocbreak() curses.echo() curses.endwin() sys.exit(0) def main(): n_mov = 0 #Imprimi a tela de abertura display_tela() autor() pause(3) ''' # Fica piscando a tela (mudando de cor) for i in range(6): pause(.3) curses.init_pair(11, curses.COLOR_GREEN, curses.COLOR_WHITE) pause(.3) curses.init_pair(11, curses.COLOR_BLUE, curses.COLOR_WHITE) ''' display_tela() while True: # Desenha os botoes bt_solto(1) bt_solto(2) bt_solto(3) screen.addstr(24, 1, (' ' * 80), curses.color_pair(12)) screen.addstr(24, 63, 'Movimentos: %5i' % n_mov, curses.color_pair(12) | curses.A_BOLD) #Pede para o usuario fazer o movimento screen.addstr(24, 1, ' Entre com o nº da torre de origem ', curses.color_pair(12) | curses.A_BOLD) origem = Hprompt() if origem == 0: continue bt_press(origem) if TORRE[origem] == []: # Torre vazia curses.beep() screen.addstr(24, 1, ' Esta torre esta vazia... ', curses.color_pair(12) | curses.A_BOLD) pause(2) continue screen.addstr(24, 1, ' Entre com o nº da torre de destino', curses.color_pair(12) | curses.A_BOLD) destino = Hprompt() if destino == 0: continue bt_press(destino) pause(.1) if destino == origem: curses.beep() continue # Verifica se o movimento e valido if TORRE[origem] > TORRE[destino] and TORRE[destino] != []: curses.beep() screen.addstr(24, 1, ' Movimento ilegal... ', curses.color_pair(12) | curses.A_BOLD) pause(2) continue #Move o disco de uma torre para a outra #Apaga o disco col = 26 * origem - 23 lin = 18 - len(TORRE[origem]) screen.addstr(lin, col, " "*10 + unichr(c_178) + " "*10, curses.color_pair(11)) n_disco = TORRE[origem][0] TORRE[origem] = TORRE[origem][1:] TORRE[destino] = [n_disco] + TORRE[destino] cor_disco = COR[origem][0] COR[origem] = COR[origem][1:] COR[destino] = [cor_disco] + COR[destino] #Desenha o disco col = 26 * destino - 23 lin = 18 - len(TORRE[destino]) screen.addstr(lin, col, DISCO[n_disco], curses.color_pair(cor_disco)) n_mov = n_mov + 1 #Verifica se chegou no fim do jogo if len(TORRE[pos_1]) == N_DISCOS or len(TORRE[pos_2]) == N_DISCOS: ENCERRA(False) if __name__ == '__main__': try: curses.wrapper(main()) except KeyboardInterrupt: curses.endwin() # sys.exit(main())
Conversor de Temperaturas Kelvin Celsius e Fahrenheit
Troca de wallpaper temporizado para LXDE
Instalar e Configurar o Slackware Linux em 2025
Como configurar os repositórios do apt no Debian 12 em 2025
Passkeys: A Evolução da Autenticação Digital
Instalação de distro Linux em computadores, netbooks, etc, em rede com o Clonezilla
Configurando o Conky para iniciar corretamente no sistema
3 configurações básicas que podem melhorar muito a sua edição pelo editor nano
Como colorir os logs do terminal com ccze
Instalação Microsoft Edge no Linux Mint 22
Como configurar posicionamento e movimento de janelas no Lubuntu (Openbox) com atalhos de teclado
Ingress NGINX Controller CVSS base score of 9.8 (2)
Impossível corrigir problemas, você manteve (hold) pacotes quebrados. (2)
Linux Mint não conecta Wi-Fi sem fio (18)