Genius - jogo de memória
Publicado por Washington Luis de O Santos (última atualização em 14/02/2020)
[ Hits: 6.473 ]
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/
#!/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 ) ┌ ─ ┐
# 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)
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()
ISOsync_pt-BR.py - Um Baixador Automático de ISOs de Sabayon, escrito em Python
run_update - Atualizador de Sabayon
Calculadora de funções do 1º grau
Nenhum comentário foi encontrado.
Monitorando o Preço do Bitcoin ou sua Cripto Favorita em Tempo Real com um Widget Flutuante
IA Turbina o Desktop Linux enquanto distros renovam forças
Como extrair chaves TOTP 2FA a partir de QRCODE (Google Authenticator)
Ativando e usando "zoom" no ambiente Cinnamon
Vídeo Nostálgico de Instalação do Conectiva Linux 9
Como realizar um ataque de força bruta para desobrir senhas?
Estou tentando ser legalista, mas tá complicado! (8)
Thinkpads são bons mesmo ?! (0)
Queda no serviços da Cloudflare, alguns sites estão fora do ar. (1)









