Genius - jogo de memória

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

[ Hits: 6.008 ]

Download genius-1.0.py




Este programa simula um jogo de memória eletrônico, que nos Estados Unidos é chamado de Simon e aqui no Brasil foi batizado de Genius pela fabricante de brinquedos Estrela S/A.

O brinquedo buscava estimular a memorização de cores e sons. Com um formato semelhante a um OVNI, possuía botões coloridos que emitiam sons harmônicos e se iluminavam em sequência. Cabia aos jogadores repetir o processo sem errar.

O Genius original possuía três jogos diferentes e quatro níveis de dificuldade. Para mais detalhes veja o link: https://pt.wikipedia.org/wiki/Genius_(jogo)

Eu não quis complicar muito o programa. O importante é que já da para brincar e ir aprendendo um pouco mais sobre Python e ncurses e que vocês entenda a lógica.

Observações:

- Para rodar o programa use o Python3
- No Debian, instale o pacote " sox " através do apt-get para poder reproduzir os beeps através do " play "
- O play é um utilitário de linha de comando (shell), para testar o play direto no terminal copie e cole a linha abaixo:

play --no-show-progress --null -t alsa --channels 1 synth .5 sine 1000

Bom... é isso então. Novamente se divirtam e dêem 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 -*-

'''
   Genius version 1.0 - Program
   
   blinken - KDE version of the Simon electronic memory game
   
   Copyright (c) 2018-2019 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, 14 de outubro de 2019
'''

import sys
import time
import curses
import random
import os

# janela principal
screen = curses.initscr()

# tamanho da janela principal
screen_x, screen_y = screen.getmaxyx()

if screen_x < 24 or screen_y < 81:
   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 81 colunas.\n')
   print('Reajuste o tamanho do seu terminal para poder jogar... \n')
   sys.exit(0)


screen.notimeout(False)
screen.keypad(True)
screen.clear()

# atualiza a tela automaticamente mais causa perda de performance
# pode ser usado no lugar das chamadas da funcao  screen.refresh()
#screen.immedok(True)

#screen.set_title('G E N I U S')

curses.mousemask(curses.ALL_MOUSE_EVENTS)

# iniciando cores
curses.start_color()
curses.use_default_colors()

# Define as cores dos 'botãozões'
curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_GREEN)
curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_YELLOW)
curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_RED)
curses.init_pair(4, curses.COLOR_WHITE, curses.COLOR_BLUE)

# Define cor do box lateral
curses.init_pair(10, curses.COLOR_YELLOW, curses.COLOR_BLACK)
curses.init_pair(11, curses.COLOR_WHITE, curses.COLOR_BLACK)

# Define cor dos textos
curses.init_pair(12, curses.COLOR_BLUE, curses.COLOR_WHITE)

# Define cor da Barra de Status
curses.init_pair(13, curses.COLOR_WHITE, curses.COLOR_CYAN)

# Define cor da tela de abertura
curses.init_pair(14, curses.COLOR_GREEN, curses.COLOR_WHITE)

# Define cor da mensagem de error
curses.init_pair(15, curses.COLOR_RED, curses.COLOR_WHITE)

curses.cbreak()

# Não retorna caracteres na tela
curses.noecho()

# move o cursor para a posicao 0,0
#screen.move(0,0)

# esconde o cursor do mouse e do terminal
curses.curs_set(0)

# Define Constantes
K_CTRL_Q = 17
K_ESC    = 27
K_1      = 49
K_2      = 50
K_3      = 51
K_4      = 52

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


class Box:

   def Fill(lt,ce,lb,cd, cor):
      #Desenha uma caixa sem bordas e sem sombras
      for x in range(lt,lb+1):
         screen.addstr(x, ce, c_032 * (cd-ce+1), curses.color_pair(cor))

   def Display(lt,ce,lb,cd,cor):
      #Desenha uma caixa com bordas e sem sombras
      
      __class__.Fill(lt,ce,lb,cd,cor)

      screen.addstr(lt, ce, c_196 * (cd-ce), curses.color_pair(cor))
      screen.addstr(lt, ce, c_218, curses.color_pair(cor))
      screen.addstr(lt, cd, c_191, curses.color_pair(cor))
      
      screen.addstr(lb, ce, c_196 * (cd-ce), curses.color_pair(cor))
      screen.addstr(lb, ce, c_192, curses.color_pair(cor))
      screen.addstr(lb, cd, c_217, curses.color_pair(cor))

      for x in range(lt+1,lb):
         screen.addstr(x, ce, c_179, curses.color_pair(cor))
         screen.addstr(x, cd, c_179, curses.color_pair(cor))

   def Shadow(lt,ce,lb,cd,cor):
      #Desenha uma caixa com bordas e com sombras
      
      __class__.Display(lt,ce,lb,cd,cor)

      #Desenha a Sombra da Caixa
      for x in range(lt+1,lb+1):
         screen.addstr(x, cd+1, c_032, curses.color_pair(0))
      
      screen.addstr(lb+1, ce+1, c_032 * (cd-ce+1), curses.color_pair(0))


