Reduced the usage of magic numbers in the code, it's more verbose now but a little easier to read. Introduced position and velocity to each marble, instead of calculating them in __draw__ on the fly.
This commit is contained in:
@@ -37,11 +37,21 @@ class Game:
|
|||||||
COLOR_BLACK = (0, 0, 0, 255)
|
COLOR_BLACK = (0, 0, 0, 255)
|
||||||
SCREEN_WIDTH = 800
|
SCREEN_WIDTH = 800
|
||||||
SCREEN_HEIGHT = 600
|
SCREEN_HEIGHT = 600
|
||||||
STATE_FALLING = 0
|
|
||||||
STATE_NONE = 1
|
STATE_NONE = 0
|
||||||
|
STATE_FALLING = 1
|
||||||
STATE_SELECTED = 2
|
STATE_SELECTED = 2
|
||||||
STATE_DEAD = 3
|
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):
|
def __init__(self):
|
||||||
pygame.init()
|
pygame.init()
|
||||||
self.__display__ = pygame.display.set_mode((Game.SCREEN_WIDTH, Game.SCREEN_HEIGHT))
|
self.__display__ = pygame.display.set_mode((Game.SCREEN_WIDTH, Game.SCREEN_HEIGHT))
|
||||||
@@ -54,7 +64,7 @@ class Game:
|
|||||||
self.__moves__ = 0
|
self.__moves__ = 0
|
||||||
self.__maxMarbleMoves__ = 4
|
self.__maxMarbleMoves__ = 4
|
||||||
|
|
||||||
self.__selectedMarble__ = [-1, -1]
|
self.__setSelectedMarble__([-1, -1])
|
||||||
self.__selectionRect__ = None
|
self.__selectionRect__ = None
|
||||||
self.__selectionSurface__ = pygame.Surface(
|
self.__selectionSurface__ = pygame.Surface(
|
||||||
(Game.MARBLE_WIDTH, Game.MARBLE_HEIGHT),
|
(Game.MARBLE_WIDTH, Game.MARBLE_HEIGHT),
|
||||||
@@ -75,37 +85,47 @@ class Game:
|
|||||||
|
|
||||||
def __setMap__(self, maparray):
|
def __setMap__(self, maparray):
|
||||||
self.__curMap__ = []
|
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(
|
self.__curMapRect__ = pygame.Rect(
|
||||||
((Game.SCREEN_WIDTH - (Game.MARBLE_WIDTH * len(self.__curMap__[0])))/2),
|
((Game.SCREEN_WIDTH - (Game.MARBLE_WIDTH * len(maparray[0])))/2),
|
||||||
((Game.SCREEN_HEIGHT - (Game.MARBLE_HEIGHT * len(self.__curMap__)))/2),
|
((Game.SCREEN_HEIGHT - (Game.MARBLE_HEIGHT * len(maparray)))/2),
|
||||||
(Game.MARBLE_WIDTH * len(self.__curMap__[0])),
|
(Game.MARBLE_WIDTH * len(maparray[0])),
|
||||||
(Game.MARBLE_HEIGHT * len(self.__curMap__))
|
(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):
|
def __draw__(self):
|
||||||
self.__display__.fill(Game.COLOR_BLACK)
|
self.__display__.fill(Game.COLOR_BLACK)
|
||||||
self.__blitTarget__.fill(Game.COLOR_MAGICPINK)
|
self.__blitTarget__.fill(Game.COLOR_MAGICPINK)
|
||||||
if not self.__curMap__:
|
if not self.__curMap__:
|
||||||
return
|
return
|
||||||
x = self.__curMapRect__.left
|
|
||||||
y = self.__curMapRect__.top
|
|
||||||
for row in self.__curMap__:
|
for row in self.__curMap__:
|
||||||
x = self.__curMapRect__.left
|
|
||||||
for col in row:
|
for col in row:
|
||||||
if col[1]:
|
if col[Game.M_IDX_TYPE]:
|
||||||
self.__blitTarget__.blit(self.__marbles__[col[1]], (x, y))
|
x = col[Game.M_IDX_POS][Game.P_IDX_X]
|
||||||
text = self.__gameFont__.render("{}".format(col[0]), 1, Game.COLOR_WHITE)
|
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),
|
textpos = text.get_rect(right = x + (Game.MARBLE_WIDTH),
|
||||||
top = y)
|
top = y)
|
||||||
self.__blitTarget__.blit(text, textpos)
|
self.__blitTarget__.blit(text, textpos)
|
||||||
x += Game.MARBLE_WIDTH
|
|
||||||
y += Game.MARBLE_HEIGHT
|
|
||||||
if self.__selectionRect__ :
|
if self.__selectionRect__ :
|
||||||
self.__blitTarget__.blit(
|
self.__blitTarget__.blit(
|
||||||
self.__selectionSurface__,
|
self.__selectionSurface__,
|
||||||
@@ -116,8 +136,8 @@ class Game:
|
|||||||
def __canSelectMarble__(self, x, y):
|
def __canSelectMarble__(self, x, y):
|
||||||
if self.__selectedMarble__ == [-1, -1]:
|
if self.__selectedMarble__ == [-1, -1]:
|
||||||
return True
|
return True
|
||||||
curx = self.__selectedMarble__[0]
|
curx = self.__selectedMarble__[Game.P_IDX_X]
|
||||||
cury = self.__selectedMarble__[1]
|
cury = self.__selectedMarble__[Game.P_IDX_Y]
|
||||||
selectable = [
|
selectable = [
|
||||||
[curx, cury - 1], # --S--
|
[curx, cury - 1], # --S--
|
||||||
[curx - 1, cury], # -SX--
|
[curx - 1, cury], # -SX--
|
||||||
@@ -126,58 +146,130 @@ class Game:
|
|||||||
]
|
]
|
||||||
if [x, y] not in selectable:
|
if [x, y] not in selectable:
|
||||||
return False
|
return False
|
||||||
#if self.__curMap__[y][x] != self.__curMap__[cury][curx] :
|
if self.__curMap__[y][x][Game.M_IDX_STATE] != Game.STATE_NONE:
|
||||||
# print "Neighbor at ({}, {}) is type {} while I am {}".format(x, y, self.__curMap__[cury][curx], self.__curMap__[y][x])
|
return False
|
||||||
# return False
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def __flipMarbles__(self, m1, m2):
|
def __flipMarbles__(self, m1, m2):
|
||||||
if self.__selectedMarble__ == [-1, -1]:
|
if self.__selectedMarble__ == [-1, -1]:
|
||||||
return
|
return
|
||||||
# Skip empty (black) marbles
|
# Skip empty (black) marbles
|
||||||
if ( ( self.__curMap__[m1[1]][m1[0]][0] == 0 ) or
|
if ( ( self.__curMap__[m1[Game.P_IDX_Y]][m1[Game.P_IDX_X]][Game.M_IDX_TYPE] == 0 ) or
|
||||||
( self.__curMap__[m2[1]][m2[0]][0] == 0 ) ):
|
( self.__curMap__[m2[Game.P_IDX_Y]][m2[Game.P_IDX_X]][Game.M_IDX_TYPE] == 0 ) ):
|
||||||
return
|
return
|
||||||
|
|
||||||
tmp = self.__curMap__[m1[1]][m1[0]]
|
# Swap marbles
|
||||||
self.__curMap__[m1[1]][m1[0]] = self.__curMap__[m2[1]][m2[0]]
|
tmp = self.__curMap__[m1[Game.P_IDX_Y]][m1[Game.P_IDX_X]]
|
||||||
self.__curMap__[m2[1]][m2[0]] = tmp
|
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__[m1[1]][m1[0]][0] -= 1
|
self.__curMap__[m2[Game.P_IDX_Y]][m2[Game.P_IDX_X]] = tmp
|
||||||
self.__curMap__[m2[1]][m2[0]][0] -= 1
|
|
||||||
|
# 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):
|
def __setMarbleState__(self, x, y, state):
|
||||||
self.__curMap__[y][x][2] = state
|
self.__curMap__[y][x][2] = state
|
||||||
|
|
||||||
def __mouseClicked__(self, event):
|
def __setSelectedMarble__(self, pos):
|
||||||
mouse_x = event.pos[0]
|
self.__selectedMarble__ = pos
|
||||||
mouse_y = event.pos[1]
|
if pos == [-1, -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]
|
|
||||||
self.__selectionRect__ = None
|
self.__selectionRect__ = None
|
||||||
return
|
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
|
return False
|
||||||
if event.button == 1:
|
if event.button == 1:
|
||||||
self.__selectedMarble__ = [marble_x, marble_y]
|
self.__setSelectedMarble__([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)
|
|
||||||
elif event.button in [2, 3]:
|
elif event.button in [2, 3]:
|
||||||
if not self.__canSelectMarble__(marble_x, marble_y):
|
if not self.__canSelectMarble__(marble_x, marble_y):
|
||||||
return
|
return
|
||||||
self.__flipMarbles__(self.__selectedMarble__, [marble_x, marble_y])
|
self.__flipMarbles__(self.__selectedMarble__, [marble_x, marble_y])
|
||||||
|
#self.__setGroupState__()
|
||||||
return
|
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):
|
def run(self):
|
||||||
while True:
|
while True:
|
||||||
|
self.__update__()
|
||||||
self.__draw__()
|
self.__draw__()
|
||||||
|
|
||||||
for event in pygame.event.get():
|
for event in pygame.event.get():
|
||||||
|
|||||||
Reference in New Issue
Block a user