Updated the code to now allow for a fill_rows optional argument for Grid, that determines how many rows are filled with values. I have also added some experimental code to invert the dropping, as in all of the values can float to the top. Other code is even more experimental and not yet working right that pulls the nodes to the right or left, with hope of being able to apply gravity in all 4 directions. But I still need to work out the bugs. Any help is greatly appreciated. Thanks for all of the contributions so far.

#CODE BELOW
import random


class GameTile():
    def __init__(self, col, row, values=None, value=None, **kwargs):
        # values is not required because the value can be directly set.
        # This is to support a future feature that will allow me to build a
        # board off of a list.
        # id is grid(X,Y) which is equal to grid(col,row)
        self.id = str(col) + ',' + str(row)
        self.col = col
        self.row = row
        if value is None:
            value = random.choice(values)
        self.value = value
        self.eliminated = False
        # hide_anim = hidden for animation purposes
        self.hide_anim = False
        # drop_value = value to be dropped during animation
        self.drop_value = None
        # drop_to could have inversely been a drop_from
        # drop_to = the id of where the value should be dropped too.
        self.drop_to = None

    def __str__(self):
        return "%2d" % self.value


class GameGrid():
    def __init__(self, cols=8, rows=7, fill_rows=None, **kwargs):
        if cols < 3 or rows < 3:
raise ValueError('Minimum board size is 3x3! %sx%s is too small.'
                 % (cols, rows))
        if fill_rows > rows:
            string = 'Can not fill more rows than actual rows ' + \
                'exist. fill_rows=%s rows=%s'
            raise ValueError(string % (fill_rows, rows))
        self.cols = cols
        self.rows = rows
        self.values = [5, 6, 11, 19, 20]
        self.make_grid(fill_rows)

    def __str__(self):
        output = []
        for row in self.transposed_grid:
            s = '| '
            for node in row:
                s += str(node) + ' | '
            output.append(s)
        return '\n'.join(output)

    def make_grid(self, fill_rows=None):
        # grid is 2d array as x, y ie [x][y].
        # transposed_grid is 2d array as y, x ie [y][x]
        self.transposed_grid = []
        for row_num in range(self.rows):
            if fill_rows is None:
                values = self.values
            elif row_num < self.rows - fill_rows:
                values = [0, ]
            else:
                values = self.values
            row = [GameTile(col_num, row_num, values)
                for col_num in range(self.cols)]
            self.transposed_grid.append(row)
        self.grid = list(zip(*self.transposed_grid))

    def draw(self):
        print(self)

    def draw_by_id(self):
        # Why does this one use self.transposed_grid instead of self.grid ?
        output = []
        for row in self.transposed_grid:
            s = '| '
            for node in row:
                s += str(node.id) + ' | '
            output.append(s)
        return '\n'.join(output)

    def draw_by_id_proc(self):
        # Draw Procedurally
        output = []
        for row_num in range(self.rows):
            s = '| '
            for col_num in range(self.cols):
s += (str(self.grid[col_num][row_num].id) + '(' + str(col_num) +
                    ',' + str(row_num) + ')' + ' | ')
            output.append(s)
        return '\n'.join(output)

    def draw_by_id_trans(self):
        # Why does this one use self.grid instead of self.transposed_grid ?
        output = []
        for col in self.grid:
            s = '| '
            for node in col:
                s += str(node.id) + ' | '
            output.append(s)
        return '\n'.join(output)

    def draw_by_id_trans_proc (self):
        # Draw Transposed & Procedurally
        output = []
        for col_num in range(self.cols):
            s = '| '
            for row_num in range(self.rows):
s += (str(self.transposed_grid[row_num][col_num].id) + '(' +
                    str(col_num) + ',' + str(row_num) + ')' + ' | ')
            output.append(s)
        return '\n'.join(output)

    def find_eliminations(self):
        #First Down the columns.
        i = 0
        for col_list in self.grid:
            while True:
                try:
                    if self.check_total(col_list[i: i + 3]):
                        self.eliminate(col_list[i: i + 3])
                    i += 1
                except ValueError:
                    i = 0
                    break
        # Now across the rows.
        for row_list in self.transposed_grid:
            while True:
                try:
                    if self.check_total(row_list[i: i + 3]):
                        self.eliminate(row_list[i: i + 3])
                    i += 1
                except ValueError:
                    i = 0
                    break
        # Set all eliminated nodes to a value of 0.
        for col in self.transposed_grid:
            for node in col:
                if node.eliminated is True:
                    node.eliminated = False
                    node.value = 0

    def check_total(self, slices):
        first, second, third = slices
        if first.value == second.value or second.value == third.value:
            total = first.value + second.value + third.value
            return total in (17, 21, 28, 29, 31, 42, 45, 46, 49, 58)

    def eliminate(self, slices):
        first, second, third = slices
        first.eliminated = True
        second.eliminated = True
        third.eliminated = True

    def drop_nodes(self):
        i = self.rows
