Still fairly new to Rails. Working on a group project to build a chess app we've got everything working except for a transaction rollback in our checkmate? method.
Moves are saved directly to the database. Then, our check? method queries the database to see if the king is in check. This created a problem for us for two reasons - 1. if you move yourself into check the move has to be undone 2. to determine checkmate you need to move pieces on the board and see if the king is still in check. We implemented transactions for problem 1. and it works fine.
However, for checkmate the first thing we check is to see if the king can move himself out of check. This method runs through the 9 squares the king might occupy to see if any of them successfully move him out of check. I know the method is a bit sloppy now, but we're trying to get it to work then we can refactor.
Our goal is to move the king, see if it gets him out of check, then rollback the move. The rollback should happen every time but the rollback never occurs.
# determine if king can move himself out of check
def can_move_out_of_check?
success = false
y_start = y_position
((x_position - 1)..(x_position + 1)).each do |x|
((y_start - 1)..(y_start + 1)).each do |y|
Piece.transaction do
move_to(x, y) if valid_move?(x, y)
# if game.check?(color) comes up false,
# even once, assign true
success = true unless game.check?(color)
# reset any attempted moves
fail ActiveRecord::Rollback
end
end
end
success
end
I've tried different options King.transaction
ActiveRecord::Base.transaction
. Per one suggestion I tried ActiveRecord::Base.transaction(require_new: true)
which rolled back on each check but also wouldn't allow me to make a valid move when the king was in check.
I feel like I'm missing something really simple.