First an explanation of how the game works: The game is a simple matching game but with a twist. Instead of matching a straight 3 in a row, we have some rules that only certain combinations will result in an elimination. In general 2 of the same value in a row with with 1 of 2 other possible values will eliminate all three nodes. Eliminations can occur either horizontally or vertically but not diagonally. Each tile has a value now, that value is used when evaluating the rules. Currently there are only 5 allowed values of 0-4 although more could be added later, so any solution needs to be expandable. These are the basic rules that allow for an elimination to occur(values are put in quotes to distinguish values):
2 "5"s followed or proceeded by a "19" will eliminate all 3 nodes.
2 "5"s followed or proceeded by an "11" will eliminate all 3 nodes.
2 "6"s followed or proceeded by a "5" will eliminate all 3 nodes.
2 "6"s followed or proceeded by a "19" will eliminate all 3 nodes.
2 "11"s followed or proceeded by a "6" will eliminate all 3 nodes.
2 "11"s followed or proceeded by a "20" will eliminate all 3 nodes.
2 "19"s followed or proceeded by a "20" will eliminate all 3 nodes.
2 "19"s followed or proceeded by an "11" will eliminate all 3 nodes.
2 "20"s followed or proceeded by a "6" will eliminate all 3 nodes.
2 "20"s followed or proceeded by a "5" will eliminate all 3 nodes.

The main focus of the code is the find_eliminations method. I think its implementation is smart since it uses a math trick, but then again I wrote it. My math trick works by first finding 2 matching nodes next to each other out of every 3 nodes, then adding the values of all 3 nodes together and checking for specific totals. None of the possible totals overlap.

Here is the code:

import random


class GameTile():
    def __init__(self, value, col, row, **kwargs):
        # id is grid (X,Y) which is equal to grid (col,row)
        self.id = str(col) + ',' + str(row)
        self.col = col
        self.row = row
        self.value = value
        self.eliminated = False

    def __str__(self):
        #return '%d, %d' % (self.col, self.row)
        if len(str(self.value)) == 1:
            return ' ' + str(self.value)
        return str(self.value)


class GameGrid():
    def __init__(self, cols=8, rows=7, **kwargs):
        self.cols = cols
        self.rows = rows
        self.make_grid()

    def make_grid(self):
        # grid is 2d array as x, y ie [x][y].
        self.grid = []
        for row_num in range(self.rows):
self.grid.append([GameTile(value=random.choice([5, 6, 11, 19, 20]), col=col_num,
                row=row_num) for col_num in range(self.cols)])

    def print_by_col(self):
        # As in going down the column assuming we started at the top.
        for col_num in range(self.cols):
            for row_list in self.grid:
                print(row_list[col_num])

    def print_by_row(self):
        # As in going right across the row assuming we started at the left.
        for row in self.grid:
            for node in row:
                print(node)

    def check_bounds(self, x, y):
        return (0 <= x < self.rows) and (0 <= y < self.cols)

    def lookup_node(self, x, y):
        if not self.check_bounds(x, y):
            return False
        return self.grid[x][y]

    def draw(self):
        for col in self.grid:
            print(end='| ')
            for node in col:
                print(node, end=' | ')
            print()

    def find_eliminations(self):
        # I define 3 variables for holding the 3 nodes/tiles that I am
        # currently checking to see if an elimination possibility exists.
# It uses a math trick to check for elimination by adding the values # and checking for specific totals. None of the possible totals overlap.
        #First Down the columns.
        for col_num in range(self.cols):
            first = None
            second = None
            third = None
            for row_list in self.grid:
                if row_list[col_num].row == 0:
                    first = row_list[col_num]
                elif row_list[col_num].row == 1:
                    second = row_list[col_num]
                elif row_list[col_num].row == 2:
                    third = row_list[col_num]
                else:
                    first = second
                    second = third
                    third = row_list[col_num]
                if third is not None:
                    self.check_total_and_eliminate(first, second, third)
        # Now across the rows.
        for row in self.grid:
            first = None
            second = None
            third = None
            for node in row:
                if node.col == 0:
                    first = node
                elif node.col == 1:
                    second = node
                elif node.col == 2:
                    third = node
                else:
                    first = second
                    second = third
                    third = node
                if third is not None:
                    self.check_total_and_eliminate(first, second, third)
        # Set all eliminated nodes to a value of 0.
        for col in self.grid:
            for node in col:
                if node.eliminated is True:
                    node.eliminated = False
                    node.value = 0

    def check_total_and_eliminate(self, first, second, third):
        total = None
        if first.value == second.value:
            total = first.value + second.value + third.value
        elif second.value == third.value:
            total = first.value + second.value + third.value
        if total == 17 or total == 21 or total == 28 or total == 29 or \
            total == 31 or total == 42 or total == 45 or total == 46 \
            or total == 49 or total == 58:
            first.eliminated = True
            second.eliminated = True
            third.eliminated = True



grid = GameGrid(4, 8)
grid.draw()
grid.find_eliminations()
print('After Eliminations')
grid.draw()


# END CODE

After this part has been improved, I then need to search the columns backwards to be able to drop any floating values. Any none zero values should not have a zero value below it. That is what I mean by drop floating values. I think this will be simple by just using range method to count backwards. I will be working on coding that in the meantime.
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to