# first_zero_row serves as memory for how far to drop non-zero values
        first_zero_row = None
        for col_list in self.grid:
            while True:
# Low is on Top it is low because it is the lower numbered row # High is on Bottom it is high because it is the higher numbered
                low, high = col_list[i - 2: i]  # Goes Up the Rows
                if high.value == 0:
                    if low.value != 0:
                        if first_zero_row is None:
                            high.value = low.value
                            low.value = 0
                            first_zero_row = low
                        else:
                            first_zero_row.value = low.value
                            low.value = 0
                            row = first_zero_row.row - 1
                            col = first_zero_row.col
                            first_zero_row = self.grid[col][row]
                    else:
                        if first_zero_row is None:
                            first_zero_row = high
                i -= 1
                if i == 1:
                    i = self.rows
                    first_zero_row = None
                    break

    def invert_drop_nodes(self):
        i = 0
# first_zero_row serves as memory for how far to drop non-zero values
        first_zero_row = None
        for col_list in self.grid:
            while True:
# Low is on Top it is low because it is the lower numbered row # High is on Bottom it is high because it is the higher numbered
                low, high = col_list[i: i + 2]  # Goes Down the Rows
                if low.value == 0:
                    if high.value != 0:
                        if first_zero_row is None:
                            low.value = high.value
                            high.value = 0
                            first_zero_row = high
                        else:
                            first_zero_row.value = high.value
                            high.value = 0
                            row = first_zero_row.row + 1
                            col = first_zero_row.col
                            first_zero_row = self.grid[col][row]
                    else:
                        if first_zero_row is None:
                            first_zero_row = low
                i += 1
                if i == self.rows - 1:
                    i = 0
                    first_zero_row = None
                    break

    def pull_nodes(self):
        i = self.cols
# first_zero_row serves as memory for how far to drop non-zero values
        first_zero_row = None
        for row_list in self.transposed_grid:
            while True:
# Low is on Top it is low because it is the lower numbered row # High is on Bottom it is high because it is the higher numbered
                low, high = row_list[i - 2: i]  # Goes Up the Columns
                if high.value == 0:
                    if low.value != 0:
                        if first_zero_row is None:
                            high.value = low.value
                            low.value = 0
                            first_zero_row = low
                        else:
                            first_zero_row.value = low.value
                            low.value = 0
                            try:
row = first_zero_row.row - 1 # Testing Here
                                col = first_zero_row.col  # Or Here?
first_zero_row = self.transposed_grid[col][row]
                            except:
                                i = self.cols
                                print('broke', col, row)
print(first_zero_row.col, first_zero_row.row)
                                first_zero_row = None
                                break
                    else:
                        if first_zero_row is None:
                            first_zero_row = high
                i -= 1
                if i == 1:
                    i = self.cols
                    first_zero_row = None
                    break

    def invert_pull_nodes(self):
        i = 0
# first_zero_row serves as memory for how far to drop non-zero values
        first_zero_row = None
        for row_list in self.transposed_grid:
            while True:
# Low is on Top it is low because it is the lower numbered row # High is on Bottom it is high because it is the higher numbered
                low, high = row_list[i: i + 2]  # Goes Down the Columns
                if low.value == 0:
                    if high.value != 0:
                        if first_zero_row is None:
                            low.value = high.value
                            high.value = 0
                            first_zero_row = high
                        else:
                            first_zero_row.value = high.value
                            high.value = 0
                            try:
                                row = first_zero_row.row  # Testing Here
                                col = first_zero_row.col + 1  # Or Here?
first_zero_row = self.transposed_grid[col][row]
                            except:
                                i = 0
                                print('broke', col, row)
print(first_zero_row.col, first_zero_row.row)
                                first_zero_row = None
                                break
                    else:
                        if first_zero_row is None:
                            first_zero_row = low
                i += 1
                if i == self.cols - 1:
                    i = 0
                    first_zero_row = None
                    break


grid = GameGrid(4, 8, 6)
print(grid)
grid.find_eliminations()
print('After Eliminations')
print(grid)
grid.drop_nodes()
print('After Drops')
print(grid)
grid.invert_drop_nodes()
print('Reverse Gravity aka Inverted')
print(grid)
#grid.pull_nodes()
#print('Pull Nodes')
#print(grid)
#grid.invert_pull_nodes()
#print('Invert Pull Nodes')
#print(grid)
print(grid.draw_by_id())

_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to