En este tutorial Desarrollaremos un bingo para un solo usuario utilizando sessiones para guardar el progreso de la partida
Creamos la Aplicacion
rails bingo
Ahora metemos en en la carpeta \app\models las clase Bingo.rb y Carton.rb
class Bingo
attr_accessor :bombo
attr_accessor :mesa
def initialize
@bombo=Array.new
@mesa=Array.new
(0…80).each {|x| @bombo[x]= true}
end
# Devuelve un numero aleatorio y Apunta que salio
def canta
num= rand(80)+1
until self.bombo[num]
num= rand(80)
end
self.bombo[num] = false
mesa << num
num
end
def bombo_vacio?
res=false
self.bombo.each {|x| res=true if x}
res
end
def ver_bolas
@mesa.sort
end
end
class Carton
attr_accessor :carton
attr_accessor :lineas_cantadas
def initialize
numeros=Array.new
while numeros.size < 15 #Genera 15 Numeros Unicos
numeros<< rand(79)+1
numeros.uniq!
end
numeros.sort! # Los Ordena
carton=Array.new
(0…3).each do |y| # Los deordena de Arriba a Abbajo y de Izquierda a Dedecha
fila=Array.new
(0…5).each do |x|
fila[x]= numeros[x*3+y]
end
carton[y]= fila
end
@carton=carton
@lineas_cantadas= Array.new
(0…3).each do|x| # Define que no se han cantado Lineas
@lineas_cantadas[x]=false
end
end
def recorrer
self.carton.each_index do |nlinea|
self.carton[nlinea].each_index do |num|
yield(nlinea,num)
end
end
end
def tachar_numero(num)
res=false
self.recorrer do |x,y|
if self.carton[x][y]==num
self.carton[x][y]*=-1
res=true
end
end
res
end
# Devuelve si se canta linea y si se canta apunta que se canto
def es_linea?
res= false
(0…3).each do |x|
linea= true
(0…5).each do |y|
if self.carton[x][y] >0
linea=false
end
end
if linea and !self.lineas_cantadas[x]
res=true
self.lineas_cantadas[x]=true
end
end
res
end
def es_bingo?
res=true
self.recorrer { |x,y| res=false if self.carton[x][y] > 0}
res
end
end
creamos el Controlador
ruby script\generate controller bingo
Y lo Editamos
class BingoController < ApplicationController
#Pagina principal Recoge los valores de la sesion y segun Estado este
#Parado => Partida sin empezar
#Funcionando => Canta una bola y muestra el resultado
#hasta_en_fin => Juega Hasta el final y guarda lo que pasa en @mensaje
def index
@partida=busca_partida
@cartones=busca_cartones
@mensaje= Array.new
@estado=busca_estado
bolas_sacadas=0
salir=false
if @estado != “parado”
while (@estado == “hasta_el_fin” or bolas_sacadas==0) and !salir
@bola= @partida.canta
@bolas=@partida.ver_bolas
bolas_sacadas+=1
@cartones.each do|c|
n_carton= @cartones.index(c)
if c.tachar_numero(@bola)
@mensaje << “Se Tacha el numero #@bola en el carton numero #{n_carton}”
if c.es_linea?
@mensaje << “Cantas Linea en el carton numero #{n_carton}”
if c.es_bingo?
@mensaje << “El Carton numero #{n_carton} ha Hecho Bingo”
@mensaje << “Ha necesitado #{bolas_sacadas} Bolas”
salir=true
session[:cartones]=nil
session[:partida]=nil
session[:estado]=nil
break
end
end
end
end
end
end
end
# Añade un carton
def compra_carton
@cartones=busca_cartones
@cartones << Carton.new
session[:cartones] =@cartones
ir_a_index
end
# Solo regirige al index
def ir_a_index(msg = nil)
redirect_to :action => :index
end
# Devuelve la PARTIDA almacenados en la Session o una PARTIDA Nueva
def busca_partida
session[:partida] ||= Bingo.new
end
# Devuelve un Array con los cartones almacenados en la Session o una Array Nuevo
def busca_cartones
session[:cartones] ||= Array.new
end
# Devuelve el Estadoalmacenado en la Session o “parado” si no hay session
def busca_estado
session[:estado] ||= “parado”
end
# si esisten cartones Pones ESTADO = hasta_el_fin
def hasta_el_fin
@cartones=busca_cartones
session[:estado] = “funcionando” if @cartones.size>0
session[:estado] = “hasta_el_fin”
ir_a_index
end
# Si esisten cartones Pones ESTADO = “funcionando”
def empezar
@cartones=busca_cartones
session[:estado] = “funcionando” if @cartones.size>0
ir_a_index
end
end
Ya esta el programa ahora necesitamos gestionar como mostrarlo. Para lo que usaremos plantillas (Layouts) y Vistas
Primero la Plantilla, creamos \app\views\layouts\bingo.html.erb
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” xml:lang=”en” lang=”en”>
<head>
<meta http-equiv=”content-type” content=”text/html;charset=UTF-8″ />
<title>Productos: <%= controller.action_name %></title>
<%= stylesheet_link_tag ‘bingo’ %>
<%= javascript_include_tag :defaults %>
</head>
<body>
<h1>Bingo</h1>
<div id=”all”>
<div id=”cabecera”>
<h2>BINGO SOBRE RAILES</h2>
</div>
<div id=”izquierda”>
<h2>Numeros Cantados</h2>
<ul>
<%= render(:partial => “bolas”,
bject => @bolas) %>
</ul>
</div>
<div id=”contenedor”>
<div id=”centro”>
<%= yield %>
</div>
<div id=”derecha”>
<ul>
<li><%= button_to “Comprar Carton” , :action => :compra_carton %></li>
<li><%= button_to “Empezar”, :action => :empezar %></li>
<li><%= button_to “Ir al Final” , :action => :hasta_el_fin %></li>
</ul>
</div>
</div>
</div>
</body>
</html>
Ahora las Vistas:
\app\views\bingo\index.html.erb es la vista de la Accion index
<div class=”cartones”>
<% if @cartones.size>0 %>
<% @cartones.each do |c| %>
<div class=”carton”>
<table>
<% c.carton.each do |linea|%>
<tr>
<% linea.each do |num|%>
<td <%= ‘class=”tachado”‘ if num >0 %>> <%= ” #{num.abs} ” %></td>
<% end %>
</tr>
<% end%>
</table>
</div>
<% end %>
<% else %>
<h2>Bienvenido a Bingo sobre Railes </h2>
<h3>compra uno o mas cartones y dale a empezar</h3>
<% end %>
</div>
<% if @bola %>
<div id=”pantalla”>
<p><%= @bola %></p>
<% if @mensaje %>
<ul>
<% @mensaje.each do |m| %>
<li><%= h(m) %></li>
<% end %>
</ul>
<% end %>
</div>
<% end %>
\app\views\bingo\_bolas.html.erb es llamada desde la plantilla con <%= render(:partial => “bolas”,
bject => @bolas) %>
<ul>
<% if @bolas %>
<% @bolas.each do |bola_salida| %>
<li><%= bola_salida %></li>
<% end %>
<% end %>
</ul>
Por ultimo podemos darle Estilos con \public\stylesheets\bingo.css
BODY{ padding: 1em 1%; text-align:center;}
H1{display:none;}
UL{
list-style:none;
padding:0px;
margin:0px;
}
#all
{
width: 100%;
}
#cabecera
{
padding:0.4em 0%;
margin: 0em 0% 0.2em;
background:#CCCCCC;
}
#izquierda
{
float:left;
width: 20%;
background:#FFFFCC;
}
#contenedor
{
float:left;
width:80%;
}
#centro
{
float:left;
width:70%;
}
#derecha
{
float:right;
width:28%;
padding: 1em 0% 1em 0%;
background:#FFFFCC;
}
#derecha INPUT
{
width:70%;
padding: 0.3em 5%;
margin: 0.3em auto;
}
.carton
{
width:23%;
float:left;
padding: 0.5em 0.5%;
margin: 0.5em 0.5%;
background:#FFCC99;
}
.carton TABLE
{
width:90%;
margin:auto;
}
.carton TABLE TD{color:#009900 ;}
.carton TABLE TD.tachado{color: #990000 ;}
#pantalla{ clear:both;}
#pantalla P
{
width: 4em;
font-size:2em;
padding: 0.5em;
background:#99FFFF;
margin:auto;
}


