O Barqueiro (versão 2.0)
Publicado por Washington Luis de O Santos (última atualização em 23/09/2020)
[ Hits: 2.320 ]
Esta é uma nova versão que foi bem melhorada com a eliminação do recurso de threading que na versão 1.0 do prg ( ver link: https://www.vivaolinux.com.br/script/O-Barqueiro/ ) executava a rotina water_display() de tempo em tempo para simular o movimento da água.
Infelizmente eu descobri depois de publicado a versão 1.0 que esse recurso sob certas circunstâncias fazia o programa ficar todo maluco. Por isso eu peço desculpas a vocês e estou publicando esta nova versão.
Arquivos zipados incluídos no pacote:
* LEIAME.txt --> este texto
* o_barqueiro-2.0.py --> prg
* obarqueiro.png --> ícone do prg
* O Barqueiro.desktop --> edite este arquivo, coloque o caminho onde foi salvo o prg e o ícone e copie ele dentro da pasta "Área de Trabalho" do KDE, para criar um atalho.
Novamente... não deixe seu barco afundar, você só pode levar um passageiro de cada vez, mas tem um porém, você não pode deixar o Lobo sozinho com a Cabra porque ele vai comer ela e nem pode deixar a Cabra sozinha com o Pasto porque é ele que será comido. Resumindo, deem seus pulos e aproveitem para aprender mais um pouquinho sobre o módulo "ncurses" e o Python.
Para selecionar o passageiro use as letras L, C e P.
A tecla [ Esc ] aborta o jogo.
A tecla [ F1 ] apresenta a tela do autor e qualquer outra tecla faz o barco movimentar.
Então é isso... divirtam-se, deem um joinha se gostaram e vejam os outros programas no link: https://www.vivaolinux.com.br/~WashingtonLuis/scripts/
#!/usr/bin/env python3 # -*- coding:UTF-8 -*- ''' O B A R Q U E I R O version 2.0 - Program Copyright (c) 2019-2020 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. Taubaté - SP, 16 de setembro de 2020 ''' import sys import time import curses import os #import tempfile from random import randint # janela principal screen = curses.initscr() # tamanho da janela principal screen_x, screen_y = screen.getmaxyx() if screen_x < 24 or screen_y < 80: screen.clear() curses.endwin() print('Tamanho atual do terminal: {} x {}'.format(screen_x, screen_y)) print('\nO seu terminal tem que ter no minimo 24 linhas por 80 colunas.\n') print('Reajuste o tamanho do seu terminal para poder jogar... \n') sys.exit(0) screen.keypad(True) #screen.notimeout(False) curses.cbreak() # Não retorna caracteres na tela curses.noecho() # esconde o cursor do mouse e do terminal curses.curs_set(0) # move o cursor para a posicao 0,0 #screen.move(0,0) # limpa a tela screen.clear() #screen.set_title('O BARQUEIRO') curses.mousemask(curses.ALL_MOUSE_EVENTS) # atualiza a tela automaticamente mais causa perda de performance # pode ser usado no lugar das chamadas da funcao screen.refresh() #screen.immedok(True) # iniciando cores curses.start_color() curses.use_default_colors() # Define cor da tela de abertura (autor) curses.init_pair( 1, curses.COLOR_GREEN, curses.COLOR_WHITE) # Define cor dos textos (autor) e box curses.init_pair( 2, curses.COLOR_BLUE, curses.COLOR_WHITE) # Define cor da Versão (autor) e sombra curses.init_pair( 3, curses.COLOR_BLACK, curses.COLOR_WHITE) # Define cor da Barra de Status curses.init_pair( 4, curses.COLOR_WHITE, curses.COLOR_CYAN) # Define cor da mensagem de error (box) curses.init_pair( 5, curses.COLOR_RED, curses.COLOR_WHITE) # cor das letras LCP curses.init_pair( 6, curses.COLOR_GREEN, curses.COLOR_WHITE) # cor da agua curses.init_pair( 7, curses.COLOR_WHITE, curses.COLOR_BLUE) # cor das colunas dos cais curses.init_pair( 8, curses.COLOR_RED, curses.COLOR_BLUE) # 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 = chr( 32) # espaço c_177 = chr(9619) # bloco c_179 = chr(9474) c_191 = chr(9488) c_192 = chr(9492) c_196 = chr(9472) c_217 = chr(9496) c_218 = chr(9484) # Define Constantes K_CTRL_Q = 17 K_ESC = 27 class Box: def Fill(self,lt,ce,lb,cd, cor): #Desenha uma caixa sem bordas e sem sombras for x in range(lt,lb+1): self.addstr(x, ce, c_032 * (cd-ce+1), curses.color_pair(cor)) def Display(self,lt,ce,lb,cd,cor): #Desenha uma caixa com bordas e sem sombras __class__.Fill(self,lt,ce,lb,cd,cor) self.addstr(lt, ce, c_196 * (cd-ce), curses.color_pair(cor)) self.addstr(lt, ce, c_218, curses.color_pair(cor)) self.addstr(lt, cd, c_191, curses.color_pair(cor)) self.addstr(lb, ce, c_196 * (cd-ce), curses.color_pair(cor)) self.addstr(lb, ce, c_192, curses.color_pair(cor)) self.addstr(lb, cd, c_217, curses.color_pair(cor)) for x in range(lt+1,lb): self.addstr(x, ce, c_179, curses.color_pair(cor)) self.addstr(x, cd, c_179, curses.color_pair(cor)) def Shadow(self,lt,ce,lb,cd,cor): #Desenha uma caixa com bordas e com sombras __class__.Display(self,lt,ce,lb,cd,cor) #Desenha a Sombra da Caixa for x in range(lt+1,lb+1): self.addstr(x, cd+1, c_032, curses.color_pair(0)) self.addstr(lb+1, ce+1, c_032 * (cd-ce+1), curses.color_pair(0)) def Beep(duration = .1, frequency = 850): #curses.beep() #os.system('beep -f %s -l %s' % (frequency,duration)) #os.system('beep -f 555 -l 460') # Observação: # O play é um utilitário de linha de comando (shell), para poder usa-lo # instale o Pacote sox atraves do apt-get no Debian # Para testar o play direto no bash copie e cole a linha abaixo: #play --no-show-progress --null -t alsa --channels 1 synth .5 sine 1000 try: pass os.system('play --no-show-progress --null -t alsa --channels 1 synth %s sine %f' % (duration, frequency)) except: pass def pause(tempo): # Atualiza a tela screen.refresh() # Pausa por um tempo time.sleep(tempo) # Limpa qualquer outra coisa que o usuário tenha digitado curses.flushinp() def autor(): # Mostra a tela de abertura # Obs: As 'fontes' usadas foram criadas através do programa # figlet - http://www.figlet.org/ # digite o cmd abaixo para ver as fontes disponiveis # showfigfonts # digite o cmd abaixo para criar o arquivo com o texto # figlet -f big "O Barqueiro" >> o_barqueiro.txt # figlet -f small "Versao 2.0" >> o_barqueiro.txt #win1 = curses.newwin(nlines, ncols, begin_y, begin_x) win1 = curses.newwin( 19, 60, 2, 10) #win1.box() Box.Display(win1, 0, 0, 17, 57, 2) win1.addstr( 2, 2, ' ___ ____ _ ', curses.color_pair(1) | curses.A_BOLD) win1.addstr( 3, 2, ' / _ \ | __ ) __ _ _ __ __ _ _ _ ___(_)_ __ ___ ', curses.color_pair(1) | curses.A_BOLD) win1.addstr( 4, 2, '| | | | | _ \ / _` | \'__/ _` | | | |/ _ \ | \'__/ _ \ ', curses.color_pair(1) | curses.A_BOLD) win1.addstr( 5, 2, '| |_| | | |_) | (_| | | | (_| | |_| | __/ | | | (_) |', curses.color_pair(1) | curses.A_BOLD) win1.addstr( 6, 2, ' \___/ |____/ \__,_|_| \__, |\__,_|\___|_|_| \___/ ', curses.color_pair(1) | curses.A_BOLD) win1.addstr( 7, 2, ' |_| ', curses.color_pair(1) | curses.A_BOLD) win1.addstr( 8, 10, '__ __ __ ___ __ ', curses.color_pair(1) | curses.A_BOLD) win1.addstr( 9, 10, '\ \ / /__ _ _ ___ __ _ ___ |_ ) / \ ', curses.color_pair(1) | curses.A_BOLD) win1.addstr(10, 10, ' \ V / -_) \'_(_-</ _` / _ \ / / | () |', curses.color_pair(1) | curses.A_BOLD) win1.addstr(11, 10, ' \_/\___|_| /__/\__,_\___/ /___(_)__/ ', curses.color_pair(1) | curses.A_BOLD) win1.addstr(14, 5, 'Autor: Washington Luis de Oliveira Santos', curses.color_pair(2)) win1.addstr(15, 5, 'End. : Av. Campinas, 749 - Chácara do Visconde', curses.color_pair(2)) win1.addstr(16, 18, 'Taubaté - São Paulo', curses.color_pair(2)) win1.refresh() def ENCERRA(): #Restaura a cor do terminal screen.refresh() screen.clear() curses.nocbreak() screen.keypad(False) curses.echo() curses.endwin() sys.exit(0) def savescreen(): # Salva o estado da tela em um arquivo chamado 'screendat.tmp' with open('screendat.tmp', mode='wb+') as f: screen.putwin(f) def restscreen(): # Restaura o estado da tela lendo 'screendat.tmp' with open('screendat.tmp', mode='rb+') as f: f.seek(0) screen = curses.getwin(f) screen.refresh() os.remove('screendat.tmp') def water_display(l_ini=13, l_end=20): for line in range(l_ini, l_end-1): water_line = '' while len(water_line) <= 80: water_line += ('^' * randint(0,6)) + (' ' * randint(1,6)) screen.addstr(line, 0, water_line[:80], curses.color_pair(7)) screen.addstr(l_end-1, 0, ('~' * 80), curses.color_pair(7)) def chk_cais(cais): cais = ''.join(cais) quem = 'O Lobo' if cais == 'LC ' else 'A Cabra' if cais == ' CP' else '' #'ninguem' vitima = 'a Cabra' if cais == 'LC ' else 'o Pasto' if cais == ' CP' else '' #'nada ' if quem + vitima: Box.Shadow(screen, 8,23,14,55, 5) screen.addstr(10, 26, 'Sinto muito...', curses.color_pair(5)) screen.addstr(11, 26, quem + ' comeu ' + vitima, curses.color_pair(5)) pause(1) return True def chk_lotacao(carga): if carga.count(' ') == 1: # Apaga o 'Barco' na posição acima do rio screen.addstr(10,38, ' ', curses.color_pair(1)) # f branco screen.addstr(11,38, ' ', curses.color_pair(1)) # f branco # Movimenta o 'Barco' para o fundo do rio for line in range(13,18): for _ in range(5): water_display() screen.addstr(line+0,37, ' + ', curses.color_pair(8)) screen.addstr(line+1,37, '\^^^/', curses.color_pair(8) | curses.A_UNDERLINE) pause(.2) Box.Shadow(screen, 8,23,14,55, 5) screen.addstr(10, 26, 'Sinto muito... Lotado', curses.color_pair(5)) screen.addstr(11, 26, 'O Barco afundou...' , curses.color_pair(5)) return True def chk_fim(cais_2): if ''.join(cais_2) == 'LCP': Box.Shadow(screen, 8,23,14,55, 2) screen.addstr(10, 26, 'Muito Bem !!!', curses.color_pair(2)) return True def embarque(cais, carga, x_cais, x_carga): if ''.join(cais) != ' ': key = inkey('Por no Barco?') if key == chr(K_ESC): Box.Shadow(screen, 8,23,14,55, 5) screen.addstr(10, 26, 'Jogo abortado...', curses.color_pair(5)) return True elif key != chr(32): try: i = cais.index(key) cais [i] = ' ' carga [i] = key except: pass screen.addstr(10, x_cais, ''.join(cais), curses.color_pair(6) | curses.A_BOLD) screen.addstr(10, x_carga, ''.join(carga), curses.color_pair(6) | curses.A_BOLD) def desembarque(cais, carga, x_cais, x_carga): if ''.join(carga) != ' ': key = inkey('Tirar do Barco?') if key == chr(K_ESC): Box.Shadow(screen, 8,23,14,55, 5) screen.addstr(10, 26, 'Jogo abortado...', curses.color_pair(5)) return True elif key != chr(32): try: i = carga.index(key) cais [i] = key carga [i] = ' ' except: pass screen.addstr(10, x_cais, ''.join(cais), curses.color_pair(6) | curses.A_BOLD) screen.addstr(10, x_carga, ''.join(carga), curses.color_pair(6) | curses.A_BOLD) def navegar(carga, barco, flag): global nv #numero de viagens x = [i for i in range(7,67)] if flag: x.reverse() aux = ' '+''.join(carga)+' ' for col in x: water_display() screen.addstr(10, col, aux, curses.color_pair(6) | curses.A_BOLD) screen.addstr(11, col, barco, curses.color_pair(5) | curses.A_BOLD) pause(.2) if col == 37 and chk_lotacao(carga): return True nv += 1 def inkey(msg): global nv #numero de viagens #msg = (msg + ' ' * 10) #Limpa a Barra de Status screen.addstr(23, 0, c_032 * 80, curses.color_pair(4)) screen.addstr(23, 1, msg, curses.color_pair(4) | curses.A_BOLD | curses.A_BLINK) screen.addstr(23,62, 'Nº de Viagens: {:2} '.format(nv), curses.color_pair(4) | curses.A_BOLD) # O comando abaixo faz com que a chamada a getch() retorne depois # de um tempo simulando a função inkey(<tempo>) do CLIPPER curses.halfdelay(4) while True: water_display() key = screen.getch() if key in (curses.KEY_F1, ord('h'), ord('H')): # help acionado savescreen() autor() screen.addstr(23, 1, 'Tecle algo para sair...', curses.color_pair(4) | curses.A_BOLD) while True: key = screen.getch() if key != -1:break # Fica piscando a tela (mudando de cor) curses.init_pair(1, randint(0, 7), curses.COLOR_WHITE) screen.refresh() restscreen() #Limpa a Barra de Status screen.addstr(23, 0, c_032 * 80, curses.color_pair(4)) screen.addstr(23, 1, msg, curses.color_pair(4) | curses.A_BOLD | curses.A_BLINK) continue elif key != -1: break screen.addstr(23, 1, ' '*15, curses.color_pair(4)) curses.cbreak() #cancela o halfdelay return chr(key).upper() def gameloop(): global nv #numero de viagens nv = 0 # Define Variaveis usadas no jogo cais_1 = ['L','C','P'] cais_2 = [' ',' ',' '] carga = [' ',' ',' '] barco = ' \___/ ' #Cria um quadro na tela com char azul e fundo branco Box.Display(screen,0,0,23,79, 2) screen.addstr( 2,30, 'O B A R Q U E I R O', curses.color_pair(2) | curses.A_BOLD) screen.addstr( 3,42, 'ver. 2.0', curses.color_pair(2)) screen.addstr(10, 0, '[' + ' '*78 + ']', curses.color_pair(5)) screen.addstr(10, 3, ''.join(cais_1), curses.color_pair(6) | curses.A_BOLD) screen.addstr(11, 0, '|//////' + barco + ' '*59 + '//////|', curses.color_pair(5)) screen.addstr(12, 0, ('~' * 80), curses.color_pair(7)) screen.addstr(12, 0, '|', curses.color_pair(8) | curses.A_UNDERLINE) screen.addstr(12, 6, '|', curses.color_pair(8) | curses.A_UNDERLINE) screen.addstr(12,73, '|', curses.color_pair(8) | curses.A_UNDERLINE) screen.addstr(12,79, '|', curses.color_pair(8) | curses.A_UNDERLINE) while True: if desembarque(cais_1, carga, 3, 9): break if embarque(cais_1, carga, 3, 9): break # Movimenta o barco de C1 para C2 if navegar(carga, barco, flag=0): break if chk_cais(cais_1): break if desembarque(cais_2, carga, 74, 68): break if chk_fim(cais_2): break if embarque(cais_2, carga, 74, 68): break # Movimenta o barco de C2 para C1 if navegar(carga, barco, flag=1): break if chk_cais(cais_2): break return def main(): while True: screen.clear() #Apresenta a tela de abertura screen.addstr(0, 0, ('~' * 80), curses.color_pair(7)) for _ in range(10): water_display(1,24) screen.refresh() autor() # Fica piscando a tela (mudando de cor) curses.init_pair(1, randint(0, 7), curses.COLOR_WHITE) pause(.7) screen.clear() gameloop() # Verifica se quer brincar novamente screen.addstr(13, 26, 'Quer tentar outra vez? (S/N)', curses.color_pair(2)) pause(.1) key = screen.getch() if key not in (ord('S'), ord('s')): ENCERRA() if __name__ == '__main__': try: curses.wrapper(main()) except KeyboardInterrupt: ENCERRA()
Cup - um gerenciador de notas simples
Script para fazer o Scroll Lock funcionar no Linux
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Efeito "livro" em arquivos PDF
Como resolver o erro no CUPS: Unable to get list of printer drivers
Flatpak: remover runtimes não usados e pacotes
Mudar o gerenciador de login (GDM para SDDM e vice-versa) - parte 2
Como atualizar o Debian 8 para o 10 (10)
Dica sobre iptables ACCEPT e DROP (6)
NGNIX - Aplicar SNAT para evitar roteamento assimetrico (29)
[Python] Automação de scan de vulnerabilidades
[Python] Script para analise de superficie de ataque
[Shell Script] Novo script para redimensionar, rotacionar, converter e espelhar arquivos de imagem
[Shell Script] Iniciador de DOOM (DSDA-DOOM, Doom Retro ou Woof!)
[Shell Script] Script para adicionar bordas às imagens de uma pasta