
Приветствую хабралюди. Я начал изучать Python курс на Coursera, решил изучить этот чудесный язык, и как 1-й проект нужно было сделать игру по мотивам «The Big Bang Theory» — «Rock-paper-scissors-lizard-Spock». Но это же первый проект, но в Python'e нумерация начинается с 0, и по этому была нулевая неделя с 0-ым проектом типа:
print "We want... a shrubbery!"
Мне захотелось большего и я решил чуток опередить график.
Сначала было яйцо, ой о чем это я, ах да о том что…
Подумав я решил сделать простенькую консольную программку, продумав логику приступил к написанию.
Для хранения жестов, и возможных использовал список вида:
gestures = {'rock': {'win': ['lizard', 'scissors']},
'paper': {'win': ['rock', 'spock']},
'scissors': {'win': ['lizard', 'paper']},
'lizard': {'win': ['paper', 'spock']},
'spock': {'win': ['rock', 'scissors']}}
Да и процес обработки вышел довольно банальный:
def process(user, comp):
global user_won, comp_won, draw, won, users, comps
users = user
comps = comp
if user == comp:
draw += 1
won = 'Draw'
return draw
if gestures.get(user):
if comp in gestures[user]['win']:
user_won += 1
won = 'User Won'
return texts(user_won, comp_won), hand_set(user, comp)
else:
comp_won += 1
won = 'Computer Won'
return texts(user_won, comp_won), hand_set(user, comp)
else:
raise Exception('Gesture not found in dict.')
За помощь с этой функцией спасибо sadovnychyi.
Думаю давать комментариев что и как не нужно.
Ну и в общем полная консольная версия:
Консольная верся игры
#!/usr/bin/python
import random
print '''
This is "Rock-paper-scissors-lizard-Spock" game
for play you must choose one of gestures(put number):
0.spock
1.scissors
2.lizard
3.paper
4.rock
'''
you_won = 0
you_luse = 0
draw = 0
def process(user, comp):
global you_won, you_luse, draw
if user == comp:
draw += 1
return 'Draw'
if gestures.get(user):
if comp in gestures[user]['win']:
you_won += 1
return 'You won!'
else:
you_luse += 1
return 'You loser :-('
else:
raise Exception('Gesture not found in dict.')
gestures = {'rock': {'win': ['lizard', 'scissors']},
'paper': {'win': ['rock', 'spock']},
'scissors': {'win': ['lizard', 'paper']},
'lizard': {'win': ['paper', 'spock']},
'spock': {'win': ['rock', 'scissors']}}
while 1:
try:
user_gest_inputed = int(raw_input('\nWrite gestures: '))
except ValueError:
print 'You must input number'
else:
if user_gest_inputed >= 5 or user_gest_inputed < 0:
print 'You input wrong number(s)'
else:
user_gest = gestures.keys()[user_gest_inputed]
print "User choise:", user_gest
comp_gest = str(random.sample(gestures.keys(), 1))
comp_gest = comp_gest[2:-2]
print "Comp choise:", comp_gest
result = process(user_gest, comp_gest)
print result
print "You won %s, lose %s and draw %s" % (you_won, you_luse, draw)
После этого я подумал, а что если сделать графику, и пальцы забились об клавиатуру в поиске методов как это сделать, и довольно быстро была обнаружена Pygame, после первого взгляда на сайт
И честно говоря я был приятно удивлен количеством не плохих игр. Так как опыт в написании программ я имел не большой, а написать хотелось быстрее и проще — я начал искать туториалы о Pygame, и этот ресурс очень помог. После переваривания инфы начался процесс написания (который не так долго продолжался, больше времени на графику затратил.
Ну что же пришло время посмотреть на
Логику определения победителя я конечно же позаимствовал из консольной версии, которая оказалось может быть еще проще, но сейчас не об этом).
Сначала был нарисован каркас в GIMPe, и добавлен оный вместе с кнопками и подсветкой, сделаными там же:
background = pygame.Surface(screen.get_size())
background = pygame.image.load("src/layout_whitout.jpg").convert()
btnRock = pygame.image.load('src/rock.png').convert_alpha()
btnPaper = pygame.image.load('src/paper.png').convert_alpha()
btnSciss = pygame.image.load('src/scissors.png').convert_alpha()
btnLizard = pygame.image.load('src/lizard.png').convert_alpha()
btnSpock = pygame.image.load('src/spock.png').convert_alpha()
lightBtn = pygame.image.load('src/supernovaBtn.png').convert_alpha()
После того как что то начало появляться нужно было сделать что бы что то и выполнялось. Подсмотрев в туториале как настроить поведение мышки, сделал подобное:
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
pos = pygame.mouse.get_pos()
# Определение координат мышки
x = pos[0]
y = pos[1]
# Если ЛКМ нажата - пеередаем координаты на выполнение у функцию, что бы определить на какую кнопку нажато
position(x, y)
mouse_click = True
print("Click ", pos, "Grid coordinates: ", x, y)
#Все тоже самое только передается при движении в функцию для создания подсветки
elif event.type == pygame.MOUSEMOTION:
pos = event.pos
x = pos[0]
y = pos[1]
blur_pos(x, y)
Здесь происходит определение на какую кнопку нажато:
def position(x, y):
comp_gest = str(random.sample(gestures.keys(), 1))
comp_gest = comp_gest[2: -2]
print "Comp choise:", comp_gest
if y > 500:
if x in range(btnRock_x, btnRock_x + 92):
user_gest = 'rock'
process(user_gest, comp_gest)
print 'User choise: rock'
elif x in range(btnPaper_x, btnPaper_x + 92):
user_gest = 'paper'
process(user_gest, comp_gest)
print 'User choise: paper' . . .
Потом еще прикрутил что бы выводило на экран очки игроков, кто выиграл и проиграл, а главное жесты рук (которые делал в blender 3d).
Версия из GUI
#!/usr/bin/python
import pygame
import random
# Initialize the game engine
pygame.init()
# Define the colors we will use in RGB format
black = [0, 0, 0]
#Dict with elems
gestures = {'rock': {'win': ['lizard', 'scissors']},
'paper': {'win': ['rock', 'spock']},
'scissors': {'win': ['lizard', 'paper']},
'lizard': {'win': ['paper', 'spock']},
'spock': {'win': ['rock', 'scissors']}}
#Score
user_won = 0
comp_won = 0
draw = 0
won = ""
#Var for visible won label
mouse_click = False
#Var for hands
users = ''
comps = ''
#Location on screen
x = 0
y = 0
#Labels
font = pygame.font.SysFont("Comic Sans MS", 18)
font_won = pygame.font.SysFont("Comic Sans MS", 32)
label_comp_score = font.render("User Win: " + str(comp_won), 1, black)
label_user_score = font.render("Comp Win: " + str(user_won), 1, black)
label_draw_score = font.render("Draw: " + str(user_won), 1, black)
label_won = font_won.render(str(won), 1, black)
# Set the height and width of the screen
size = [800, 600]
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Rock-paper-scissors-lizard-Spock game")
#Loop until the user clicks the close button.
done = False
clock = pygame.time.Clock()
#Set background picture
background = pygame.Surface(screen.get_size())
background = pygame.image.load("src/layout_whitout.jpg").convert()
#Set picture for buttons
btnRock = pygame.image.load('src/rock.png').convert_alpha()
btnPaper = pygame.image.load('src/paper.png').convert_alpha()
btnSciss = pygame.image.load('src/scissors.png').convert_alpha()
btnLizard = pygame.image.load('src/lizard.png').convert_alpha()
btnSpock = pygame.image.load('src/spock.png').convert_alpha()
lightBtn = pygame.image.load('src/supernovaBtn.png').convert_alpha()
pushBtn = pygame.image.load('src/lightBtn.png').convert_alpha()
#Set hands
lHadn_rock = pygame.image.load('src/lRock.png').convert_alpha()
lHadn_paper = pygame.image.load('src/lPaper.png').convert_alpha()
lHadn_sciss = pygame.image.load('src/lScissors.png').convert_alpha()
lHadn_lizard = pygame.image.load('src/lLizard.png').convert_alpha()
lHadn_spock = pygame.image.load('src/lSpock.png').convert_alpha()
rotated = pygame.transform.rotate(lHadn_rock, 0)
rHand_rock = pygame.transform.flip(lHadn_rock, True, False)
rHadn_paper = pygame.transform.flip(lHadn_paper, True, False)
rHadn_sciss = pygame.transform.flip(lHadn_sciss, True, False)
rHadn_lizard = pygame.transform.flip(lHadn_lizard, True, False)
rHadn_spock = pygame.transform.flip(lHadn_spock, True, False)
#Set btn possition x-axis
btnRock_x = 50
btnPaper_x = 200
btnSciss_x = 350
btnLizard_x = 500
btnSpock_x = 650
def win_screen():
global label_won
if mouse_click:
#set win label
label_won_rect = label_won.get_rect()
label_won_x = screen.get_width() / 2 - label_won_rect.width / 2
label_won_y = screen.get_height() / 2 - label_won_rect.height / 2
screen.blit(label_won, [label_won_x, label_won_y])
label_won = font_won.render(str(won), 1, black)
def texts(user_won, comp_won):
#Set fount and label
global label_comp_score, label_user_score, label_draw_score
label_comp_score = font.render("User Win: " + str(comp_won), 1, black)
label_user_score = font.render("Comp Win: " + str(user_won), 1, black)
label_draw_score = font.render("Draw: " + str(draw), 1, black)
def process(user, comp):
global user_won, comp_won, draw, won, users, comps
users = user
comps = comp
if user == comp:
draw += 1
won = 'Draw'
return draw
if gestures.get(user):
if comp in gestures[user]['win']:
user_won += 1
won = 'User Won'
return texts(user_won, comp_won), hand_set(user, comp)
else:
comp_won += 1
won = 'Computer Won'
return texts(user_won, comp_won), hand_set(user, comp)
else:
raise Exception('Gesture not found in dict.')
#Set users and comp hands
def hand_set(user, comp):
if won == '':
screen.blit(lHadn_rock, [5, 200])
screen.blit(rHand_rock, [540, 200])
if user == 'rock':
screen.blit(lHadn_rock, [5, 200])
elif user == 'paper':
screen.blit(lHadn_paper, [5, 200])
elif user == 'scissors':
screen.blit(lHadn_sciss, [5, 200])
elif user == 'lizard':
screen.blit(lHadn_lizard, [5, 200])
elif user == 'spock':
screen.blit(lHadn_spock, [5, 200])
if comp == 'rock':
screen.blit(rHand_rock, [540, 200])
elif comp == 'paper':
screen.blit(rHadn_paper, [400, 200])
elif comp == 'scissors':
screen.blit(rHadn_sciss, [400, 200])
elif comp == 'lizard':
screen.blit(rHadn_lizard, [400, 200])
elif comp == 'spock':
screen.blit(rHadn_spock, [400, 200])
def position(x, y):
comp_gest = str(random.sample(gestures.keys(), 1))
comp_gest = comp_gest[2: -2]
print "Comp choise:", comp_gest
if y > 500:
if x in range(btnRock_x, btnRock_x + 92):
user_gest = 'rock'
process(user_gest, comp_gest)
print 'User choise: rock'
elif x in range(btnPaper_x, btnPaper_x + 92):
user_gest = 'paper'
process(user_gest, comp_gest)
print 'User choise: paper'
elif x in range(btnSciss_x, btnSciss_x + 92):
user_gest = 'scissors'
process(user_gest, comp_gest)
print 'User choise: scissor'
elif x in range(btnLizard_x, btnLizard_x + 92):
user_gest = 'lizard'
process(user_gest, comp_gest)
print 'User choise: lizard'
elif x in range(btnSpock_x, btnSpock_x + 92):
user_gest = 'spock'
process(user_gest, comp_gest)
print 'User choise: spock'
def blur_pos(x, y):
global blur_rock, blur_paper, blur_scissor, blur_lizard, blur_spock
if y > 500:
if x in range(btnRock_x, btnRock_x + 92):
screen.blit(lightBtn, [btnRock_x, 500])
elif x in range(btnPaper_x, btnPaper_x + 92):
screen.blit(lightBtn, [btnPaper_x, 500])
elif x in range(btnSciss_x, btnSciss_x + 92):
screen.blit(lightBtn, [btnSciss_x, 500])
elif x in range(btnLizard_x, btnLizard_x + 92):
screen.blit(lightBtn, [btnLizard_x, 500])
elif x in range(btnSpock_x, btnSpock_x + 92):
screen.blit(lightBtn, [btnSpock_x, 500])
while done == False:
global x, y
clock.tick(10)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True # Flag that we are done so we exit this loop
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
pos = pygame.mouse.get_pos()
# Change the x/y screen coordinates to grid coordinates
x = pos[0]
y = pos[1]
# Pass values to function
position(x, y)
mouse_click = True
print("Click ", pos, "Grid coordinates: ", x, y)
elif event.type == pygame.MOUSEMOTION:
pos = event.pos
x = pos[0]
y = pos[1]
blur_pos(x, y)
#set background
screen.blit(background, [0, 0])
#set buttons
screen.blit(btnRock, [btnRock_x, 500])
screen.blit(btnPaper, [btnPaper_x, 500])
screen.blit(btnSciss, [btnSciss_x, 500])
screen.blit(btnLizard, [btnLizard_x, 500])
screen.blit(btnSpock, [btnSpock_x, 500])
#set light for buttons
blur_pos(x, y)
#set labels
screen.blit(label_comp_score, (70, 40))
screen.blit(label_user_score, (575, 42))
screen.blit(label_draw_score, (375, 42))
hand_set(users, comps)
win_screen()
mouse_click = False
pygame.display.flip()
pygame.quit()
Вот, к стати, скрин того что вышло:

P.S. После того как открылся для реализации проект на Coursera, я понял что можно было обойтись более простой логикой и без использования словарей.
Кому интересно вот полный проект со всеми ресурсами: ubuntuone.com/7IcRcnTyQEPaciOIuTGrOl