I am trying to solve a basic puzzle by using Google OR-Tools, this is my first try with OR-Tools and I am trying to learn. I completed almost everything and was ready to conclude the program until I came across this problem.
For information my
game_board is a dictionary including entire board, with already given values and not given values that are set to
I have several values in each cell as following:
- Variable, cell is set as
IntVarwhich were initially 0 in board, so it will be determined to be filled or not, values are 0 for empty, 1 for filled)
- 8, the cell is free connection, indicating this is just a virtual cell added to represent the game in a matrix so cell above this, is connected to cell below it directly
- 9, the cell is a solid block, so it separates its above and below cells.
What I do is, I iterate over the board and I am try to fill water according to gravity (and some other rules), so I assigned A cell should be equal to the cell below it if there is no block between them. However I forgot that, cell below can be full and the cell above can be empty, however with the constraint set above they can only be equal.
I used the part below the set the constraint mentioned above and I have 2 problems at this point.
if (row+1 <= max(row_variable_indices)) and (game_board[(row+1,column)] == 8): if (game_board[(row+1,column)] == -1): model.Add(game_board[(row,column)] == game_board[(row+1,column)]) else: model.Add(game_board[(row,column)] == game_board[(row+2,column)])
I overcame this by other methods, but still wanted to ask how can I differentiate
IntVarfrom something else. I can not differentiate
IntVar == Intor
IntVar != Intsince thety both return
Truefor any given
Int. So I checked if cell is equal to 8 first, if cell is 8 then cell is either a free connection or a variable, and then I checked if cell is -1 as -1 is not used in the board anywhere, it would only choose the variables.
My main problem is I need to change this constraint to A cell should be equal to the cell below it if there is no block between them and the cell below is assigned to 0. I tried doing it
.OnlyEnforceIf()by something like following, but it didn't work and gave following error. How can I solve this. I understand I need to use
BoolVarhowever I am not sure how to set a
BoolVarfor this condition (and for every other cell I have) because if I can not say if a variable A is set to value x, I can not set the bool based on if A is set to x either
model.Add(game_board[(row,column)] == game_board[(row+1,column)]).OnlyEnforceIf(game_board[(row+1,column)] == 1)
Note I actually tried it on some dummy matrix as following:
/usr/local/lib/python3.6/dist-packages/ortools/sat/python/cp_model.py in OnlyEnforceIf(self, boolvar) 607 self.__constraint.enforcement_literal.append(b.Index()) 608 else: --> 609 self.__constraint.enforcement_literal.append(boolvar.Index()) 610 return self 611 AttributeError: 'BoundedLinearExpression' object has no attribute 'Index'
Edited to add that, I can not change (or I don't know if I can) my
IntVar variables to
BoolVar variables and check this filling problem, because I also use
sum() somewhere else counting the filled cells of that row/column by adding up the all
IntVar variables of that row/column. I don't think it works in
BoolVar as they don't have a value to be summed up unlike integer value of
IntVar which is summable.