def Beep(duration = .1, frequency = 3000):
   #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:
      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 "G e n i u s" >> genius.txt 
   # figlet -f small "Versao 1.0" >> genius.txt 

   Box.Shadow(1,10,20,68,12)

   screen.addstr( 4, 18, '  _____                  _                ', curses.color_pair(14) | curses.A_BOLD)
   screen.addstr( 5, 18, ' / ____|                (_)               ', curses.color_pair(14) | curses.A_BOLD)
   screen.addstr( 6, 18, '| |  __    ___   _ __    _   _   _   ___  ', curses.color_pair(14) | curses.A_BOLD)
   screen.addstr( 7, 18, '| | |_ |  / _ \ | \'_ \  | | | | | | / __|', curses.color_pair(14) | curses.A_BOLD)
   screen.addstr( 8, 18, '| |__| | |  __/ | | | | | | | |_| | \__ \\', curses.color_pair(14) | curses.A_BOLD)
   screen.addstr( 9, 18, ' \_____|  \___| |_| |_| |_|  \__,_| |___/ ', curses.color_pair(14) | curses.A_BOLD)

   screen.addstr(11, 20, '__   __           __         _   __  ', curses.color_pair(14) | curses.A_BOLD)
   screen.addstr(12, 20, '\ \ / /__ _ _ ___ __ _ ___  / | /  \ ', curses.color_pair(14) | curses.A_BOLD)
   screen.addstr(13, 20, ' \ V / -_) \'_(_-</ _` / _ \ | || () |', curses.color_pair(14) | curses.A_BOLD)
   screen.addstr(14, 20, '  \_/\___|_| /__/\__,_\___/ |_(_)__/ ', curses.color_pair(14) | curses.A_BOLD)
                                     
   screen.addstr(17, 15, 'Autor: Washington Luis de Oliveira Santos', curses.color_pair(12))
   screen.addstr(18, 15, 'End. : Av. Campinas, 749 - Chácara do Visconde', curses.color_pair(12))
   screen.addstr(19, 28, 'Taubaté - São Paulo', curses.color_pair(12))


def inkey():

   while True:

      try:
         key = screen.getch()

         if key == curses.KEY_MOUSE:
            # botao esquerdo do mouse foi pressionado
            _, mx, my, _, _ = curses.getmouse()
            #screen.addstr (22, 1,"my = %i | mx = %i" % (my, mx))

            # Verifica em que posicao foi pressionado
            #        linhas            colunas 
            if   ( 4 <= my <= 10) and ( 4 <= mx <= 24):
               return 1

            elif ( 4 <= my <= 10) and (26 <= mx <= 46):
               return 2

            elif (12 <= my <= 18) and ( 4 <= mx <= 24):
               return 3

            elif (12 <= my <= 18) and (26 <= mx <= 46):
               return 4

      except curses.error:
         pass


      if key in (K_ESC, K_CTRL_Q, ord('q'), ord('Q')):
         # encerra o programa
         screen.addstr(23, 1, 'Jogo abortado...       ', curses.color_pair(13) | curses.A_BOLD)
         pause(3)
         ENCERRA()

      elif key in (curses.KEY_F1, ord('h'), ord('H')):
         # help acionado
         return 0

      elif key == K_1:
         return 1

      elif key == K_2:
         return 2

      elif key == K_3:
         return 3

      elif key == K_4:
         return 4


def showBotao(n, cor=0):
   #Desenha o botãozão
   botao = {1:(4,4,10,24), 2:(4,26,10,46), 3:(12,4,18,24), 4:(12,26,18,46)}
   label = {1:(7,13), 2:(7,35), 3:(15,13), 4:(15,35)}
   beep  = [500, 1100, 700, 900]

   Box.Display(*botao[n], cor=cor)

   screen.addstr(label[n][0], label[n][1], ' %s ' % n, curses.color_pair(12))

   if cor: Beep(.12, beep[n-1])


def display_tela():
   #Cria um quadro na tela com char azul e fundo branco
   Box.Display(0,0,23,79,12)

   Box.Display(1,50,22,77,11)
   screen.addstr( 3, 55, 'Genius version 1.0', curses.color_pair(10))

   screen.addstr( 6, 54, 'by: Washington Luis', curses.color_pair(10))
   
   screen.addstr( 9, 52, 'My version of the Simon', curses.color_pair(10))
   screen.addstr(11, 53, 'electronic memory game', curses.color_pair(10))
   
   screen.addstr(14, 56, 'This program is', curses.color_pair(10))
   screen.addstr(16, 57, 'free software', curses.color_pair(10))

   screen.addstr(19, 52, 'Copyright (c) 2018-2019', curses.color_pair(10))

   #Escreve o titulo
   screen.addstr(2, 20, 'G E N I U S', curses.color_pair(12) | curses.A_BOLD)

   #Desenha os botões
   for n in (1,2,3,4):
      showBotao(n, n)

   #Limpa a Barra de Status
   screen.addstr(23, 0, c_032 * 80, curses.color_pair(13))
   pause(.01)

