O Barqueiro (versão 2.0)

Publicado por Washington Luis de O Santos (última atualização em 23/09/2020)

[ Hits: 2.352 ]

Download O Barqueiro_2.0.zip




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/

  



Esconder código-fonte

#!/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 ) &#9484; &#9472; &#9488;
# Chr( 179 ) + Chr(  32 ) + Chr( 179 ) &#9474;   &#9474;
# Chr( 192 ) + Chr( 196 ) + Chr( 217 ) &#9492; &#9472; &#9496;

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()


Scripts recomendados

Backup em Python

Fazendo processos rodarem em background

Calcular aproximação de raiz quadrada

Contagem

Cria no fluxbox um menu para mudar o wallpaper


  

Comentários
[1] Comentário enviado por maurixnovatrento em 24/09/2020 - 13:29h


Bem legal. Muito bom.

___________________________________________________________
[code]Conhecimento não se Leva para o Túmulo.
https://github.com/MauricioFerrari-NovaTrento [/code]


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts