├── requirements.txt └── colorsapp.py /requirements.txt: -------------------------------------------------------------------------------- 1 | appdirs==1.4.3 2 | packaging==16.8 3 | pygame==1.9.3 4 | pyparsing==2.2.0 5 | six==1.10.0 6 | -------------------------------------------------------------------------------- /colorsapp.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import math 3 | import random 4 | import pygame 5 | 6 | from pygame.locals import * 7 | 8 | # define colours 9 | GRAY = (245, 245, 245) 10 | LIGHTCYAN = (204, 229, 255) 11 | NAVYBLUE = (60, 60, 100) 12 | 13 | BGCOLOR = LIGHTCYAN 14 | BACKSQUARECOLOR = GRAY 15 | 16 | WINWIDTH = 500 # main window's width 17 | WINHEIGHT = 560 # main window's height 18 | MARGINX = 40 # left/right margin 19 | MARGINY = 100 # distance from the top of the window 20 | GAPSIZE = 4 # gap between boxes 21 | BACKSQUARESIZE = WINWIDTH - (MARGINX * 2) 22 | 23 | TIME = 60 24 | 25 | TEXTCOLOR = NAVYBLUE 26 | 27 | 28 | ## Game loop 29 | def main(): 30 | global DISPLAY 31 | pygame.init() 32 | FONT = pygame.font.Font('freesansbold.ttf', 24) 33 | DISPLAY = pygame.display.set_mode((WINWIDTH, WINHEIGHT)) 34 | pygame.display.set_caption("Colors Game") 35 | 36 | mousex = 0 # mouse x coord 37 | mousey = 0 # mouse y coord 38 | 39 | gameLevel = 1 40 | col1, col2 = getColorPair(gameLevel) 41 | secs = TIME 42 | 43 | mainBoard = getRandomBoard(gameLevel) 44 | 45 | pygame.time.set_timer(USEREVENT, 1000) 46 | 47 | # main loop 48 | while True: 49 | DISPLAY.fill(BGCOLOR) 50 | 51 | drawBoard(mainBoard, gameLevel, col1, col2) 52 | 53 | timeLeftText = FONT.render(str(secs) + ' seconds left', True, TEXTCOLOR) 54 | gameOver = FONT.render("Time's up", True, TEXTCOLOR) 55 | gameOverRect = gameOver.get_rect() 56 | gameOverRect.center = (WINWIDTH/2, WINHEIGHT/2 - 50) 57 | score = FONT.render("Your final score is " + str(gameLevel - 1), True, TEXTCOLOR) 58 | scoreRect = score.get_rect() 59 | scoreRect.center = (WINWIDTH/2, WINHEIGHT/2) 60 | startAgain = FONT.render("Press Enter to play again", True, TEXTCOLOR) 61 | startAgainRect = startAgain.get_rect() 62 | startAgainRect.center = (WINWIDTH/2, WINHEIGHT/2 + 50) 63 | 64 | DISPLAY.blit(timeLeftText, (20, 20)) 65 | 66 | for event in pygame.event.get(): 67 | if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE): 68 | pygame.quit() 69 | sys.exit() 70 | elif event.type == MOUSEBUTTONDOWN and secs > 0: 71 | mousex, mousey = event.pos 72 | elif event.type == USEREVENT and secs > 0: 73 | secs -= 1 74 | elif event.type == KEYDOWN and event.key == K_RETURN: 75 | gameLevel = 1 76 | secs = TIME 77 | mainBoard = getRandomBoard(gameLevel) 78 | drawBoard(mainBoard, gameLevel, col1, col2) 79 | boxx, boxy = None, None 80 | 81 | boxx, boxy = getBoxAtPixel(mainBoard, mousex, mousey) 82 | 83 | if boxx is not None and boxy is not None and secs > 0: 84 | if mainBoard[boxx][boxy] == 0: 85 | gameLevel += 1 86 | mainBoard = getRandomBoard(gameLevel) 87 | col1, col2 = getColorPair(gameLevel) 88 | drawBoard(mainBoard, gameLevel, col1, col2) 89 | elif secs == 0: 90 | DISPLAY.fill(BGCOLOR) 91 | DISPLAY.blit(gameOver, gameOverRect) 92 | DISPLAY.blit(score, scoreRect) 93 | DISPLAY.blit(startAgain, startAgainRect) 94 | 95 | pygame.display.update() 96 | 97 | 98 | def getRandomBoard(level): 99 | dim = getBoardDim(level) 100 | boxes = [1] * (dim**2) 101 | boxes[random.randrange(len(boxes))] = 0 102 | 103 | board = [] 104 | for i in range(dim): 105 | column = [] 106 | for j in range(dim): 107 | column.append(boxes[0]) 108 | del boxes[0] 109 | board.append(column) 110 | return(board) 111 | 112 | 113 | def getBoardDim(level): 114 | if level >= 9: 115 | dim = 10 116 | else: 117 | dim = level + 1 118 | return dim 119 | 120 | 121 | def getBoxSize(board): 122 | return (BACKSQUARESIZE - (GAPSIZE * (len(board) + 1)))/len(board) 123 | 124 | 125 | def leftTopCoordsOfBox(boxx, boxy, boxsize): 126 | # convert board coordinates into pixel coordinates 127 | left = boxy * (boxsize + GAPSIZE) + MARGINX + GAPSIZE 128 | top = boxx * (boxsize + GAPSIZE) + MARGINY + GAPSIZE 129 | return(left, top) 130 | 131 | 132 | def drawBoard(board, level, col1, col2): 133 | dim = getBoardDim(level) 134 | boxsize = getBoxSize(board) 135 | pygame.draw.rect(DISPLAY, BACKSQUARECOLOR, (MARGINX, MARGINY, BACKSQUARESIZE, BACKSQUARESIZE)) 136 | 137 | for boxx in range(dim): 138 | for boxy in range(dim): 139 | left, top = leftTopCoordsOfBox(boxx, boxy, boxsize) 140 | if board[boxx][boxy] == 1: 141 | pygame.draw.rect(DISPLAY, col1, (left, top, boxsize, boxsize)) 142 | else: 143 | pygame.draw.rect(DISPLAY, col2, (left, top, boxsize, boxsize)) 144 | 145 | 146 | def getBoxAtPixel(board, x, y): 147 | dim = len(board) 148 | boxsize = getBoxSize(board) 149 | for boxx in range(dim): 150 | for boxy in range(dim): 151 | left, top = leftTopCoordsOfBox(boxx, boxy, boxsize) 152 | boxRect = pygame.Rect(left, top, boxsize, boxsize) 153 | if boxRect.collidepoint(x,y): 154 | return(boxx, boxy) 155 | return(None, None) 156 | 157 | 158 | def hsv_to_rgb(h, s, v): 159 | # see wikipedia for conversion 160 | # https://en.wikipedia.org/wiki/HSL_and_HSV#Converting_to_RGB 161 | c = v * s 162 | hhat = h/60 163 | x = c*(1-math.fabs(hhat % 2 - 1)) 164 | 165 | r1, b1, g1 = 0, 0, 0 166 | 167 | if hhat >= 0 and hhat < 1: 168 | r1, b1, g1 = c, x, 0 169 | elif hhat >= 1 and hhat < 2: 170 | r1, b1, g1 = x, c, 0 171 | elif hhat >= 2 and hhat < 3: 172 | r1, b1, g1 = 0, c, x 173 | elif hhat >= 3 and hhat < 4: 174 | r1, b1, g1 = 0, x, c 175 | elif hhat >= 4 and hhat < 5: 176 | r1, b1, g1 = x, 0, c 177 | elif hhat >= 5 and hhat < 6: 178 | r1, b1, g1 = c, 0, x 179 | 180 | m = v - c 181 | return int(255*(r1+m)), int(255*(b1+m)), int(255*(g1+m)) 182 | 183 | 184 | def getColorPair(level): 185 | h = random.randrange(0, 360) 186 | v1 = random.uniform(0.6, 0.9) 187 | s1 = random.uniform(0.75, 1) 188 | 189 | if level <= 5: 190 | s2 = s1 - 0.5 191 | v2 = v1 + 0.1 192 | elif level > 5 and level <= 12: 193 | s2 = s1 - 0.4 194 | v2 = v1 + 0.05 195 | else: 196 | s2 = s1 - 0.3 197 | v2 = v1 198 | 199 | col1 = hsv_to_rgb(h, s1, v1) 200 | col2 = hsv_to_rgb(h, s2, v2) 201 | 202 | return col1, col2 203 | 204 | 205 | if __name__ == '__main__': 206 | main() 207 | --------------------------------------------------------------------------------