diff --git a/fuckthiscollapse/Game.py b/fuckthiscollapse/Game.py index 13fd407..f775e08 100644 --- a/fuckthiscollapse/Game.py +++ b/fuckthiscollapse/Game.py @@ -37,11 +37,21 @@ class Game: COLOR_BLACK = (0, 0, 0, 255) SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 - STATE_FALLING = 0 - STATE_NONE = 1 + + STATE_NONE = 0 + STATE_FALLING = 1 STATE_SELECTED = 2 STATE_DEAD = 3 + M_IDX_MOVES = 0 + M_IDX_TYPE = 1 + M_IDX_STATE = 2 + M_IDX_POS = 3 + M_IDX_VEL = 4 + + P_IDX_X = 0 + P_IDX_Y = 1 + def __init__(self): pygame.init() self.__display__ = pygame.display.set_mode((Game.SCREEN_WIDTH, Game.SCREEN_HEIGHT)) @@ -54,7 +64,7 @@ class Game: self.__moves__ = 0 self.__maxMarbleMoves__ = 4 - self.__selectedMarble__ = [-1, -1] + self.__setSelectedMarble__([-1, -1]) self.__selectionRect__ = None self.__selectionSurface__ = pygame.Surface( (Game.MARBLE_WIDTH, Game.MARBLE_HEIGHT), @@ -75,37 +85,47 @@ class Game: def __setMap__(self, maparray): self.__curMap__ = [] - for row in maparray: - mrow = [] - self.__curMap__.append(mrow) - for col in row: - mrow.append([self.__maxMarbleMoves__, col, Game.STATE_NONE, 0]) - self.__curMapRect__ = pygame.Rect( - ((Game.SCREEN_WIDTH - (Game.MARBLE_WIDTH * len(self.__curMap__[0])))/2), - ((Game.SCREEN_HEIGHT - (Game.MARBLE_HEIGHT * len(self.__curMap__)))/2), - (Game.MARBLE_WIDTH * len(self.__curMap__[0])), - (Game.MARBLE_HEIGHT * len(self.__curMap__)) + ((Game.SCREEN_WIDTH - (Game.MARBLE_WIDTH * len(maparray[0])))/2), + ((Game.SCREEN_HEIGHT - (Game.MARBLE_HEIGHT * len(maparray)))/2), + (Game.MARBLE_WIDTH * len(maparray[0])), + (Game.MARBLE_HEIGHT * len(maparray)) ) + x = self.__curMapRect__.left + y = self.__curMapRect__.top + for row in maparray: + x = self.__curMapRect__.left + mrow = [] + self.__curMap__.append(mrow) + for col in row: + mrow.append( + [self.__maxMarbleMoves__, + col, + Game.STATE_NONE, + [x, y], + [0, 0]]) + x += Game.MARBLE_WIDTH + y += Game.MARBLE_HEIGHT + + def __update__(self): + return + def __draw__(self): self.__display__.fill(Game.COLOR_BLACK) self.__blitTarget__.fill(Game.COLOR_MAGICPINK) if not self.__curMap__: return - x = self.__curMapRect__.left - y = self.__curMapRect__.top for row in self.__curMap__: - x = self.__curMapRect__.left for col in row: - if col[1]: - self.__blitTarget__.blit(self.__marbles__[col[1]], (x, y)) - text = self.__gameFont__.render("{}".format(col[0]), 1, Game.COLOR_WHITE) + if col[Game.M_IDX_TYPE]: + x = col[Game.M_IDX_POS][Game.P_IDX_X] + y = col[Game.M_IDX_POS][Game.P_IDX_Y] + self.__blitTarget__.blit(self.__marbles__[col[Game.M_IDX_TYPE]], (x, y)) + text = self.__gameFont__.render("{}".format(col[Game.M_IDX_MOVES]), 1, Game.COLOR_WHITE) textpos = text.get_rect(right = x + (Game.MARBLE_WIDTH), top = y) self.__blitTarget__.blit(text, textpos) - x += Game.MARBLE_WIDTH - y += Game.MARBLE_HEIGHT if self.__selectionRect__ : self.__blitTarget__.blit( self.__selectionSurface__, @@ -116,8 +136,8 @@ class Game: def __canSelectMarble__(self, x, y): if self.__selectedMarble__ == [-1, -1]: return True - curx = self.__selectedMarble__[0] - cury = self.__selectedMarble__[1] + curx = self.__selectedMarble__[Game.P_IDX_X] + cury = self.__selectedMarble__[Game.P_IDX_Y] selectable = [ [curx, cury - 1], # --S-- [curx - 1, cury], # -SX-- @@ -126,58 +146,130 @@ class Game: ] if [x, y] not in selectable: return False - #if self.__curMap__[y][x] != self.__curMap__[cury][curx] : - # print "Neighbor at ({}, {}) is type {} while I am {}".format(x, y, self.__curMap__[cury][curx], self.__curMap__[y][x]) - # return False + if self.__curMap__[y][x][Game.M_IDX_STATE] != Game.STATE_NONE: + return False return True def __flipMarbles__(self, m1, m2): if self.__selectedMarble__ == [-1, -1]: return # Skip empty (black) marbles - if ( ( self.__curMap__[m1[1]][m1[0]][0] == 0 ) or - ( self.__curMap__[m2[1]][m2[0]][0] == 0 ) ): + if ( ( self.__curMap__[m1[Game.P_IDX_Y]][m1[Game.P_IDX_X]][Game.M_IDX_TYPE] == 0 ) or + ( self.__curMap__[m2[Game.P_IDX_Y]][m2[Game.P_IDX_X]][Game.M_IDX_TYPE] == 0 ) ): return - tmp = self.__curMap__[m1[1]][m1[0]] - self.__curMap__[m1[1]][m1[0]] = self.__curMap__[m2[1]][m2[0]] - self.__curMap__[m2[1]][m2[0]] = tmp - self.__curMap__[m1[1]][m1[0]][0] -= 1 - self.__curMap__[m2[1]][m2[0]][0] -= 1 + # Swap marbles + tmp = self.__curMap__[m1[Game.P_IDX_Y]][m1[Game.P_IDX_X]] + self.__curMap__[m1[Game.P_IDX_Y]][m1[Game.P_IDX_X]] = self.__curMap__[m2[Game.P_IDX_Y]][m2[Game.P_IDX_X]] + self.__curMap__[m2[Game.P_IDX_Y]][m2[Game.P_IDX_X]] = tmp + + # Swap positions of the marbles + tmp = self.__curMap__[m1[Game.P_IDX_Y]][m1[Game.P_IDX_X]][Game.M_IDX_POS] + self.__curMap__[m1[Game.P_IDX_Y]][m1[Game.P_IDX_X]][Game.M_IDX_POS] = self.__curMap__[m2[Game.P_IDX_Y]][m2[Game.P_IDX_X]][Game.M_IDX_POS] + self.__curMap__[m2[Game.P_IDX_Y]][m2[Game.P_IDX_X]][Game.M_IDX_POS] = tmp + + # Decrement movecount remaining on both marbles + self.__curMap__[m1[Game.P_IDX_Y]][m1[Game.P_IDX_X]][Game.M_IDX_MOVES] -= 1 + self.__curMap__[m2[Game.P_IDX_Y]][m2[Game.P_IDX_X]][Game.M_IDX_MOVES] -= 1 + self.__setSelectedMarble__(m2) def __setMarbleState__(self, x, y, state): self.__curMap__[y][x][2] = state - def __mouseClicked__(self, event): - mouse_x = event.pos[0] - mouse_y = event.pos[1] - marble_x = ( (mouse_x - self.__curMapRect__.left) / Game.MARBLE_WIDTH) - marble_y = ( (mouse_y - self.__curMapRect__.top) / Game.MARBLE_HEIGHT) - if ( ( not self.__curMapRect__.collidepoint((mouse_x, mouse_y))) or - (self.__curMap__[marble_y][marble_x][1] == 0 ) ): - if self.__curMap__[self.__selectedMarble__[1]][self.__selectedMarble__[0]][2] == Game.STATE_SELECTED : - self.__curMap__[self.__selectedMarble__[1]][self.__selectedMarble__[0]][2] = Game.STATE_NONE - self.__selectedMarble__ = [-1, -1] + def __setSelectedMarble__(self, pos): + self.__selectedMarble__ = pos + if pos == [-1, -1]: self.__selectionRect__ = None return - if self.__curMap__[marble_y][marble_x][1] == 0: + self.__selectionRect__ = pygame.Rect( + (self.__curMapRect__.left + (pos[Game.P_IDX_X] * Game.MARBLE_WIDTH)), + (self.__curMapRect__.top + (pos[Game.P_IDX_Y] * Game.MARBLE_HEIGHT)), + Game.MARBLE_WIDTH, + Game.MARBLE_HEIGHT) + self.__setMarbleState__(pos[Game.P_IDX_X], pos[Game.P_IDX_Y], Game.STATE_SELECTED) + + def __mouseClicked__(self, event): + mouse_x = event.pos[Game.P_IDX_X] + mouse_y = event.pos[Game.P_IDX_Y] + marble_x = ( (mouse_x - self.__curMapRect__.left) / Game.MARBLE_WIDTH) + marble_y = ( (mouse_y - self.__curMapRect__.top) / Game.MARBLE_HEIGHT) + + if ( ( not self.__curMapRect__.collidepoint((mouse_x, mouse_y))) or + (self.__curMap__[marble_y][marble_x][Game.M_IDX_TYPE] == 0 ) ): + if self.__curMap__[self.__selectedMarble__[Game.P_IDX_Y]][self.__selectedMarble__[Game.P_IDX_X]][2] == Game.STATE_SELECTED : + self.__curMap__[self.__selectedMarble__[Game.P_IDX_Y]][self.__selectedMarble__[Game.P_IDX_X]][2] = Game.STATE_NONE + self.__setSelectedMarble__([-1, -1]) + self.__selectionRect__ = None + return + if self.__curMap__[marble_y][marble_x][Game.M_IDX_TYPE] == 0: return False if event.button == 1: - self.__selectedMarble__ = [marble_x, marble_y] - self.__selectionRect__ = pygame.Rect( - (self.__curMapRect__.left + (marble_x * Game.MARBLE_WIDTH)), - (self.__curMapRect__.top + (marble_y * Game.MARBLE_HEIGHT)), - Game.MARBLE_WIDTH, - Game.MARBLE_HEIGHT) - self.__setMarbleState__(marble_x, marble_y, Game.STATE_SELECTED) + self.__setSelectedMarble__([marble_x, marble_y]) elif event.button in [2, 3]: if not self.__canSelectMarble__(marble_x, marble_y): return self.__flipMarbles__(self.__selectedMarble__, [marble_x, marble_y]) + #self.__setGroupState__() return + def __setGroupState__(self): + groups = { + 0: [], + 1: [], + 2: [], + 3: [], + 4: [] + } + groups_of_3 = [ + [], + [], + [], + [] + ] + x = 0 + y = 0 + curMatchMarble = 0 + prevy = 0 + group = None + for row in self.__curMap__: + x = 0 + for col in row: + if col[Game.M_IDX_TYPE] != 0: + candidates = [ + [x, y - 1], # --C-- + [x - 1, y], # -CX-- + [x + 1, y], # --XC- + [x, y + 1] # --C-- + ] + for c in candidates: + if self.__curMap__[c[Game.P_IDX_Y]][c[Game.P_IDX_X]][Game.M_IDX_TYPE] == col[Game.M_IDX_TYPE]: + if ( (prevy != y and curMatchMarble != col[Game.M_IDX_TYPE]) or + (prevy != y) ): + curMatchMarble = col[Game.M_IDX_TYPE] + group = None + for group in groups[curMatchMarble]: + if ( ( [c[Game.P_IDX_Y], c[Game.P_IDX_X]] in group ) or + ( self.__curMap__[c[Game.P_IDX_Y]][c[Game.P_IDX_X]] in group ) ): + break + if not group: + group = [[c[Game.P_IDX_Y], c[Game.P_IDX_X]]] + groups[curMatchMarble].append(group) + group.append([self.__curMap__[c[Game.P_IDX_Y]][c[Game.P_IDX_X]]]) + x += 1 + prevy = y + y += 1 + # Go through all the matches, and make sets of all the marbles in groups > 3 + for marble, group in groups.iteritems(): + for grp in group: + if len(grp) > 2: + groups_of_3[marble] += grp + for group in groups_of_3: + for pair in set(group): + self.__curMap__[pair[Game.P_IDX_Y]][pair[Game.P_IDX_X]][2] = Game.STATE_FALLING + def run(self): while True: + self.__update__() self.__draw__() for event in pygame.event.get():