我成功地完成了这场比赛,我相信你以前也遇到过。如果你运行它,就会有关于该做什么的说明。有什么代码建议/改进吗?
import pygame,random,math
from time import sleep
pygame.init()
#window resolution
screen_width = 800
screen_height = 800
screen = pygame.display.set_mode( ( screen_width,screen_height ) )
pygame.display.set_caption( 'The Flash Game - Marek Borik' )
n_squares_in_row = 7
line_thickness = 20 #pixels
wait_duration = 1.5 #seconds
flash_duration = 0.3 #seconds
fontsize = screen_width // 25
rounds = 10 #rounds of flashes
#defining colors
RED = ( 255,0,0 )
BLUE = ( 0,0,255 )
WHITE = ( 255,255,255 )
BLACK = ( 0,0,0 )
def TextObjects( string,font,color ):
textSurface = font.render( string,True,color )
return textSurface,textSurface.get_rect()
def DrawText( string,fontSizeX,color,x,y ):
text = pygame.font.SysFont( "timesnewroman",int( math.ceil( fontSizeX ) ) )
TextSurf, TextRect = TextObjects( string,text,color )
TextRect.center = ( x,y )
screen.blit( TextSurf,TextRect )
def GenerateColorInfo( n_squares_in_row ):
n_squares_total = n_squares_in_row ** 2
not5050 = True #Prevents from having the same amount of red and blue squares if applicable ( e.g. field with dimentions 7 x 7 squares squares will never have this issue )
while( not5050 ):
color_info = []
for i in range( n_squares_total + 1 ):
rand = random.randint( 0,1 )
color_info.append( rand )
counter_red = 0
counter_blue = 0
for i in color_info:
if i == 0:
counter_red += 1
if i == 1:
counter_blue += 1
if counter_red == n_squares_total // 2 or counter_blue == n_squares_total // 2 or counter_red == counter_blue:
not5050 = True
else:
not5050 = False
return color_info,counter_red,counter_blue
def DrawSquares( n_squares_in_row,color_info,square_width,square_height ):
for i in range( n_squares_in_row ):
for j in range( n_squares_in_row ):
if color_info[ i * n_squares_in_row + j ] == 0:
pygame.draw.rect( screen,RED,( j * square_width,i * square_height,j * square_width + square_width,i * square_height + screen_height ),0 )
else:
pygame.draw.rect( screen,BLUE,( j * square_width,i * square_height,j * square_width + square_width,i * square_height + screen_height ),0 )
def DrawGrid( n_squares_in_row,line_thickness,square_width,square_height ):
for i in range( 1,n_squares_in_row ):
pygame.draw.line( screen,BLACK,( i * square_width,0 ),( i * square_width,screen_height ),line_thickness )
for i in range( 1,n_squares_in_row ):
pygame.draw.line( screen,BLACK,( 0,i * square_height ),( screen_height,i * square_width ),line_thickness )
pygame.draw.line( screen,BLACK,( 0,0 ),( 0,screen_height ),line_thickness )
pygame.draw.line( screen,BLACK,( 0,0 ),( screen_width,0 ),line_thickness )
pygame.draw.line( screen,BLACK,( screen_width,0 ),( screen_width,screen_height ),line_thickness )
pygame.draw.line( screen,BLACK,( 0,screen_height ),( screen_width,screen_height ),line_thickness )
def DrawStartScreen():
end = False
while not end:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
end = True
if event.type == pygame.QUIT:
pygame.quit()
quit()
screen.fill( BLACK )
DrawText( "The Flash Game - Created by Marek Borik",fontsize * 1.4,WHITE,screen_width * 0.5,screen_height * 0.05 )
DrawText( "This game will test your subconscious perception.",fontsize,WHITE,screen_width * 0.5,screen_height * 0.2 )
DrawText( ( "You will be shown a grid of red and blue squares " + str( rounds ) + " times." ),fontsize,WHITE,screen_width * 0.5, screen_height * 0.25 )
DrawText( "Your task is to determine if you saw more red or blue circles.",fontsize,WHITE,screen_width * 0.5, screen_height * 0.3 )
DrawText( "If you see more:",fontsize,WHITE,screen_width * 0.3,screen_height * 0.45 )
DrawText( "If you see more:",fontsize,WHITE,screen_width * 0.7,screen_height * 0.45 )
pygame.draw.rect( screen,RED,( screen_width * 0.2, screen_height * 0.5,screen_width * 0.2,screen_height * 0.2 ),0 )
pygame.draw.rect( screen,BLUE,( screen_width * 0.6, screen_height * 0.5,screen_width * 0.2,screen_height * 0.2 ),0 )
DrawText( "Press Left Arrow",fontsize,WHITE,screen_width * 0.3,screen_height * 0.75 )
DrawText( "Press Right Arrow",fontsize,WHITE,screen_width * 0.7,screen_height * 0.75 )
DrawText( "Press spacebar to start",fontsize,WHITE,screen_width * 0.5,screen_height * 0.93 )
pygame.display.update()
def DoRound():
left_arrow = False
right_arrow = False
turn = False
#if the windows isn't square, then squares are not squares and we need to treat them like rectangles
square_width = screen_width / n_squares_in_row
square_height = screen_height / n_squares_in_row
color_info,n_red,n_blue = GenerateColorInfo( n_squares_in_row )
screen.fill( BLACK )
pygame.display.update()
sleep( wait_duration )
#flicker squares for the flash duration
DrawSquares( n_squares_in_row,color_info,square_width,square_height )
DrawGrid( n_squares_in_row,line_thickness,square_width,square_height )
pygame.display.update()
sleep( flash_duration )
screen.fill( BLACK )
pygame.display.update()
while not turn: # after flash wait for the turn to be completed by pressing either arrow to indicate the answer
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
left_arrow = True
turn = True
if event.key == pygame.K_RIGHT:
right_arrow = True
turn = True
if event.type == pygame.QUIT:
pygame.quit()
quit()
if n_red >= n_blue and left_arrow == True: #if the arrow coresponds to the correct answer, return 1, else 0
return 1
elif n_blue >= n_red and right_arrow == True:
return 1
else:
return 0
def Game():
guesses = []
for i in range( rounds ):
guesses.append( DoRound() )
return guesses.count( 1 ) #count ones, meaning correct answers
def EndScreen( correct ):
screen.fill( BLACK )
DrawText( "You got " + str( correct ) + " / " + str( rounds ) + " correct!",fontsize * 2,WHITE,screen_width * 0.5,screen_height * 0.5 )
pygame.display.update()
end = False
while not end:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
end = True
if event.type == pygame.QUIT:
pygame.quit()
quit()
DrawStartScreen()
correct = Game()
EndScreen( correct )
pygame.quit()
quit()发布于 2016-10-04 13:42:26
我很高兴看到一个只处理逻辑的函数,还有一些处理绘图和交互的函数。它使我很容易测试,分析和简化它。
generate_color_info这一职能过于复杂和冗长,难以简化其任务。
not5050变量不是必需的(您可以直接使用该条件)。list.count被忽略了。我首先编写了一个测试(用doctest运行),然后更简单地重新实现它:
def GenerateColorInfo( n_squares_in_row ):
"""
>>> random.seed(0)
>>> GenerateColorInfo( 5 )
([1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0], 10, 16)
"""
while True:
randoms = [random.randint(0, 1) for _ in range(n_squares_in_row ** 2 + 1)]
if randoms.count(0) != randoms.count(1):
break
return randoms, randoms.count(0), randoms.count(1)Game中的应用
Game不必要地长:
def Game():
return [DoRound() for _ in range( rounds )].count(True)if n_red >= n_blue and left_arrow == True: #if the arrow coresponds to the correct answer, return 1, else 0
return 1
elif n_blue >= n_red and right_arrow == True:
return 1
else:
return 0是相同的
return (n_red >= n_blue and left_arrow) or \
(n_blue >= n_red and right_arrow)但是第二种方法显然更简单(而且它更好,因为它返回True / False而不是1和0,从而使它更加清楚,它是一个布尔函数)。
的任意内存任务
右箭头和左箭头是如何分配给红色和蓝色的?让用户输入R ( Red )和B ( Blue )更合理。这样,连接是显而易见的,用户不需要使用内存。
你的一些代码似乎是用来处理矩形的:
#if the windows isn't square, then squares are not squares and we need to treat them like rectangles
square_width = screen_width / n_squares_in_row
square_height = screen_height / n_squares_in_row其他代码意味着正方形网格:
def DrawSquares( n_squares_in_row,color_info,square_width,square_height ):
for i in range( n_squares_in_row ):
for j in range( n_squares_in_row ):
if color_info[ i * n_squares_in_row + j ] == 0:
pygame.draw.rect( screen,RED,( j * square_width,i * square_height,j * square_width + square_width,i * square_height + screen_height ),0 )
else:
pygame.draw.rect( screen,BLUE,( j * square_width,i * square_height,j * square_width + square_width,i * square_height + screen_height ),0 )请要么编写所有的代码来容纳矩形,要么一点也不写,只是其中的一些代码会造成复杂性和混乱,而不会带来任何好处。
您的代码多次声明相同的概念:
if color_info[ i * n_squares_in_row + j ] == 0:
pygame.draw.rect( screen,RED,( j * square_width,i * square_height,j * square_width + square_width,i * square_height + screen_height ),0 )
else:
pygame.draw.rect( screen,BLUE,( j * square_width,i * square_height,j * square_width + square_width,i * square_height + screen_height ),0 )if和else除BLUE或RED作为颜色外是相等的。干原理是软件开发中最重要的原理之一。
下面是如何修复复制:
color = RED if color_info[ i * n_squares_in_row + j ] == 0 else BLUE
pygame.draw.rect( screen, color, ( j * square_width,i * square_height,j * square_width + square_width,i * square_height + screen_height ),0 )现在只调用一次绘图代码,很明显,只有颜色发生了变化。
pygame.draw.line( screen,BLACK,( 0,0 ),( 0,screen_height ),line_thickness )
pygame.draw.line( screen,BLACK,( 0,0 ),( screen_width,0 ),line_thickness )
pygame.draw.line( screen,BLACK,( screen_width,0 ),( screen_width,screen_height ),line_thickness )
pygame.draw.line( screen,BLACK,( 0,screen_height ),( screen_width,screen_height ),line_thickness )在这个代码块中,段pygame.draw.line( screen,BLACK, ... line_thickness)被重复4次。只有起点和终点发生变化,所以我们可以使用一个循环:
for (start, end) in [ ( ( 0,0 ),( 0,screen_height) ),
( ( 0,0 ),( screen_width,0 ) ),
(( screen_width,0 ),( screen_width,screen_height )),
(( 0,screen_height ),( screen_width,screen_height )) ]:
pygame.draw.line(screen, BLACK, start, end, line_thickness)当DrawText fontsize是fontsize,color是WHITE时,可以将其定义为关键字默认参数,以减少重复,从而在需要其他颜色时显式化。
这些代码块类似:
while not turn: # after flash wait for the turn to be completed by pressing either arrow to indicate the answer
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
left_arrow = True
turn = True
if event.key == pygame.K_RIGHT:
right_arrow = True
turn = True
if event.type == pygame.QUIT:
pygame.quit()
quit()和
while not end:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
end = True
if event.type == pygame.QUIT:
pygame.quit()
quit()应该可以编写一个函数一次,并使用它两次。
您可以称它为次要的,但是Python (PEP8)有一个非常广泛采用的样式指南,说明常量应该是ALL_UPPERCASE和所有其他名称lowercase_with_underscores。它有助于提高程序之间的一致性。我建议在您的代码上运行autopep8,以修正间距,使之与广泛接受的样式保持一致。
https://codereview.stackexchange.com/questions/143107
复制相似问题