def ENCERRA():
   #Restaura a cor do terminal
   screen.refresh()
   screen.clear()
   screen.keypad(False)
   curses.nocbreak()
   curses.echo()
   curses.endwin()
   sys.exit(0)


def gerasequencia(size=10):
   return ''.join(random.choice('1234') for _ in range(size))

def main():
   msg   = {1:'Botão verde   ', 2:'Botão amarelo ', 3:'Botão vermelho', 4:'Botão azul    '}

   #Imprimi a tela de abertura
   display_tela()

   autor()

   for _ in range(5):
      # Fica piscando a tela (mudando de cor)
      curses.init_pair(14, random.randint(0, 7), curses.COLOR_WHITE)
      pause(.7)

   niveis      = 32
   seq_pc      = gerasequencia(niveis)
   seq_user    = ''
   dificuldade = 1

   display_tela()

   while True:

      # mostra a sequencia gerada pelo computador (só pra depuração)
      #screen.addstr(21, 1, 'sequencia -> %s    ' % seq_pc[:dificuldade], curses.color_pair(12))

      #Limpa a Barra de Status
      screen.addstr(23, 0, c_032 * 80, curses.color_pair(13))
      screen.addstr(23, 61, 'Dificuldade: %5i ' % dificuldade, curses.color_pair(13) | curses.A_BOLD)
      pause(1)

      for n in range(dificuldade):
         showBotao(int(seq_pc[n]), 0)
         pause(.2)
         showBotao(int(seq_pc[n]), int(seq_pc[n]))
         pause(.2)


      while True:

         botao = inkey()

         if   botao == 0:
            # help acionado
            autor()

            screen.addstr(23, 1, 'Tecle algo para sair...', curses.color_pair(13) | 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(7)

            while True:
               key = screen.getch()
               if key != -1:break
               # Fica piscando a tela (mudando de cor)
               curses.init_pair(14, random.randint(0, 7), curses.COLOR_WHITE)
               screen.refresh()

            display_tela()
            #continue
            break

         elif 1 <= botao <= 4:
            #Aciona o botãozão
            screen.addstr(23, 1, msg[botao], curses.color_pair(13) | curses.A_BOLD)
            showBotao(botao, 0)
            pause(.01)
            showBotao(botao, botao)
            pause(.01)

            seq_user += str(botao)

            if seq_user == seq_pc:
               Box.Shadow(9,23,15,55,12)
               
               screen.addstr(11, 25, 'Parabéns!!! Você conseguiu...', curses.color_pair(12))
               screen.addstr(13, 25, 'Quer Jogar Novamente? (S/N) ', curses.color_pair(12))
               pause(.01)
               key = screen.getch()

               if key in (ord('S'), ord('s')):
                  seq_pc      = gerasequencia(niveis)
                  seq_user    = ''
                  dificuldade = 1
                  display_tela()
                  break
               else:
                  ENCERRA()

            elif seq_user == seq_pc[:len(seq_user)]:
               if len(seq_user) == dificuldade:
                  screen.addstr(23, 16, 'OK  Próximo nivel...', curses.color_pair(13) | curses.A_BOLD)
                  pause(2)
                  seq_user     = ''
                  dificuldade += 1
                  break

               else:
                  screen.addstr(23, 16, 'OK', curses.color_pair(13) | curses.A_BOLD)
                  pause(.05)

            else:
               Beep(.2, 2000)
               Beep(.2, 1600)
               Beep(.2, 2200)
               screen.addstr(23, 16, 'NOK', curses.color_pair(13) | curses.A_BOLD)
               Box.Shadow(9,23,15,55,15)
               
               screen.addstr(11, 26, 'Você   E R R O U ...', curses.color_pair(15) | curses.A_BLINK)
               screen.addstr(13, 26, 'Quer Jogar Novamente? (S/N)', curses.color_pair(12))
               pause(.01)
               key = screen.getch()

               if key in (ord('S'), ord('s')):
                  seq_pc      = gerasequencia(niveis)
                  seq_user    = ''
                  dificuldade = 1
                  display_tela()
                  break
               else:
                  ENCERRA()


if __name__ == '__main__':
   try:
      curses.wrapper(main())
   except KeyboardInterrupt:
      ENCERRA()

Scripts recomendados

Memory info em python

Fatorial de um número

Cálculo do dia da Páscoa

Verificar se um número é primo

Cálculo de um número binomial


  

Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts