Reputation: 149
I am building a tic-tac-toe game on RoR. At the moment, the whole board is set up, with a form below it that tracks the moves. I have been told to use the model to figure out such things as if there is a winner(3 in a row), a tie(full board), etc. I thought I had it, but apparently not. Not sure what I'm doing wrong with the players
method in the model.
show.html.erb
:
<div id="board" align = center>
<table>
<tr>
<td data-position="0" class="square <%= class_for_move(0)%>"></td>
<td data-position="1" class="square v <%= class_for_move(1)%>"></td>
<td data-position="2" class="square <%= class_for_move(2)%>"></td>
</tr>
<tr>
<td data-position="3" class="square h <%= class_for_move(3)%>"></td>
<td data-position="4" class="square v h <%= class_for_move(4)%>"></td>
<td data-position="5" class="square h <%= class_for_move(5)%>"></td>
</tr>
<tr>
<td data-position="6" class="square <%= class_for_move(6)%>"></td>
<td data-position="7" class="square v <%= class_for_move(7)%>"></td>
<td data-position="8" class="square <%= class_for_move(8)%>"></td>
</tr>
</table>
</div>
<table>
<tr>
<td><%= @game.player_1 %></td>
<td><%= @game.player_2 %></td>
</tr>
<tr>
<td>X</td>
<td>O</td>
</tr>
</table>
<%= link_to "Play Again", games_path %>
<%= nested_form_for @game do |f| %>
<%= f.fields_for :moves do |move_form| %>
<div id="table" data-current-player="<%=session[:current_player] %>">
<%= move_form.label :position %><br>
<%= move_form.text_field :player, data: {position: move_form.object.position} %>
<%= move_form.hidden_field :id %>
</div>
<% end %>
<input type="Submit">
<% end %>
game.rb
:
class Game < ActiveRecord::Base
has_many :moves
after_create :initialize_moves
accepts_nested_attributes_for :moves
def initialize_moves
9.times do |i|
Move.create(position: i, game:self)
end
end
def players(number)
move = moves.find_by(position: number)
player = move.player
end
def tie?
end
def winner?
if players(0) == players(1) && players(1) == players(2)
return players(0)
end
end
end
games_controller
:
class GamesController < ApplicationController
def create
@game = Game.new(game_params)
@game.save
redirect_to @game
end
def update
@game = Game.find(params[:id])
@game.update(game_params)
if @game.tie?
flash[:error] = "Game over. 'Tis a tie."
elsif @game.winner?
flash[:notice] = "Winner is #{session[:current_player]}"
else
switch_player
end
redirect_to @game
end
def show
@game = Game.find(params[:id])
end
def switch_player
session[:current_player] = session[:current_player] == "X" ? "O" : "X"
end
private
def game_params
params.require(:game).permit(:player_1, :player_2, moves_attributes: [:player, :id])
end
end
When I run what I have at the moment, the game plays out until I have a three-in-a-row(only doing slots 0,1,2 as test at the moment), switching players and acting normal. The moment the three-in-a-row is true, it stays on whatever the current player is, and won't switch. It's not ending the game, or giving me the flash notice. Just sticks to the current player. Same goes with if I try to add an elsif trying to put in another winning position combo.
I realize this is probably elementary level stuff, but I just cannot seem to wrap my head around it, and haven't found anything useful online so far. And, if the if
statement route isn't the right way to go, I am willing to go another way. I just can't think of a different way at the moment.
Any help is much appreciated.
Upvotes: 0
Views: 53
Reputation: 149
Figured it out. Just needed to set up each combo in the winner?
method with !players(0).blank? &&
. With the respective number for each players
after ==
.
Was going to delete the question, but just in case anyone was actually curious of the answer, there it is.
Upvotes: 1