O Barqueiro (versão 2.0)
Publicado por Washington Luis de O Santos (última atualização em 23/09/2020)
[ Hits: 2.575 ]
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()
Mensagem Randômica ao Conectar via SSH
Adicione a opção Redimensionar e rotacionar imagens ao Nautilus
Exercício com números randômicos - randint
Calcula quantos dias uma pessoa viveu
IA Turbina o Desktop Linux enquanto distros renovam forças
Como extrair chaves TOTP 2FA a partir de QRCODE (Google Authenticator)
Linux em 2025: Segurança prática para o usuário
Desktop Linux em alta: novos apps, distros e privacidade marcam o sábado
IA chega ao desktop e impulsiona produtividade no mundo Linux
Como instalar o repositório do DBeaver no Ubuntu
Como instalar o Plex Media Server no Ubuntu
Digitando underscore com "shift" + "barra de espaços"
Como ativar a lixeira e recuperar aquivos deletados em um servidor Linux
Como mudar o nome de dispositivos Bluetooth via linha de comando
Assinador JNLP do Site Portal da Nota Fiscal Eletrônica (4)
Warcraft II Remastered no Linux? (3)









